Skip to content

Commit ee39bd0

Browse files
committed
Add RawValuePropertyAccessor to see how it will look in 8.4, pre support for lazy objects.
1 parent 65bfdcf commit ee39bd0

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/Mapping/ClassMetadata.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Doctrine\ORM\Mapping\PropertyAccessors\EnumPropertyAccessor;
1919
use Doctrine\ORM\Mapping\PropertyAccessors\ObjectCastPropertyAccessor;
2020
use Doctrine\ORM\Mapping\PropertyAccessors\PropertyAccessor;
21+
use Doctrine\ORM\Mapping\PropertyAccessors\RawValuePropertyAccessor;
2122
use Doctrine\ORM\Mapping\PropertyAccessors\ReadonlyAccessor;
2223
use Doctrine\ORM\Mapping\PropertyAccessors\TypedNoDefaultPropertyAccessor;
2324
use Doctrine\Persistence\Mapping\ClassMetadata as PersistenceClassMetadata;
@@ -62,6 +63,8 @@
6263
use function trait_exists;
6364
use function trim;
6465

66+
use const PHP_VERSION_ID;
67+
6568
/**
6669
* A <tt>ClassMetadata</tt> instance holds all the object-relational mapping metadata
6770
* of an entity and its associations.
@@ -2689,7 +2692,10 @@ public function getSequencePrefix(AbstractPlatform $platform): string
26892692
private function createPropertyAccessor(string $className, string $propertyName): PropertyAccessor
26902693
{
26912694
$reflectionProperty = new ReflectionProperty($className, $propertyName);
2692-
$accessor = ObjectCastPropertyAccessor::fromReflectionProperty($reflectionProperty);
2695+
2696+
$accessor = PHP_VERSION_ID >= 80400
2697+
? RawValuePropertyAccessor::fromReflectionProperty($reflectionProperty)
2698+
: ObjectCastPropertyAccessor::fromReflectionProperty($reflectionProperty);
26932699

26942700
if ($reflectionProperty->hasType() && ! $reflectionProperty->getType()->allowsNull()) {
26952701
$accessor = new TypedNoDefaultPropertyAccessor($accessor, $reflectionProperty);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\ORM\Mapping\PropertyAccessors;
6+
7+
use Doctrine\ORM\Proxy\InternalProxy;
8+
use ReflectionProperty;
9+
10+
use function ltrim;
11+
12+
/**
13+
* This is a PHP 8.4 and up only class and replaces ObjectCastPropertyAccessor.
14+
*
15+
* It works based on the raw values of a property, which for a case of property hooks
16+
* is the backed value. If we kept using setValue/getValue, this would go through the hooks,
17+
* which potentially change the data.
18+
*/
19+
class RawValuePropertyAccessor implements PropertyAccessor
20+
{
21+
public static function fromReflectionProperty(ReflectionProperty $reflectionProperty): self
22+
{
23+
$name = $reflectionProperty->getName();
24+
$key = $reflectionProperty->isPrivate() ? "\0" . ltrim($reflectionProperty->getDeclaringClass()->getName(), '\\') . "\0" . $name : ($reflectionProperty->isProtected() ? "\0*\0" . $name : $name);
25+
26+
return new self($reflectionProperty, $key);
27+
}
28+
29+
private function __construct(private ReflectionProperty $reflectionProperty, private string $key)
30+
{
31+
}
32+
33+
public function setValue(object $object, mixed $value): void
34+
{
35+
if (! ($object instanceof InternalProxy && ! $object->__isInitialized())) {
36+
$this->reflectionProperty->setRawValue($object, $value);
37+
38+
return;
39+
}
40+
41+
$object->__setInitialized(true);
42+
43+
$this->reflectionProperty->setRawValue($object, $value);
44+
45+
$object->__setInitialized(false);
46+
}
47+
48+
public function getValue(object $object): mixed
49+
{
50+
return ((array) $object)[$this->key] ?? null;
51+
}
52+
}

0 commit comments

Comments
 (0)