|
| 1 | +Sequentially |
| 2 | +============ |
| 3 | + |
| 4 | +This constraint allows you to apply a set of rules that should be validated |
| 5 | +step-by-step, allowing to interrupt the validation once the first violation is raised. |
| 6 | + |
| 7 | +As an alternative in situations ``Sequentially`` cannot solve, you may consider |
| 8 | +using :doc:`GroupSequence</validation/sequence_provider>` which allows more control. |
| 9 | + |
| 10 | +.. versionadded:: 5.1 |
| 11 | + |
| 12 | + The ``Sequentially`` constraint was introduced in Symfony 5.1. |
| 13 | + |
| 14 | +========== =================================================================== |
| 15 | +Applies to :ref:`property or method <validation-property-target>` |
| 16 | +Options - `constraints`_ |
| 17 | + - `groups`_ |
| 18 | + - `payload`_ |
| 19 | +Class :class:`Symfony\\Component\\Validator\\Constraints\\Sequentially` |
| 20 | +Validator :class:`Symfony\\Component\\Validator\\Constraints\\SequentiallyValidator` |
| 21 | +========== =================================================================== |
| 22 | + |
| 23 | +Basic Usage |
| 24 | +----------- |
| 25 | + |
| 26 | +Suppose that you have a ``Place`` object with an ``$address`` property which |
| 27 | +must match the following requirements: |
| 28 | +- it's a non-blank string |
| 29 | +- of at least 10 chars long |
| 30 | +- with a specific format |
| 31 | +- and geolocalizable using an external service |
| 32 | + |
| 33 | +In such situations, you may encounter three issues: |
| 34 | +- the ``Length`` or ``Regex`` constraints may fail hard with a :class:`Symfony\\Component\\Validator\\Exception\\UnexpectedValueException` |
| 35 | +exception if the actual value is not a string, as enforced by ``Type``. |
| 36 | +- you may end with multiple error messages for the same property |
| 37 | +- you may perform a useless and heavy external call to geolocalize the address, |
| 38 | +while the format isn't valid. |
| 39 | + |
| 40 | +You can validate each of these constraints sequentially to solve these issues: |
| 41 | + |
| 42 | +.. configuration-block:: |
| 43 | + |
| 44 | + .. code-block:: php-annotations |
| 45 | +
|
| 46 | + // src/Localization/Place.php |
| 47 | + namespace App\Localization; |
| 48 | +
|
| 49 | + use App\Validator\Constraints as AcmeAssert; |
| 50 | + use Symfony\Component\Validator\Constraints as Assert; |
| 51 | +
|
| 52 | + class Place |
| 53 | + { |
| 54 | + /** |
| 55 | + * @var string |
| 56 | + * |
| 57 | + * @Assert\Sequentially({ |
| 58 | + * @Assert\NotBlank(), |
| 59 | + * @Assert\Type("string"), |
| 60 | + * @Assert\Length(min=10), |
| 61 | + * @Assert\Regex(Place::ADDRESS_REGEX), |
| 62 | + * @AcmeAssert\Geolocalizable(), |
| 63 | + * }) |
| 64 | + */ |
| 65 | + public $address; |
| 66 | + } |
| 67 | +
|
| 68 | + .. code-block:: yaml |
| 69 | +
|
| 70 | + # config/validator/validation.yaml |
| 71 | + App\Localization\Place: |
| 72 | + properties: |
| 73 | + address: |
| 74 | + - Sequentially: |
| 75 | + - NotBlank: ~ |
| 76 | + - Type: string |
| 77 | + - Length: { min: 10 } |
| 78 | + - Regex: !php/const App\Localization\Place::ADDRESS_REGEX |
| 79 | + - App\Validator\Constraints\Geolocalizable: ~ |
| 80 | +
|
| 81 | + .. code-block:: xml |
| 82 | +
|
| 83 | + <!-- config/validator/validation.xml --> |
| 84 | + <?xml version="1.0" encoding="UTF-8" ?> |
| 85 | + <constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping" |
| 86 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 87 | + xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd"> |
| 88 | +
|
| 89 | + <class name="App\Localization\Place"> |
| 90 | + <property name="address"> |
| 91 | + <constraint name="Sequentially"> |
| 92 | + <constraint name="NotBlank"/> |
| 93 | + <constraint name="Type">string</constraint> |
| 94 | + <constraint name="Length"> |
| 95 | + <option name="min">10</option> |
| 96 | + </constraint> |
| 97 | + <constraint name="Regex"> |
| 98 | + <option name="pattern">/address-regex/</option> |
| 99 | + </constraint> |
| 100 | + <constraint name="App\Validator\Constraints\Geolocalizable"/> |
| 101 | + </constraint> |
| 102 | + </property> |
| 103 | + </class> |
| 104 | + </constraint-mapping> |
| 105 | +
|
| 106 | + .. code-block:: php |
| 107 | +
|
| 108 | + // src/Localization/Place.php |
| 109 | + namespace App\Localization; |
| 110 | +
|
| 111 | + use App\Validator\Constraints as AcmeAssert; |
| 112 | + use Symfony\Component\Validator\Constraints as Assert; |
| 113 | + use Symfony\Component\Validator\Mapping\ClassMetadata; |
| 114 | +
|
| 115 | + class Place |
| 116 | + { |
| 117 | + public static function loadValidatorMetadata(ClassMetadata $metadata) |
| 118 | + { |
| 119 | + $metadata->addPropertyConstraint('address', new Assert\Sequentially([ |
| 120 | + new Assert\NotBlank(), |
| 121 | + new Assert\Type("string"), |
| 122 | + new Assert\Length(['min' => 10]), |
| 123 | + new Assert\Regex(self::ADDRESS_REGEX), |
| 124 | + new AcmeAssert\Geolocalizable(), |
| 125 | + ])); |
| 126 | + } |
| 127 | + } |
| 128 | +
|
| 129 | +Options |
| 130 | +------- |
| 131 | + |
| 132 | +``constraints`` |
| 133 | +~~~~~~~~~~~~~~~ |
| 134 | + |
| 135 | +**type**: ``array`` [:ref:`default option <validation-default-option>`] |
| 136 | + |
| 137 | +This required option is the array of validation constraints that you want |
| 138 | +to apply sequentially. |
| 139 | + |
| 140 | +.. include:: /reference/constraints/_groups-option.rst.inc |
| 141 | + |
| 142 | +.. include:: /reference/constraints/_payload-option.rst.inc |
0 commit comments