1 | <?php |
||||||
2 | |||||||
3 | declare(strict_types=1); |
||||||
4 | |||||||
5 | namespace Doctrine\ORM\Cache; |
||||||
6 | |||||||
7 | use Doctrine\ORM\EntityManagerInterface; |
||||||
8 | use Doctrine\ORM\Mapping\ClassMetadata; |
||||||
9 | use Doctrine\ORM\Mapping\FetchMode; |
||||||
10 | use Doctrine\ORM\Mapping\FieldMetadata; |
||||||
11 | use Doctrine\ORM\Mapping\OneToOneAssociationMetadata; |
||||||
12 | use Doctrine\ORM\Mapping\ToOneAssociationMetadata; |
||||||
13 | use Doctrine\ORM\Query; |
||||||
14 | use Doctrine\ORM\UnitOfWork; |
||||||
15 | use Doctrine\ORM\Utility\StaticClassNameConverter; |
||||||
16 | use function array_merge; |
||||||
17 | |||||||
18 | /** |
||||||
19 | * Default hydrator cache for entities |
||||||
20 | */ |
||||||
21 | class DefaultEntityHydrator implements EntityHydrator |
||||||
22 | { |
||||||
23 | /** @var EntityManagerInterface */ |
||||||
24 | private $em; |
||||||
25 | |||||||
26 | /** @var UnitOfWork */ |
||||||
27 | private $uow; |
||||||
28 | |||||||
29 | /** @var mixed[] */ |
||||||
30 | private static $hints = [Query::HINT_CACHE_ENABLED => true]; |
||||||
31 | |||||||
32 | /** |
||||||
33 | * @param EntityManagerInterface $em The entity manager. |
||||||
34 | */ |
||||||
35 | 210 | public function __construct(EntityManagerInterface $em) |
|||||
36 | { |
||||||
37 | 210 | $this->em = $em; |
|||||
38 | 210 | $this->uow = $em->getUnitOfWork(); |
|||||
39 | 210 | } |
|||||
40 | |||||||
41 | /** |
||||||
42 | * {@inheritdoc} |
||||||
43 | */ |
||||||
44 | 118 | public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity) |
|||||
45 | { |
||||||
46 | 118 | $identifierFlattener = $this->em->getIdentifierFlattener(); |
|||||
47 | 118 | $persister = $this->uow->getEntityPersister($metadata->getClassName()); |
|||||
48 | |||||||
49 | 118 | $data = $this->uow->getOriginalEntityData($entity); |
|||||
50 | 118 | $data = array_merge($data, $persister->getIdentifier($entity)); // why update has no identifier values ? |
|||||
51 | |||||||
52 | 118 | if ($metadata->isVersioned()) { |
|||||
53 | 1 | $data[$metadata->versionProperty->getName()] = $metadata->versionProperty->getValue($entity); |
|||||
54 | } |
||||||
55 | |||||||
56 | 118 | foreach ($metadata->getPropertiesIterator() as $name => $association) { |
|||||
57 | 118 | if (! isset($data[$name]) || $association instanceof FieldMetadata) { |
|||||
58 | 118 | continue; |
|||||
59 | } |
||||||
60 | |||||||
61 | 70 | if (! $association instanceof ToOneAssociationMetadata) { |
|||||
62 | 59 | unset($data[$name]); |
|||||
63 | |||||||
64 | 59 | continue; |
|||||
65 | } |
||||||
66 | |||||||
67 | 69 | $targetEntity = $association->getTargetEntity(); |
|||||
68 | 69 | $targetClassMetadata = $this->em->getClassMetadata($targetEntity); |
|||||
69 | 69 | $targetPersister = $this->uow->getEntityPersister($targetEntity); |
|||||
70 | |||||||
71 | 69 | if (! $association->getCache()) { |
|||||
72 | 5 | $owningAssociation = ! $association->isOwningSide() |
|||||
73 | 1 | ? $targetClassMetadata->getProperty($association->getMappedBy()) |
|||||
74 | 5 | : $association; |
|||||
75 | 5 | $associationIds = $identifierFlattener->flattenIdentifier( |
|||||
76 | 5 | $targetClassMetadata, |
|||||
77 | 5 | $targetPersister->getIdentifier($data[$name]) |
|||||
78 | ); |
||||||
79 | |||||||
80 | 5 | unset($data[$name]); |
|||||
81 | |||||||
82 | 5 | foreach ($associationIds as $fieldName => $fieldValue) { |
|||||
83 | // $fieldName = "name" |
||||||
84 | // $fieldColumnName = "custom_name" |
||||||
85 | 5 | $property = $targetClassMetadata->getProperty($fieldName); |
|||||
86 | |||||||
87 | 5 | if ($property instanceof FieldMetadata) { |
|||||
88 | 5 | foreach ($owningAssociation->getJoinColumns() as $joinColumn) { |
|||||
89 | // $joinColumnName = "custom_name" |
||||||
90 | // $joinColumnReferencedColumnName = "other_side_of_assoc_column_name" |
||||||
91 | 5 | if ($joinColumn->getReferencedColumnName() !== $property->getColumnName()) { |
|||||
92 | continue; |
||||||
93 | } |
||||||
94 | |||||||
95 | 5 | $data[$joinColumn->getColumnName()] = $fieldValue; |
|||||
96 | |||||||
97 | 5 | break; |
|||||
98 | } |
||||||
99 | |||||||
100 | 5 | continue; |
|||||
101 | } |
||||||
102 | |||||||
103 | 1 | $targetAssociation = $targetClassMetadata->getProperty($fieldName); |
|||||
104 | |||||||
105 | 1 | foreach ($association->getJoinColumns() as $assocJoinColumn) { |
|||||
106 | 1 | foreach ($targetAssociation->getJoinColumns() as $targetAssocJoinColumn) { |
|||||
107 | 1 | if ($assocJoinColumn->getReferencedColumnName() !== $targetAssocJoinColumn->getColumnName()) { |
|||||
108 | 1 | continue; |
|||||
109 | } |
||||||
110 | |||||||
111 | 1 | $data[$assocJoinColumn->getColumnName()] = $fieldValue; |
|||||
112 | } |
||||||
113 | } |
||||||
114 | } |
||||||
115 | |||||||
116 | 5 | continue; |
|||||
117 | } |
||||||
118 | |||||||
119 | 65 | if (! $association->isPrimaryKey()) { |
|||||
120 | 64 | $targetClass = StaticClassNameConverter::getClass($data[$name]); |
|||||
121 | 64 | $targetId = $this->uow->getEntityIdentifier($data[$name]); |
|||||
122 | 64 | $data[$name] = new AssociationCacheEntry($targetClass, $targetId); |
|||||
123 | |||||||
124 | 64 | continue; |
|||||
125 | } |
||||||
126 | |||||||
127 | // handle association identifier |
||||||
128 | 5 | $targetId = $this->em->getIdentifierFlattener()->flattenIdentifier( |
|||||
129 | 5 | $targetClassMetadata, |
|||||
130 | 5 | $targetPersister->getIdentifier($data[$name]) |
|||||
131 | ); |
||||||
132 | |||||||
133 | 5 | $data[$name] = new AssociationCacheEntry($targetEntity, $targetId); |
|||||
134 | } |
||||||
135 | |||||||
136 | 118 | return new EntityCacheEntry($metadata->getClassName(), $data); |
|||||
137 | } |
||||||
138 | |||||||
139 | /** |
||||||
140 | * {@inheritdoc} |
||||||
141 | */ |
||||||
142 | 42 | public function loadCacheEntry( |
|||||
143 | ClassMetadata $metadata, |
||||||
144 | EntityCacheKey $key, |
||||||
145 | EntityCacheEntry $entry, |
||||||
146 | $entity = null |
||||||
147 | ) { |
||||||
148 | 42 | $data = $entry->data; |
|||||
149 | 42 | $hints = self::$hints; |
|||||
150 | |||||||
151 | 42 | if ($entity !== null) { |
|||||
152 | 6 | $hints[Query::HINT_REFRESH] = true; |
|||||
153 | 6 | $hints[Query::HINT_REFRESH_ENTITY] = $entity; |
|||||
154 | } |
||||||
155 | |||||||
156 | 42 | foreach ($metadata->getPropertiesIterator() as $name => $association) { |
|||||
157 | 42 | if ($association instanceof FieldMetadata || ! isset($data[$name]) || ! $association->getCache()) { |
|||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||||
158 | 42 | continue; |
|||||
159 | } |
||||||
160 | |||||||
161 | 28 | $assocClass = $data[$name]->class; |
|||||
162 | 28 | $assocId = $data[$name]->identifier; |
|||||
163 | $isEagerLoad = ( |
||||||
164 | 28 | $association->getFetchMode() === FetchMode::EAGER || |
|||||
165 | 28 | ($association instanceof OneToOneAssociationMetadata && ! $association->isOwningSide()) |
|||||
166 | ); |
||||||
167 | |||||||
168 | 28 | if (! $isEagerLoad) { |
|||||
169 | 26 | $data[$name] = $this->em->getReference($assocClass, $assocId); |
|||||
170 | |||||||
171 | 26 | continue; |
|||||
172 | } |
||||||
173 | |||||||
174 | 3 | $targetEntity = $association->getTargetEntity(); |
|||||
0 ignored issues
–
show
The method
getTargetEntity() does not exist on Doctrine\ORM\Mapping\Property . It seems like you code against a sub-type of Doctrine\ORM\Mapping\Property such as Doctrine\ORM\Mapping\AssociationMetadata .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
175 | 3 | $assocMetadata = $this->em->getClassMetadata($targetEntity); |
|||||
176 | 3 | $assocKey = new EntityCacheKey($assocMetadata->getRootClassName(), $assocId); |
|||||
177 | 3 | $assocPersister = $this->uow->getEntityPersister($targetEntity); |
|||||
178 | 3 | $assocRegion = $assocPersister->getCacheRegion(); |
|||||
179 | 3 | $assocEntry = $assocRegion->get($assocKey); |
|||||
180 | |||||||
181 | 3 | if ($assocEntry === null) { |
|||||
182 | return null; |
||||||
183 | } |
||||||
184 | |||||||
185 | 3 | $data[$name] = $this->uow->createEntity( |
|||||
186 | 3 | $assocEntry->class, |
|||||
187 | 3 | $assocEntry->resolveAssociationEntries($this->em), |
|||||
188 | $hints |
||||||
189 | ); |
||||||
190 | } |
||||||
191 | |||||||
192 | 42 | if ($entity !== null) { |
|||||
193 | 6 | $this->uow->registerManaged($entity, $key->identifier, $data); |
|||||
194 | } |
||||||
195 | |||||||
196 | 42 | $result = $this->uow->createEntity($entry->class, $data, $hints); |
|||||
197 | |||||||
198 | 42 | $this->uow->hydrationComplete(); |
|||||
199 | |||||||
200 | 42 | return $result; |
|||||
201 | } |
||||||
202 | } |
||||||
203 |