[Validator] Added entry point "Validation" for more convenient usage outside of Symfony2

This commit is contained in:
Bernhard Schussek 2012-07-30 10:57:16 +02:00
parent ed8736140f
commit 2185ca80e2
11 changed files with 569 additions and 15 deletions

View File

@ -1271,6 +1271,25 @@
private $password;
```
* The classes `ValidatorContext` and `ValidatorFactory` were deprecated and
will be removed in Symfony 2.3. You should use the new entry point
`Validation` instead.
Before:
```
$validator = ValidatorFactory::buildDefault(array('path/to/mapping.xml'))
->getValidator();
```
After:
```
$validator = Validation::createValidatorBuilder()
->addXmlMapping('path/to/mapping.xml')
->getValidator();
```
### Session
* Flash messages now return an array based on their type. The old method is

View File

@ -93,10 +93,10 @@ use Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationExtension;
* This extension needs a validator object to function properly:
*
* <code>
* use Symfony\Component\Validator\ValidatorFactory;
* use Symfony\Component\Validator\Validation;
* use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
*
* $validator = ValidatorFactory::buildDefault()->getValidator();
* $validator = Validation::createValidator();
* $formFactory = Forms::createFormFactoryBuilder()
* ->addExtension(new ValidatorExtension($validator))
* ->getFormFactory();

View File

@ -26,3 +26,5 @@ CHANGELOG
* added Range constraint
* deprecated the Min and Max constraints
* deprecated the MinLength and MaxLength constraints
* added Validation and ValidatorBuilderInterface
* deprecated ValidatorContext, ValidatorContextInterface and ValidatorFactory

View File

@ -35,7 +35,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
protected $loadedClasses = array();
public function __construct(LoaderInterface $loader, CacheInterface $cache = null)
public function __construct(LoaderInterface $loader = null, CacheInterface $cache = null)
{
$this->loader = $loader;
$this->cache = $cache;
@ -68,9 +68,11 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
$metadata->mergeConstraints($this->getClassMetadata($interface->name));
}
$this->loader->loadClassMetadata($metadata);
if (null !== $this->loader) {
$this->loader->loadClassMetadata($metadata);
}
if ($this->cache !== null) {
if (null !== $this->cache) {
$this->cache->write($metadata);
}

View File

@ -2,19 +2,34 @@ Validator Component
===================
This component is based on the JSR-303 Bean Validation specification and
enables specifying validation rules for classes using XML, YAML or
enables specifying validation rules for classes using XML, YAML, PHP or
annotations, which can then be checked against instances of these classes.
use Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ConstraintValidatorFactory;
Usage
-----
$validator = new Validator(
new ClassMetadataFactory(new StaticMethodLoader()),
new ConstraintValidatorFactory()
);
The component provides "validation constraints", which are simple objects
containing the rules for the validation. Let's validate a simple string
as an example:
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints\MinLength;
$validator = Validation::createValidator();
$violations = $validator->validateValue('Bernhard', new MinLength(10));
This validation will fail because the given string is shorter than ten
characters. The precise errors, here called "constraint violations", are
returned by the validator. You can analyze these or return them to the user.
If the violation list is empty, validation succeeded.
Validation of arrays is possible using the `Collection` constraint:
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
$validator = Validation::createValidator();
$constraint = new Assert\Collection(array(
'name' => new Assert\Collection(array(
@ -30,6 +45,58 @@ annotations, which can then be checked against instances of these classes.
$violations = $validator->validateValue($input, $constraint);
Again, the validator returns the list of violations.
Validation of objects is possible using "constraint mapping". With such
a mapping you can put constraints onto properties and objects of classes.
Whenever an object of this class is validated, its properties and
method results are matched against the constraints.
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
class User
{
/**
* @Assert\MinLength(3)
* @Assert\NotBlank
*/
private $name;
/**
* @Assert\Email
* @Assert\NotBlank
*/
private $email;
public function __construct($name, $email)
{
$this->name = $name;
$this->email = $email;
}
/**
* @Assert\True(message = "The user should have a Google Mail account")
*/
public function isGmailUser()
{
return false !== strpos($this->email, '@gmail.com');
}
}
$validator = Validation::createValidatorBuilder()
->setAnnotationMapping(true)
->getValidator();
$user = new User('John Doe', 'john@example.com');
$violations = $validator->validate($user);
This example uses the annotation support of Doctrine Common to
map constraints to properties and methods. You can also map constraints
using XML, YAML or plain PHP. Check the documentation for more information
about these drivers.
Resources
---------

View File

@ -0,0 +1,43 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator;
/**
* Entry point for the Validator component.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
final class Validation
{
/**
* Creates a new validator.
*
* If you want to configure the validator, use
* {@link createValidatorBuilder()} instead.
*
* @return ValidatorInterface The new validator.
*/
public static function createValidator()
{
return self::createValidatorBuilder()->getValidator();
}
/**
* Creates a configurable builder for validator objects.
*
* @return ValidatorBuilderInterface The new builder.
*/
public static function createValidatorBuilder()
{
return new ValidatorBuilder();
}
}

View File

@ -0,0 +1,258 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
use Symfony\Component\Validator\Exception\ValidatorException;
use Symfony\Component\Validator\Mapping\BlackholeMetadataFactory;
use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
use Doctrine\Common\Annotations\AnnotationReader;
/**
* The default implementation of {@link ValidatorBuilderInterface}.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ValidatorBuilder implements ValidatorBuilderInterface
{
/**
* @var array
*/
private $initializers = array();
/**
* @var array
*/
private $xmlMappings = array();
/**
* @var array
*/
private $yamlMappings = array();
/**
* @var array
*/
private $methodMappings = array();
/**
* @var Boolean
*/
private $annotationMapping = false;
/**
* @var ClassMetadataFactoryInterface
*/
private $metadataFactory;
/**
* @var ConstraintValidatorFactoryInterface
*/
private $validatorFactory;
/**
* @var CacheInterface
*/
private $metadataCache;
/**
* {@inheritdoc}
*/
public function addObjectInitializer(ObjectInitializerInterface $initializer)
{
$this->initializers[] = $initializer;
}
/**
* {@inheritdoc}
*/
public function addObjectInitializers(array $initializers)
{
$this->initializers = array_merge($this->initializers, $initializers);
}
/**
* {@inheritdoc}
*/
public function addXmlMapping($path)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->xmlMappings[] = $path;
}
/**
* {@inheritdoc}
*/
public function addXmlMappings(array $paths)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->xmlMappings = array_merge($this->xmlMappings, $paths);
}
/**
* {@inheritdoc}
*/
public function addYamlMapping($path)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->yamlMappings[] = $path;
}
/**
* {@inheritdoc}
*/
public function addYamlMappings(array $paths)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->yamlMappings = array_merge($this->yamlMappings, $paths);
}
/**
* {@inheritdoc}
*/
public function addMethodMapping($methodName)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->methodMappings[] = $methodName;
}
/**
* {@inheritdoc}
*/
public function addMethodMappings(array $methodNames)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot add custom mappings after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->methodMappings = array_merge($this->methodMappings, $methodNames);
}
/**
* {@inheritdoc}
*/
public function setAnnotationMapping($enabled)
{
if ($enabled && null !== $this->metadataFactory) {
throw new ValidatorException('You cannot enable annotation mapping after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->annotationMapping = $enabled;
}
/**
* {@inheritdoc}
*/
public function setMetadataFactory(ClassMetadataFactoryInterface $metadataFactory)
{
if (count($this->xmlMappings) > 0 || count($this->yamlMappings) > 0 || count($this->methodMappings) > 0 || $this->annotationMapping) {
throw new ValidatorException('You cannot set a custom metadata factory after adding custom mappings. You should do either of both.');
}
$this->metadataFactory = $metadataFactory;
}
/**
* {@inheritdoc}
*/
public function setMetadataCache(CacheInterface $cache)
{
if (null !== $this->metadataFactory) {
throw new ValidatorException('You cannot set a custom metadata cache after setting a custom metadata factory. Configure your metadata factory instead.');
}
$this->metadataCache = $cache;
}
/**
* {@inheritdoc}
*/
public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
{
$this->validatorFactory = $validatorFactory;
}
/**
* {@inheritdoc}
*/
public function getValidator()
{
$metadataFactory = $this->metadataFactory;
if (!$metadataFactory) {
$loaders = array();
if (count($this->xmlMappings) > 1) {
$loaders[] = new XmlFilesLoader($this->xmlMappings);
} elseif (1 === count($this->xmlMappings)) {
$loaders[] = new XmlFileLoader($this->xmlMappings[0]);
}
if (count($this->yamlMappings) > 1) {
$loaders[] = new YamlFilesLoader($this->yamlMappings);
} elseif (1 === count($this->yamlMappings)) {
$loaders[] = new YamlFileLoader($this->yamlMappings[0]);
}
if (count($this->methodMappings) > 0) {
foreach ($this->methodMappings as $methodName) {
$loaders[] = new StaticMethodLoader($methodName);
}
}
if ($this->annotationMapping) {
if (!class_exists('Doctrine\Common\Annotations\AnnotationReader')) {
throw new \RuntimeException('Requested a ValidatorFactory with an AnnotationLoader, but the AnnotationReader was not found. You should add Doctrine Common to your project.');
}
$loaders[] = new AnnotationLoader(new AnnotationReader());
}
$loader = null;
if (count($loaders) > 1) {
$loader = new LoaderChain($loaders);
} elseif (1 === count($loaders)) {
$loader = $loaders[0];
}
$metadataFactory = new ClassMetadataFactory($loader, $this->metadataCache);
}
$validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory();
return new Validator($metadataFactory, $validatorFactory, $this->initializers);
}
}

View File

@ -0,0 +1,114 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Validator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
/**
* A configurable builder for ValidatorInterface objects.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface ValidatorBuilderInterface
{
/**
* Adds an object initializer to the validator.
*
* @param ObjectInitializerInterface $initializer The initializer.
*/
public function addObjectInitializer(ObjectInitializerInterface $initializer);
/**
* Adds a list of object initializers to the validator.
*
* @param array $initializers The initializer.
*/
public function addObjectInitializers(array $initializers);
/**
* Adds an XML constraint mapping file to the validator.
*
* @param string $path The path to the mapping file.
*/
public function addXmlMapping($path);
/**
* Adds a list of XML constraint mapping files to the validator.
*
* @param array $paths The paths to the mapping files.
*/
public function addXmlMappings(array $paths);
/**
* Adds a YAML constraint mapping file to the validator.
*
* @param string $path The path to the mapping file.
*/
public function addYamlMapping($path);
/**
* Adds a list of YAML constraint mappings file to the validator.
*
* @param array $paths The paths to the mapping files.
*/
public function addYamlMappings(array $paths);
/**
* Enables constraint mapping using the given static method.
*
* @param string $methodName The name of the method.
*/
public function addMethodMapping($methodName);
/**
* Enables constraint mapping using the given static methods.
*
* @param array $methodNames The names of the methods.
*/
public function addMethodMappings(array $methodNames);
/**
* Enables or disables annotation based constraint mapping.
*
* @param Boolean $enabled Whether annotation mapping should be enabled.
*/
public function setAnnotationMapping($enabled);
/**
* Sets the class metadata factory used by the validator.
*
* @param ClassMetadataFactoryInterface $metadataFactory The metadata factory.
*/
public function setMetadataFactory(ClassMetadataFactoryInterface $metadataFactory);
/**
* Sets the cache for caching class metadata.
*
* @param CacheInterface $cache The cache instance.
*/
public function setMetadataCache(CacheInterface $cache);
/**
* Sets the constraint validator factory used by the validator.
*
* @param ConstraintValidatorFactoryInterface $validatorFactory The validator factory.
*/
public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory);
/**
* Builds and returns a new validator object.
*
* @return ValidatorInterface The built validator.
*/
public function getValidator();
}

View File

@ -17,6 +17,9 @@ use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
* Default implementation of ValidatorContextInterface
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
class ValidatorContext implements ValidatorContextInterface
{
@ -34,6 +37,9 @@ class ValidatorContext implements ValidatorContextInterface
/**
* {@inheritDoc}
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function setClassMetadataFactory(ClassMetadataFactoryInterface $classMetadataFactory)
{
@ -44,6 +50,9 @@ class ValidatorContext implements ValidatorContextInterface
/**
* {@inheritDoc}
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $constraintValidatorFactory)
{
@ -54,6 +63,9 @@ class ValidatorContext implements ValidatorContextInterface
/**
* {@inheritDoc}
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidator()} instead.
*/
public function getValidator()
{
@ -67,6 +79,8 @@ class ValidatorContext implements ValidatorContextInterface
* Returns the class metadata factory used in the new validator
*
* @return ClassMetadataFactoryInterface The factory instance
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
*/
public function getClassMetadataFactory()
{
@ -77,6 +91,8 @@ class ValidatorContext implements ValidatorContextInterface
* Returns the constraint validator factory used in the new validator
*
* @return ConstraintValidatorFactoryInterface The factory instance
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
*/
public function getConstraintValidatorFactory()
{

View File

@ -27,6 +27,9 @@ use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
* </code>
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
interface ValidatorContextInterface
{
@ -34,6 +37,9 @@ interface ValidatorContextInterface
* Sets the class metadata factory used in the new validator
*
* @param ClassMetadataFactoryInterface $classMetadataFactory The factory instance
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function setClassMetadataFactory(ClassMetadataFactoryInterface $classMetadataFactory);
@ -41,6 +47,9 @@ interface ValidatorContextInterface
* Sets the constraint validator factory used in the new validator
*
* @param ConstraintValidatorFactoryInterface $constraintValidatorFactory The factory instance
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $constraintValidatorFactory);
@ -48,6 +57,9 @@ interface ValidatorContextInterface
* Creates a new validator with the settings stored in this context
*
* @return ValidatorInterface The new validator
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidator()} instead.
*/
public function getValidator();
}

View File

@ -73,6 +73,9 @@ use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
* ValidatorFactory instances should be cached and reused in your application.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
class ValidatorFactory implements ValidatorContextInterface
{
@ -94,9 +97,15 @@ class ValidatorFactory implements ValidatorContextInterface
* use, if static method loading should
* be enabled
*
* @return ValidatorFactory The validator factory.
*
* @throws MappingException If any of the files in $mappingFiles
* has neither the extension ".xml" nor
* ".yml" nor ".yaml"
* @throws \RuntimeException If annotations are not supported.
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public static function buildDefault(array $mappingFiles = array(), $annotations = false, $staticMethod = null)
{
@ -155,6 +164,9 @@ class ValidatorFactory implements ValidatorContextInterface
* Sets the given context as default context
*
* @param ValidatorContextInterface $defaultContext A preconfigured context
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function __construct(ValidatorContextInterface $defaultContext = null)
{
@ -168,6 +180,9 @@ class ValidatorFactory implements ValidatorContextInterface
* @param ClassMetadataFactoryInterface $metadataFactory The new factory instance
*
* @return ValidatorContextInterface The preconfigured form context
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function setClassMetadataFactory(ClassMetadataFactoryInterface $metadataFactory)
{
@ -183,6 +198,9 @@ class ValidatorFactory implements ValidatorContextInterface
* @param ClassMetadataFactoryInterface $validatorFactory The new factory instance
*
* @return ValidatorContextInterface The preconfigured form context
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidatorBuilder()} instead.
*/
public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
{
@ -195,6 +213,9 @@ class ValidatorFactory implements ValidatorContextInterface
* Creates a new validator with the settings stored in the default context
*
* @return ValidatorInterface The new validator
*
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
* {@link Validation::createValidator()} instead.
*/
public function getValidator()
{