diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index c56f7ba57e..20d499f855 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -26,6 +26,8 @@ CHANGELOG * changed `ValidatorInterface::getMetadataFactory` to return a `MetadataFactoryInterface` instead of a `ClassMetadataFactoryInterface` * removed `ClassMetadataFactoryInterface` type hint from `ValidatorBuilderInterface::setMetadataFactory`. As of Symfony 2.3, this method will be typed against `MetadataFactoryInterface` instead. + * [BC BREAK] the switches `traverse` and `deep` in the `Valid` constraint and in `GraphWalker::walkReference` + are ignored for arrays now. Arrays are always traversed recursively. 2.1.0 ----- diff --git a/src/Symfony/Component/Validator/Tests/ValidationVisitorTest.php b/src/Symfony/Component/Validator/Tests/ValidationVisitorTest.php index ab35b6f799..86fdbd5e95 100644 --- a/src/Symfony/Component/Validator/Tests/ValidationVisitorTest.php +++ b/src/Symfony/Component/Validator/Tests/ValidationVisitorTest.php @@ -426,6 +426,46 @@ class ValidationVisitorTest extends \PHPUnit_Framework_TestCase $this->assertEquals($violations, $this->visitor->getViolations()); } + // https://github.com/symfony/symfony/issues/6246 + public function testValidateCascadedPropertyRecursesArraysByDefault() + { + $entity = new Entity(); + $entity->reference = array( + 'key' => array( + 'nested' => new Entity(), + ), + ); + + // add a constraint for the entity that always fails + $this->metadata->addConstraint(new FailingConstraint()); + + // validate iterator when validating the property "reference" + $this->metadata->addPropertyConstraint('reference', new Valid()); + + $this->visitor->validate($entity, 'Default', ''); + + $violations = new ConstraintViolationList(array( + // generated by the root object + new ConstraintViolation( + 'Failed', + array(), + 'Root', + '', + $entity + ), + // nothing generated by the reference! + new ConstraintViolation( + 'Failed', + array(), + 'Root', + 'reference[key][nested]', + $entity->reference['key']['nested'] + ), + )); + + $this->assertEquals($violations, $this->visitor->getViolations()); + } + public function testValidateCascadedPropertyRecursesIfDeepIsSet() { $entity = new Entity(); diff --git a/src/Symfony/Component/Validator/ValidationVisitor.php b/src/Symfony/Component/Validator/ValidationVisitor.php index c8268304cd..6b1a53074f 100644 --- a/src/Symfony/Component/Validator/ValidationVisitor.php +++ b/src/Symfony/Component/Validator/ValidationVisitor.php @@ -129,7 +129,10 @@ class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionCo } } - if ($traverse && (is_array($value) || $value instanceof \Traversable)) { + // Validate arrays recursively by default, otherwise every driver needs + // to implement special handling for arrays. + // https://github.com/symfony/symfony/issues/6246 + if (is_array($value) || ($traverse && $value instanceof \Traversable)) { foreach ($value as $key => $element) { // Ignore any scalar values in the collection if (is_object($element) || is_array($element)) {