[Validator] try to call __get method if property is uninitialized
This commit is contained in:
parent
b2339b5e32
commit
427bc3aa18
@ -50,8 +50,21 @@ class PropertyMetadata extends MemberMetadata
|
||||
{
|
||||
$reflProperty = $this->getReflectionMember($object);
|
||||
|
||||
if (\PHP_VERSION_ID >= 70400 && !$reflProperty->isInitialized($object)) {
|
||||
return null;
|
||||
if (\PHP_VERSION_ID >= 70400 && $reflProperty->hasType() && !$reflProperty->isInitialized($object)) {
|
||||
// There is no way to check if a property has been unset or if it is uninitialized.
|
||||
// When trying to access an uninitialized property, __get method is triggered.
|
||||
|
||||
// If __get method is not present, no fallback is possible
|
||||
// Otherwise we need to catch an Error in case we are trying to access an uninitialized but set property.
|
||||
if (!method_exists($object, '__get')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return $reflProperty->getValue($object);
|
||||
} catch (\Error $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return $reflProperty->getValue($object);
|
||||
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Validator\Tests\Fixtures;
|
||||
|
||||
class Entity_74_Proxy extends Entity_74
|
||||
{
|
||||
public string $notUnset;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
unset($this->uninitialized);
|
||||
}
|
||||
|
||||
public function __get($name)
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
}
|
@ -15,11 +15,13 @@ use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Validator\Mapping\PropertyMetadata;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\Entity;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\Entity_74;
|
||||
use Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy;
|
||||
|
||||
class PropertyMetadataTest extends TestCase
|
||||
{
|
||||
const CLASSNAME = 'Symfony\Component\Validator\Tests\Fixtures\Entity';
|
||||
const CLASSNAME_74 = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74';
|
||||
const CLASSNAME_74_PROXY = 'Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy';
|
||||
const PARENTCLASS = 'Symfony\Component\Validator\Tests\Fixtures\EntityParent';
|
||||
|
||||
public function testInvalidPropertyName()
|
||||
@ -66,4 +68,17 @@ class PropertyMetadataTest extends TestCase
|
||||
|
||||
$this->assertNull($metadata->getPropertyValue($entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.4
|
||||
*/
|
||||
public function testGetPropertyValueFromUninitializedPropertyShouldNotReturnNullIfMagicGetIsPresent()
|
||||
{
|
||||
$entity = new Entity_74_Proxy();
|
||||
$metadata = new PropertyMetadata(self::CLASSNAME_74_PROXY, 'uninitialized');
|
||||
$notUnsetMetadata = new PropertyMetadata(self::CLASSNAME_74_PROXY, 'notUnset');
|
||||
|
||||
$this->assertNull($notUnsetMetadata->getPropertyValue($entity));
|
||||
$this->assertEquals(42, $metadata->getPropertyValue($entity));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user