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\Utility\StaticClassNameConverter; |
||||||
15 | |||||||
16 | /** |
||||||
17 | * Default hydrator cache for entities |
||||||
18 | */ |
||||||
19 | class DefaultEntityHydrator implements EntityHydrator |
||||||
20 | { |
||||||
21 | /** |
||||||
22 | * @var \Doctrine\ORM\EntityManagerInterface |
||||||
23 | */ |
||||||
24 | private $em; |
||||||
25 | |||||||
26 | /** |
||||||
27 | * @var \Doctrine\ORM\UnitOfWork |
||||||
28 | */ |
||||||
29 | private $uow; |
||||||
30 | |||||||
31 | /** |
||||||
32 | * @var mixed[] |
||||||
33 | */ |
||||||
34 | private static $hints = [Query::HINT_CACHE_ENABLED => true]; |
||||||
35 | |||||||
36 | /** |
||||||
37 | * @param \Doctrine\ORM\EntityManagerInterface $em The entity manager. |
||||||
38 | */ |
||||||
39 | 209 | public function __construct(EntityManagerInterface $em) |
|||||
40 | { |
||||||
41 | 209 | $this->em = $em; |
|||||
42 | 209 | $this->uow = $em->getUnitOfWork(); |
|||||
43 | 209 | } |
|||||
44 | |||||||
45 | /** |
||||||
46 | * {@inheritdoc} |
||||||
47 | */ |
||||||
48 | 117 | public function buildCacheEntry(ClassMetadata $metadata, EntityCacheKey $key, $entity) |
|||||
49 | { |
||||||
50 | 117 | $identifierFlattener = $this->em->getIdentifierFlattener(); |
|||||
51 | 117 | $persister = $this->uow->getEntityPersister($metadata->getClassName()); |
|||||
52 | |||||||
53 | 117 | $data = $this->uow->getOriginalEntityData($entity); |
|||||
54 | 117 | $data = array_merge($data, $persister->getIdentifier($entity)); // why update has no identifier values ? |
|||||
55 | |||||||
56 | 117 | foreach ($metadata->getDeclaredPropertiesIterator() as $name => $association) { |
|||||
57 | 117 | if (! isset($data[$name]) || $association instanceof FieldMetadata) { |
|||||
58 | 117 | 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()) |
|||||
0 ignored issues
–
show
|
|||||||
74 | 5 | : $association; |
|||||
75 | 5 | $associationIds = $identifierFlattener->flattenIdentifier( |
|||||
76 | 5 | $targetClassMetadata, |
|||||
0 ignored issues
–
show
$targetClassMetadata of type Doctrine\Common\Persistence\Mapping\ClassMetadata is incompatible with the type Doctrine\ORM\Mapping\ClassMetadata expected by parameter $class of Doctrine\ORM\Utility\Ide...er::flattenIdentifier() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
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 | 117 | return new EntityCacheEntry($metadata->getClassName(), $data); |
|||||
137 | } |
||||||
138 | |||||||
139 | /** |
||||||
140 | * {@inheritdoc} |
||||||
141 | */ |
||||||
142 | 41 | public function loadCacheEntry( |
|||||
143 | ClassMetadata $metadata, |
||||||
144 | EntityCacheKey $key, |
||||||
145 | EntityCacheEntry $entry, |
||||||
146 | $entity = null |
||||||
147 | ) { |
||||||
148 | 41 | $data = $entry->data; |
|||||
149 | 41 | $hints = self::$hints; |
|||||
150 | |||||||
151 | 41 | if ($entity !== null) { |
|||||
152 | 6 | $hints[Query::HINT_REFRESH] = true; |
|||||
153 | 6 | $hints[Query::HINT_REFRESH_ENTITY] = $entity; |
|||||
154 | } |
||||||
155 | |||||||
156 | 41 | foreach ($metadata->getDeclaredPropertiesIterator() as $name => $association) { |
|||||
157 | 41 | if ($association instanceof FieldMetadata || ! isset($data[$name]) || ! $association->getCache()) { |
|||||
0 ignored issues
–
show
The method
getCache() 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 or Doctrine\ORM\Mapping\EmbeddedClassMetadata .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
158 | 41 | continue; |
|||||
159 | } |
||||||
160 | |||||||
161 | 28 | $assocClass = $data[$name]->class; |
|||||
162 | 28 | $assocId = $data[$name]->identifier; |
|||||
163 | $isEagerLoad = ( |
||||||
164 | 28 | $association->getFetchMode() === FetchMode::EAGER || |
|||||
0 ignored issues
–
show
The method
getFetchMode() 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...
|
|||||||
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); |
|||||
0 ignored issues
–
show
The method
getRootClassName() does not exist on Doctrine\Common\Persistence\Mapping\ClassMetadata .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||||||
177 | 3 | $assocPersister = $this->uow->getEntityPersister($targetEntity); |
|||||
178 | 3 | $assocRegion = $assocPersister->getCacheRegion(); |
|||||
0 ignored issues
–
show
The method
getCacheRegion() does not exist on Doctrine\ORM\Persisters\Entity\EntityPersister . It seems like you code against a sub-type of Doctrine\ORM\Persisters\Entity\EntityPersister such as Doctrine\ORM\Cache\Persi...y\CachedEntityPersister .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
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 | 3 | $hints |
|||||
189 | ); |
||||||
190 | } |
||||||
191 | |||||||
192 | 41 | if ($entity !== null) { |
|||||
193 | 6 | $this->uow->registerManaged($entity, $key->identifier, $data); |
|||||
194 | } |
||||||
195 | |||||||
196 | 41 | $result = $this->uow->createEntity($entry->class, $data, $hints); |
|||||
197 | |||||||
198 | 41 | $this->uow->hydrationComplete(); |
|||||
199 | |||||||
200 | 41 | return $result; |
|||||
201 | } |
||||||
202 | } |
||||||
203 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.