10000 [#3022] Adding new Expression validation constraint · symfony/symfony-docs@be86fef · GitHub
[go: up one dir, main page]

Skip to content

Commit be86fef

Browse files
committed
[#3022] Adding new Expression validation constraint
1 parent ac15bf5 commit be86fef

File tree

4 files changed

+171
-0
lines changed

4 files changed

+171
-0
lines changed

components/expression_language/introduction.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ component is a perfect candidate for the foundation of a *business rule engine*.
3232
The idea is to let the webmaster of a website configure things in a dynamic
3333
way without using PHP and without introducing security problems:
3434

35+
.. _component-expression-language-examples:
36+
3537
.. code-block:: text
3638
3739
# Get the special price if

reference/constraints.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Validation Constraints Reference
5353
constraints/Issn
5454

5555
constraints/Callback
56+
constraints/Expression
5657
constraints/All
5758
constraints/UserPassword
5859
constraints/Valid

reference/constraints/Expression.rst

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
Expression
2+
==========
3+
4+
.. versionadded:: 2.4
5+
The Expression constraint was introduced in Symfony 2.4.
6+
7+
This constraint allows you to use an :ref:`expression <component-expression-language-examples>`
8+
for more complex, dynamic validation. See `Basic Usage`_ for an example.
9+
See :doc:`/reference/constraints/Callback` for a different constraint that
10+
gives you similar flexibility.
11+
12+
+----------------+-----------------------------------------------------------------------------------------------+
13+
| Applies to | :ref:`class <validation-class-target>` or :ref:`property/method <validation-property-target>` |
14+
+----------------+-----------------------------------------------------------------------------------------------+
15+
| Options | - :ref:`expression <reference-constraint-expression-option>` |
16+
| | - `message`_ |
17+
+----------------+-----------------------------------------------------------------------------------------------+
18+
| Class | :class:`Symfony\\Component\\Validator\\Constraints\\Expression` |
19+
+----------------+-----------------------------------------------------------------------------------------------+
20+
| Validator | :class:`Symfony\\Component\\Validator\\Constraints\\ExpressionValidator` |
21+
+----------------+-----------------------------------------------------------------------------------------------+
22+
23+
Basic Usage
24+
-----------
25+
26+
Imagine you have a class ``BlogPost`` with ``category`` and ``isTechnicalPost``
27+
properties::
28+
29+
namespace Acme\DemoBundle\Model;
30+
31+
use Symfony\Component\Validator\Constraints as Assert;
32+
33+
class BlogPost
34+
{
35+
private $category;
36+
37+
private $isTechnicalPost;
38+
39+
// ...
40+
41+
public function getCategory()
42+
{
43+
return $this->category;
44+
}
45+
46+
public function setIsTechnicalPost($isTechnicalPost)
47+
{
48+
$this->isTechnicalPost = $isTechnicalPost;
49+
}
50+
51+
// ...
52+
}
53+
54+
To validate the object, you have some special requirements:
55+
56+
* A) If ``isTechnicalPost`` is true, then ``category`` must be either ``php``
57+
or ``symfony``;
58+
59+
* B) If ``isTechnicalPost`` is false, then ``category`` can be anything.
60+
61+
One way to accomplish this is with the Expression constraint:
62+
63+
.. configuration-block::
64+
65+
.. code-block:: yaml
66+
67+
# src/Acme/DemoBundle/Resources/config/validation.yml
68+
Acme\DemoBundle\Model\BlogPost:
69+
constraints:
70+
- Expression:
71+
expression: "this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()"
72+
message: "If this is a tech post, the category should be php or symfony!"
73+
74+
.. code-block:: php-annotations
75+
76+
// src/Acme/DemoBundle/Model/BlogPost.php
77+
namespace Acme\DemoBundle\Model\BlogPost;
78+
79+
use Symfony\Component\Validator\Constraints as Assert;
80+
81+
/**
82+
* @Assert\Expression(
83+
* "this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()",
84+
* message="If this is a tech post, the category should be php or symfony!"
85+
* )
86+
*/
87+
class BlogPost
88+
{
89+
// ...
90+
}
91+
92+
.. code-block:: xml
93+
94+
<!-- src/Acme/DemoBundle/Resources/config/validation.xml -->
95+
<class name="Acme\DemoBundle\Model\BlogPost">
96+
<constraint name="Expression">
97+
<option name="expression">
98+
this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()
99+
</option>
100+
<option name="message">
101+
If this is a tech post, the category should be php or symfony!
102+
</option>
103+
</constraint>
104+
</class>
105+
106+
107+
.. code-block:: php
108+
109+
// src/Acme/DemoBundle/Model/BlogPost.php
110+
namespace Acme\DemoBundle\Model\BlogPost;
111+
112+
use Symfony\Component\Validator\Mapping\ClassMetadata;
113+
use Symfony\Component\Validator\Constraints as Assert;
114+
115+
class BlogPost
116+
{
117+
public static function loadValidatorMetadata(ClassMetadata $metadata)
118+
{
119+
$metadata->addConstraint(new Assert\Expression(array(
120+
'expression' => 'this.getCategory() in ["php", "symfony"] or !this.isTechnicalPost()',
121+
'message' => 'If this is a tech post, the category should be php or symfony!',
122+
)));
123+
}
124+
125+
// ...
126+
}
127+
128+
The :ref:`expression <reference-constraint-expression-option>` option is the
129+
expression that must return true in order for validation to pass. To learn
130+
more about the expression language syntax, see
131+
:doc:`/components/expression_language/syntax`.
132+
133+
For more information about the expression and what variables you have available
134+
to you, see the :ref:`expression <reference-constraint-expression-option>`
135+
option details below.
136+
137+
Available Options
138+
-----------------
139+
140+
.. _reference-constraint-expression-option:
141+
142+
expression
143+
~~~~~~~~~~
144+
145+
**type**: ``string`` [:ref:`default option <validation-default-option>`]
146+
147+
The expression that will be evaluated. If the expression evaluates to a false
148+
value (using ``==``, not ``===``), validation will fail.
149+
150+
To learn more about the expression language syntax, see
151+
:doc:`/components/expression_language/syntax`.
152+
153+
Inside of the expression, you have access to up to 2 variables:
154+
155+
Depending on how you use the constraint, you have access to 1 or 2 variables
156+
in your expression:
157+
158+
* ``this``: The object being validated (e.g. an instance of BlogPost);
159+
* ``value``: The value of the property being validated (only available when
160+
the constraint is applied directly to a property);
161+
162+
message
163+
~~~~~~~
164+
165+
**type**: ``string`` **default**: ``This value is not valid.``
166+
167+
The default message supplied when the expression evaluates to false.

reference/constraints/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ Other Constraints
7676
~~~~~~~~~~~~~~~~~
7777

7878
* :doc:`Callback </reference/constraints/Callback>`
79+
* :doc:`Expression </reference/constraints/Expression>`
7980
* :doc:`All </reference/constraints/All>`
8081
* :doc:`UserPassword </reference/constraints/UserPassword>`
8182
* :doc:`Valid </reference/constraints/Valid>`

0 commit comments

Comments
 (0)
0