PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.36.0
MailPoet – Newsletters, Email Marketing, and Automation v5.36.0
5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor-prefixed / doctrine / orm / src / Internal / Hydration / ObjectHydrator.php
mailpoet / vendor-prefixed / doctrine / orm / src / Internal / Hydration Last commit date
AbstractHydrator.php 9 months ago ArrayHydrator.php 9 months ago HydrationException.php 9 months ago IterableResult.php 9 months ago ObjectHydrator.php 9 months ago ScalarColumnHydrator.php 9 months ago ScalarHydrator.php 9 months ago SimpleObjectHydrator.php 9 months ago SingleScalarHydrator.php 9 months ago index.php 9 months ago
ObjectHydrator.php
398 lines
1 <?php
2 declare (strict_types=1);
3 namespace MailPoetVendor\Doctrine\ORM\Internal\Hydration;
4 if (!defined('ABSPATH')) exit;
5 use BackedEnum;
6 use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection;
7 use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
8 use MailPoetVendor\Doctrine\ORM\PersistentCollection;
9 use MailPoetVendor\Doctrine\ORM\Query;
10 use MailPoetVendor\Doctrine\ORM\UnitOfWork;
11 use function array_fill_keys;
12 use function array_keys;
13 use function array_map;
14 use function count;
15 use function is_array;
16 use function key;
17 use function ltrim;
18 use function spl_object_id;
19 class ObjectHydrator extends AbstractHydrator
20 {
21 private $identifierMap = [];
22 private $resultPointers = [];
23 private $idTemplate = [];
24 private $resultCounter = 0;
25 private $rootAliases = [];
26 private $initializedCollections = [];
27 private $uninitializedCollections = [];
28 private $existingCollections = [];
29 protected function prepare()
30 {
31 if (!isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD])) {
32 $this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] = \true;
33 }
34 foreach ($this->resultSetMapping()->aliasMap as $dqlAlias => $className) {
35 $this->identifierMap[$dqlAlias] = [];
36 $this->idTemplate[$dqlAlias] = '';
37 // Remember which associations are "fetch joined", so that we know where to inject
38 // collection stubs or proxies and where not.
39 if (!isset($this->resultSetMapping()->relationMap[$dqlAlias])) {
40 continue;
41 }
42 $parent = $this->resultSetMapping()->parentAliasMap[$dqlAlias];
43 if (!isset($this->resultSetMapping()->aliasMap[$parent])) {
44 throw HydrationException::parentObjectOfRelationNotFound($dqlAlias, $parent);
45 }
46 $sourceClassName = $this->resultSetMapping()->aliasMap[$parent];
47 $sourceClass = $this->getClassMetadata($sourceClassName);
48 $assoc = $sourceClass->associationMappings[$this->resultSetMapping()->relationMap[$dqlAlias]];
49 $this->_hints['fetched'][$parent][$assoc['fieldName']] = \true;
50 if ($assoc['type'] === ClassMetadata::MANY_TO_MANY) {
51 continue;
52 }
53 // Mark any non-collection opposite sides as fetched, too.
54 if ($assoc['mappedBy']) {
55 $this->_hints['fetched'][$dqlAlias][$assoc['mappedBy']] = \true;
56 continue;
57 }
58 // handle fetch-joined owning side bi-directional one-to-one associations
59 if ($assoc['inversedBy']) {
60 $class = $this->getClassMetadata($className);
61 $inverseAssoc = $class->associationMappings[$assoc['inversedBy']];
62 if (!($inverseAssoc['type'] & ClassMetadata::TO_ONE)) {
63 continue;
64 }
65 $this->_hints['fetched'][$dqlAlias][$inverseAssoc['fieldName']] = \true;
66 }
67 }
68 }
69 protected function cleanup()
70 {
71 $eagerLoad = isset($this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD]) && $this->_hints[UnitOfWork::HINT_DEFEREAGERLOAD] === \true;
72 parent::cleanup();
73 $this->identifierMap = $this->initializedCollections = $this->uninitializedCollections = $this->existingCollections = $this->resultPointers = [];
74 if ($eagerLoad) {
75 $this->_uow->triggerEagerLoads();
76 }
77 $this->_uow->hydrationComplete();
78 }
79 protected function cleanupAfterRowIteration() : void
80 {
81 $this->identifierMap = $this->initializedCollections = $this->uninitializedCollections = $this->existingCollections = $this->resultPointers = [];
82 }
83 protected function hydrateAllData()
84 {
85 $result = [];
86 while ($row = $this->statement()->fetchAssociative()) {
87 $this->hydrateRowData($row, $result);
88 }
89 // Take snapshots from all newly initialized collections
90 foreach ($this->initializedCollections as $coll) {
91 $coll->takeSnapshot();
92 }
93 foreach ($this->uninitializedCollections as $coll) {
94 if (!$coll->isInitialized()) {
95 $coll->setInitialized(\true);
96 }
97 }
98 return $result;
99 }
100 private function initRelatedCollection($entity, ClassMetadata $class, string $fieldName, string $parentDqlAlias) : PersistentCollection
101 {
102 $oid = spl_object_id($entity);
103 $relation = $class->associationMappings[$fieldName];
104 $value = $class->reflFields[$fieldName]->getValue($entity);
105 if ($value === null || is_array($value)) {
106 $value = new ArrayCollection((array) $value);
107 }
108 if (!$value instanceof PersistentCollection) {
109 $value = new PersistentCollection($this->_em, $this->_metadataCache[$relation['targetEntity']], $value);
110 $value->setOwner($entity, $relation);
111 $class->reflFields[$fieldName]->setValue($entity, $value);
112 $this->_uow->setOriginalEntityProperty($oid, $fieldName, $value);
113 $this->initializedCollections[$oid . $fieldName] = $value;
114 } elseif (isset($this->_hints[Query::HINT_REFRESH]) || isset($this->_hints['fetched'][$parentDqlAlias][$fieldName]) && !$value->isInitialized()) {
115 // Is already PersistentCollection, but either REFRESH or FETCH-JOIN and UNINITIALIZED!
116 $value->setDirty(\false);
117 $value->setInitialized(\true);
118 $value->unwrap()->clear();
119 $this->initializedCollections[$oid . $fieldName] = $value;
120 } else {
121 // Is already PersistentCollection, and DON'T REFRESH or FETCH-JOIN!
122 $this->existingCollections[$oid . $fieldName] = $value;
123 }
124 return $value;
125 }
126 private function getEntity(array $data, string $dqlAlias)
127 {
128 $className = $this->resultSetMapping()->aliasMap[$dqlAlias];
129 if (isset($this->resultSetMapping()->discriminatorColumns[$dqlAlias])) {
130 $fieldName = $this->resultSetMapping()->discriminatorColumns[$dqlAlias];
131 if (!isset($this->resultSetMapping()->metaMappings[$fieldName])) {
132 throw HydrationException::missingDiscriminatorMetaMappingColumn($className, $fieldName, $dqlAlias);
133 }
134 $discrColumn = $this->resultSetMapping()->metaMappings[$fieldName];
135 if (!isset($data[$discrColumn])) {
136 throw HydrationException::missingDiscriminatorColumn($className, $discrColumn, $dqlAlias);
137 }
138 if ($data[$discrColumn] === '') {
139 throw HydrationException::emptyDiscriminatorValue($dqlAlias);
140 }
141 $discrMap = $this->_metadataCache[$className]->discriminatorMap;
142 $discriminatorValue = $data[$discrColumn];
143 if ($discriminatorValue instanceof BackedEnum) {
144 $discriminatorValue = $discriminatorValue->value;
145 }
146 $discriminatorValue = (string) $discriminatorValue;
147 if (!isset($discrMap[$discriminatorValue])) {
148 throw HydrationException::invalidDiscriminatorValue($discriminatorValue, array_keys($discrMap));
149 }
150 $className = $discrMap[$discriminatorValue];
151 unset($data[$discrColumn]);
152 }
153 if (isset($this->_hints[Query::HINT_REFRESH_ENTITY], $this->rootAliases[$dqlAlias])) {
154 $this->registerManaged($this->_metadataCache[$className], $this->_hints[Query::HINT_REFRESH_ENTITY], $data);
155 }
156 $this->_hints['fetchAlias'] = $dqlAlias;
157 return $this->_uow->createEntity($className, $data, $this->_hints);
158 }
159 private function getEntityFromIdentityMap(string $className, array $data)
160 {
161 // TODO: Abstract this code and UnitOfWork::createEntity() equivalent?
162 $class = $this->_metadataCache[$className];
163 if ($class->isIdentifierComposite) {
164 $idHash = UnitOfWork::getIdHashByIdentifier(array_map(
165 static function (string $fieldName) use($data, $class) {
166 return isset($class->associationMappings[$fieldName]) ? $data[$class->associationMappings[$fieldName]['joinColumns'][0]['name']] : $data[$fieldName];
167 },
168 $class->identifier
169 ));
170 return $this->_uow->tryGetByIdHash(ltrim($idHash), $class->rootEntityName);
171 } elseif (isset($class->associationMappings[$class->identifier[0]])) {
172 return $this->_uow->tryGetByIdHash($data[$class->associationMappings[$class->identifier[0]]['joinColumns'][0]['name']], $class->rootEntityName);
173 }
174 return $this->_uow->tryGetByIdHash($data[$class->identifier[0]], $class->rootEntityName);
175 }
176 protected function hydrateRowData(array $row, array &$result)
177 {
178 // Initialize
179 $id = $this->idTemplate;
180 // initialize the id-memory
181 $nonemptyComponents = [];
182 // Split the row data into chunks of class data.
183 $rowData = $this->gatherRowData($row, $id, $nonemptyComponents);
184 // reset result pointers for each data row
185 $this->resultPointers = [];
186 // Hydrate the data chunks
187 foreach ($rowData['data'] as $dqlAlias => $data) {
188 $entityName = $this->resultSetMapping()->aliasMap[$dqlAlias];
189 if (isset($this->resultSetMapping()->parentAliasMap[$dqlAlias])) {
190 // It's a joined result
191 $parentAlias = $this->resultSetMapping()->parentAliasMap[$dqlAlias];
192 // we need the $path to save into the identifier map which entities were already
193 // seen for this parent-child relationship
194 $path = $parentAlias . '.' . $dqlAlias;
195 // We have a RIGHT JOIN result here. Doctrine cannot hydrate RIGHT JOIN Object-Graphs
196 if (!isset($nonemptyComponents[$parentAlias])) {
197 // TODO: Add special case code where we hydrate the right join objects into identity map at least
198 continue;
199 }
200 $parentClass = $this->_metadataCache[$this->resultSetMapping()->aliasMap[$parentAlias]];
201 $relationField = $this->resultSetMapping()->relationMap[$dqlAlias];
202 $relation = $parentClass->associationMappings[$relationField];
203 $reflField = $parentClass->reflFields[$relationField];
204 // Get a reference to the parent object to which the joined element belongs.
205 if ($this->resultSetMapping()->isMixed && isset($this->rootAliases[$parentAlias])) {
206 $objectClass = $this->resultPointers[$parentAlias];
207 $parentObject = $objectClass[key($objectClass)];
208 } elseif (isset($this->resultPointers[$parentAlias])) {
209 $parentObject = $this->resultPointers[$parentAlias];
210 } else {
211 // Parent object of relation not found, mark as not-fetched again
212 if (isset($nonemptyComponents[$dqlAlias])) {
213 $element = $this->getEntity($data, $dqlAlias);
214 // Update result pointer and provide initial fetch data for parent
215 $this->resultPointers[$dqlAlias] = $element;
216 $rowData['data'][$parentAlias][$relationField] = $element;
217 } else {
218 $element = null;
219 }
220 // Mark as not-fetched again
221 unset($this->_hints['fetched'][$parentAlias][$relationField]);
222 continue;
223 }
224 $oid = spl_object_id($parentObject);
225 // Check the type of the relation (many or single-valued)
226 if (!($relation['type'] & ClassMetadata::TO_ONE)) {
227 // PATH A: Collection-valued association
228 $reflFieldValue = $reflField->getValue($parentObject);
229 if (isset($nonemptyComponents[$dqlAlias])) {
230 $collKey = $oid . $relationField;
231 if (isset($this->initializedCollections[$collKey])) {
232 $reflFieldValue = $this->initializedCollections[$collKey];
233 } elseif (!isset($this->existingCollections[$collKey])) {
234 $reflFieldValue = $this->initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
235 }
236 $indexExists = isset($this->identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
237 $index = $indexExists ? $this->identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : \false;
238 $indexIsValid = $index !== \false ? isset($reflFieldValue[$index]) : \false;
239 if (!$indexExists || !$indexIsValid) {
240 if (isset($this->existingCollections[$collKey])) {
241 // Collection exists, only look for the element in the identity map.
242 $element = $this->getEntityFromIdentityMap($entityName, $data);
243 if ($element) {
244 $this->resultPointers[$dqlAlias] = $element;
245 } else {
246 unset($this->resultPointers[$dqlAlias]);
247 }
248 } else {
249 $element = $this->getEntity($data, $dqlAlias);
250 if (isset($this->resultSetMapping()->indexByMap[$dqlAlias])) {
251 $indexValue = $row[$this->resultSetMapping()->indexByMap[$dqlAlias]];
252 $reflFieldValue->hydrateSet($indexValue, $element);
253 $this->identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $indexValue;
254 } else {
255 if (!$reflFieldValue->contains($element)) {
256 $reflFieldValue->hydrateAdd($element);
257 $reflFieldValue->last();
258 }
259 $this->identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] = $reflFieldValue->key();
260 }
261 // Update result pointer
262 $this->resultPointers[$dqlAlias] = $element;
263 }
264 } else {
265 // Update result pointer
266 $this->resultPointers[$dqlAlias] = $reflFieldValue[$index];
267 }
268 } elseif (!$reflFieldValue) {
269 $this->initRelatedCollection($parentObject, $parentClass, $relationField, $parentAlias);
270 } elseif ($reflFieldValue instanceof PersistentCollection && $reflFieldValue->isInitialized() === \false && !isset($this->uninitializedCollections[$oid . $relationField])) {
271 $this->uninitializedCollections[$oid . $relationField] = $reflFieldValue;
272 }
273 } else {
274 // PATH B: Single-valued association
275 $reflFieldValue = $reflField->getValue($parentObject);
276 if (!$reflFieldValue || isset($this->_hints[Query::HINT_REFRESH]) || $this->_uow->isUninitializedObject($reflFieldValue)) {
277 // we only need to take action if this value is null,
278 // we refresh the entity or its an uninitialized proxy.
279 if (isset($nonemptyComponents[$dqlAlias])) {
280 $element = $this->getEntity($data, $dqlAlias);
281 $reflField->setValue($parentObject, $element);
282 $this->_uow->setOriginalEntityProperty($oid, $relationField, $element);
283 $targetClass = $this->_metadataCache[$relation['targetEntity']];
284 if ($relation['isOwningSide']) {
285 // TODO: Just check hints['fetched'] here?
286 // If there is an inverse mapping on the target class its bidirectional
287 if ($relation['inversedBy']) {
288 $inverseAssoc = $targetClass->associationMappings[$relation['inversedBy']];
289 if ($inverseAssoc['type'] & ClassMetadata::TO_ONE) {
290 $targetClass->reflFields[$inverseAssoc['fieldName']]->setValue($element, $parentObject);
291 $this->_uow->setOriginalEntityProperty(spl_object_id($element), $inverseAssoc['fieldName'], $parentObject);
292 }
293 }
294 } else {
295 // For sure bidirectional, as there is no inverse side in unidirectional mappings
296 $targetClass->reflFields[$relation['mappedBy']]->setValue($element, $parentObject);
297 $this->_uow->setOriginalEntityProperty(spl_object_id($element), $relation['mappedBy'], $parentObject);
298 }
299 // Update result pointer
300 $this->resultPointers[$dqlAlias] = $element;
301 } else {
302 $this->_uow->setOriginalEntityProperty($oid, $relationField, null);
303 $reflField->setValue($parentObject, null);
304 }
305 // else leave $reflFieldValue null for single-valued associations
306 } else {
307 // Update result pointer
308 $this->resultPointers[$dqlAlias] = $reflFieldValue;
309 }
310 }
311 } else {
312 // PATH C: Its a root result element
313 $this->rootAliases[$dqlAlias] = \true;
314 // Mark as root alias
315 $entityKey = $this->resultSetMapping()->entityMappings[$dqlAlias] ?: 0;
316 // if this row has a NULL value for the root result id then make it a null result.
317 if (!isset($nonemptyComponents[$dqlAlias])) {
318 if ($this->resultSetMapping()->isMixed) {
319 $result[] = [$entityKey => null];
320 } else {
321 $result[] = null;
322 }
323 $resultKey = $this->resultCounter;
324 ++$this->resultCounter;
325 continue;
326 }
327 // check for existing result from the iterations before
328 if (!isset($this->identifierMap[$dqlAlias][$id[$dqlAlias]])) {
329 $element = $this->getEntity($data, $dqlAlias);
330 if ($this->resultSetMapping()->isMixed) {
331 $element = [$entityKey => $element];
332 }
333 if (isset($this->resultSetMapping()->indexByMap[$dqlAlias])) {
334 $resultKey = $row[$this->resultSetMapping()->indexByMap[$dqlAlias]];
335 if (isset($this->_hints['collection'])) {
336 $this->_hints['collection']->hydrateSet($resultKey, $element);
337 }
338 $result[$resultKey] = $element;
339 } else {
340 $resultKey = $this->resultCounter;
341 ++$this->resultCounter;
342 if (isset($this->_hints['collection'])) {
343 $this->_hints['collection']->hydrateAdd($element);
344 }
345 $result[] = $element;
346 }
347 $this->identifierMap[$dqlAlias][$id[$dqlAlias]] = $resultKey;
348 // Update result pointer
349 $this->resultPointers[$dqlAlias] = $element;
350 } else {
351 // Update result pointer
352 $index = $this->identifierMap[$dqlAlias][$id[$dqlAlias]];
353 $this->resultPointers[$dqlAlias] = $result[$index];
354 $resultKey = $index;
355 }
356 }
357 if (isset($this->_hints[Query::HINT_INTERNAL_ITERATION]) && $this->_hints[Query::HINT_INTERNAL_ITERATION]) {
358 $this->_uow->hydrationComplete();
359 }
360 }
361 if (!isset($resultKey)) {
362 $this->resultCounter++;
363 }
364 // Append scalar values to mixed result sets
365 if (isset($rowData['scalars'])) {
366 if (!isset($resultKey)) {
367 $resultKey = isset($this->resultSetMapping()->indexByMap['scalars']) ? $row[$this->resultSetMapping()->indexByMap['scalars']] : $this->resultCounter - 1;
368 }
369 foreach ($rowData['scalars'] as $name => $value) {
370 $result[$resultKey][$name] = $value;
371 }
372 }
373 // Append new object to mixed result sets
374 if (isset($rowData['newObjects'])) {
375 if (!isset($resultKey)) {
376 $resultKey = $this->resultCounter - 1;
377 }
378 $scalarCount = isset($rowData['scalars']) ? count($rowData['scalars']) : 0;
379 foreach ($rowData['newObjects'] as $objIndex => $newObject) {
380 $class = $newObject['class'];
381 $args = $newObject['args'];
382 $obj = $class->newInstanceArgs($args);
383 if ($scalarCount === 0 && count($rowData['newObjects']) === 1) {
384 $result[$resultKey] = $obj;
385 continue;
386 }
387 $result[$resultKey][$objIndex] = $obj;
388 }
389 }
390 }
391 public function onClear($eventArgs)
392 {
393 parent::onClear($eventArgs);
394 $aliases = array_keys($this->identifierMap);
395 $this->identifierMap = array_fill_keys($aliases, []);
396 }
397 }
398