Skip to content

Added Validator component documentation #6584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions components/validator/builtin_validators.rst

This file was deleted.

5 changes: 0 additions & 5 deletions components/validator/custom_validation.rst

This file was deleted.

4 changes: 0 additions & 4 deletions components/validator/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,3 @@ Validator
introduction
resources
metadata
builtin_validators
validation_groups
custom_validation
internationalization
5 changes: 0 additions & 5 deletions components/validator/internationalization.rst

This file was deleted.

44 changes: 17 additions & 27 deletions components/validator/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ The Validator Component
=======================

The Validator component provides tools to validate values following the
`JSR-303 Bean Validation specification`_. With the component, this is done in two parts:
* ``Contraints``: a constraint describes a rule that need to be validated
* ``Validators``: a list of classes that implement the validation logic for common usages
`JSR-303 Bean Validation specification`_.

Installation
------------
Expand All @@ -23,15 +21,18 @@ You can install the component in 2 different ways:
Usage
-----

The Validator component allows you to use very advanced validation rules, but
it is also really easy to do easy validation tasks. For instance, if you want
to validate that a string is at least 10 character long, the only code you need is::
The Validator component behavior is based on two concepts:

* Contraints, which define the rules to be validated;
* Validators, which are the classees that contain the actual validation logic.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

classees => classes

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thanks.


The following example shows how to validate that a string is at least 10
characters long::

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Length;

$validator = Validation::createValidator();

