diff --git a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php index 39da982bb1..57e28fb82f 100644 --- a/src/Symfony/Component/Validator/Constraints/CallbackValidator.php +++ b/src/Symfony/Component/Validator/Constraints/CallbackValidator.php @@ -33,10 +33,6 @@ class CallbackValidator extends ConstraintValidator if (!$constraint instanceof Callback) { throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\Callback'); } - - if (null === $object) { - return; - } if (null !== $constraint->callback && null !== $constraint->methods) { throw new ConstraintDefinitionException( @@ -60,18 +56,24 @@ class CallbackValidator extends ConstraintValidator } call_user_func($method, $object, $this->context); + + continue; + } + + if (null === $object) { + continue; + } + + if (!method_exists($object, $method)) { + throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method)); + } + + $reflMethod = new \ReflectionMethod($object, $method); + + if ($reflMethod->isStatic()) { + $reflMethod->invoke(null, $object, $this->context); } else { - if (!method_exists($object, $method)) { - throw new ConstraintDefinitionException(sprintf('Method "%s" targeted by Callback constraint does not exist', $method)); - } - - $reflMethod = new \ReflectionMethod($object, $method); - - if ($reflMethod->isStatic()) { - $reflMethod->invoke(null, $object, $this->context); - } else { - $reflMethod->invoke($object, $this->context); - } + $reflMethod->invoke($object, $this->context); } } } diff --git a/src/Symfony/Component/Validator/Context/ExecutionContext.php b/src/Symfony/Component/Validator/Context/ExecutionContext.php index 8f7c9ee693..fdfddf9c4b 100644 --- a/src/Symfony/Component/Validator/Context/ExecutionContext.php +++ b/src/Symfony/Component/Validator/Context/ExecutionContext.php @@ -19,7 +19,6 @@ use Symfony\Component\Validator\Exception\BadMethodCallException; use Symfony\Component\Validator\Group\GroupManagerInterface; use Symfony\Component\Validator\Mapping\PropertyMetadataInterface; use Symfony\Component\Validator\Node\Node; -use Symfony\Component\Validator\NodeVisitor\NodeObserverInterface; use Symfony\Component\Validator\Util\PropertyPath; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; @@ -32,7 +31,7 @@ use Symfony\Component\Validator\Violation\ConstraintViolationBuilder; * * @see ExecutionContextInterface */ -class ExecutionContext implements ExecutionContextInterface, NodeObserverInterface +class ExecutionContext implements ExecutionContextInterface { /** * @var ValidatorInterface @@ -75,6 +74,27 @@ class ExecutionContext implements ExecutionContextInterface, NodeObserverInterfa */ private $node; + /** + * Stores which objects have been validated in which group. + * + * @var array + */ + private $validatedObjects = array(); + + /** + * Stores which class constraint has been validated for which object. + * + * @var array + */ + private $validatedClassConstraints = array(); + + /** + * Stores which property constraint has been validated for which property. + * + * @var array + */ + private $validatedPropertyConstraints = array(); + /** * Creates a new execution context. * @@ -279,4 +299,68 @@ class ExecutionContext implements ExecutionContextInterface, NodeObserverInterfa 'or hasMetadataFor() instead or enable the legacy mode.' ); } + + /** + * {@inheritdoc} + */ + public function markObjectAsValidatedForGroup($objectHash, $groupHash) + { + if (!isset($this->validatedObjects[$objectHash])) { + $this->validatedObjects[$objectHash] = array(); + } + + $this->validatedObjects[$objectHash][$groupHash] = true; + } + + /** + * {@inheritdoc} + */ + public function isObjectValidatedForGroup($objectHash, $groupHash) + { + return isset($this->validatedObjects[$objectHash][$groupHash]); + } + + /** + * {@inheritdoc} + */ + public function markClassConstraintAsValidated($objectHash, $constraintHash) + { + if (!isset($this->validatedClassConstraints[$objectHash])) { + $this->validatedClassConstraints[$objectHash] = array(); + } + + $this->validatedClassConstraints[$objectHash][$constraintHash] = true; + } + + /** + * {@inheritdoc} + */ + public function isClassConstraintValidated($objectHash, $constraintHash) + { + return isset($this->validatedClassConstraints[$objectHash][$constraintHash]); + } + + /** + * {@inheritdoc} + */ + public function markPropertyConstraintAsValidated($objectHash, $propertyName, $constraintHash) + { + if (!isset($this->validatedPropertyConstraints[$objectHash])) { + $this->validatedPropertyConstraints[$objectHash] = array(); + } + + if (!isset($this->validatedPropertyConstraints[$objectHash][$propertyName])) { + $this->validatedPropertyConstraints[$objectHash][$propertyName] = array(); + } + + $this->validatedPropertyConstraints[$objectHash][$propertyName][$constraintHash] = true; + } + + /** + * {@inheritdoc} + */ + public function isPropertyConstraintValidated($objectHash, $propertyName, $constraintHash) + { + return isset($this->validatedPropertyConstraints[$objectHash][$propertyName][$constraintHash]); + } } diff --git a/src/Symfony/Component/Validator/Context/ExecutionContextInterface.php b/src/Symfony/Component/Validator/Context/ExecutionContextInterface.php index f6fed2fbee..b955a34f27 100644 --- a/src/Symfony/Component/Validator/Context/ExecutionContextInterface.php +++ b/src/Symfony/Component/Validator/Context/ExecutionContextInterface.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Validator\Context; use Symfony\Component\Validator\ExecutionContextInterface as LegacyExecutionContextInterface; +use Symfony\Component\Validator\Node\Node; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface; @@ -97,4 +98,92 @@ interface ExecutionContextInterface extends LegacyExecutionContextInterface * @return ValidatorInterface */ public function getValidator(); + + /** + * Sets the currently traversed node. + * + * @param Node $node The current node + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function setCurrentNode(Node $node); + + /** + * Marks an object as validated in a specific validation group. + * + * @param string $objectHash The hash of the object + * @param string $groupHash The group's name or hash, if it is group + * sequence + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function markObjectAsValidatedForGroup($objectHash, $groupHash); + + /** + * Returns whether an object was validated in a specific validation group. + * + * @param string $objectHash The hash of the object + * @param string $groupHash The group's name or hash, if it is group + * sequence + * + * @return Boolean Whether the object was already validated for that + * group + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function isObjectValidatedForGroup($objectHash, $groupHash); + + /** + * Marks a constraint as validated for an object. + * + * @param string $objectHash The hash of the object + * @param string $constraintHash The hash of the constraint + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function markClassConstraintAsValidated($objectHash, $constraintHash); + + /** + * Returns whether a constraint was validated for an object. + * + * @param string $objectHash The hash of the object + * @param string $constraintHash The hash of the constraint + * + * @return Boolean Whether the constraint was already validated + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function isClassConstraintValidated($objectHash, $constraintHash); + + /** + * Marks a constraint as validated for an object and a property name. + * + * @param string $objectHash The hash of the object + * @param string $propertyName The property name + * @param string $constraintHash The hash of the constraint + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function markPropertyConstraintAsValidated($objectHash, $propertyName, $constraintHash); + + /** + * Returns whether a constraint was validated for an object and a property + * name. + * + * @param string $objectHash The hash of the object + * @param string $propertyName The property name + * @param string $constraintHash The hash of the constraint + * + * @return Boolean Whether the constraint was already validated + * + * @internal Used by the validator engine. Should not be called by user + * code. + */ + public function isPropertyConstraintValidated($objectHash, $propertyName, $constraintHash); } diff --git a/src/Symfony/Component/Validator/NodeVisitor/AbstractVisitor.php b/src/Symfony/Component/Validator/NodeVisitor/AbstractVisitor.php index a47783ab0c..3f15359878 100644 --- a/src/Symfony/Component/Validator/NodeVisitor/AbstractVisitor.php +++ b/src/Symfony/Component/Validator/NodeVisitor/AbstractVisitor.php @@ -15,19 +15,32 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Node\Node; /** - * @since %%NextVersion%% + * Base visitor with empty method stubs. + * + * @since 2.5 * @author Bernhard Schussek + * + * @see NodeVisitorInterface */ abstract class AbstractVisitor implements NodeVisitorInterface { + /** + * {@inheritdoc} + */ public function beforeTraversal(array $nodes, ExecutionContextInterface $context) { } + /** + * {@inheritdoc} + */ public function afterTraversal(array $nodes, ExecutionContextInterface $context) { } + /** + * {@inheritdoc} + */ public function visit(Node $node, ExecutionContextInterface $context) { } diff --git a/src/Symfony/Component/Validator/NodeVisitor/ContextUpdateVisitor.php b/src/Symfony/Component/Validator/NodeVisitor/ContextUpdateVisitor.php index 4fb7f1b33a..ecf0b2694c 100644 --- a/src/Symfony/Component/Validator/NodeVisitor/ContextUpdateVisitor.php +++ b/src/Symfony/Component/Validator/NodeVisitor/ContextUpdateVisitor.php @@ -12,29 +12,24 @@ namespace Symfony\Component\Validator\NodeVisitor; use Symfony\Component\Validator\Context\ExecutionContextInterface; -use Symfony\Component\Validator\Exception\RuntimeException; use Symfony\Component\Validator\Node\Node; /** - * Updates the current context with the current node of the validation - * traversal. + * Informs the execution context about the currently validated node. * * @since 2.5 * @author Bernhard Schussek */ class ContextUpdateVisitor extends AbstractVisitor { + /** + * Updates the execution context. + * + * @param Node $node The current node + * @param ExecutionContextInterface $context The execution context + */ public function visit(Node $node, ExecutionContextInterface $context) { - if (!$context instanceof NodeObserverInterface) { - throw new RuntimeException(sprintf( - 'The ContextUpdateVisitor only supports instances of class '. - '"Symfony\Component\Validator\NodeVisitor\NodeObserverInterface". '. - 'An instance of class "%s" was given.', - get_class($context) - )); - } - $context->setCurrentNode($node); } } diff --git a/src/Symfony/Component/Validator/NodeVisitor/GroupSequenceResolvingVisitor.php b/src/Symfony/Component/Validator/NodeVisitor/DefaultGroupReplacingVisitor.php similarity index 64% rename from src/Symfony/Component/Validator/NodeVisitor/GroupSequenceResolvingVisitor.php rename to src/Symfony/Component/Validator/NodeVisitor/DefaultGroupReplacingVisitor.php index 2d9b68737a..6d152edf9c 100644 --- a/src/Symfony/Component/Validator/NodeVisitor/GroupSequenceResolvingVisitor.php +++ b/src/Symfony/Component/Validator/NodeVisitor/DefaultGroupReplacingVisitor.php @@ -18,11 +18,25 @@ use Symfony\Component\Validator\Node\ClassNode; use Symfony\Component\Validator\Node\Node; /** - * @since %%NextVersion%% + * Checks class nodes whether their "Default" group is replaced by a group + * sequence and adjusts the validation groups accordingly. + * + * If the "Default" group is replaced for a class node, and if the validated + * groups of the node contain the group "Default", that group is replaced by + * the group sequence specified in the class' metadata. + * + * @since 2.5 * @author Bernhard Schussek */ -class GroupSequenceResolvingVisitor extends AbstractVisitor +class DefaultGroupReplacingVisitor extends AbstractVisitor { + /** + * Replaces the "Default" group in the node's groups by the class' group + * sequence. + * + * @param Node $node The current node + * @param ExecutionContextInterface $context The execution context + */ public function visit(Node $node, ExecutionContextInterface $context) { if (!$node instanceof ClassNode) { @@ -30,16 +44,19 @@ class GroupSequenceResolvingVisitor extends AbstractVisitor } if ($node->metadata->hasGroupSequence()) { + // The group sequence is statically defined for the class $groupSequence = $node->metadata->getGroupSequence(); } elseif ($node->metadata->isGroupSequenceProvider()) { + // The group sequence is dynamically obtained from the validated + // object /** @var \Symfony\Component\Validator\GroupSequenceProviderInterface $value */ $groupSequence = $node->value->getGroupSequence(); - // TODO test if (!$groupSequence instanceof GroupSequence) { $groupSequence = new GroupSequence($groupSequence); } } else { + // The "Default" group is not overridden. Quit. return; } diff --git a/src/Symfony/Component/Validator/NodeVisitor/NodeObserverInterface.php b/src/Symfony/Component/Validator/NodeVisitor/NodeObserverInterface.php deleted file mode 100644 index 6588c09c90..0000000000 --- a/src/Symfony/Component/Validator/NodeVisitor/NodeObserverInterface.php +++ /dev/null @@ -1,23 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Validator\NodeVisitor; - -use Symfony\Component\Validator\Node\Node; - -/** - * @since %%NextVersion%% - * @author Bernhard Schussek - */ -interface NodeObserverInterface -{ - public function setCurrentNode(Node $node); -} diff --git a/src/Symfony/Component/Validator/NodeVisitor/NodeValidationVisitor.php b/src/Symfony/Component/Validator/NodeVisitor/NodeValidationVisitor.php index c688295da6..e36f7880c8 100644 --- a/src/Symfony/Component/Validator/NodeVisitor/NodeValidationVisitor.php +++ b/src/Symfony/Component/Validator/NodeVisitor/NodeValidationVisitor.php @@ -22,11 +22,19 @@ use Symfony\Component\Validator\Node\PropertyNode; use Symfony\Component\Validator\NodeTraverser\NodeTraverserInterface; /** - * @since %%NextVersion%% + * Validates a node's value against the constraints defined in it's metadata. + * + * @since 2.5 * @author Bernhard Schussek */ class NodeValidationVisitor extends AbstractVisitor implements GroupManagerInterface { + /** + * Stores the hashes of each validated object together with the groups + * in which that object was already validated. + * + * @var array + */ private $validatedObjects = array(); private $validatedConstraints = array(); @@ -83,19 +91,19 @@ class NodeValidationVisitor extends AbstractVisitor implements GroupManagerInter // Use the object hash for group sequences $groupHash = is_object($group) ? spl_object_hash($group) : $group; - if (isset($this->validatedObjects[$objectHash][$groupHash])) { + if ($context->isObjectValidatedForGroup($objectHash, $groupHash)) { // Skip this group when validating properties unset($node->groups[$key]); continue; } - $this->validatedObjects[$objectHash][$groupHash] = true; + //$context->markObjectAsValidatedForGroup($objectHash, $groupHash); } // Validate normal group if (!$group instanceof GroupSequence) { - $this->validateNodeForGroup($objectHash, $node, $group, $context); + $this->validateNodeForGroup($node, $group, $context, $objectHash); continue; } @@ -142,20 +150,31 @@ class NodeValidationVisitor extends AbstractVisitor implements GroupManagerInter } } - private function validateNodeForGroup($objectHash, Node $node, $group, ExecutionContextInterface $context) + private function validateNodeForGroup(Node $node, $group, ExecutionContextInterface $context, $objectHash) { try { $this->currentGroup = $group; foreach ($node->metadata->findConstraints($group) as $constraint) { - // Remember the validated constraints of each object to prevent - // duplicate validation of constraints that belong to multiple - // validated groups + // Prevent duplicate validation of constraints, in the case + // that constraints belong to multiple validated groups if (null !== $objectHash) { $constraintHash = spl_object_hash($constraint); - if (isset($this->validatedConstraints[$objectHash][$constraintHash])) { - continue; + if ($node instanceof ClassNode) { + if ($context->isClassConstraintValidated($objectHash, $constraintHash)) { + continue; + } + + $context->markClassConstraintAsValidated($objectHash, $constraintHash); + } elseif ($node instanceof PropertyNode) { + $propertyName = $node->metadata->getPropertyName(); + + if ($context->isPropertyConstraintValidated($objectHash, $propertyName, $constraintHash)) { + continue; + } + + $context->markPropertyConstraintAsValidated($objectHash, $propertyName, $constraintHash); } $this->validatedConstraints[$objectHash][$constraintHash] = true; diff --git a/src/Symfony/Component/Validator/NodeVisitor/NodeVisitorInterface.php b/src/Symfony/Component/Validator/NodeVisitor/NodeVisitorInterface.php index 012a64191c..fe22a1f219 100644 --- a/src/Symfony/Component/Validator/NodeVisitor/NodeVisitorInterface.php +++ b/src/Symfony/Component/Validator/NodeVisitor/NodeVisitorInterface.php @@ -15,8 +15,17 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Node\Node; /** - * @since %%NextVersion%% + * A node visitor invoked by the node traverser. + * + * At the beginning of the traversal, the method {@link beforeTraversal()} is + * called. For each traversed node, the method {@link visit()} is called. At + * last, the method {@link afterTraversal()} is called when the traversal is + * complete. + * + * @since 2.5 * @author Bernhard Schussek + * + * @see \Symfony\Component\Validator\NodeTraverser\NodeTraverserInterface */ interface NodeVisitorInterface { diff --git a/src/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php index e0317823d5..98f12cb954 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/CallbackValidatorTest.php @@ -129,6 +129,23 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase $this->validator->validate($object, $constraint); } + public function testClosureNullObject() + { + $constraint = new Callback(function ($object, ExecutionContext $context) { + $context->addViolation('My message', array('{{ value }}' => 'foobar'), 'invalidValue'); + + return false; + }); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('My message', array( + '{{ value }}' => 'foobar', + )); + + $this->validator->validate(null, $constraint); + } + public function testClosureExplicitName() { $object = new CallbackValidatorTest_Object(); @@ -163,6 +180,19 @@ class CallbackValidatorTest extends \PHPUnit_Framework_TestCase $this->validator->validate($object, $constraint); } + public function testArrayCallableNullObject() + { + $constraint = new Callback(array(__CLASS__.'_Class', 'validateCallback')); + + $this->context->expects($this->once()) + ->method('addViolation') + ->with('Callback message', array( + '{{ value }}' => 'foobar', + )); + + $this->validator->validate(null, $constraint); + } + public function testArrayCallableExplicitName() { $object = new CallbackValidatorTest_Object(); diff --git a/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php b/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php index 63b8c6a551..2d34116e97 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/Abstract2Dot5ApiTest.php @@ -66,25 +66,6 @@ abstract class Abstract2Dot5ApiTest extends AbstractValidatorTest return $this->validator->validatePropertyValue($object, $propertyName, $value, $groups); } - public function testNoDuplicateValidationIfConstraintInMultipleGroups() - { - $entity = new Entity(); - - $callback = function ($value, ExecutionContextInterface $context) { - $context->addViolation('Message'); - }; - - $this->metadata->addConstraint(new Callback(array( - 'callback' => $callback, - 'groups' => array('Group 1', 'Group 2'), - ))); - - $violations = $this->validator->validate($entity, new Valid(), array('Group 1', 'Group 2')); - - /** @var ConstraintViolationInterface[] $violations */ - $this->assertCount(1, $violations); - } - public function testGroupSequenceAbortsAfterFailedGroup() { $entity = new Entity(); @@ -441,4 +422,42 @@ abstract class Abstract2Dot5ApiTest extends AbstractValidatorTest $this->validator->validate($entity); } + + public function testNoDuplicateValidationIfClassConstraintInMultipleGroups() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addConstraint(new Callback(array( + 'callback' => $callback, + 'groups' => array('Group 1', 'Group 2'), + ))); + + $violations = $this->validator->validate($entity, new Valid(), array('Group 1', 'Group 2')); + + /** @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } + + public function testNoDuplicateValidationIfPropertyConstraintInMultipleGroups() + { + $entity = new Entity(); + + $callback = function ($value, ExecutionContextInterface $context) { + $context->addViolation('Message'); + }; + + $this->metadata->addPropertyConstraint('firstName', new Callback(array( + 'callback' => $callback, + 'groups' => array('Group 1', 'Group 2'), + ))); + + $violations = $this->validator->validate($entity, new Valid(), array('Group 1', 'Group 2')); + + /** @var ConstraintViolationInterface[] $violations */ + $this->assertCount(1, $violations); + } } diff --git a/src/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php b/src/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php index 5468642e7d..c9a8fb509d 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/LegacyValidator2Dot5ApiTest.php @@ -16,7 +16,7 @@ use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\LegacyExecutionContextFactory; use Symfony\Component\Validator\MetadataFactoryInterface; use Symfony\Component\Validator\NodeVisitor\ContextUpdateVisitor; -use Symfony\Component\Validator\NodeVisitor\GroupSequenceResolvingVisitor; +use Symfony\Component\Validator\NodeVisitor\DefaultGroupReplacingVisitor; use Symfony\Component\Validator\NodeVisitor\NodeValidationVisitor; use Symfony\Component\Validator\NodeTraverser\NonRecursiveNodeTraverser; use Symfony\Component\Validator\Validator\LegacyValidator; @@ -38,7 +38,7 @@ class LegacyValidator2Dot5ApiTest extends Abstract2Dot5ApiTest $nodeValidator = new NodeValidationVisitor($nodeTraverser, new ConstraintValidatorFactory()); $contextFactory = new LegacyExecutionContextFactory($nodeValidator, new DefaultTranslator()); $validator = new LegacyValidator($contextFactory, $nodeTraverser, $metadataFactory); - $groupSequenceResolver = new GroupSequenceResolvingVisitor(); + $groupSequenceResolver = new DefaultGroupReplacingVisitor(); $contextRefresher = new ContextUpdateVisitor(); $nodeTraverser->addVisitor($groupSequenceResolver); diff --git a/src/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php b/src/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php index 3edd86b410..8ba44f697d 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/LegacyValidatorLegacyApiTest.php @@ -16,7 +16,7 @@ use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\LegacyExecutionContextFactory; use Symfony\Component\Validator\MetadataFactoryInterface; use Symfony\Component\Validator\NodeVisitor\ContextUpdateVisitor; -use Symfony\Component\Validator\NodeVisitor\GroupSequenceResolvingVisitor; +use Symfony\Component\Validator\NodeVisitor\DefaultGroupReplacingVisitor; use Symfony\Component\Validator\NodeVisitor\NodeValidationVisitor; use Symfony\Component\Validator\NodeTraverser\NonRecursiveNodeTraverser; use Symfony\Component\Validator\Validator\LegacyValidator; @@ -38,7 +38,7 @@ class LegacyValidatorLegacyApiTest extends AbstractLegacyApiTest $nodeValidator = new NodeValidationVisitor($nodeTraverser, new ConstraintValidatorFactory()); $contextFactory = new LegacyExecutionContextFactory($nodeValidator, new DefaultTranslator()); $validator = new LegacyValidator($contextFactory, $nodeTraverser, $metadataFactory); - $groupSequenceResolver = new GroupSequenceResolvingVisitor(); + $groupSequenceResolver = new DefaultGroupReplacingVisitor(); $contextRefresher = new ContextUpdateVisitor(); $nodeTraverser->addVisitor($groupSequenceResolver); diff --git a/src/Symfony/Component/Validator/Tests/Validator/Validator2Dot5ApiTest.php b/src/Symfony/Component/Validator/Tests/Validator/Validator2Dot5ApiTest.php index 277d641b7a..fb6f6317c8 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/Validator2Dot5ApiTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/Validator2Dot5ApiTest.php @@ -16,7 +16,7 @@ use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\ExecutionContextFactory; use Symfony\Component\Validator\MetadataFactoryInterface; use Symfony\Component\Validator\NodeVisitor\ContextUpdateVisitor; -use Symfony\Component\Validator\NodeVisitor\GroupSequenceResolvingVisitor; +use Symfony\Component\Validator\NodeVisitor\DefaultGroupReplacingVisitor; use Symfony\Component\Validator\NodeVisitor\NodeValidationVisitor; use Symfony\Component\Validator\NodeTraverser\NonRecursiveNodeTraverser; use Symfony\Component\Validator\Validator\Validator; @@ -29,7 +29,7 @@ class Validator2Dot5ApiTest extends Abstract2Dot5ApiTest $nodeValidator = new NodeValidationVisitor($nodeTraverser, new ConstraintValidatorFactory()); $contextFactory = new ExecutionContextFactory($nodeValidator, new DefaultTranslator()); $validator = new Validator($contextFactory, $nodeTraverser, $metadataFactory); - $groupSequenceResolver = new GroupSequenceResolvingVisitor(); + $groupSequenceResolver = new DefaultGroupReplacingVisitor(); $contextRefresher = new ContextUpdateVisitor(); $nodeTraverser->addVisitor($groupSequenceResolver);