Skip to content

Commit e642384

Browse files
bug #62396 [PropertyInfo] Fix inconsistency between isWritable and getWriteInfo (yoeunes)
This PR was merged into the 6.4 branch. Discussion ---------- [PropertyInfo] Fix inconsistency between isWritable and getWriteInfo | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | - | License | MIT This PR fixes an inconsistency between `isWritable` and `getWriteInfo` in the `ReflectionExtractor`. `isWritable()` correctly found mutators for `snake_case` properties because it had a fallback mechanism: 1. Check for `setSnakeProperty` 2. If not found, check for `setSnake_method` The `getWriteInfo()` method *only* checked for the camelCase version (`setSnakeProperty`) This caused `isWritable(..., 'snake_method')` to return `true`, while `getWriteInfo(..., 'snake_method')` would incorrectly return `TYPE_NONE`. Commits ------- 340d3f9 [PropertyInfo] Fix inconsistency between isWritable and getWriteInfo
2 parents 0dd5cfb + 340d3f9 commit e642384

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ public function getWriteInfo(string $class, string $property, array $context = [
305305
$allowAdderRemover = $context['enable_adder_remover_extraction'] ?? true;
306306

307307
$camelized = $this->camelize($property);
308+
$nonCamelized = ucfirst($property);
308309
$constructor = $reflClass->getConstructor();
309310
$singulars = $this->inflector->singularize($camelized);
310311
$errors = [];
@@ -347,7 +348,26 @@ public function getWriteInfo(string $class, string $property, array $context = [
347348
}
348349
}
349350

351+
if ($camelized !== $nonCamelized) {
352+
foreach ($this->mutatorPrefixes as $mutatorPrefix) {
353+
$methodName = $mutatorPrefix.$nonCamelized;
354+
355+
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, $methodName, 1);
356+
if (!$accessible) {
357+
$errors[] = $methodAccessibleErrors;
358+
continue;
359+
}
360+
361+
$method = $reflClass->getMethod($methodName);
362+
363+
if (!\in_array($mutatorPrefix, $this->arrayMutatorPrefixes, true)) {
364+
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $methodName, $this->getWriteVisiblityForMethod($method), $method->isStatic());
365+
}
366+
}
367+
}
368+
350369
$getsetter = lcfirst($camelized);
370+
$getsetterNonCamelized = lcfirst($nonCamelized);
351371

352372
if ($allowGetterSetter) {
353373
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, $getsetter, 1);
@@ -358,6 +378,16 @@ public function getWriteInfo(string $class, string $property, array $context = [
358378
}
359379

360380
$errors[] = $methodAccessibleErrors;
381+
382+
if ($getsetter !== $getsetterNonCamelized) {
383+
[$accessible, $methodAccessibleErrors] = $this->isMethodAccessible($reflClass, $getsetterNonCamelized, 1);
384+
if ($accessible) {
385+
$method = $reflClass->getMethod($getsetterNonCamelized);
386+
387+
return new PropertyWriteInfo(PropertyWriteInfo::TYPE_METHOD, $getsetterNonCamelized, $this->getWriteVisiblityForMethod($method), $method->isStatic());
388+
}
389+
$errors[] = $methodAccessibleErrors;
390+
}
361391
}
362392

363393
if ($reflClass->hasProperty($property) && ($reflClass->getProperty($property)->getModifiers() & $this->propertyReflectionFlags)) {

src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,9 @@ public static function writeMutatorProvider(): array
633633
[Php71DummyExtended2::class, 'string', false, false, '', '', null, null, PropertyWriteInfo::VISIBILITY_PUBLIC, false],
634634
[Php71DummyExtended2::class, 'string', true, false, '', '', null, null, PropertyWriteInfo::VISIBILITY_PUBLIC, false],
635635
[Php71DummyExtended2::class, 'baz', false, true, PropertyWriteInfo::TYPE_ADDER_AND_REMOVER, null, 'addBaz', 'removeBaz', PropertyWriteInfo::VISIBILITY_PUBLIC, false],
636+
[SnakeCaseDummy::class, 'snake_property', false, true, PropertyWriteInfo::TYPE_METHOD, 'setSnakeProperty', null, null, PropertyWriteInfo::VISIBILITY_PUBLIC, false],
637+
[SnakeCaseDummy::class, 'snake_method', false, true, PropertyWriteInfo::TYPE_METHOD, 'setSnake_method', null, null, PropertyWriteInfo::VISIBILITY_PUBLIC, false],
638+
[SnakeCaseDummy::class, 'snake_readonly', false, false, PropertyWriteInfo::TYPE_NONE, null, null, null, null, null],
636639
];
637640
}
638641

0 commit comments

Comments
 (0)