Skip to content

Commit d730798

Browse files
committed
revamped custom constraints documentation to provide a bit more specific example
1 parent 3cfe971 commit d730798

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

cookbook/validation/custom_constraint.rst

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,42 @@
22
single: Validation; Custom constraints
33

44
How to create a Custom Validation Constraint
5-
--------------------------------------------
5+
============================================
66

77
You can create a custom constraint by extending the base constraint class,
8-
:class:`Symfony\\Component\\Validator\\Constraint`. Options for your
9-
constraint are represented as public properties on the constraint class. For
10-
example, the :doc:`Url</reference/constraints/Url>` constraint includes
11-
the ``message`` and ``protocols`` properties:
8+
:class:`Symfony\\Component\\Validator\\Constraint`.
9+
As an example we're going to create a simple validator that checks if string contains only alphanumeric characters.
1210

13-
.. code-block:: php
11+
Creating Constraint class
12+
-------------------------
1413

15-
namespace Symfony\Component\Validator\Constraints;
14+
First you need to create a Constraint class and extend :class:`Symfony\\Component\\Validator\\Constraint`::
15+
16+
namespace Acme\DemoBundle\Validator\Constraints;
1617

1718
use Symfony\Component\Validator\Constraint;
1819

1920
/**
2021
* @Annotation
2122
*/
22-
class Protocol extends Constraint
23+
class ContainsAlphanumeric extends Constraint
2324
{
24-
public $message = 'The value "%protocol%" is not a valid protocol';
25-
public $protocols = array('http', 'https', 'ftp', 'ftps');
25+
public $message = 'Missing at least one alphanumeric character in "%string%" string';
2626
}
2727
2828
.. note::
2929

3030
The ``@Annotation`` annotation is necessary for this new constraint in
3131
order to make it available for use in classes via annotations.
32+
Options for your constraint are represented as public properties on the constraint class.
3233

34+
Creating Validator itself
35+
-------------------------
36+
3337
As you can see, a constraint class is fairly minimal. The actual validation is
3438
performed by a another "constraint validator" class. The constraint validator
3539
class is specified by the constraint's ``validatedBy()`` method, which
36-
includes some simple default logic:
37-
38-
.. code-block:: php
40+
includes some simple default logic::
3941

4042
// in the base Symfony\Component\Validator\Constraint class
4143
public function validatedBy()
@@ -47,22 +49,19 @@ In other words, if you create a custom ``Constraint`` (e.g. ``MyConstraint``),
4749
Symfony2 will automatically look for another class, ``MyConstraintValidator``
4850
when actually performing the validation.
4951

50-
The validator class is also simple, and only has one required method: ``isValid``.
51-
Furthering our example, take a look at the ``ProtocolValidator`` as an example:
52+
The validator class is also simple, and only has one required method: ``isValid``::
5253

53-
.. code-block:: php
54-
55-
namespace Symfony\Component\Validator\Constraints;
54+
namespace Acme\DemoBundle\Validator\Constraints;
5655
5756
use Symfony\Component\Validator\Constraint;
5857
use Symfony\Component\Validator\ConstraintValidator;
5958

60-
class ProtocolValidator extends ConstraintValidator
59+
class ContainsAlphanumericValidator extends ConstraintValidator
6160
{
6261
public function isValid($value, Constraint $constraint)
6362
{
64-
if (!in_array($value, $constraint->protocols)) {
65-
$this->setMessage($constraint->message, array('%protocol%' => $value));
63+
if (!preg_match('/^[a-zA-Za0-9]+$/', $value, $matches)) {
64+
$this->setMessage($constraint->message);
6665

6766
return false;
6867
}
@@ -75,6 +74,36 @@ Furthering our example, take a look at the ``ProtocolValidator`` as an example:
7574

7675
Don't forget to call ``setMessage`` to construct an error message when the
7776
value is invalid.
77+
78+
Using newly created validator
79+
-----------------------------
80+
81+
Using custom validators is very easy, just as the ones provided by Symfony2 itself::
82+
83+
namespace Acme\DemoBundle\Entity;
84+
85+
use Doctrine\ORM\Mapping as ORM;
86+
use Symfony\Component\Validator\Constraints as Assert;
87+
use Acme\DemoBundle\Validator\Constraints as AcmeAssert;
88+
89+
class AcmeEntity
90+
{
91+
/**
92+
* @ORM\Id
93+
* @ORM\GeneratedValue
94+
* @ORM\Column(name="id", type="integer")
95+
*/
96+
protected $id;
97+
98+
/**
99+
* @Assert\NotBlank
100+
* @AcmeAssert\ContainsAlphanumeric
101+
* @ORM\Column(name="name", type="string", length=100)
102+
*/
103+
protected $name;
104+
105+
// ...
106+
}
78107

79108
Constraint Validators with Dependencies
80109
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)