|
| 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