Skip to content

Commit 55c260d

Browse files
committed
feature #6798 Finishing Validator Docs (wouterj, mickaelandrieu, javiereguiluz, weaverryan)
This PR was merged into the 2.7 branch. Discussion ---------- Finishing Validator Docs This replaces #6584 - putting it into the new structure. The PR was previously finished, so as long as all the references, etc are in the right place, this should be good to go! Commits ------- dc4d09a fixing reference 53a18d2 fixing bad reference fbe3402 Moving things around for the new structure 49a20e8 Final rewords a65855f Lots of minor fixes 8f4c292 Added a missing trailing comma b38ed60 Fixed RST syntax 0708bca Fixed typos 730781b Updated the code of the example 5909966 Fixed a typo 1e69e63 Finished the first version of the Validator documentation da02759 started to migrate metadata part from book to component docs e30d521 WouterJ comments 07a344c add example on how to use the static method loader 220f194 updated toc tree 2f2023d re added metadata section 21fde5c added custom validation section 5c0082a built the toc tree 6e4aaa3 added new sections 84027d5 added Packagist link 58d0fa5 fixed backslash on namespaces 7007300 @ricardclau review 84f4524 Applied comments by @cordoval c024ef2 Added article about loaders e50e2fa Added small configuration section 4549504 Get started with the Validator docs
2 parents c90db7f + dc4d09a commit 55c260d

File tree

3 files changed

+332
-10
lines changed

3 files changed

+332
-10
lines changed

components/validator.rst

Lines changed: 55 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,72 @@
55
The Validator Component
66
=======================
77

8-
The Validator component provides tools to validate values.
8+
The Validator component provides tools to validate values following the
9+
`JSR-303 Bean Validation specification`_.
910

1011
Installation
1112
------------
1213

13-
You can install the component in 2 different ways:
14+
You can install the component in two different ways:
1415

