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 / PersistentCollection.php
mailpoet / vendor-prefixed / doctrine / orm / src Last commit date
Cache 9 months ago Decorator 9 months ago Event 9 months ago Exception 9 months ago Id 9 months ago Internal 9 months ago Mapping 9 months ago Persisters 8 months ago Proxy 9 months ago Query 9 months ago Repository 9 months ago Tools 9 months ago Utility 9 months ago AbstractQuery.php 9 months ago Cache.php 9 months ago Configuration.php 9 months ago EntityManager.php 9 months ago EntityManagerInterface.php 9 months ago EntityNotFoundException.php 9 months ago EntityRepository.php 9 months ago Events.php 9 months ago LazyCriteriaCollection.php 9 months ago NativeQuery.php 9 months ago NoResultException.php 9 months ago NonUniqueResultException.php 9 months ago ORMException.php 9 months ago ORMInvalidArgumentException.php 9 months ago ORMSetup.php 9 months ago OptimisticLockException.php 9 months ago PersistentCollection.php 9 months ago PessimisticLockException.php 9 months ago Query.php 9 months ago QueryBuilder.php 9 months ago TransactionRequiredException.php 9 months ago UnexpectedResultException.php 9 months ago UnitOfWork.php 9 months ago Version.php 9 months ago index.php 9 months ago
PersistentCollection.php
350 lines
1 <?php
2 declare (strict_types=1);
3 namespace MailPoetVendor\Doctrine\ORM;
4 if (!defined('ABSPATH')) exit;
5 use MailPoetVendor\Doctrine\Common\Collections\AbstractLazyCollection;
6 use MailPoetVendor\Doctrine\Common\Collections\ArrayCollection;
7 use MailPoetVendor\Doctrine\Common\Collections\Collection;
8 use MailPoetVendor\Doctrine\Common\Collections\Criteria;
9 use MailPoetVendor\Doctrine\Common\Collections\Selectable;
10 use MailPoetVendor\Doctrine\ORM\Internal\CriteriaOrderings;
11 use MailPoetVendor\Doctrine\ORM\Mapping\ClassMetadata;
12 use ReturnTypeWillChange;
13 use RuntimeException;
14 use UnexpectedValueException;
15 use function array_combine;
16 use function array_diff_key;
17 use function array_map;
18 use function array_values;
19 use function array_walk;
20 use function assert;
21 use function get_class;
22 use function is_object;
23 use function spl_object_id;
24 final class PersistentCollection extends AbstractLazyCollection implements Selectable
25 {
26 use CriteriaOrderings;
27 private $snapshot = [];
28 private $owner;
29 private $association;
30 private $em;
31 private $backRefFieldName;
32 private $typeClass;
33 private $isDirty = \false;
34 public function __construct(EntityManagerInterface $em, $class, Collection $collection)
35 {
36 $this->collection = $collection;
37 $this->em = $em;
38 $this->typeClass = $class;
39 $this->initialized = \true;
40 }
41 public function setOwner($entity, array $assoc) : void
42 {
43 $this->owner = $entity;
44 $this->association = $assoc;
45 $this->backRefFieldName = $assoc['inversedBy'] ?: $assoc['mappedBy'];
46 }
47 public function getOwner()
48 {
49 return $this->owner;
50 }
51 public function getTypeClass() : Mapping\ClassMetadataInfo
52 {
53 assert($this->typeClass !== null);
54 return $this->typeClass;
55 }
56 private function getUnitOfWork() : UnitOfWork
57 {
58 assert($this->em !== null);
59 return $this->em->getUnitOfWork();
60 }
61 public function hydrateAdd($element) : void
62 {
63 $this->unwrap()->add($element);
64 // If _backRefFieldName is set and its a one-to-many association,
65 // we need to set the back reference.
66 if ($this->backRefFieldName && $this->getMapping()['type'] === ClassMetadata::ONE_TO_MANY) {
67 assert($this->typeClass !== null);
68 // Set back reference to owner
69 $this->typeClass->reflFields[$this->backRefFieldName]->setValue($element, $this->owner);
70 $this->getUnitOfWork()->setOriginalEntityProperty(spl_object_id($element), $this->backRefFieldName, $this->owner);
71 }
72 }
73 public function hydrateSet($key, $element) : void
74 {
75 $this->unwrap()->set($key, $element);
76 // If _backRefFieldName is set, then the association is bidirectional
77 // and we need to set the back reference.
78 if ($this->backRefFieldName && $this->getMapping()['type'] === ClassMetadata::ONE_TO_MANY) {
79 assert($this->typeClass !== null);
80 // Set back reference to owner
81 $this->typeClass->reflFields[$this->backRefFieldName]->setValue($element, $this->owner);
82 }
83 }
84 public function initialize() : void
85 {
86 if ($this->initialized || !$this->association) {
87 return;
88 }
89 $this->doInitialize();
90 $this->initialized = \true;
91 }
92 public function takeSnapshot() : void
93 {
94 $this->snapshot = $this->unwrap()->toArray();
95 $this->isDirty = \false;
96 }
97 public function getSnapshot() : array
98 {
99 return $this->snapshot;
100 }
101 public function getDeleteDiff() : array
102 {
103 $collectionItems = $this->unwrap()->toArray();
104 return array_values(array_diff_key(array_combine(array_map('spl_object_id', $this->snapshot), $this->snapshot), array_combine(array_map('spl_object_id', $collectionItems), $collectionItems)));
105 }
106 public function getInsertDiff() : array
107 {
108 $collectionItems = $this->unwrap()->toArray();
109 return array_values(array_diff_key(array_combine(array_map('spl_object_id', $collectionItems), $collectionItems), array_combine(array_map('spl_object_id', $this->snapshot), $this->snapshot)));
110 }
111 public function getMapping() : array
112 {
113 if ($this->association === null) {
114 throw new UnexpectedValueException('The underlying association mapping is null although it should not be');
115 }
116 return $this->association;
117 }
118 private function changed() : void
119 {
120 if ($this->isDirty) {
121 return;
122 }
123 $this->isDirty = \true;
124 if ($this->association !== null && $this->getMapping()['isOwningSide'] && $this->getMapping()['type'] === ClassMetadata::MANY_TO_MANY && $this->owner && $this->em !== null && $this->em->getClassMetadata(get_class($this->owner))->isChangeTrackingNotify()) {
125 $this->getUnitOfWork()->scheduleForDirtyCheck($this->owner);
126 }
127 }
128 public function isDirty() : bool
129 {
130 return $this->isDirty;
131 }
132 public function setDirty($dirty) : void
133 {
134 $this->isDirty = $dirty;
135 }
136 public function setInitialized($bool) : void
137 {
138 $this->initialized = $bool;
139 }
140 public function remove($key)
141 {
142 // TODO: If the keys are persistent as well (not yet implemented)
143 // and the collection is not initialized and orphanRemoval is
144 // not used we can issue a straight SQL delete/update on the
145 // association (table). Without initializing the collection.
146 $removed = parent::remove($key);
147 if (!$removed) {
148 return $removed;
149 }
150 $this->changed();
151 if ($this->association !== null && $this->getMapping()['type'] & ClassMetadata::TO_MANY && $this->owner && $this->getMapping()['orphanRemoval']) {
152 $this->getUnitOfWork()->scheduleOrphanRemoval($removed);
153 }
154 return $removed;
155 }
156 public function removeElement($element) : bool
157 {
158 $removed = parent::removeElement($element);
159 if (!$removed) {
160 return $removed;
161 }
162 $this->changed();
163 if ($this->association !== null && $this->getMapping()['type'] & ClassMetadata::TO_MANY && $this->owner && $this->getMapping()['orphanRemoval']) {
164 $this->getUnitOfWork()->scheduleOrphanRemoval($element);
165 }
166 return $removed;
167 }
168 public function containsKey($key) : bool
169 {
170 if (!$this->initialized && $this->getMapping()['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY && isset($this->getMapping()['indexBy'])) {
171 $persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping());
172 return $this->unwrap()->containsKey($key) || $persister->containsKey($this, $key);
173 }
174 return parent::containsKey($key);
175 }
176 public function contains($element) : bool
177 {
178 if (!$this->initialized && $this->getMapping()['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY) {
179 $persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping());
180 return $this->unwrap()->contains($element) || $persister->contains($this, $element);
181 }
182 return parent::contains($element);
183 }
184 public function get($key)
185 {
186 if (!$this->initialized && $this->getMapping()['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY && isset($this->getMapping()['indexBy'])) {
187 assert($this->em !== null);
188 assert($this->typeClass !== null);
189 if (!$this->typeClass->isIdentifierComposite && $this->typeClass->isIdentifier($this->getMapping()['indexBy'])) {
190 return $this->em->find($this->typeClass->name, $key);
191 }
192 return $this->getUnitOfWork()->getCollectionPersister($this->getMapping())->get($this, $key);
193 }
194 return parent::get($key);
195 }
196 public function count() : int
197 {
198 if (!$this->initialized && $this->association !== null && $this->getMapping()['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY) {
199 $persister = $this->getUnitOfWork()->getCollectionPersister($this->association);
200 return $persister->count($this) + ($this->isDirty ? $this->unwrap()->count() : 0);
201 }
202 return parent::count();
203 }
204 public function set($key, $value) : void
205 {
206 parent::set($key, $value);
207 $this->changed();
208 if (is_object($value) && $this->em) {
209 $this->getUnitOfWork()->cancelOrphanRemoval($value);
210 }
211 }
212 public function add($value) : bool
213 {
214 $this->unwrap()->add($value);
215 $this->changed();
216 if (is_object($value) && $this->em) {
217 $this->getUnitOfWork()->cancelOrphanRemoval($value);
218 }
219 return \true;
220 }
221 public function offsetExists($offset) : bool
222 {
223 return $this->containsKey($offset);
224 }
225 #[\ReturnTypeWillChange]
226 public function offsetGet($offset)
227 {
228 return $this->get($offset);
229 }
230 public function offsetSet($offset, $value) : void
231 {
232 if (!isset($offset)) {
233 $this->add($value);
234 return;
235 }
236 $this->set($offset, $value);
237 }
238 #[\ReturnTypeWillChange]
239 public function offsetUnset($offset)
240 {
241 return $this->remove($offset);
242 }
243 public function isEmpty() : bool
244 {
245 return $this->unwrap()->isEmpty() && $this->count() === 0;
246 }
247 public function clear() : void
248 {
249 if ($this->initialized && $this->isEmpty()) {
250 $this->unwrap()->clear();
251 return;
252 }
253 $uow = $this->getUnitOfWork();
254 $association = $this->getMapping();
255 if ($association['type'] & ClassMetadata::TO_MANY && $association['orphanRemoval'] && $this->owner) {
256 // we need to initialize here, as orphan removal acts like implicit cascadeRemove,
257 // hence for event listeners we need the objects in memory.
258 $this->initialize();
259 foreach ($this->unwrap() as $element) {
260 $uow->scheduleOrphanRemoval($element);
261 }
262 }
263 $this->unwrap()->clear();
264 $this->initialized = \true;
265 // direct call, {@link initialize()} is too expensive
266 if ($association['isOwningSide'] && $this->owner) {
267 $this->changed();
268 $uow->scheduleCollectionDeletion($this);
269 $this->takeSnapshot();
270 }
271 }
272 public function __sleep() : array
273 {
274 return ['collection', 'initialized'];
275 }
276 public function slice($offset, $length = null) : array
277 {
278 if (!$this->initialized && !$this->isDirty && $this->getMapping()['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY) {
279 $persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping());
280 return $persister->slice($this, $offset, $length);
281 }
282 return parent::slice($offset, $length);
283 }
284 public function __clone()
285 {
286 if (is_object($this->collection)) {
287 $this->collection = clone $this->collection;
288 }
289 $this->initialize();
290 $this->owner = null;
291 $this->snapshot = [];
292 $this->changed();
293 }
294 public function matching(Criteria $criteria) : Collection
295 {
296 if ($this->isDirty) {
297 $this->initialize();
298 }
299 if ($this->initialized) {
300 return $this->unwrap()->matching($criteria);
301 }
302 $association = $this->getMapping();
303 if ($association['type'] === ClassMetadata::MANY_TO_MANY) {
304 $persister = $this->getUnitOfWork()->getCollectionPersister($association);
305 return new ArrayCollection($persister->loadCriteria($this, $criteria));
306 }
307 $builder = Criteria::expr();
308 $ownerExpression = $builder->eq($this->backRefFieldName, $this->owner);
309 $expression = $criteria->getWhereExpression();
310 $expression = $expression ? $builder->andX($expression, $ownerExpression) : $ownerExpression;
311 $criteria = clone $criteria;
312 $criteria->where($expression);
313 $criteria->orderBy(self::mapToOrderEnumIfAvailable(self::getCriteriaOrderings($criteria) ?: $association['orderBy'] ?? []));
314 $persister = $this->getUnitOfWork()->getEntityPersister($association['targetEntity']);
315 return $association['fetch'] === ClassMetadata::FETCH_EXTRA_LAZY ? new LazyCriteriaCollection($persister, $criteria) : new ArrayCollection($persister->loadCriteria($criteria));
316 }
317 public function unwrap() : Collection
318 {
319 assert($this->collection instanceof Collection);
320 assert($this->collection instanceof Selectable);
321 return $this->collection;
322 }
323 protected function doInitialize() : void
324 {
325 // Has NEW objects added through add(). Remember them.
326 $newlyAddedDirtyObjects = [];
327 if ($this->isDirty) {
328 $newlyAddedDirtyObjects = $this->unwrap()->toArray();
329 }
330 $this->unwrap()->clear();
331 $this->getUnitOfWork()->loadCollection($this);
332 $this->takeSnapshot();
333 if ($newlyAddedDirtyObjects) {
334 $this->restoreNewObjectsInDirtyCollection($newlyAddedDirtyObjects);
335 }
336 }
337 private function restoreNewObjectsInDirtyCollection(array $newObjects) : void
338 {
339 $loadedObjects = $this->unwrap()->toArray();
340 $newObjectsByOid = array_combine(array_map('spl_object_id', $newObjects), $newObjects);
341 $loadedObjectsByOid = array_combine(array_map('spl_object_id', $loadedObjects), $loadedObjects);
342 $newObjectsThatWereNotLoaded = array_diff_key($newObjectsByOid, $loadedObjectsByOid);
343 if ($newObjectsThatWereNotLoaded) {
344 // Reattach NEW objects added through add(), if any.
345 array_walk($newObjectsThatWereNotLoaded, [$this->unwrap(), 'add']);
346 $this->isDirty = \true;
347 }
348 }
349 }
350