Skip to content

Commit ee8f431

Browse files
committed
[Validator] Allow to define a reusable set of constraints
1 parent df3759b commit ee8f431

File tree

4 files changed

+129
-0
lines changed

4 files changed

+129
-0
lines changed

reference/constraints.rst

Lines 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/Compound
6566
constraints/Callback
6667
constraints/Expression
6768
constraints/All

reference/constraints/Compound.rst

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
Compound
2+
========
3+
4+
.. versionadded:: 5.1
5+
6+
The :class:`Symfony\\Component\\Validator\\Constraints\\Compound` class was
7+
introduced in Symfony 5.1.
8+
9+
To the contrary to the other constraints, this constraint cannot be used on its own.
10+
Instead, it allows you to create your own set of reusable constraints, representing
11+
rules to use consistently across your application, by extending the constraint.
12+
13+
========== ===================================================================
14+
Applies to :ref:`class <validation-class-target>` or :ref:`property or method <validation-property-target>`
15+
Options - `groups`_
16+
- `payload`_
17+
Class :class:`Symfony\\Component\\Validator\\Constraints\\Compound`
18+
Validator :class:`Symfony\\Component\\Validator\\Constraints\\CompoundValidator`
19+
========== ===================================================================
20+
21+
Basic Usage
22+
-----------
23+
24+
Suppose that you have different places where a user password must be validated,
25+
you can create your own named set or requirements to be reused consistently everywhere:
26+
27+
.. configuration-block::
28+
29+
.. code-block:: php
30+
31+
// src/Validator/Constraints/PasswordRequirements.php
32+
namespace App\Validator\Constraints;
33+
34+
use Symfony\Component\Validator\Compound;
35+
use Symfony\Component\Validator\Constraints as Assert;
36+
37+
/**
38+
* @Annotation
39+
*/
40+
class PasswordRequirements extends Compound
41+
{
42+
protected function getConstraints(array $options): array
43+
{
44+
return [
45+
new Assert\NotBlank(),
46+
new Assert\Type('string'),
47+
new Assert\Length(['min' => 12]),
48+
new Assert\NotCompromisedPassword(),
49+
];
50+
}
51+
}
52+
53+
You can now use it anywhere you need it:
54+
55+
.. configuration-block::
56+
57+
.. code-block:: php-annotations
58+
59+
// src/User/RegisterUser.php
60+
namespace App\User;
61+
62+
use App\Validator\Constraints as AcmeAssert;
63+
64+
class RegisterUser
65+
{
66+
/**
67+
* @AcmeAssert\PasswordRequirements()
68+
*/
69+
public $password;
70+
}
71+
72+
.. code-block:: yaml
73+
74+
# config/validator/validation.yaml
75+
App\User\RegisterUser:
76+
properties:
77+
password:
78+
- App\Validator\Constraints\PasswordRequirements: ~
79+
80+
.. code-block:: xml
81+
82+
<!-- config/validator/validation.xml -->
83+
<?xml version="1.0" encoding="UTF-8" ?>
84+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
85+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
86+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
87+
88+
<class name="App\User\RegisterUser">
89+
<property name="password">
90+
<constraint name="App\Validator\Constraints\PasswordRequirements"/>
91+
</property>
92+
</class>
93+
</constraint-mapping>
94+
95+
.. code-block:: php
96+
97+
// src/Entity/User.php
98+
namespace App\DTO;
99+
100+
use App\Validator\Constraints as AcmeAssert;
101+
use Symfony\Component\Validator\Mapping\ClassMetadata;
102+
103+
class RegisterUser
104+
{
105+
public static function loadValidatorMetadata(ClassMetadata $metadata)
106+
{
107+
$metadata->addPropertyConstraint('password', new AcmeAssert\PasswordRequirements());
108+
}
109+
}
110+
111+
Options
112+
-------
113+
114+
.. include:: /reference/constraints/_groups-option.rst.inc
115+
116+
.. include:: /reference/constraints/_payload-option.rst.inc

reference/constraints/map.rst.inc

Lines 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:`Compound </reference/constraints/Compound>`
8687
* :doc:`Callback </reference/constraints/Callback>`
8788
* :doc:`Expression </reference/constraints/Expression>`
8889
* :doc:`All </reference/constraints/All>`

validation/custom_constraint.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,17 @@ then your validator is already registered as a service and :doc:`tagged </servic
181181
with the necessary ``validator.constraint_validator``. This means you can
182182
:ref:`inject services or configuration <services-constructor-injection>` like any other service.
183183

184+
Create a Reusable Set of Constraints
185+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186+
187+
.. versionadded:: 5.1
188+
189+
The :doc:`Compound constraint</reference/constraints/Compound>` was
190+
introduced in Symfony 5.1.
191+
192+
In case you need to apply some common set of constraints in different places
193+
consistently across your application, you can extend the :doc:`Compound constraint</reference/constraints/Compound>`.
194+
184195
Class Constraint Validator
185196
~~~~~~~~~~~~~~~~~~~~~~~~~~
186197

0 commit comments

Comments
 (0)