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 783fda7

Browse filesBrowse files
committed
[Validator] Add a constraint to sequentially validate a set of constraints
1 parent df3759b commit 783fda7
Copy full SHA for 783fda7

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
@@ -62,6 +62,7 @@ Validation Constraints Reference
6262
constraints/Isbn
6363
constraints/Issn
6464

65+
constraints/Sequentially
6566
constraints/Callback
6667
constraints/Expression
6768
constraints/All
+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 collection of rules that should be
5+
validated step-by-step, allowing to interrupt the validation of further ones
6+
in the collection once the first violation is raised.
7+
8+
It's a simpler, but less powerful alternative to :doc:`GroupSequence</validation/sequence_provider>`.
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 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
@@ -83,6 +83,7 @@ Financial and other Number Constraints
8383
Other Constraints
8484
~~~~~~~~~~~~~~~~~
8585

86+
* :doc:`Sequentially </reference/constraints/Sequentially>`
8687
* :doc:`Callback </reference/constraints/Callback>`
8788
* :doc:`Expression </reference/constraints/Expression>`
8889
* :doc:`All </reference/constraints/All>`

‎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+
In most simple cases, 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 simpler 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.