Skip to content

Commit 03f39f9

Browse files
committed
Extract new logic so the attribute driver can use it as well
1 parent c9c7d67 commit 03f39f9

File tree

3 files changed

+51
-40
lines changed

3 files changed

+51
-40
lines changed

lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
class AnnotationDriver extends CompatibilityAnnotationDriver
3535
{
3636
use ColocatedMappingDriver;
37+
use ReflectionBasedDriverTrait;
3738

3839
/**
3940
* The annotation reader.
@@ -344,37 +345,7 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad
344345

345346
// Evaluate annotations on properties/fields
346347
foreach ($class->getProperties() as $property) {
347-
// Handle the case that reflection may report properties inherited from parent classes.
348-
// When we know about the fields already (inheritance has been anticipanted in ClassMetadataFactory),
349-
// skip them.
350-
// The declaring classes may mismatch when there are private properties: The same property name may be
351-
// reported multiple times, but since it is private, it is in fact multiple (different) properties in
352-
// different classes. In that case, report the property as an individual field. (ClassMetadataFactory will
353-
// probably fail in that case, though.)
354-
355-
$declaringClass = $property->getDeclaringClass()->getName();
356-
357-
if (
358-
isset($metadata->fieldMappings[$property->name])
359-
&& isset($metadata->fieldMappings[$property->name]['declared'])
360-
&& $metadata->fieldMappings[$property->name]['declared'] === $declaringClass
361-
) {
362-
continue;
363-
}
364-
365-
if (
366-
isset($metadata->associationMappings[$property->name])
367-
&& isset($metadata->associationMappings[$property->name]['declared'])
368-
&& $metadata->associationMappings[$property->name]['declared'] === $declaringClass
369-
) {
370-
continue;
371-
}
372-
373-
if (
374-
isset($metadata->embeddedClasses[$property->name])
375-
&& isset($metadata->embeddedClasses[$property->name]['declared'])
376-
&& $metadata->embeddedClasses[$property->name]['declared'] === $declaringClass
377-
) {
348+
if ($this->isRepeatedPropertyDeclaration($property, $metadata)) {
378349
continue;
379350
}
380351

lib/Doctrine/ORM/Mapping/Driver/AttributeDriver.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
class AttributeDriver extends CompatibilityAnnotationDriver
3131
{
3232
use ColocatedMappingDriver;
33+
use ReflectionBasedDriverTrait;
3334

3435
private const ENTITY_ATTRIBUTE_CLASSES = [
3536
Mapping\Entity::class => 1,
@@ -294,15 +295,8 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad
294295

295296
foreach ($reflectionClass->getProperties() as $property) {
296297
assert($property instanceof ReflectionProperty);
297-
if (
298-
$metadata->isMappedSuperclass && ! $property->isPrivate()
299-
||
300-
$metadata->isInheritedField($property->name)
301-
||
302-
$metadata->isInheritedAssociation($property->name)
303-
||
304-
$metadata->isInheritedEmbeddedClass($property->name)
305-
) {
298+
299+
if ($this->isRepeatedPropertyDeclaration($property, $metadata)) {
306300
continue;
307301
}
308302

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\ORM\Mapping\Driver;
6+
7+
use Doctrine\ORM\Mapping\ClassMetadata;
8+
use ReflectionProperty;
9+
10+
trait ReflectionBasedDriverTrait
11+
{
12+
/**
13+
* Helps to deal with the case that reflection may report properties inherited from parent classes.
14+
* When we know about the fields already (inheritance has been anticipated in ClassMetadataFactory),
15+
* the driver must skip them.
16+
*
17+
* The declaring classes may mismatch when there are private properties: The same property name may be
18+
* reported multiple times, but since it is private, it is in fact multiple (different) properties in
19+
* different classes. In that case, report the property as an individual field. (ClassMetadataFactory will
20+
* probably fail in that case, though.)
21+
*/
22+
private function isRepeatedPropertyDeclaration(ReflectionProperty $property, ClassMetadata $metadata): bool
23+
{
24+
$declaringClass = $property->getDeclaringClass()->getName();
25+
26+
if (
27+
isset($metadata->fieldMappings[$property->name])
28+
&& isset($metadata->fieldMappings[$property->name]['declared'])
29+
&& $metadata->fieldMappings[$property->name]['declared'] === $declaringClass
30+
) {
31+
return true;
32+
}
33+
34+
if (
35+
isset($metadata->associationMappings[$property->name])
36+
&& isset($metadata->associationMappings[$property->name]['declared'])
37+
&& $metadata->associationMappings[$property->name]['declared'] === $declaringClass
38+
) {
39+
return true;
40+
}
41+
42+
return isset($metadata->embeddedClasses[$property->name])
43+
&& isset($metadata->embeddedClasses[$property->name]['declared'])
44+
&& $metadata->embeddedClasses[$property->name]['declared'] === $declaringClass;
45+
}
46+
}

0 commit comments

Comments
 (0)