8000 [PropertyAccess] Fix checking for missing properties · symfony/symfony@9610a7c · GitHub
[go: up one dir, main page]

Skip to content

Commit 9610a7c

Browse files
[PropertyAccess] Fix checking for missing properties
1 parent 9d473e3 commit 9610a7c

File tree

4 files changed

+29
-9
lines changed

4 files changed

+29
-9
lines changed

src/Symfony/Component/PropertyAccess/PropertyAccessor.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,18 @@ private function readProperty(array $zval, string $property, bool $ignoreInvalid
411411
throw $e;
412412
}
413413
} elseif (PropertyReadInfo::TYPE_PROPERTY === $type) {
414-
if ($access->canBeReference() && !isset($object->$name) && !\array_key_exists($name, (array) $object) && !(new \ReflectionProperty($class, $name))->hasType()) {
415-
throw new UninitializedPropertyException(sprintf('The property "%s::$%s" is not initialized.', $class, $name));
414+
if (!isset($object->$name) && !\array_key_exists($name, (array) $object)) {
415+
try {
416+
$r = new \ReflectionProperty($class, $name);
417+
418+
if ($r->isPublic() && !$r->hasType()) {
419+
throw new UninitializedPropertyException(sprintf('The property "%s::$%s" is not initialized.', $class, $name));
420+
}
421+
} catch (\ReflectionException $e) {
422+
if (!$ignoreInvalidProperty) {
423+
throw new NoSuchPropertyException(sprintf('Can\'t get a way to read the property "%s" in class "%s".', $property, $class));
424+
}
425+
}
416426
}
417427

418428
$result[self::VALUE] = $object->$name;

src/Symfony/Component/PropertyAccess/Tests/Fixtures/TestClassMagicGet.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,9 @@ public function __get(string $property)
3939
return 'constant value';
4040
}
4141
}
42+
43+
public function __isset(string $property)
44+
{
45+
return \in_array($property, ['magicProperty', 'constantMagicProperty'], true);
46+
}
4247
}

src/Symfony/Component/PropertyAccess/Tests/PropertyAccessorTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -990,12 +990,19 @@ public function testGetValuePropertyThrowsExceptionIfUninitializedWithLazyGhost(
990990

991991
public function testGetValueGetterThrowsExceptionIfUninitializedWithLazyGhost()
992992
{
993+
$lazyGhost = $this->createUninitializedObjectPropertyGhost();
994+
993995
$this->expectException(UninitializedPropertyException::class);
994996
$this->expectExceptionMessage('The property "Symfony\Component\PropertyAccess\Tests\Fixtures\UninitializedObjectProperty::$privateUninitialized" is not readable because it is typed "DateTimeInterface". You should initialize it or declare a default value instead.');
995997

998+
$this->propertyAccessor->getValue($lazyGhost, 'privateUninitialized');
999+
}
1000+
1001+
public function testIsReadableWithMissingPropertyAndLazyGhost()
1002+
{
9961003
$lazyGhost = $this->createUninitializedObjectPropertyGhost();
9971004

998-
$this->propertyAccessor->getValue($lazyGhost, 'privateUninitialized');
1005+
$this->assertFalse($this->propertyAccessor->isReadable($lazyGhost, 'dummy'));
9991006
}
10001007

10011008
private function createUninitializedObjectPropertyGhost(): UninitializedObjectProperty

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,14 +274,12 @@ public function getReadInfo(string $class, string $property, array $context = []
274274
return new PropertyReadInfo(PropertyReadInfo::TYPE_METHOD, $getsetter, $this->getReadVisiblityForMethod($method), $method->isStatic(), false);
275275
}
276276

277-
if ($allowMagicGet && $reflClass->hasMethod('__get') && ($reflClass->getMethod('__get')->getModifiers() & $this->methodReflectionFlags)) {
278-
return new PropertyReadInfo(PropertyReadInfo::TYPE_PROPERTY, $property, PropertyReadInfo::VISIBILITY_PUBLIC, false, false);
277+
if ($allowMagicGet && $reflClass->hasMethod('__get') && (($r = $reflClass->getMethod('__get'))->getModifiers() & $this->methodReflectionFlags)) {
278+
return new PropertyReadInfo(PropertyReadInfo::TYPE_PROPERTY, $property, PropertyReadInfo::VISIBILITY_PUBLIC, false, $r->returnsReference());
279279
}
280280

281-
if ($hasProperty && ($reflClass->getProperty($property)->getModifiers() & $this->propertyReflectionFlags)) {
282-
$reflProperty = $reflClass->getProperty($property);
283-
284-
return new PropertyReadInfo(PropertyReadInfo::TYPE_PROPERTY, $property, $this->getReadVisiblityForProperty($reflProperty), $reflProperty->isStatic(), true);
281+
if ($hasProperty && (($r = $reflClass->getProperty($property))->getModifiers() & $this->propertyReflectionFlags)) {
282+
return new PropertyReadInfo(PropertyReadInfo::TYPE_PROPERTY, $property, $this->getReadVisiblityForProperty($r), $r->isStatic(), true);
285283
}
286284

287285
if ($allowMagicCall && $reflClass->hasMethod('__call') && ($reflClass->getMethod('__call')->getModifiers() & $this->methodReflectionFlags)) {

0 commit comments

Comments
 (0)
0