|
| 1 | +Squirrel Validator Cascade |
| 2 | +========================== |
| 3 | + |
| 4 | +[](https://travis-ci.com/squirrelphp/validator-cascade) [](https://codeclimate.com/github/squirrelphp/validator-cascade/test_coverage)  [](https://packagist.org/packages/squirrelphp/validator-cascade) [](https://packagist.org/packages/squirrelphp/validator-cascade) [](LICENSE) |
| 5 | + |
| 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. |
| 7 | + |
| 8 | +Installation |
| 9 | +------------ |
| 10 | + |
| 11 | + composer require squirrelphp/validator-cascade |
| 12 | + |
| 13 | +Usage |
| 14 | +----- |
| 15 | + |
| 16 | +`Cascade` makes sure an object (or an array of objects) are validated, so it cascades validation. |
| 17 | + |
| 18 | +There are only two options: |
| 19 | + |
| 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. |
| 21 | + |
| 22 | +- `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. |
| 23 | + |
| 24 | +That is it! |
| 25 | + |
| 26 | +Example |
| 27 | +------- |
| 28 | + |
| 29 | +Belong is a common example in real applications: You might have an order and multiple possible addresses for the order (one for shipping, one for invoice) with different requirements, and some addresses should be optional, but if they are specified they should still be validated in full. |
| 30 | + |
| 31 | +`$shippingAddress` shows how to trigger specific validation groups in the child object, in this case to make the phone number a mandatory part of the information (often the case for shipping, but not necessarily for invoice or other address use) in addition to the "Default" constraints. |
| 32 | + |
| 33 | +`$invoiceAddress` is only validated if the validation group "alternateInvoiceAddress" is passed to the validator (which could be done if the user selected an option like "choose different invoice address"). The phone number is optional, as we do not pass the `trigger` option so only the Default group is validated in the Adress object. |
| 34 | + |
| 35 | +```php |
| 36 | +use Squirrel\ValidatorCascade\Cascade; |
| 37 | +use Symfony\Component\Validator\Constraints as Assert; |
| 38 | + |
| 39 | +class Order |
| 40 | +{ |
| 41 | + /** |
| 42 | + * Validate $shippingAddress if validation with no validation |
| 43 | + * group or the "Default" validation group is triggered |
| 44 | + * |
| 45 | + * Validates "Default" and "phoneNumberMandatory" validation groups in $shippingAddress |
| 46 | + * |
| 47 | + * @Assert\NotNull() |
| 48 | + * @Assert\Type(type="Address") |
| 49 | + * @Cascade(trigger={"Default", "phoneNumberMandatory"}) |
| 50 | + */ |
| 51 | + public $shippingAddress; |
| 52 | + |
| 53 | + /** |
| 54 | + * Validate $invoiceAddress only if validation group |
| 55 | + * "alternateInvoiceAddress" is passed to validator |
| 56 | + * |
| 57 | + * Validates only "Default" validation group in $invoiceAddress, so phone number is optional |
| 58 | + * |
| 59 | + * @Assert\NotNull() |
| 60 | + * @Assert\Type(type="Address") |
| 61 | + * @Cascade(groups={"alternateInvoiceAddress"}) |
| 62 | + */ |
| 63 | + public $invoiceAddress; |
| 64 | +} |
| 65 | + |
| 66 | +class Address |
| 67 | +{ |
| 68 | + /** |
| 69 | + * @Assert\NotNull() |
| 70 | + * @Assert\NotBlank() |
| 71 | + * @Assert\Length( |
| 72 | + * min = 1, |
| 73 | + * max = 50 |
| 74 | + * ) |
| 75 | + * |
| 76 | + * @var string |
| 77 | + */ |
| 78 | + public $street = ''; |
| 79 | + |
| 80 | + /** |
| 81 | + * @Assert\NotNull() |
| 82 | + * @Assert\NotBlank() |
| 83 | + * @Assert\Length( |
| 84 | + * min = 1, |
| 85 | + * max = 50 |
| 86 | + * ) |
| 87 | + * |
| 88 | + * @var string |
| 89 | + */ |
| 90 | + public $city = ''; |
| 91 | + |
| 92 | + /** |
| 93 | + * @Assert\NotNull(groups={"phoneNumberMandatory"}) |
| 94 | + * @Assert\NotBlank(groups={"phoneNumberMandatory"}) |
| 95 | + * @Assert\Length( |
| 96 | + * min = 1, |
| 97 | + * max = 50 |
| 98 | + * ) |
| 99 | + * |
| 100 | + * @var string |
| 101 | + */ |
| 102 | + public $phoneNumber = ''; |
| 103 | +} |
| 104 | + |
| 105 | +$order = new Order(); |
| 106 | +$order->shippingAddress = new Address(); |
| 107 | +$order->invoiceAddress = new Address(); |
| 108 | + |
| 109 | +// This validates with the "Default" validation group, |
| 110 | +// so only shippingAddress must be specified |
| 111 | +$symfonyValidator->validate($order); |
| 112 | + |
| 113 | +// This also validates the invoice address |
| 114 | +$symfonyValidator->validate($order, null, [ |
| 115 | + "Default", |
| 116 | + "alternateInvoiceAddress", |
| 117 | +]); |
| 118 | +``` |
0 commit comments