diff --git a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php index 9e0afe06390be..49ebef0c7c013 100644 --- a/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Validator/RecursiveValidatorTest.php @@ -12,6 +12,10 @@ namespace Symfony\Component\Validator\Tests\Validator; use Symfony\Component\Translation\IdentityTranslator; +use Symfony\Component\Validator\Constraints\All; +use Symfony\Component\Validator\Constraints\Collection; +use Symfony\Component\Validator\Constraints\Length; +use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\ConstraintValidatorFactory; use Symfony\Component\Validator\Context\ExecutionContextFactory; use Symfony\Component\Validator\Mapping\Factory\MetadataFactoryInterface; @@ -95,4 +99,38 @@ public function testRelationBetweenChildAAndChildB() $validator->validate($entity, null, array()); } + + public function testCollectionConstraintValidateAllGroupsForNestedConstraints() + { + $this->metadata->addPropertyConstraint('data', new Collection(array('fields' => array( + 'one' => array(new NotBlank(array('groups' => 'one')), new Length(array('min' => 2, 'groups' => 'two'))), + 'two' => array(new NotBlank(array('groups' => 'two'))), + )))); + + $entity = new Entity(); + $entity->data = array('one' => 't', 'two' => ''); + + $violations = $this->validator->validate($entity, null, array('one', 'two')); + + $this->assertCount(2, $violations); + $this->assertInstanceOf(Length::class, $violations->get(0)->getConstraint()); + $this->assertInstanceOf(NotBlank::class, $violations->get(1)->getConstraint()); + } + + public function testAllConstraintValidateAllGroupsForNestedConstraints() + { + $this->metadata->addPropertyConstraint('data', new All(array('constraints' => array( + new NotBlank(array('groups' => 'one')), + new Length(array('min' => 2, 'groups' => 'two')), + )))); + + $entity = new Entity(); + $entity->data = array('one' => 't', 'two' => ''); + + $violations = $this->validator->validate($entity, null, array('one', 'two')); + + $this->assertCount(2, $violations); + $this->assertInstanceOf(NotBlank::class, $violations->get(0)->getConstraint()); + $this->assertInstanceOf(Length::class, $violations->get(1)->getConstraint()); + } } diff --git a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php index f50f767bd9685..2301618367b86 100644 --- a/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php +++ b/src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Validator\Validator; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\Composite; use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\ConstraintValidatorFactoryInterface; use Symfony\Component\Validator\Context\ExecutionContext; @@ -787,6 +788,10 @@ private function validateInGroup($value, $cacheKey, MetadataInterface $metadata, if (null !== $cacheKey) { $constraintHash = spl_object_hash($constraint); + if ($constraint instanceof Composite) { + $constraintHash .= $group; + } + if ($context->isConstraintValidated($cacheKey, $constraintHash)) { continue; }