DDC-2704 - providing hotfix - also storing inherited transient properties in the class metadata
This commit is contained in:
parent
5ae980e0f9
commit
0a3d6966d6
@ -20,6 +20,7 @@
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use BadMethodCallException;
|
||||
use Doctrine\Common\Persistence\Mapping\ReflectionService;
|
||||
use Doctrine\Instantiator\Instantiator;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
@ -649,6 +650,12 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
*/
|
||||
private $instantiator;
|
||||
|
||||
/**
|
||||
* @var \ReflectionProperty[]|null (null if not yet initialized) - all instance properties of the class,
|
||||
* transient or not, in accessible form.
|
||||
*/
|
||||
private $reflectionProperties;
|
||||
|
||||
/**
|
||||
* Initializes a new ClassMetadata instance that will hold the object-relational mapping
|
||||
* metadata of the class with the given name.
|
||||
@ -667,13 +674,30 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
/**
|
||||
* Gets the ReflectionProperties of the mapped class.
|
||||
*
|
||||
* @return array An array of ReflectionProperty instances.
|
||||
* @return \ReflectionProperty[] An array of ReflectionProperty instances.
|
||||
*/
|
||||
public function getReflectionProperties()
|
||||
{
|
||||
return $this->reflFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all ReflectionProperties of this class, considering inherited and transient ones
|
||||
*
|
||||
* Note that this method should only be used after `wakeupReflection`
|
||||
*/
|
||||
public function getAllReflectionProperties()
|
||||
{
|
||||
if (null === $this->reflectionProperties) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'You cannot read the reflection properties before calling %s#wakeupReflection() first',
|
||||
get_class($this)
|
||||
));
|
||||
}
|
||||
|
||||
return $this->reflectionProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a ReflectionProperty for a specific field of the mapped class.
|
||||
*
|
||||
@ -963,6 +987,8 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
? $reflService->getAccessibleProperty($mapping['declared'], $field)
|
||||
: $reflService->getAccessibleProperty($this->name, $field);
|
||||
}
|
||||
|
||||
$this->initializeAllReflectionProperties($reflService);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3313,4 +3339,52 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
|
||||
return $sequencePrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the internal `reflectionProperties` property
|
||||
*
|
||||
* @param ReflectionService $reflectionService
|
||||
*/
|
||||
private function initializeAllReflectionProperties(ReflectionService $reflectionService)
|
||||
{
|
||||
$class = $this->reflClass;
|
||||
$properties = array();
|
||||
|
||||
do {
|
||||
$className = $class->getName();
|
||||
|
||||
foreach ($class->getProperties() as $property) {
|
||||
// static properties are not instance properties
|
||||
if ($property->isStatic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// indexing by logical name to avoid duplicates
|
||||
$logicalName = $property->getDeclaringClass()->getName() . $property->getName();
|
||||
$propertyName = $property->getName();
|
||||
$existingField = isset($this->reflFields[$propertyName]) ? $this->reflFields[$propertyName] : null;
|
||||
|
||||
if (! $existingField) {
|
||||
$properties[$logicalName] = $reflectionService->getAccessibleProperty($className, $propertyName);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// private properties are not inherited: need to handle them separately and precisely
|
||||
if ($property->isPrivate()
|
||||
&& $existingField->getDeclaringClass()->getName() !== $property->getDeclaringClass()->getName()
|
||||
) {
|
||||
$properties[$logicalName] = $reflectionService->getAccessibleProperty($className, $propertyName);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$properties[$logicalName] = $existingField;
|
||||
}
|
||||
|
||||
$parentClass = $class->getParentClass();
|
||||
} while ($parentClass && $class = $reflectionService->getClass($parentClass->getName()));
|
||||
|
||||
$this->reflectionProperties = array_values($properties);
|
||||
}
|
||||
}
|
||||
|
@ -3348,7 +3348,7 @@ class UnitOfWork implements PropertyChangedListener
|
||||
{
|
||||
$class = $this->em->getClassMetadata(get_class($entity));
|
||||
|
||||
foreach ($class->reflClass->getProperties() as $prop) {
|
||||
foreach ($class->getAllReflectionProperties() as $prop) {
|
||||
$name = $prop->name;
|
||||
|
||||
$prop->setAccessible(true);
|
||||
|
Loading…
x
Reference in New Issue
Block a user