/src/Symfony/Component/Validator/ValidatorFactory.php

https://github.com/stedekay/symfony · PHP · 196 lines · 72 code · 20 blank · 104 comment · 13 complexity · 287748636d92a23903460f9355a95a9e MD5 · raw file

  1. <?php
  2. namespace Symfony\Component\Validator;
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. use Doctrine\Common\Annotations\AnnotationReader;
  12. use Symfony\Component\Validator\Exception\MappingException;
  13. use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
  14. use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface;
  15. use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
  16. use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
  17. use Symfony\Component\Validator\Mapping\Loader\AnnotationLoader;
  18. use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
  19. use Symfony\Component\Validator\Mapping\Loader\LoaderChain;
  20. /**
  21. * Creates and configures new validator objects
  22. *
  23. * Usually you will use the static method buildDefault() to initialize a
  24. * factory with default configuration. To this method you can pass various
  25. * parameters that configure where the validator mapping is found. If you
  26. * don't pass a parameter, the mapping will be read from annotations.
  27. *
  28. * <code>
  29. * // read from annotations only
  30. * $factory = ValidatorFactory::buildDefault();
  31. *
  32. * // read from XML and YAML, suppress annotations
  33. * $factory = ValidatorFactory::buildDefault(array(
  34. * '/path/to/mapping.xml',
  35. * '/path/to/other/mapping.yml',
  36. * ), false);
  37. * </code>
  38. *
  39. * You then have to call getValidator() to create new validators.
  40. *
  41. * <code>
  42. * $validator = $factory->getValidator();
  43. * </code>
  44. *
  45. * When manually constructing a factory, the default configuration of the
  46. * validators can be passed to the constructor as a ValidatorContextInterface
  47. * object.
  48. *
  49. * <code>
  50. * $defaultContext = new ValidatorContext();
  51. * $defaultContext->setClassMetadataFactory($metadataFactory);
  52. * $defaultContext->setConstraintValidatorFactory($validatorFactory);
  53. * $factory = new ValidatorFactory($defaultContext);
  54. *
  55. * $form = $factory->getValidator();
  56. * </code>
  57. *
  58. * You can also override the default configuration by calling any of the
  59. * methods in this class. These methods return a ValidatorContextInterface object
  60. * on which you can override further settings or call getValidator() to create
  61. * a form.
  62. *
  63. * <code>
  64. * $form = $factory
  65. * ->setClassMetadataFactory($customFactory);
  66. * ->getValidator();
  67. * </code>
  68. *
  69. * ValidatorFactory instances should be cached and reused in your application.
  70. *
  71. * @author Bernhard Schussek <bernhard.schussek@symfony.com>
  72. */
  73. class ValidatorFactory implements ValidatorContextInterface
  74. {
  75. /**
  76. * Holds the context with the default configuration
  77. * @var ValidatorContextInterface
  78. */
  79. protected $defaultContext;
  80. /**
  81. * Builds a validator factory with the default mapping loaders
  82. *
  83. * @param array $mappingFiles A list of XML or YAML file names
  84. * where mapping information can be
  85. * found. Can be empty.
  86. * @param Boolean $annotations Whether to use annotations for
  87. * retrieving mapping information
  88. * @param string $staticMethod The name of the static method to
  89. * use, if static method loading should
  90. * be enabled
  91. * @throws MappingException If any of the files in $mappingFiles
  92. * has neither the extension ".xml" nor
  93. * ".yml" nor ".yaml"
  94. */
  95. static public function buildDefault(array $mappingFiles = array(), $annotations = true, $staticMethod = null)
  96. {
  97. $xmlMappingFiles = array();
  98. $yamlMappingFiles = array();
  99. $loaders = array();
  100. $context = new ValidatorContext();
  101. foreach ($mappingFiles as $file) {
  102. $extension = pathinfo($file, PATHINFO_EXTENSION);
  103. if ($extension === 'xml') {
  104. $xmlMappingFiles[] = $file;
  105. } else if ($extension === 'yaml' || $extension === 'yml') {
  106. $yamlMappingFiles[] = $file;
  107. } else {
  108. throw new MappingException('The only supported mapping file formats are XML and YAML');
  109. }
  110. }
  111. if (count($xmlMappingFiles) > 0) {
  112. $loaders[] = new XmlFilesLoader($xmlMappingFiles);
  113. }
  114. if (count($yamlMappingFiles) > 0) {
  115. $loaders[] = new YamlFilesLoader($yamlMappingFiles);
  116. }
  117. if ($annotations) {
  118. $loaders[] = new AnnotationLoader(new AnnotationReader());
  119. }
  120. if ($staticMethod) {
  121. $loaders[] = new StaticMethodLoader($staticMethod);
  122. }
  123. if (count($loaders) > 1) {
  124. $loader = new LoaderChain($loaders);
  125. } else if (count($loaders) === 1) {
  126. $loader = $loaders[0];
  127. } else {
  128. throw new MappingException('No mapping loader was found for the given parameters');
  129. }
  130. $context->setClassMetadataFactory(new ClassMetadataFactory($loader));
  131. $context->setConstraintValidatorFactory(new ConstraintValidatorFactory());
  132. return new static($context);
  133. }
  134. /**
  135. * Sets the given context as default context
  136. *
  137. * @param ValidatorContextInterface $defaultContext A preconfigured context
  138. */
  139. public function __construct(ValidatorContextInterface $defaultContext = null)
  140. {
  141. $this->defaultContext = null === $defaultContext ? new ValidatorContext() : $defaultContext;
  142. }
  143. /**
  144. * Overrides the class metadata factory of the default context and returns
  145. * the new context
  146. *
  147. * @param ClassMetadataFactoryInterface $metadataFactory The new factory instance
  148. * @return ValidatorContextInterface The preconfigured form context
  149. */
  150. public function setClassMetadataFactory(ClassMetadataFactoryInterface $metadataFactory)
  151. {
  152. $context = clone $this->defaultContext;
  153. return $context->setClassMetadataFactory($metadataFactory);
  154. }
  155. /**
  156. * Overrides the constraint validator factory of the default context and
  157. * returns the new context
  158. *
  159. * @param ClassMetadataFactoryInterface $validatorFactory The new factory instance
  160. * @return ValidatorContextInterface The preconfigured form context
  161. */
  162. public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory)
  163. {
  164. $context = clone $this->defaultContext;
  165. return $context->setConstraintValidatorFactory($validatorFactory);
  166. }
  167. /**
  168. * Creates a new validator with the settings stored in the default context
  169. *
  170. * @return ValidatorInterface The new validator
  171. */
  172. public function getValidator()
  173. {
  174. return $this->defaultContext->getValidator();
  175. }
  176. }