Viewing file: ValidationVisitor.php (6.17 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?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\Exception\NoSuchMetadataException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Translation\TranslatorInterface;
/** * Default implementation of {@link ValidationVisitorInterface} and * {@link GlobalExecutionContextInterface}. * * @author Bernhard Schussek <bschussek@gmail.com> */ class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionContextInterface { /** * @var mixed */ private $root;
/** * @var MetadataFactoryInterface */ private $metadataFactory;
/** * @var ConstraintValidatorFactoryInterface */ private $validatorFactory;
/** * @var TranslatorInterface */ private $translator;
/** * @var null|string */ private $translationDomain;
/** * @var array */ private $objectInitializers;
/** * @var ConstraintViolationList */ private $violations;
/** * @var array */ private $validatedObjects = array();
/** * Creates a new validation visitor. * * @param mixed $root The value passed to the validator. * @param MetadataFactoryInterface $metadataFactory The factory for obtaining metadata instances. * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating constraint validators. * @param TranslatorInterface $translator The translator for translating violation messages. * @param string|null $translationDomain The domain of the translation messages. * @param ObjectInitializerInterface[] $objectInitializers The initializers for preparing objects before validation. * * @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface */ public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, TranslatorInterface $translator, $translationDomain = null, array $objectInitializers = array()) { foreach ($objectInitializers as $initializer) { if (!$initializer instanceof ObjectInitializerInterface) { throw new UnexpectedTypeException($initializer, 'Symfony\Component\Validator\ObjectInitializerInterface'); } }
$this->root = $root; $this->metadataFactory = $metadataFactory; $this->validatorFactory = $validatorFactory; $this->translator = $translator; $this->translationDomain = $translationDomain; $this->objectInitializers = $objectInitializers; $this->violations = new ConstraintViolationList(); }
/** * {@inheritdoc} */ public function visit(MetadataInterface $metadata, $value, $group, $propertyPath) { $context = new ExecutionContext( $this, $this->translator, $this->translationDomain, $metadata, $value, $group, $propertyPath );
$context->validateValue($value, $metadata->findConstraints($group)); }
/** * {@inheritdoc} */ public function validate($value, $group, $propertyPath, $traverse = false, $deep = false) { if (null === $value) { return; }
if (is_object($value)) { $hash = spl_object_hash($value);
// Exit, if the object is already validated for the current group if (isset($this->validatedObjects[$hash][$group])) { return; }
// Remember validating this object before starting and possibly // traversing the object graph $this->validatedObjects[$hash][$group] = true;
foreach ($this->objectInitializers as $initializer) { if (!$initializer instanceof ObjectInitializerInterface) { throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.'); } $initializer->initialize($value); } }
// Validate arrays recursively by default, otherwise every driver needs // to implement special handling for arrays. // https://github.com/symfony/symfony/issues/6246 if (is_array($value) || ($traverse && $value instanceof \Traversable)) { foreach ($value as $key => $element) { // Ignore any scalar values in the collection if (is_object($element) || is_array($element)) { // Only repeat the traversal if $deep is set $this->validate($element, $group, $propertyPath.'['.$key.']', $deep, $deep); } }
try { $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath); } catch (NoSuchMetadataException $e) { // Metadata doesn't necessarily have to exist for // traversable objects, because we know how to validate // them anyway. Optionally, additional metadata is supported. } } else { $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath); } }
/** * {@inheritdoc} */ public function getViolations() { return $this->violations; }
/** * {@inheritdoc} */ public function getRoot() { return $this->root; }
/** * {@inheritdoc} */ public function getVisitor() { return $this; }
/** * {@inheritdoc} */ public function getValidatorFactory() { return $this->validatorFactory; }
/** * {@inheritdoc} */ public function getMetadataFactory() { return $this->metadataFactory; } }
|