Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit aee10cd

Browse files
committed
bug #36627 [Validator] fix lazy property usage. (bendavies)
This PR was squashed before being merged into the 3.4 branch (closes #36627). Discussion ---------- [Validator] fix lazy property usage. | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #36343 | License | MIT | Doc PR | This attempts to fix a large regression introduced in #36343, which broke recursing values returned from `getter` Constraints, because they are now wrapped in in a `LazyProperty`. The `LazyProperty` needs to be evaluated because some checks are done on the type of `$value`, i.e `is_array` etc... in `validateGenericNode`. I'm concerned that the original PR didn't really add sufficient test coverage for the introduction of `LazyProperty`, and I'm not 100% sure that I've caught all the cases where the `instanceof` check are needed in this PR. For the tests, I added the `@dataProvider getConstraintMethods` to every test that hit the problem area of code. ~~The only issue is that my fixed has broken the test introduced in #36343, `testGroupedMethodConstraintValidateInSequence`.~~ ~~I think I need @HeahDude to help me work through this. Maybe there is a more simple solution, one that doesn't require doing `instanceof LazyPropery` checks in multiple places, because this feels very brittle.~~ EDIT: fixed that test. Commits ------- 281861e [Validator] fix lazy property usage.
2 parents d765a09 + 281861e commit aee10cd

File tree

3 files changed

+56
-13
lines changed

3 files changed

+56
-13
lines changed

src/Symfony/Component/Validator/Tests/Fixtures/Entity.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ public function __construct($internal = null)
5353
$this->internal = $internal;
5454
}
5555

56+
public function getFirstName()
57+
{
58+
return $this->firstName;
59+
}
60+
5661
public function getInternal()
5762
{
5863
return $this->internal.' from getter';
@@ -141,4 +146,9 @@ public function setChildB($childB)
141146
{
142147
$this->childB = $childB;
143148
}
149+
150+
public function getReference()
151+
{
152+
return $this->reference;
153+
}
144154
}

src/Symfony/Component/Validator/Tests/Validator/AbstractValidatorTest.php

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ abstract class AbstractValidatorTest extends TestCase
3232

3333
const REFERENCE_CLASS = 'Symfony\Component\Validator\Tests\Fixtures\Reference';
3434

35+
const LAZY_PROPERTY = 'Symfony\Component\Validator\Validator\LazyProperty';
36+
3537
/**
3638
* @var FakeMetadataFactory
3739
*/
@@ -54,6 +56,7 @@ protected function setUp()
5456
$this->referenceMetadata = new ClassMetadata(self::REFERENCE_CLASS);
5557
$this->metadataFactory->addMetadata($this->metadata);
5658
$this->metadataFactory->addMetadata($this->referenceMetadata);
59+
$this->metadataFactory->addMetadata(new ClassMetadata(self::LAZY_PROPERTY));
5760
}
5861

5962
protected function tearDown()
@@ -510,7 +513,10 @@ public function testFailOnScalarReferences()
510513
$this->validate($entity);
511514
}
512515

513-
public function testArrayReference()
516+
/**
517+
* @dataProvider getConstraintMethods
518+
*/
519+
public function testArrayReference($constraintMethod)
514520
{
515521
$entity = new Entity();
516522
$entity->reference = ['key' => new Reference()];
@@ -528,7 +534,7 @@ public function testArrayReference()
528534
$context->addViolation('Message %param%', ['%param%' => 'value']);
529535
};
530536

