RecursiveValidator.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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\Validator;
  11. use Symfony\Component\Validator\Constraint;
  12. use Symfony\Component\Validator\Constraints\GroupSequence;
  13. use Symfony\Component\Validator\Constraints\Valid;
  14. use Symfony\Component\Validator\ConstraintValidatorFactoryInterface;
  15. use Symfony\Component\Validator\Context\ExecutionContextFactoryInterface;
  16. use Symfony\Component\Validator\Context\ExecutionContextInterface;
  17. use Symfony\Component\Validator\MetadataFactoryInterface;
  18. use Symfony\Component\Validator\ObjectInitializerInterface;
  19. use Symfony\Component\Validator\ValidatorInterface as LegacyValidatorInterface;
  20. /**
  21. * Recursive implementation of {@link ValidatorInterface}.
  22. *
  23. * @author Bernhard Schussek <bschussek@gmail.com>
  24. */
  25. class RecursiveValidator implements ValidatorInterface, LegacyValidatorInterface
  26. {
  27. protected $contextFactory;
  28. protected $metadataFactory;
  29. protected $validatorFactory;
  30. protected $objectInitializers;
  31. /**
  32. * Creates a new validator.
  33. *
  34. * @param ExecutionContextFactoryInterface $contextFactory The factory for
  35. * creating new contexts
  36. * @param MetadataFactoryInterface $metadataFactory The factory for
  37. * fetching the metadata
  38. * of validated objects
  39. * @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating
  40. * constraint validators
  41. * @param ObjectInitializerInterface[] $objectInitializers The object initializers
  42. */
  43. public function __construct(ExecutionContextFactoryInterface $contextFactory, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = array())
  44. {
  45. $this->contextFactory = $contextFactory;
  46. $this->metadataFactory = $metadataFactory;
  47. $this->validatorFactory = $validatorFactory;
  48. $this->objectInitializers = $objectInitializers;
  49. }
  50. /**
  51. * {@inheritdoc}
  52. */
  53. public function startContext($root = null)
  54. {
  55. return new RecursiveContextualValidator(
  56. $this->contextFactory->createContext($this, $root),
  57. $this->metadataFactory,
  58. $this->validatorFactory,
  59. $this->objectInitializers
  60. );
  61. }
  62. /**
  63. * {@inheritdoc}
  64. */
  65. public function inContext(ExecutionContextInterface $context)
  66. {
  67. return new RecursiveContextualValidator(
  68. $context,
  69. $this->metadataFactory,
  70. $this->validatorFactory,
  71. $this->objectInitializers
  72. );
  73. }
  74. /**
  75. * {@inheritdoc}
  76. */
  77. public function getMetadataFor($object)
  78. {
  79. return $this->metadataFactory->getMetadataFor($object);
  80. }
  81. /**
  82. * {@inheritdoc}
  83. */
  84. public function hasMetadataFor($object)
  85. {
  86. return $this->metadataFactory->hasMetadataFor($object);
  87. }
  88. /**
  89. * {@inheritdoc}
  90. */
  91. public function validate($value, $groups = null, $traverse = false, $deep = false)
  92. {
  93. $numArgs = \func_num_args();
  94. // Use new signature if constraints are given in the second argument
  95. if (self::testConstraints($groups) && ($numArgs < 3 || 3 === $numArgs && self::testGroups($traverse))) {
  96. // Rename to avoid total confusion ;)
  97. $constraints = $groups;
  98. $groups = $traverse;
  99. } else {
  100. @trigger_error('The Symfony\Component\Validator\ValidatorInterface::validate method is deprecated in version 2.5 and will be removed in version 3.0. Use the Symfony\Component\Validator\Validator\ValidatorInterface::validate method instead.', E_USER_DEPRECATED);
  101. $constraints = new Valid(array('traverse' => $traverse, 'deep' => $deep));
  102. }
  103. return $this->startContext($value)
  104. ->validate($value, $constraints, $groups)
  105. ->getViolations();
  106. }
  107. /**
  108. * {@inheritdoc}
  109. */
  110. public function validateProperty($object, $propertyName, $groups = null)
  111. {
  112. return $this->startContext($object)
  113. ->validateProperty($object, $propertyName, $groups)
  114. ->getViolations();
  115. }
  116. /**
  117. * {@inheritdoc}
  118. */
  119. public function validatePropertyValue($objectOrClass, $propertyName, $value, $groups = null)
  120. {
  121. // If a class name is passed, take $value as root
  122. return $this->startContext(\is_object($objectOrClass) ? $objectOrClass : $value)
  123. ->validatePropertyValue($objectOrClass, $propertyName, $value, $groups)
  124. ->getViolations();
  125. }
  126. /**
  127. * {@inheritdoc}
  128. */
  129. public function validateValue($value, $constraints, $groups = null)
  130. {
  131. @trigger_error('The '.__METHOD__.' method is deprecated in version 2.5 and will be removed in version 3.0. Use the Symfony\Component\Validator\Validator\ValidatorInterface::validate method instead.', E_USER_DEPRECATED);
  132. return $this->validate($value, $constraints, $groups);
  133. }
  134. /**
  135. * {@inheritdoc}
  136. */
  137. public function getMetadataFactory()
  138. {
  139. @trigger_error('The '.__METHOD__.' method is deprecated in version 2.5 and will be removed in version 3.0. Use the Symfony\Component\Validator\Validator\ValidatorInterface::getMetadataFor or Symfony\Component\Validator\Validator\ValidatorInterface::hasMetadataFor method instead.', E_USER_DEPRECATED);
  140. return $this->metadataFactory;
  141. }
  142. private static function testConstraints($constraints)
  143. {
  144. return null === $constraints || $constraints instanceof Constraint || (\is_array($constraints) && (0 === \count($constraints) || current($constraints) instanceof Constraint));
  145. }
  146. private static function testGroups($groups)
  147. {
  148. return null === $groups || \is_string($groups) || $groups instanceof GroupSequence || (\is_array($groups) && (0 === \count($groups) || \is_string(current($groups)) || current($groups) instanceof GroupSequence));
  149. }
  150. }