1516
* :doc:`Install it via Composer </components/using_components>` (``symfony/validator`` on `Packagist`_);
16-
* Use the official Git repository (https://github.com/symfony/validator).
17+
* Use the official Git repository (https://github.com/symfony/Validator).
1718

18-
For more information, see the code in the Git Repository.
19+
.. include:: /components/require_autoload.rst.inc
1920

20-
Learn more
21+
Usage
22+
-----
23+
24+
The Validator component behavior is based on two concepts:
25+
26+
* Contraints, which define the rules to be validated;
27+
* Validators, which are the classes that contain the actual validation logic.
28+
29+
The following example shows how to validate that a string is at least 10
30+
characters long::
31+
32+
use Symfony\Component\Validator\Validation;
33+
use Symfony\Component\Validator\Constraints\Length;
34+
use Symfony\Component\Validator\Constraints\NotBlank;
35+
36+
$validator = Validation::createValidator();
37+
$violations = $validator->validate('Bernhard', array(
38+
new Length(array('min' => 10)),
39+
new NotBlank(),
40+
));
41+
42+
if (0 !== count($violations)) {
43+
// there are errors, now you can show them
44+
foreach ($violations as $violation) {
45+
echo $violation->getMessage().'<br>';
46+
}
47+
}
48+
49+
Retrieving a Validator Instance
50+
-------------------------------
51+
52+
The :class:`Symfony\\Component\\Validator\\Validator` class is the main access
53+
point of the Validator component. To create a new instance of this class, it's
54+
recommended to use the :class:`Symfony\\Component\\Validator\\Validation` class::
55+
56+
use Symfony\Component\Validator\Validation;
57+
58+
$validator = Validation::createValidator();
59+
60+
This ``$validator`` object can validate simple variables such as strings, numbers
61+
and arrays, but it can't validate objects. To do so, configure the
62+
``Validator`` class as explained in the next sections.
63+
64+
Learn More
2165
----------
2266

2367
.. toctree::
24-
:maxdepth: 1
25-
:glob:
68+
:maxdepth: 1
69+
:glob:
2670

27-
/validation
28-
/validation/*
29-
/reference/constraints/*
71+
/components/validator/*
72+
/validation
73+
/validation/*
3074

75+
.. _`JSR-303 Bean Validation specification`: http://jcp.org/en/jsr/detail?id=303
3176
.. _Packagist: https://packagist.org/packages/symfony/validator

components/validator/metadata.rst

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
.. index::
2+
single: Validator; Metadata
3+
4+
Metadata
5+
========
6+
7+
The :class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata` class
8+
represents and manages all the configured constraints on a given class.
9+
10+
Properties
11+
----------
12+
13+
The Validator component can validate public, protected or private properties.
14+
The following example shows how to validate that the ``$firstName`` property of
15+
the ``Author`` class has at least 3 characters::
16+
17+
// ...
18+
use Symfony\Component\Validator\Mapping\ClassMetadata;
19+
use Symfony\Component\Validator\Constraints as Assert;
20+
21+
class Author
22+
{
23+
private $firstName;
24+
25+
public static function loadValidatorMetadata(ClassMetadata $metadata)
26+
{
27+
$metadata->addPropertyConstraint('firstName', new Assert\NotBlank());
28+
$metadata->addPropertyConstraint(
29+
'firstName',
30+
new Assert\Length(array("min" => 3))
31+
);
32+
}
33+
}
34+
35+
Getters
36+
-------
37+
38+
Constraints can also be applied to the value returned by any public *getter*
39+
method, which are the methods whose names start with ``get`` or ``is``. This
40+
feature allows to validate your objects dynamically.
41+
42+
Suppose that, for security reasons, you want to validate that a password field
43+
doesn't match the first name of the user. First, create a public method called
44+
``isPasswordSafe`` to define this custom validation logic::
45+
46+
public function isPasswordSafe()
47+
{
48+
return $this->firstName !== $this->password;
49+
}
50+
51+
Then, add the Validator component configuration to the class::
52+
53+
// ...
54+
use Symfony\Component\Validator\Mapping\ClassMetadata;
55+
use Symfony\Component\Validator\Constraints as Assert;
56+
57+
class Author
58+
{
59+
public static function loadValidatorMetadata(ClassMetadata $metadata)
60+
{
61+
$metadata->addGetterConstraint('passwordSafe', new Assert\True(array(
62+
'message' => 'The password cannot match your first name',
63+
)));
64+
}
65+
}
66+
67+
Classes
68+
-------
69+
70+
Some constraints allow to validate the entire object. For example, the
71+
:doc:`Callback </reference/constraints/Callback>` constraint is a generic
72+
constraint that's applied to the class itself.

components/validator/resources.rst

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
.. index::
2+
single: Validator; Loading Resources
3+
4+
Loading Resources
5+
=================
6+
7+
The Validator component uses metadata to validate a value. This metadata defines
8+
how a class, array or any other value should be validated. When validating a
9+
class, the metadata is defined by the class itself. When validating simple values,
10+
the metadata must be passed to the validation methods.
11+
12+
Class metadata can be defined in a configuration file or in the class itself.
13+
The Validator component collects that metadata using a set of loaders.
14+
15+
.. seealso::
16+
17+
You'll learn how to define the metadata in :doc:`metadata`.
18+
19+
The StaticMethodLoader
20+
----------------------
21+
22+
The most basic loader is the
23+
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\StaticMethodLoader`.
24+
This loader gets the metadata by calling a static method of the class. The name
25+
of the method is configured using the
26+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMapping`
27+
method of the validator builder::
28+
29+
use Symfony\Component\Validator\Validation;
30+
31+
$validator = Validation::createValidatorBuilder()
32+
->addMethodMapping('loadValidatorMetadata')
33+
->getValidator();
34+
35+
In this example, the validation metadata is retrieved executing the
36+
``loadValidatorMetadata()`` method of the class::
37+
38+
use Symfony\Component\Validator\Mapping\ClassMetadata;
39+
use Symfony\Component\Validator\Constraints as Assert;
40+
41+
class User
42+
{
43+
protected $name;
44+
45+
public static function loadValidatorMatadata(ClassMetadata $metadata)
46+
{
47+
$metadata->addPropertyConstraint('name', new Assert\NotBlank());
48+
$metadata->addPropertyConstraint('name', new Asert\Length(array(
49+
'min' => 5,
50+
'max' => 20,
51+
)));
52+
}
53+
}
54+
55+
.. tip::
56+
57+
Instead of calling ``addMethodMapping()`` multiple times to add several
58+
method names, you can also use
59+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMappings`
60+
to set an array of supported method names.
61+
62+
The File Loaders
63+
----------------
64+
65+
The component also provides two file loaders, one to load YAML files and one to
66+
load XML files. Use
67+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addYamlMapping` or
68+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMapping` to
69+
configure the locations of these files::
70+
71+
use Symfony\Component\Validator\Validation;
72+
73+
$validator = Validation::createValidatorBuilder()
74+
->addYamlMapping('config/validation.yml')
75+
->getValidator();
76+
77+
.. note::
78+
79+
If you want to load YAML mapping files then you will also need to install
80+
:doc:`the Yaml component </components/yaml>`.
81+
82+
.. tip::
83+
84+
Just like with the method mappings, you can also use
85+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addYamlMappings` and
86+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMappings`
87+
to configure an array of file paths.
88+
89+
The AnnotationLoader
90+
--------------------
91+
92+
At last, the component provides an
93+
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader` to get
94+
the metadata from the annotations of the class. Annotations are defined as ``@``
95+
prefixed classes included in doc block comments (``/** ... */``). For example::
96+
97+
use Symfony\Component\Validator\Constraints as Assert;
98+
// ...
99+
100+
class User
101+
{
102+
/**
103+
* @Assert\NotBlank()
104+
*/
105+
protected $name;
106+
}
107+
108+
To enable the annotation loader, call the
109+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping`
110+
method. It takes an optional annotation reader instance, which defaults to
111+
``Doctrine\Common\Annotations\AnnotationReader``::
112+
113+
use Symfony\Component\Validator\Validation;
114+
115+
$validator = Validation::createValidatorBuilder()
116+
->enableAnnotationMapping()
117+
->getValidator();
118+
119+
To disable the annotation loader after it was enabled, call
120+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAnnotationMapping`.
121+
122+
.. note::
123+
124+
In order to use the annotation loader, you should have installed the
125+
``doctrine/annotations`` and ``doctrine/cache`` packages from `Packagist`_.
126+
127+
Using Multiple Loaders
128+
----------------------
129+
130+
The component provides a
131+
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderChain` class to
132+
execute several loaders sequentially in the same order they were defined:
133+
134+
The ``ValidatorBuilder`` will already take care of this when you configure
135+
multiple mappings::
136+
137+
use Symfony\Component\Validator\Validation;
138+
139+
$validator = Validation::createValidatorBuilder()
140+
->enableAnnotationMapping()
141+
->addMethodMapping('loadValidatorMetadata')
142+
->addXmlMapping('config/validation.xml')
143+
->getValidator();
144+
145+
Caching
146+
-------
147+
148+
Using many loaders to load metadata from different places is convenient, but it
149+
can slow down your application because each file needs to be parsed, validated
150+
and converted into a :class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata`
151+
instance. To solve this problem, you can cache the ``ClassMetadata`` information.
152+
153+
The Validator component comes with an
154+
:class:`Symfony\\Component\\Validator\\Mapping\\Cache\\ApcCache`
155+
implementation. You can easily create other cachers by creating a class which
156+
implements :class:`Symfony\\Component\\Validator\\Mapping\\Cache\\CacheInterface`.
157+
158+
.. note::
159+
160+
The loaders already use a singleton load mechanism. That means that the
161+
loaders will only load and parse a file once and put that in a property,
162+
which will then be used the next time it is asked for metadata. However,
163+
the Validator still needs to merge all metadata of one class from every
164+
loader when it is requested.
165+
166+
Enable the cache calling the
167+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataCache`
168+
method of the Validator builder::
169+
170+
use Symfony\Component\Validator\Validation;
171+
use Symfony\Component\Validator\Mapping\Cache\ApcCache;
172+
173+
$validator = Validation::createValidatorBuilder()
174+
// ... add loaders
175+
->setMetadataCache(new ApcCache('some_apc_prefix'));
176+
->getValidator();
177+
178+
Using a Custom MetadataFactory
179+
------------------------------
180+
181+
All the loaders and the cache are passed to an instance of
182+
:class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadataFactory`. This
183+
class is responsible for creating a ``ClassMetadata`` instance from all the
184+
configured resources.
185+
186+
You can also use a custom metadata factory implementation by creating a class
187+
which implements
188+
:class:`Symfony\\Component\\Validator\\MetadataFactoryInterface`. You can set
189+
this custom implementation using
190+
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataFactory`::
191+
192+
use Acme\Validation\CustomMetadataFactory;
193+
use Symfony\Component\Validator\Validation;
194+
195+
$validator = Validation::createValidatorBuilder()
196+
->setMetadataFactory(new CustomMetadataFactory(...));
197+
->getValidator();
198+
199+
.. caution::
200+
201+
Since you are using a custom metadata factory, you can't configure loaders
202+
and caches using the ``add*Mapping()`` methods anymore. You now have to
203+
inject them into your custom metadata factory yourself.
204+
205+
.. _`Packagist`: https://packagist.org

0 commit comments

Comments
 (0)