Skip to content

Commit 01966bc

Browse files
committed
bug #31481 [Validator] Autovalidation: skip readonly props (dunglas)
This PR was merged into the 4.3 branch. Discussion ---------- [Validator] Autovalidation: skip readonly props | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | BC breaks? | no | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | n/a | License | MIT | Doc PR | n/a Read-only properties (such as an autogenerated ID) must be skipped during the validation (it makes no sense to validate a RO property anyway). This is an allowed BC break because this feature will be introduced in 4.3. Commits ------- e7dc5e1045 [Validator] Autovalidation: skip readonly props
2 parents 90f8636 + 7ebf976 commit 01966bc

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

Mapping/Loader/PropertyInfoLoader.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Validator\Mapping\Loader;
1313

14+
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
1415
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
1516
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
1617
use Symfony\Component\PropertyInfo\Type as PropertyInfoType;
@@ -29,12 +30,14 @@ final class PropertyInfoLoader implements LoaderInterface
2930
{
3031
private $listExtractor;
3132
private $typeExtractor;
33+
private $accessExtractor;
3234
private $classValidatorRegexp;
3335

34-
public function __construct(PropertyListExtractorInterface $listExtractor, PropertyTypeExtractorInterface $typeExtractor, string $classValidatorRegexp = null)
36+
public function __construct(PropertyListExtractorInterface $listExtractor, PropertyTypeExtractorInterface $typeExtractor, PropertyAccessExtractorInterface $accessExtractor, string $classValidatorRegexp = null)
3537
{
3638
$this->listExtractor = $listExtractor;
3739
$this->typeExtractor = $typeExtractor;
40+
$this->accessExtractor = $accessExtractor;
3841
$this->classValidatorRegexp = $classValidatorRegexp;
3942
}
4043

@@ -53,6 +56,10 @@ public function loadClassMetadata(ClassMetadata $metadata)
5356
}
5457

5558
foreach ($properties as $property) {
59+
if (false === $this->accessExtractor->isWritable($className, $property)) {
60+
continue;
61+
}
62+
5663
$types = $this->typeExtractor->getTypes($className, $property);
5764
if (null === $types) {
5865
continue;

Tests/Fixtures/PropertyInfoLoaderEntity.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,6 @@ class PropertyInfoLoaderEntity
4646
* })
4747
*/
4848
public $alreadyPartiallyMappedCollection;
49+
50+
public $readOnly;
4951
}

Tests/Mapping/Loader/PropertyInfoLoaderTest.php

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function testLoadClassMetadata()
4545
'alreadyMappedNotNull',
4646
'alreadyMappedNotBlank',
4747
'alreadyPartiallyMappedCollection',
48+
'readOnly',
4849
])
4950
;
5051
$propertyInfoStub
@@ -58,11 +59,27 @@ public function testLoadClassMetadata()
5859
[new Type(Type::BUILTIN_TYPE_FLOAT, true)], // The existing constraint is float
5960
[new Type(Type::BUILTIN_TYPE_STRING, true)],
6061
[new Type(Type::BUILTIN_TYPE_STRING, true)],
61-
[new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true, null, new Type(Type::BUILTIN_TYPE_FLOAT))]
62+
[new Type(Type::BUILTIN_TYPE_ARRAY, true, null, true, null, new Type(Type::BUILTIN_TYPE_FLOAT))],
63+
[new Type(Type::BUILTIN_TYPE_STRING)]
64+
))
65+
;
66+
$propertyInfoStub
67+
->method('isWritable')
68+
->will($this->onConsecutiveCalls(
69+
true,
70+
true,
71+
true,
72+
true,
73+
true,
74+
true,
75+
true,
76+
true,
77+
true,
78+
false
6279
))
6380
;
6481

65-
$propertyInfoLoader = new PropertyInfoLoader($propertyInfoStub, $propertyInfoStub);
82+
$propertyInfoLoader = new PropertyInfoLoader($propertyInfoStub, $propertyInfoStub, $propertyInfoStub);
6683

6784
$validator = Validation::createValidatorBuilder()
6885
->enableAnnotationMapping()
@@ -137,6 +154,9 @@ public function testLoadClassMetadata()
137154
$this->assertSame('string', $alreadyPartiallyMappedCollectionConstraints[0]->constraints[0]->type);
138155
$this->assertInstanceOf(Iban::class, $alreadyPartiallyMappedCollectionConstraints[0]->constraints[1]);
139156
$this->assertInstanceOf(NotNull::class, $alreadyPartiallyMappedCollectionConstraints[0]->constraints[2]);
157+
158+
$readOnlyMetadata = $classMetadata->getPropertyMetadata('readOnly');
159+
$this->assertEmpty($readOnlyMetadata);
140160
}
141161

142162
/**
@@ -154,7 +174,7 @@ public function testClassValidator(bool $expected, string $classValidatorRegexp
154174
->willReturn([new Type(Type::BUILTIN_TYPE_STRING)])
155175
;
156176

157-
$propertyInfoLoader = new PropertyInfoLoader($propertyInfoStub, $propertyInfoStub, $classValidatorRegexp);
177+
$propertyInfoLoader = new PropertyInfoLoader($propertyInfoStub, $propertyInfoStub, $propertyInfoStub, $classValidatorRegexp);
158178

159179
$classMetadata = new ClassMetadata(PropertyInfoLoaderEntity::class);
160180
$this->assertSame($expected, $propertyInfoLoader->loadClassMetadata($classMetadata));

0 commit comments

Comments
 (0)