ValidationVisitor.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Validator;
  11. @trigger_error('The '.__NAMESPACE__.'\ValidationVisitor class is deprecated since Symfony 2.5 and will be removed in 3.0.', E_USER_DEPRECATED);
  12. use Symfony\Component\Translation\TranslatorInterface;
  13. use Symfony\Component\Validator\Exception\NoSuchMetadataException;
  14. use Symfony\Component\Validator\Exception\UnexpectedTypeException;
  15. /**
  16. * Default implementation of {@link ValidationVisitorInterface} and
  17. * {@link GlobalExecutionContextInterface}.
  18. *
  19. * @author Bernhard Schussek <bschussek@gmail.com>
  20. *
  21. * @deprecated since version 2.5, to be removed in 3.0.
  22. */
  23. class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionContextInterface
  24. {
  25. private $root;
  26. private $metadataFactory;
  27. private $validatorFactory;
  28. private $translator;
  29. private $translationDomain;
  30. private $objectInitializers;
  31. private $violations;
  32. private $validatedObjects = array();
  33. /**
  34. * Creates a new validation visitor.
  35. *
  36. * @param mixed $root The value passed to the validator
  37. * @param MetadataFactoryInterface $metadataFactory The factory for obtaining metadata instances
  38. * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating constraint validators
  39. * @param TranslatorInterface $translator The translator for translating violation messages
  40. * @param string|null $translationDomain The domain of the translation messages
  41. * @param ObjectInitializerInterface[] $objectInitializers The initializers for preparing objects before validation
  42. *
  43. * @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface
  44. */
  45. public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, TranslatorInterface $translator, $translationDomain = null, array $objectInitializers = array())
  46. {
  47. foreach ($objectInitializers as $initializer) {
  48. if (!$initializer instanceof ObjectInitializerInterface) {
  49. throw new UnexpectedTypeException($initializer, 'Symfony\Component\Validator\ObjectInitializerInterface');
  50. }
  51. }
  52. $this->root = $root;
  53. $this->metadataFactory = $metadataFactory;
  54. $this->validatorFactory = $validatorFactory;
  55. $this->translator = $translator;
  56. $this->translationDomain = $translationDomain;
  57. $this->objectInitializers = $objectInitializers;
  58. $this->violations = new ConstraintViolationList();
  59. }
  60. /**
  61. * {@inheritdoc}
  62. */
  63. public function visit(MetadataInterface $metadata, $value, $group, $propertyPath)
  64. {
  65. $context = new ExecutionContext(
  66. $this,
  67. $this->translator,
  68. $this->translationDomain,
  69. $metadata,
  70. $value,
  71. $group,
  72. $propertyPath
  73. );
  74. $context->validateValue($value, $metadata->findConstraints($group));
  75. }
  76. /**
  77. * {@inheritdoc}
  78. */
  79. public function validate($value, $group, $propertyPath, $traverse = false, $deep = false)
  80. {
  81. if (null === $value) {
  82. return;
  83. }
  84. if (\is_object($value)) {
  85. $hash = spl_object_hash($value);
  86. // Exit, if the object is already validated for the current group
  87. if (isset($this->validatedObjects[$hash][$group])) {
  88. return;
  89. }
  90. // Initialize if the object wasn't initialized before
  91. if (!isset($this->validatedObjects[$hash])) {
  92. foreach ($this->objectInitializers as $initializer) {
  93. if (!$initializer instanceof ObjectInitializerInterface) {
  94. throw new \LogicException('Validator initializers must implement ObjectInitializerInterface.');
  95. }
  96. $initializer->initialize($value);
  97. }
  98. }
  99. // Remember validating this object before starting and possibly
  100. // traversing the object graph
  101. $this->validatedObjects[$hash][$group] = true;
  102. }
  103. // Validate arrays recursively by default, otherwise every driver needs
  104. // to implement special handling for arrays.
  105. // https://github.com/symfony/symfony/issues/6246
  106. if (\is_array($value) || ($traverse && $value instanceof \Traversable)) {
  107. foreach ($value as $key => $element) {
  108. // Ignore any scalar values in the collection
  109. if (\is_object($element) || \is_array($element)) {
  110. // Only repeat the traversal if $deep is set
  111. $this->validate($element, $group, $propertyPath.'['.$key.']', $deep, $deep);
  112. }
  113. }
  114. try {
  115. $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
  116. } catch (NoSuchMetadataException $e) {
  117. // Metadata doesn't necessarily have to exist for
  118. // traversable objects, because we know how to validate
  119. // them anyway. Optionally, additional metadata is supported.
  120. }
  121. } else {
  122. $this->metadataFactory->getMetadataFor($value)->accept($this, $value, $group, $propertyPath);
  123. }
  124. }
  125. /**
  126. * {@inheritdoc}
  127. */
  128. public function getViolations()
  129. {
  130. return $this->violations;
  131. }
  132. /**
  133. * {@inheritdoc}
  134. */
  135. public function getRoot()
  136. {
  137. return $this->root;
  138. }
  139. /**
  140. * {@inheritdoc}
  141. */
  142. public function getVisitor()
  143. {
  144. return $this;
  145. }
  146. /**
  147. * {@inheritdoc}
  148. */
  149. public function getValidatorFactory()
  150. {
  151. return $this->validatorFactory;
  152. }
  153. /**
  154. * {@inheritdoc}
  155. */
  156. public function getMetadataFactory()
  157. {
  158. return $this->metadataFactory;
  159. }
  160. }