Browse files

[Validator] Added entry point "Validation" for more convenient usage …

…outside of Symfony2
  • Loading branch information...
1 parent fd56fd6 commit 19695e96f95a833141c2fa218824102e75caf93b @webmozart webmozart committed Jul 30, 2012
Showing with 547 additions and 12 deletions.
  1. +2 −0 CHANGELOG.md
  2. +5 −3 Mapping/ClassMetadataFactory.php
  3. +76 −9 README.md
  4. +43 −0 Validation.php
  5. +258 −0 ValidatorBuilder.php
  6. +114 −0 ValidatorBuilderInterface.php
  7. +16 −0 ValidatorContext.php
  8. +12 −0 ValidatorContextInterface.php
  9. +21 −0 ValidatorFactory.php
View
2 CHANGELOG.md
@@ -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
8 Mapping/ClassMetadataFactory.php
@@ -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 @@ public function getClassMetadata($class)
$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
85 README.md
@@ -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;
+Usage
+-----
+
+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;
- use Symfony\Component\Validator\ConstraintValidatorFactory;
- $validator = new Validator(
- new ClassMetadataFactory(new StaticMethodLoader()),
- new ConstraintValidatorFactory()
- );
+ $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
43 Validation.php
@@ -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
258 ValidatorBuilder.php
@@ -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
114 ValidatorBuilderInterface.php
@@ -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
16 ValidatorContext.php
@@ -17,6 +17,9 @@
* 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 @@ public function setClassMetadataFactory(ClassMetadataFactoryInterface $classMeta
/**
* {@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 @@ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterfac
/**
* {@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 @@ public function getValidator()
* 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 @@ public function getClassMetadataFactory()
* 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
12 ValidatorContextInterface.php
@@ -27,27 +27,39 @@
* </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
{
/**
* 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);
/**
* 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);
/**
* 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
21 ValidatorFactory.php
@@ -73,6 +73,9 @@
* 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 @@ public static function buildDefault(array $mappingFiles = array(), $annotations
* 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 @@ public function __construct(ValidatorContextInterface $defaultContext = null)
* @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 @@ public function setClassMetadataFactory(ClassMetadataFactoryInterface $metadataF
* @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 @@ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterfac
* 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()
{

0 comments on commit 19695e9

Please sign in to comment.