Skip to content

Commit c149e26

Browse files
committed
Improve documentation
1 parent d72bdfd commit c149e26

1 file changed

Lines changed: 51 additions & 4 deletions

File tree

README.md

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,28 @@ Squirrel Validator Cascade
33

44
[![Build Status](https://img.shields.io/travis/com/squirrelphp/validator-cascade.svg)](https://travis-ci.com/squirrelphp/validator-cascade) [![Test Coverage](https://api.codeclimate.com/v1/badges/e056be025c6db0eb31f1/test_coverage)](https://codeclimate.com/github/squirrelphp/validator-cascade/test_coverage) ![PHPStan](https://img.shields.io/badge/style-level%207-success.svg?style=flat-round&label=phpstan) [![Packagist Version](https://img.shields.io/packagist/v/squirrelphp/validator-cascade.svg?style=flat-round)](https://packagist.org/packages/squirrelphp/validator-cascade) [![PHP Version](https://img.shields.io/packagist/php-v/squirrelphp/validator-cascade.svg)](https://packagist.org/packages/squirrelphp/validator-cascade) [![Software License](https://img.shields.io/badge/license-MIT-success.svg?style=flat-round)](LICENSE)
55

6-
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.
77

88
Installation
99
------------
1010

1111
composer require squirrelphp/validator-cascade
1212

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+
1320
Usage
1421
-----
1522

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.
1724

1825
There are only two options:
1926

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.
2128

2229
- `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.
2330

@@ -115,4 +122,44 @@ $symfonyValidator->validate($order, null, [
115122
"Default",
116123
"alternateInvoiceAddress",
117124
]);
118-
```
125+
```
126+
127+
Why not use the `Valid` constraint?
128+
-----------------------------------
129+
130+
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

Comments
 (0)