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

Skip to content

Commit 72cfcf7

Browse files
mrossardnicolas-grekas
authored andcommitted
[Validator] fix mapping properties using property hooks
1 parent 4169409 commit 72cfcf7

3 files changed

Lines changed: 69 additions & 2 deletions

File tree

Mapping/PropertyMetadata.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ public function getPropertyValue(mixed $object): mixed
5151
// There is no way to check if a property has been unset or if it is uninitialized.
5252
// When trying to access an uninitialized property, __get method is triggered.
5353

54-
// If __get method is not present, no fallback is possible
54+
// If there is neither __get method nor get hook, no fallback is possible
5555
// Otherwise we need to catch an Error in case we are trying to access an uninitialized but set property.
56-
if (!method_exists($object, '__get')) {
56+
if (!method_exists($object, '__get') && (\PHP_VERSION_ID < 80400 || !$reflProperty->hasHook(\PropertyHookType::Get))) {
5757
return null;
5858
}
5959

Tests/Fixtures/EntityWithHook.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Fixtures;
13+
14+
class EntityWithHook
15+
{
16+
public string $name;
17+
18+
protected int $id = 1;
19+
20+
protected string $withHook {
21+
get {
22+
$this->withHook ??= strtolower($this->name);
23+
24+
return $this->withHook;
25+
}
26+
}
27+
28+
protected string $withHookOnSelf {
29+
get => strtolower($this->withHookOnSelf);
30+
}
31+
}

Tests/Mapping/PropertyMetadataTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Validator\Mapping\PropertyMetadata;
1717
use Symfony\Component\Validator\Tests\Fixtures\Entity_74;
1818
use Symfony\Component\Validator\Tests\Fixtures\Entity_74_Proxy;
19+
use Symfony\Component\Validator\Tests\Fixtures\EntityWithHook;
1920
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity;
2021
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\EntityParent;
2122

@@ -77,4 +78,39 @@ public function testGetPropertyValueFromUninitializedPropertyShouldNotReturnNull
7778
$this->assertNull($notUnsetMetadata->getPropertyValue($entity));
7879
$this->assertEquals(42, $metadata->getPropertyValue($entity));
7980
}
81+
82+
/**
83+
* @requires PHP 8.4
84+
*/
85+
public function testGetPropertyValueFromUninitializedPropertyShouldUseHookIfPresent()
86+
{
87+
$entity = new EntityWithHook();
88+
$entity->name = 'FOOBAR';
89+
$metadata = new PropertyMetadata(EntityWithHook::class, 'withHook');
90+
91+
$this->assertEquals('foobar', $metadata->getPropertyValue($entity));
92+
}
93+
94+
/**
95+
* @requires PHP 8.4
96+
*/
97+
public function testGetPropertyValueFromUninitializedPropertyShouldReturnNullIfHookFails()
98+
{
99+
$entity = new EntityWithHook();
100+
// $withHook uses $entity->name but it's not initialized
101+
$metadata = new PropertyMetadata(EntityWithHook::class, 'withHook');
102+
103+
$this->assertNull($metadata->getPropertyValue($entity));
104+
}
105+
106+
/**
107+
* @requires PHP 8.4
108+
*/
109+
public function testGetPropertyValueFromUninitializedPropertyWithHookReferencingItself()
110+
{
111+
$entity = new EntityWithHook();
112+
$metadata = new PropertyMetadata(EntityWithHook::class, 'withHookOnSelf');
113+
114+
$this->assertNull($metadata->getPropertyValue($entity));
115+
}
80116
}

0 commit comments

Comments
 (0)