4 * This file is part of the Symfony package.
6 * (c) Fabien Potencier <fabien@symfony.com>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Symfony\Component\Validator;
14 @trigger_error('The '.__NAMESPACE__.'\ValidationVisitor class is deprecated since version 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
16 use Symfony\Component\Translation\TranslatorInterface;
17 use Symfony\Component\Validator\Exception\NoSuchMetadataException;
18 use Symfony\Component\Validator\Exception\UnexpectedTypeException;
21 * Default implementation of {@link ValidationVisitorInterface} and
22 * {@link GlobalExecutionContextInterface}.
24 * @author Bernhard Schussek <bschussek@gmail.com>
26 * @deprecated since version 2.5, to be removed in 3.0.
28 class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionContextInterface
36 * @var MetadataFactoryInterface
38 private $metadataFactory;
41 * @var ConstraintValidatorFactoryInterface
43 private $validatorFactory;
46 * @var TranslatorInterface
53 private $translationDomain;
58 private $objectInitializers;
61 * @var ConstraintViolationList
68 private $validatedObjects = array();
71 * Creates a new validation visitor.
73 * @param mixed $root The value passed to the validator
74 * @param MetadataFactoryInterface $metadataFactory The factory for obtaining metadata instances
75 * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating constraint validators
76 * @param TranslatorInterface $translator The translator for translating violation messages
77 * @param string|null $translationDomain The domain of the translation messages
78 * @param ObjectInitializerInterface[] $objectInitializers The initializers for preparing objects before validation
80 * @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface
82 public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, TranslatorInterface $translator, $translationDomain = null, array $objectInitializers = array())
84 foreach ($objectInitializers as $initializer) {
85 if (!$initializer instanceof ObjectInitializerInterface) {
86 throw new UnexpectedTypeException($initializer, 'Symfony\Component\Validator\ObjectInitializerInterface');
91 $this->metadataFactory = $metadataFactory;
92 $this->validatorFactory = $validatorFactory;
93 $this->translator = $translator;
94 $this->translationDomain = $translationDomain;
95 $this->objectInitializers = $objectInitializers;
96 $this->violations = new ConstraintViolationList();
102 public function visit(MetadataInterface $metadata, $value, $group, $propertyPath)
104 $context = new ExecutionContext(
107 $this->translationDomain,
114 $context->validateValue($value, $metadata->findConstraints($group));
120 public function validate($value, $group, $propertyPath, $traverse = false, $deep = false)
122 if (null === $value) {
126 if (is_object($value)) {
127 $hash = spl_object_hash($value);
129 // Exit, if the object is already validated for the current group
130 if (isset($this->validatedObjects[$hash][$group])) {
134 // Initialize if the object wasn't initialized before
135 if (!isset($this->validatedObjects[$hash])) {
136 foreach ($this->objectInitializers as $initializer) {
137 if (!$initializer instanceof ObjectInitializerInterface) {
138 throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.');
140 $initializer->initialize($value);
144 // Remember validating this object before starting and possibly
145 // traversing the object graph
146 $this->validatedObjects[$hash][$group] = true;
149 // Validate arrays recursively by default, otherwise every driver needs
150 // to implement special handling for arrays.
151 // https://github.com/symfony/symfony/issues/6246
152 if (is_array($value) || ($traverse && $value instanceof \Traversable)) {
153 foreach ($value as $key => $element) {
154 // Ignore any scalar values in the collection
155 if (is_object($element) || is_array($element)) {
156 // Only repeat the traversal if $deep is set
157 $this->validate($element, $group, $propertyPath.'['.$key.']', $deep, $deep);
162 $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
163 } catch (NoSuchMetadataException $e) {
164 // Metadata doesn't necessarily have to exist for
165 // traversable objects, because we know how to validate
166 // them anyway. Optionally, additional metadata is supported.
169 $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
176 public function getViolations()
178 return $this->violations;
184 public function getRoot()
192 public function getVisitor()
200 public function getValidatorFactory()
202 return $this->validatorFactory;
208 public function getMetadataFactory()
210 return $this->metadataFactory;