You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reimplements the `Valid` constraint in the Symfony Validator component as `Cascade` annotation which is much more straightforward to use and has no surprising behavior.
6
+
Reimplements the `Valid` constraint in the Symfony Validator component as `Cascade` annotation which is more straightforward to use and has no surprising behavior.
7
7
8
8
Installation
9
9
------------
10
10
11
11
composer require squirrelphp/validator-cascade
12
12
13
+
Table of contents
14
+
-----------------
15
+
16
+
-[Usage](#usage)
17
+
-[Example](#example)
18
+
-[Why not use the Valid constraint?](#why-not-use-the-valid-constraint)
19
+
13
20
Usage
14
21
-----
15
22
16
-
`Cascade` makes sure an object (or an array of objects) are validated, so it cascades validation.
23
+
`Cascade` makes sure an object or an array of objects are validated, so it cascades validation.
17
24
18
25
There are only two options:
19
26
20
-
-`groups` defines to which validation groups the `Cascade` constraint belongs to, with the same behavior as any regular validator constraint. If you do not define `groups` it is set to `Default` and the`Cascade` constraint is only executed if one of the validation groups matches.
27
+
-`groups` defines to which validation groups the `Cascade` constraint belongs to, with the same behavior as any regular validator constraint. If you do not define `groups` it is set to `Default`. The`Cascade` constraint is only executed if one of the validation groups matches.
21
28
22
29
-`trigger` defines which validation groups to trigger on the child object(s). By default only `Default` is triggered, so if you want any other validation groups to trigger you have to specify them with `trigger`. The validation groups of the "parent" are never cascaded.
The current implementation of the `Valid` constraint in the Symfony validator component has severe limitations when it comes to validation groups and behaves differently than any other constraint:
131
+
132
+
### `Valid` constraint without validation group
133
+
134
+
```php
135
+
/**
136
+
* @Assert\Valid()
137
+
*/
138
+
public $someobject;
139
+
```
140
+
141
+
The above code looks like a regular assertion, but it behaves differently:
142
+
143
+
- The assertion is always executed, no matter what validation group you give to the validator
144
+
- The assertion therefore does not belong to the "Default" group
145
+
146
+
This is fine for simple objects or when you don't need any validation groups at all, but it is still different from any other assertion, as you cannot "skip" this constraint even if you later add validation groups.
147
+
148
+
### `Valid` constraint with validation group(s)
149
+
150
+
```php
151
+
/**
152
+
* @Assert\Valid(groups={"invoice"})
153
+
*/
154
+
public $someobject;
155
+
```
156
+
157
+
The `Valid` assertion above only triggers when you validate the "invoice" validation group, which is what you would expect. Yet there is plenty of other unexpected behavior:
158
+
159
+
- It only triggers the validation group "invoice" in $someobject, no other validation groups are passed to the object (if, for example, you are validating the groups "Default" and "invoice" the group "Default" never reaches $someobject, only "invoice")
160
+
- There is no way to change which validation groups are triggered in $someobject
161
+
- There is a "traverse" option for `Valid` which is not used when defining a validation group. Although the "traverse" option seems a bit exotic anyway, it is another behavior change
162
+
163
+
Having validation groups both as a trigger and as a filter severly limits how you can use it, and makes most use cases (like our example with addresses) impossible to do with `Valid`. Even if you manage to make it work, your options will not be self explanatory and it is easy to make mistakes.
164
+
165
+
`Cascade` as defined in this component separates which validation group the constraint belongs to and which validation groups are triggered in the child object(s). What it cannot do is cascade the validation groups of the parent to the child object, as this information is only available in the `RecursiveContextualValidator` class of the validator component and cannot be accessed without changing a lot of the internals of the validator component.
0 commit comments