Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fdd9bad

Browse filesBrowse files
committed
[Validator] Add a constraint to sequentially validate a set of constraints
1 parent 8bf1f5e commit fdd9bad
Copy full SHA for fdd9bad

File tree

4 files changed

+155
-0
lines changed
Filter options

4 files changed

+155
-0
lines changed

‎reference/constraints.rst

Copy file name to clipboardExpand all lines: reference/constraints.rst
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ Validation Constraints Reference
6363
constraints/Isbn
6464
constraints/Issn
6565

66+
constraints/Sequentially
6667
constraints/Compound
6768
constraints/Callback
6869
constraints/Expression
+142Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
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 following the requirements:
28+
- it's a non-blank string
29+
- of at least 10 chars long
30+
- matching 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 & heavy external call to the service allowing you
38+
to geolocalize the address, 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\Compound;
51+
use Symfony\Component\Validator\Constraints as Assert;
52+
53+
class Place
54+
{
55+
/**
56+
* @var string
57+
*
58+
* @Assert\Sequentially({
59+
* @Assert\NotBlank(),
60+
* @Assert\Type("string"),
61+
* @Assert\Length(min=10),
62+
* @Assert\Regex(Place::ADDRESS_REGEX),
63+
* @AcmeAssert\Geolocalizable(),
64+
* })
65+
*/
66+
public $address;
67+
}
68+
69+
.. code-block:: yaml
70+
71+
# config/validator/validation.yaml
72+
App\Localization\Place:
73+
properties:
74+
address:
75+
- Sequentially:
76+
- NotBlank: ~
77+
- Type: string
78+
- Length: { min: 10 }
79+
- Regex: !php/const Place::ADDRESS_REGEX
80+
- App\Validator\Constraints\Geolocalizable: ~
81+
82+
.. code-block:: xml
83+
84+
<!-- config/validator/validation.xml -->
85+
<?xml version="1.0" encoding="UTF-8" ?>
86+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
87+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
88+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
89+
90+
<class name="App\Localization\Place">
91+
<property name="address">
92+
<constraint name="Sequentially">
93+
<constraint name="NotBlank"/>
94+
<constraint name="Type">string</constraint>
95+
<constraint name="Length">
96+
<option name="min">10</option>
97+
</constraint>
98+
<constraint name="Regex">
99+
<option name="pattern">/address-regex/</option>
100+
</constraint>
101+
<constraint name="App\Validator\Constraints\Geolocalizable"/>
102+
</constraint>
103+
</property>
104+
</class>
105+
</constraint-mapping>
106+
107+
.. code-block:: php
108+
109+
// src/Localization/Place.php
110+
namespace App\Localization;
111+
112+
use App\Validator\Constraints as AcmeAssert;
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

‎reference/constraints/map.rst.inc

Copy file name to clipboardExpand all lines: reference/constraints/map.rst.inc
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Financial and other Number Constraints
8484
Other Constraints
8585
~~~~~~~~~~~~~~~~~
8686

87+
* :doc:`Sequentially </reference/constraints/Sequentially>`
8788
* :doc:`Compound </reference/constraints/Compound>`
8889
* :doc:`Callback </reference/constraints/Callback>`
8990
* :doc:`Expression </reference/constraints/Expression>`

‎validation/sequence_provider.rst

Copy file name to clipboardExpand all lines: validation/sequence_provider.rst
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,3 +355,14 @@ provides a sequence of groups to be validated:
355355
// ...
356356
}
357357
}
358+
359+
How to Sequentially Apply Constraints on a Single Property
360+
==========================================================
361+
362+
Sometimes, you may want to apply constraints sequentially on a single
363+
property. The :doc:`Sequentially constraint</reference/constraints/Sequentially>`
364+
can solve this for you in a more straightforward way than using a ``GroupSequence``.
365+
366+
.. versionadded:: 5.1
367+
368+
The ``Sequentially`` constraint was introduced in Symfony 5.1.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.