Skip to content

Commit 62eb70b

Browse files
committed
[Validator] Add the Conditional constraint and validator docs
1 parent 93fd497 commit 62eb70b

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed

reference/constraints.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Validation Constraints Reference
7171
constraints/Compound
7272
constraints/Callback
7373
constraints/Expression
74+
constraints/Conditional
7475
constraints/All
7576
constraints/UserPassword
7677
constraints/NotCompromisedPassword

reference/constraints/Conditional.rst

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
Conditional
2+
===========
3+
4+
This constraint allows you to apply constraints validation only if the provided condition is matched.
5+
See `Basic Usage`_ for an example.
6+
7+
========== ===================================================================
8+
Applies to :ref:`class <validation-class-target>`
9+
or :ref:`property/method <validation-property-target>`
10+
Options - :ref:`condition <reference-constraint-condition-option>`
11+
- :ref:`constraints <reference-constraint-constraints-option>`
12+
- `groups`_
13+
- `payload`_
14+
- `values`_
15+
Class :class:`Symfony\\Component\\Validator\\Constraints\\Conditional`
16+
Validator :class:`Symfony\\Component\\Validator\\Constraints\\ConditionalValidator`
17+
========== ===================================================================
18+
19+
Basic Usage
20+
-----------
21+
22+
Imagine you have a class ``Discount`` with ``type`` and ``value``
23+
properties::
24+
25+
// src/Model/Discount.php
26+
namespace App\Model;
27+
28+
use Symfony\Component\Validator\Constraints as Assert;
29+
30+
class Discount
31+
{
32+
private $type;
33+
34+
private $value;
35+
36+
// ...
37+
38+
public function getType()
39+
{
40+
return $this->type;
41+
}
42+
43+
public function getValue()
44+
{
45+
return $this->value;
46+
}
47+
48+
// ...
49+
}
50+
51+
To validate the object, you have some requirements:
52+
53+
A) If ``type`` is ``percent``, then ``value`` must be less than 100;
54+
B) If ``type`` is ``absolute``, then ``value`` can be anything;
55+
C) No matter the value of ``type``, the ``value`` must be greater than 0.
56+
57+
One way to accomplish this is with the Conditional constraint:
58+
59+
.. configuration-block::
60+
61+
.. code-block:: php-annotations
62+
63+
// src/Model/Discount.php
64+
namespace App\Model;
65+
66+
use Symfony\Component\Validator\Constraints as Assert;
67+
68+
class Discount
69+
{
70+
/**
71+
* @Assert\GreaterThan(0)
72+
* @Assert\Conditional(
73+
* condition="this.type == 'percent'",
74+
* constraints={@LessThan(100, message="The value should be between 0 and 100!")}
75+
* )
76+
*/
77+
private $value;
78+
// ...
79+
}
80+
81+
.. code-block:: yaml
82+
83+
# config/validator/validation.yaml
84+
App\Model\Discount:
85+
properties:
86+
value:
87+
- GreaterThan: 0
88+
- Conditional:
89+
condition: "this.type == 'percent'"
90+
constraints:
91+
- LessThan:
92+
value: 100
93+
message: "The value should be between 0 and 100!"
94+
95+
.. code-block:: xml
96+
97+
<!-- config/validator/validation.xml -->
98+
<?xml version="1.0" encoding="UTF-8" ?>
99+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
100+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
101+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
102+
<class name="App\Model\Discount">
103+
<property name="value">
104+
<constraint name="GreaterThan">
105+
0
106+
</constraint>
107+
<constraint name="Conditional">
108+
<option name="condition">
109+
this.type == 'percent'
110+
</option>
111+
<option name="constraints">
112+
<constraint name="LessThan">
113+
<option name="value">100</option>
114+
<option name="message">The value should be between 0 and 100!</option>
115+
</constraint>
116+
</option>
117+
</constraint>
118+
</property>
119+
</class>
120+
</constraint-mapping>
121+
122+
.. code-block:: php
123+
124+
// src/Model/Discount.php
125+
namespace App\Model;
126+
127+
use Symfony\Component\Validator\Constraints as Assert;
128+
use Symfony\Component\Validator\Mapping\ClassMetadata;
129+
130+
class Discount
131+
{
132+
public static function loadValidatorMetadata(ClassMetadata $metadata)
133+
{
134+
$metadata->addPropertyConstraint(new Assert\GreaterThan(0));
135+
$metadata->addPropertyConstraint(new Assert\Conditional([
136+
'condition' => 'this.type == "percent"',
137+
'constraints' => [
138+
new Assert\LessThan([
139+
'value' => 100,
140+
]),
141+
],
142+
]));
143+
}
144+
145+
// ...
146+
}
147+
148+
The :ref:`condition <reference-constraint-condition-option>` option is the
149+
expression that must return true in order to trigger the validation of the attached constraints.
150+
To learn more about the expression language syntax, see
151+
:doc:`/components/expression_language/syntax`.
152+
153+
For more information about the expression and what variables are available
154+
to you, see the :ref:`condition <reference-constraint-condition-option>`
155+
option details below.
156+
157+
Options
158+
-------
159+
160+
.. _reference-constraint-condition-option:
161+
162+
``condition``
163+
~~~~~~~~~~~~~~
164+
165+
**type**: ``string``
166+
167+
The condition written with the expression language syntax that will be evaluated.
168+
If the expression evaluates to a false value (using ``==``, not ``===``),
169+
validation of constraints won't be triggered.
170+
171+
To learn more about the expression language syntax, see
172+
:doc:`/components/expression_language/syntax`.
173+
174+
Inside of the expression, you have access to up to 2 variables:
175+
176+
Depending on how you use the constraint, you have access to 1 or 2 variables
177+
in your expression:
178+
179+
* ``this``: The object being validated (e.g. an instance of Discount);
180+
* ``value``: The value of the property being validated (only available when
181+
the constraint is applied directly to a property);
182+
183+
.. _reference-constraint-constraints-option:
184+
185+
``constraints``
186+
~~~~~~~~~~~~~~~
187+
188+
**type**: ``array``
189+
190+
The constraints that are applied if the condition is true.
191+
192+
.. include:: /reference/constraints/_groups-option.rst.inc
193+
194+
.. include:: /reference/constraints/_payload-option.rst.inc
195+
196+
``values``
197+
~~~~~~~~~~
198+
199+
**type**: ``array`` **default**: ``[]``
200+
201+
The values of the custom variables used in the condition. Values can be of any
202+
type (numeric, boolean, strings, null, etc.)

0 commit comments

Comments
 (0)