diff --git a/components/index.rst b/components/index.rst index 739b9e84f9c..3079cc63867 100644 --- a/components/index.rst +++ b/components/index.rst @@ -28,6 +28,7 @@ The Components stopwatch templating/index translation/index + validator/index yaml/index .. include:: /components/map.rst.inc diff --git a/components/map.rst.inc b/components/map.rst.inc index fbc1872afb8..6dbaef3a02c 100644 --- a/components/map.rst.inc +++ b/components/map.rst.inc @@ -128,6 +128,11 @@ * :doc:`/components/translation/introduction` * :doc:`/components/translation/usage` +* :doc:`/components/validator/index` + + * :doc:`/components/validator/introduction` + * :doc:`/components/validator/resources` + * :doc:`/components/yaml/index` * :doc:`/components/yaml/introduction` diff --git a/components/validator/index.rst b/components/validator/index.rst new file mode 100644 index 00000000000..c653e23078a --- /dev/null +++ b/components/validator/index.rst @@ -0,0 +1,8 @@ +Validator +========= + +.. toctree:: + :maxdepth: 2 + + introduction + resources diff --git a/components/validator/introduction.rst b/components/validator/introduction.rst new file mode 100644 index 00000000000..d1cfffaf3eb --- /dev/null +++ b/components/validator/introduction.rst @@ -0,0 +1,77 @@ +.. index:: + single: Validator + single: Components; Validator + +The Validator Component +======================= + + The Validator component provides tools to validate values following the + `JSR-303 Bean Validation specification`_. + +Installation +------------ + +You can install the component in 2 different ways: + +* :doc:`Install it via Composer ` (``symfony/validator`` on `Packagist`_); +* Use the official Git repository (https://github.com/symfony/Validator). + +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 a string is at least 10 character long, the only code you need is:: + + use Symfony\Component\Validator\Validation; + use Symfony\Component\Validator\Constraints\Length; + + $validator = Validation::createValidator(); + + $violations = $validator->validateValue('Bernhard', new Length(array('min' => 10))); + + if (0 !== count($violations)) { + // there are errors, now you can show them + foreach ($violations as $violation) { + echo $violation->getMessage().'
'; + } + } + +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 recommend to use the :class:`Symfony\\Component\Validator\Validation` +class. + +You can get a very basic ``Validator`` by calling +:method:`Validation::createValidator() `:: + + use Symfony\Component\Validator\Validation; + + $validator = Validation::createValidator(); + +The created validator can be used to validate strings, array, numbers, but it +can't validate classes. To be able to do 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() ` +method:: + + use Symfony\Component\Validator\Validation; + + $validator = Validation::createValidatorBuilder() + // ... build a custom instance of the Validator + ->getValidator(); + +What things you can configure will be documented in the following sections. + +Sections +-------- + +* :doc:`/components/validator/resources` +* :doc:`/components/validator/metadata` +* :doc:`/components/validator/validating_values` + +.. _`JSR-303 Bean Validation specification`: http://jcp.org/en/jsr/detail?id=303 diff --git a/components/validator/resources.rst b/components/validator/resources.rst new file mode 100644 index 00000000000..c2975d14e55 --- /dev/null +++ b/components/validator/resources.rst @@ -0,0 +1,182 @@ +.. index:: + single: Validator; Loading Resources + +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. + +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. + +.. seealso:: + + You'll learn how to define the metadata in :doc:`metadata`. + +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 +:method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMapping` +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. + +.. tip:: + + You can call this method multiple times to add multiple supported method + names. You can also use + :method:`Symfony\\Component\\Validator\\ValidatorBuilder::addMethodMappings` + to set an array of supported method names. + +The FileLoaders +--------------- + +The component also provides 2 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 +configure the locations of these files:: + + use Symfony\Component\Validator\Validation; + + $validator = Validation::createValidatorBuilder() + ->addYamlMapping('config/validation.yml') + ->getValidator(); + +.. tip:: + + Just like with the method mappings, you can also use + :method:`Symfony\\Component\\Validator\\ValidatorBuilder::addYamlMappings` and + :method:`Symfony\\Component\\Validator\\ValidatorBuilder::addXmlMappings` + to configure an array of file paths. + +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:: + + // ... + + /** + * @Assert\NotBlank() + */ + protected $name; + +To enable the annotation loader, call the +:method:`Symfony\\Component\\Validator\\ValidatorBuilder::enableAnnotationMapping` +method. It takes an optional annotation reader instance, which defaults to +``Doctrine\Common\Annotations\AnnotationReader``:: + + use Symfony\Component\Validator\Validation; + + $validator = Validation::createValidatorBuilder() + ->enableAnnotationMapping() + ->getValidator(); + +To disable the annotation loader after it was enabled, call +:method:`Symfony\\Component\\Validator\\ValidatorBuilder::disableAnnotationMapping`. + +.. note:: + + In order to use the annotation loader, you should have installed the + ``doctrine/annotations`` and ``doctrine/cache`` packages from Packagist. + +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. + +The ``ValidatorBuilder`` will already take care of this when you configure +multiple mappings:: + + use Symfony\Component\Validator\Validation; + + $validator = Validation::createValidatorBuilder() + ->enableAnnotationMapping() + ->addMethodMapping('loadValidatorMetadata') + ->addXmlMapping('config/validation.xml') + ->getValidator(); + +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 problems, you can configure a cacher which will be used to cache +the ``ClassMetadata`` after it was loaded. + +The Validator component comes with a +:class:`Symfony\\Component\\Validator\\Mapping\\Cache\\ApcCache` +implementation. You can easily create other cachers by creating a class which +implements :class:`Symfony\\Component\\Validator\\Mapping\\Cache\\CacheInterface`. + +.. note:: + + The loaders already use a singleton load mechanism. That means that the + loaders will only load and parse a file once and put that in a property, + which will then be used the next time it is asked for metadata. However, + 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:: + + use Symfony\Component\Validator\Validation; + use Symfony\Component\Validator\Mapping\Cache\ApcCache; + + $validator = Validation::createValidatorBuilder() + // ... add loaders + ->setMetadataCache(new ApcCache('some_apc_prefix')); + ->getValidator(); + +Using a Custom MetadataFactory +------------------------------ + +All loaders and the cacher 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. + +You can also use a custom metadata factory implementation by creating a class +which implements +:class:`Symfony\\Component\\Validator\\MetadataFactoryInterface`. You can set +this custom implementation using +:method:`Symfony\\Component\\Validator\\ValidatorBuilder::setMetadataFactory`:: + + use Acme\Validation\CustomMetadataFactory; + use Symfony\Component\Validator\Validation; + + $validator = Validation::createValidatorBuilder() + ->setMetadataFactory(new CustomMetadataFactory(...)); + ->getValidator(); + +.. 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 + inject them into your custom metadata factory yourself.