531-
$this->metadata->addPropertyConstraint('reference', new Valid());
537+
$this->metadata->$constraintMethod('reference', new Valid());
532538
$this->referenceMetadata->addConstraint(new Callback([
533539
'callback' => $callback,
534540
'groups' => 'Group',
@@ -548,8 +554,10 @@ public function testArrayReference()
548554
$this->assertNull($violations[0]->getCode());
549555
}
550556

551-
// https://github.com/symfony/symfony/issues/6246
552-
public function testRecursiveArrayReference()
557+
/**
558+
* @dataProvider getConstraintMethods
559+
*/
560+
public function testRecursiveArrayReference($constraintMethod)
553561
{
554562
$entity = new Entity();
555563
$entity->reference = [2 => ['key' => new Reference()]];
@@ -567,7 +575,7 @@ public function testRecursiveArrayReference()
567575
$context->addViolation('Message %param%', ['%param%' => 'value']);
568576
};
569577

570-
$this->metadata->addPropertyConstraint('reference', new Valid());
578+
$this->metadata->$constraintMethod('reference', new Valid());
571579
$this->referenceMetadata->addConstraint(new Callback([
572580
'callback' => $callback,
573581
'groups' => 'Group',
@@ -611,7 +619,10 @@ public function testOnlyCascadedArraysAreTraversed()
611619
$this->assertCount(0, $violations);
612620
}
613621

614-
public function testArrayTraversalCannotBeDisabled()
622+
/**
623+
* @dataProvider getConstraintMethods
624+
*/
625+
public function testArrayTraversalCannotBeDisabled($constraintMethod)
615626
{
616627
$entity = new Entity();
617628
$entity->reference = ['key' => new Reference()];
@@ -620,7 +631,7 @@ public function testArrayTraversalCannotBeDisabled()
620631
$context->addViolation('Message %param%', ['%param%' => 'value']);
621632
};
622633

623-
$this->metadata->addPropertyConstraint('reference', new Valid([
634+
$this->metadata->$constraintMethod('reference', new Valid([
624635
'traverse' => false,
625636
]));
626637
$this->referenceMetadata->addConstraint(new Callback($callback));
@@ -631,7 +642,10 @@ public function testArrayTraversalCannotBeDisabled()
631642
$this->assertCount(1, $violations);
632643
}
633644

634-
public function testRecursiveArrayTraversalCannotBeDisabled()
645+
/**
646+
* @dataProvider getConstraintMethods
647+
*/
648+
public function testRecursiveArrayTraversalCannotBeDisabled($constraintMethod)
635649
{
636650
$entity = new Entity();
637651
$entity->reference = [2 => ['key' => new Reference()]];
@@ -640,9 +654,10 @@ public function testRecursiveArrayTraversalCannotBeDisabled()
640654
$context->addViolation('Message %param%', ['%param%' => 'value']);
641655
};
642656

643-
$this->metadata->addPropertyConstraint('reference', new Valid([
657+
$this->metadata->$constraintMethod('reference', new Valid([
644658
'traverse' => false,
645659
]));
660+
646661
$this->referenceMetadata->addConstraint(new Callback($callback));
647662

648663
$violations = $this->validate($entity);
@@ -651,25 +666,31 @@ public function testRecursiveArrayTraversalCannotBeDisabled()
651666
$this->assertCount(1, $violations);
652667
}
653668

654-
public function testIgnoreScalarsDuringArrayTraversal()
669+
/**
670+
* @dataProvider getConstraintMethods
671+
*/
672+
public function testIgnoreScalarsDuringArrayTraversal($constraintMethod)
655673
{
656674
$entity = new Entity();
657675
$entity->reference = ['string', 1234];
658676

659-
$this->metadata->addPropertyConstraint('reference', new Valid());
677+
$this->metadata->$constraintMethod('reference', new Valid());
660678

661679
$violations = $this->validate($entity);
662680

663681
/* @var ConstraintViolationInterface[] $violations */
664682
$this->assertCount(0, $violations);
665683
}
666684

667-
public function testIgnoreNullDuringArrayTraversal()
685+
/**
686+
* @dataProvider getConstraintMethods
687+
*/
688+
public function testIgnoreNullDuringArrayTraversal($constraintMethod)
668689
{
669690
$entity = new Entity();
670691
$entity->reference = [null];
671692

672-
$this->metadata->addPropertyConstraint('reference', new Valid());
693+
$this->metadata->$constraintMethod('reference', new Valid());
673694

674695
$violations = $this->validate($entity);
675696

@@ -1218,6 +1239,14 @@ public function testReplaceDefaultGroup($sequence, array $assertViolations)
12181239
}
12191240
}
12201241

1242+
public function getConstraintMethods()
1243+
{
1244+
return [
1245+
['addPropertyConstraint'],
1246+
['addGetterConstraint'],
1247+
];
1248+
}
1249+
12211250
public function getTestReplaceDefaultGroup()
12221251
{
12231252
return [

src/Symfony/Component/Validator/Validator/RecursiveContextualValidator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,10 @@ private function validateGenericNode($value, $object, $cacheKey, MetadataInterfa
677677
// See validateClassNode()
678678
$cascadedGroups = null !== $cascadedGroups && \count($cascadedGroups) > 0 ? $cascadedGroups : $groups;
679679

680+
if ($value instanceof LazyProperty) {
681+
$value = $value->getPropertyValue();
682+
}
683+
680684
if (\is_array($value)) {
681685
// Arrays are always traversed, independent of the specified
682686
// traversal strategy

0 commit comments

Comments
 (0)