1
0
mirror of synced 2025-01-18 22:41:43 +03:00

DDC-2704 - providing hotfix - also storing inherited transient properties in the class metadata

This commit is contained in:
Marco Pivetta 2015-01-20 14:21:51 +01:00
parent 5ae980e0f9
commit 0a3d6966d6
2 changed files with 76 additions and 2 deletions

View File

@ -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);
}
}

View File

@ -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);