$violations = $validator->validateValue('Bernhard', new Length(array('min' => 10)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note this call is deprecated since Symfony 2.5, also we can pass an array of constraints too:

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;

$validator = Validation::createValidator();
$violations = $validator->validate('Bernhard', array(
    new Length(array('min' => 10)),
    new NotBlank()
));

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! I've fixed it.


if (0 !== count($violations)) {
Expand All @@ -45,40 +46,29 @@ Retrieving a Validator Instance
-------------------------------

The :class:`Symfony\\Component\\Validator\\Validator` class is the main access
point of the Validator component. To create a new instance of this class, it
is recommended to use the :class:`Symfony\\Component\\Validator\\Validation`
class.

You can get a very basic ``Validator`` by calling
:method:`Validation::createValidator() <Symfony\\Component\\Validator\\Validation::createValidator>`::
point of the Validator component. To create a new instance of this class, it's
recommended to use the :class:`Symfony\\Component\\Validator\\Validation` class::

use Symfony\Component\Validator\Validation;

$validator = Validation::createValidator();

The created validator can be used to validate strings, arrays, numbers, but it
can't validate classes. In order to achieve that, you have to configure the ``Validator``
class. To do that, you can use the :class:`Symfony\\Component\\Validator\\ValidatorBuilder`.
This class can be retrieved by using the
:method:`Validation::createValidatorBuilder() <Symfony\\Component\\Validator\\Validation::createValidatorBuilder>`
method::
This ``$validator`` object can validate simple variables such as strings, numbers
and arrays, but it can't validate objects. To do so, use the
:class:`Symfony\\Component\\Validator\\ValidatorBuilder` class to configure the
``Validator`` class::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph looks weird to me. What is the goal behind it and the following code?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but the paragraph tries to say: "if you want to validate objects, don't use the createValidator() method. You have to build a validator with the builder class". How would you reword it or improve it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem I see with this right now is that the code that is shown after the sentence is the same that is already executed in the background when using Validation::createValidator(). I would then instead just write that you need to configure the validator and link to the resources chapter instead.


use Symfony\Component\Validator\Validation;

$validator = Validation::createValidatorBuilder()
// ... build a custom instance of the Validator
->getValidator();

In the next sections, you'll learn about all things you can configure in the Validator.

Sections
--------
In the next sections, you'll learn about all the validator features that you
can configure:

* :doc:`/components/validator/resources`
* :doc:`/components/validator/builtin_validators`
* :doc:`/components/validator/validation_groups`
* :doc:`/components/validator/internationalization`
* :doc:`/components/validator/custom_validation`
* :doc:`/components/validator/metadata`

.. _`JSR-303 Bean Validation specification`: http://jcp.org/en/jsr/detail?id=303
.. _Packagist: https://packagist.org/packages/symfony/validator
51 changes: 23 additions & 28 deletions components/validator/metadata.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
Metadata
========

The :class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata` class represents and manages all the configured constraints on a given class.
The :class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata` class
represents and manages all the configured constraints on a given class.

Properties
----------

Validating class properties is the most basic validation technique. Validation component
allows you to validate private, protected or public properties. The next
listing shows you how to configure the ``$firstName`` property of an ``Author``
class to have at least 3 characters::
The Validator component can validate public, protected or private properties.
The following example shows how to validate that the ``$firstName`` property of
the ``Author`` class has at least 3 characters::

// ...
use Symfony\Component\Validator\Mapping\ClassMetadata;
Expand All @@ -35,16 +35,20 @@ class to have at least 3 characters::
Getters
-------

Constraints can also be applied to the return value of a method. Symfony
allows you to add a constraint to any public method whose name starts with
"get" or "is". In this guide, both of these types of methods are referred
to as "getters".
Constraints can also be applied to the value returned by any public *getter*
method, which are the methods whose names start with ``get`` or ``is``. This
feature allows to validate your objects dynamically.

The benefit of this technique is that it allows you to validate your object
dynamically. For example, suppose you want to make sure that a password field
doesn't match the first name of the user (for security reasons). You can
do this by creating an ``isPasswordLegal`` method, and then asserting that
this method must return ``true``::
Suppose that, for security reasons, you want to validate that a password field
doesn't match the first name of the user. First, create a public method called
``isPasswordSafe`` to define this custom validation logic::

public function isPasswordSafe()
{
return $this->firstName !== $this->password;
}

Then, add the Validator component configuration to the class::

// ...
use Symfony\Component\Validator\Mapping\ClassMetadata;
Expand All @@ -54,31 +58,22 @@ this method must return ``true``::
{
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addGetterConstraint('passwordLegal', new Assert\True(array(
$metadata->addGetterConstraint('passwordSafe', new Assert\True(array(
'message' => 'The password cannot match your first name',
)));
}
}

Now, create the ``isPasswordLegal()`` method and include the logic you need::

public function isPasswordLegal()
{
return $this->firstName !== $this->password;
}

.. note::

The keen-eyed among you will have noticed that the prefix of the getter
("get" or "is") is omitted in the mapping. This allows you to move the
(``get`` or ``is``) is omitted in the mapping. This allows you to move the
constraint to a property with the same name later (or vice versa) without
changing your validation logic.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this (you will later have to use addPropertyConstraint() instead of addGetterConstraint() nonetheless, don't you?).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I remove this note then?


Classes
-------

Some constraints apply to the entire class being validated. For example,
the :doc:`Callback </reference/constraints/Callback>` constraint is a generic
constraint that's applied to the class itself. When that class is validated,
methods specified by that constraint are simply executed so that each can
provide more custom validation.
Some constraints allow to validate the entire object. For example, the
:doc:`Callback </reference/constraints/Callback>` constraint is a generic
constraint that's applied to the class itself.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use cases misses an example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't add this example ... but I've created an issue to not forget about this: #6738

60 changes: 27 additions & 33 deletions components/validator/resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
Loading Resources
=================

The Validator uses metadata to validate a value. This metadata defines how a
class, array or any other value should be validated. When validating a class,
each class contains its own specific metadata. When validating another value,
the metadata must be passed to the validate methods.
The Validator component uses metadata to validate a value. This metadata defines
how a class, array or any other value should be validated. When validating a
class, the metadata is defined by the class itself. When validating simple values,
the metadata must be passed to the validation methods.

Class metadata should be defined somewhere in a configuration file, or in the
class itself. The ``Validator`` needs to be able to retrieve this metadata
from the file or class. To do that, it uses a set of loaders.
Class metadata can be defined in a configuration file or in the class itself.
The Validator component retrieves that metadata using a set of loaders.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"collects" instead of "retrieves"


.. seealso::

Expand All @@ -22,19 +21,19 @@ The StaticMethodLoader

The most basic loader is the
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\StaticMethodLoader`.
This loader will call a static method of the class in order to get the
metadata for that class. The name of the method is configured using the
This loader gets the metadata by calling a static method of the class. The name
of the method is configured using the
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMapping`
method of the Validator builder::
method of the validator builder::

use Symfony\Component\Validator\Validation;

$validator = Validation::createValidatorBuilder()
->addMethodMapping('loadValidatorMetadata')
->getValidator();

Now, the retrieved ``Validator`` tries to find the ``loadValidatorMetadata()``
method of the class to validate to load its metadata::
In this example, the validation metadata is retrieved executing the
``loadValidatorMetadata()`` method of the class::

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints as Assert;
Expand All @@ -55,15 +54,14 @@ method of the class to validate to load its metadata::

.. tip::

You can call this method multiple times to add multiple supported method
names. You can also use
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMappings`
You can call this method multiple times to add several method names. You can
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] call addMethodMapping() multiple [...]

also use :method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMappings`
to set an array of supported method names.

The FileLoaders
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The File Loaders

---------------

The component also provides 2 file loaders, one to load Yaml files and one to
The component also provides two file loaders, one to load YAML files and one to
load XML files. Use
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addYamlMapping` or
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMapping` to
Expand Down Expand Up @@ -91,10 +89,9 @@ The AnnotationLoader
--------------------

At last, the component provides an
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader`.
This loader uses an annotation reader to parse the annotations of a class.
Annotations are placed in doc block comments (``/** ... */``) and start with an
``@``. For instance::
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\AnnotationLoader` to get
the metadata from the annotations of the class. Annotations are defined as ``@``
prefixed classes included in doc block comments (``/** ... */``). For example::

use Symfony\Component\Validator\Constraints as Assert;
// ...
Expand Down Expand Up @@ -128,8 +125,7 @@ Using Multiple Loaders

The component provides a
:class:`Symfony\\Component\\Validator\\Mapping\\Loader\\LoaderChain` class to
chain multiple loaders. This means you can configure as many loaders as you
want at the same time.
execute several loaders sequentially in the same order they were defined:

The ``ValidatorBuilder`` will already take care of this when you configure
multiple mappings::
Expand All @@ -145,12 +141,10 @@ multiple mappings::
Caching
-------

Using many loaders to load metadata from different places is very easy when
creating the metadata, but it can easily slow down your application since each
file needs to be parsed, validated and converted to a
:class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata` instance. To
solve this problem, you can configure a cacher which will be used to cache
the ``ClassMetadata`` after it was loaded.
Using many loaders to load metadata from different places is convenient, but it
can slow down your application because each file needs to be parsed, validated
and converted to a :class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadata`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[...] converted into a [...]

instance. To solve this problem, you can cache the ``ClassMetadata`` information.

The Validator component comes with an
:class:`Symfony\\Component\\Validator\\Mapping\\Cache\\ApcCache`
Expand All @@ -165,9 +159,9 @@ implements :class:`Symfony\\Component\\Validator\\Mapping\\Cache\\CacheInterface
the Validator still needs to merge all metadata of one class from every
loader when it is requested.

To set a cacher, call the
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataCache` of
the Validator builder::
Enable the cache calling the
:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataCache`
method of the Validator builder::

use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Mapping\Cache\ApcCache;
Expand All @@ -180,7 +174,7 @@ the Validator builder::
Using a Custom MetadataFactory
------------------------------

All loaders and the cacher are passed to an instance of
All the loaders and the cache are passed to an instance of
:class:`Symfony\\Component\\Validator\\Mapping\\ClassMetadataFactory`. This
class is responsible for creating a ``ClassMetadata`` instance from all the
configured resources.
Expand All @@ -201,7 +195,7 @@ this custom implementation using
.. caution::

Since you are using a custom metadata factory, you can't configure loaders
and cachers using the ``add*Mapping()`` methods anymore. You now have to
and caches using the ``add*Mapping()`` methods anymore. You now have to
inject them into your custom metadata factory yourself.

.. _Packagist: https://packagist.org
5 changes: 0 additions & 5 deletions components/validator/validation_groups.rst

This file was deleted.