1818use function array_map ;
1919use function array_values ;
2020use function array_walk ;
21+ use function assert ;
2122use function get_class ;
2223use function is_object ;
2324use function spl_object_id ;
3334 *
3435 * @psalm-template TKey of array-key
3536 * @psalm-template T
36- * @template-implements Collection<TKey,T>
37+ * @template-extends AbstractLazyCollection<TKey,T>
38+ * @template-implements Selectable<TKey,T>
3739 */
3840final class PersistentCollection extends AbstractLazyCollection implements Selectable
3941{
@@ -71,7 +73,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
7173 * The name of the field on the target entities that points to the owner
7274 * of the collection. This is only set if the association is bi-directional.
7375 *
74- * @var string
76+ * @var string|null
7577 */
7678 private $ backRefFieldName ;
7779
@@ -148,7 +150,7 @@ public function getTypeClass(): Mapping\ClassMetadataInfo
148150 */
149151 public function hydrateAdd ($ element ): void
150152 {
151- $ this ->collection ->add ($ element );
153+ $ this ->unwrap () ->add ($ element );
152154
153155 // If _backRefFieldName is set and its a one-to-many association,
154156 // we need to set the back reference.
@@ -176,7 +178,7 @@ public function hydrateAdd($element): void
176178 */
177179 public function hydrateSet ($ key , $ element ): void
178180 {
179- $ this ->collection ->set ($ key , $ element );
181+ $ this ->unwrap () ->set ($ key , $ element );
180182
181183 // If _backRefFieldName is set, then the association is bidirectional
182184 // and we need to set the back reference.
@@ -210,7 +212,7 @@ public function initialize(): void
210212 */
211213 public function takeSnapshot (): void
212214 {
213- $ this ->snapshot = $ this ->collection ->toArray ();
215+ $ this ->snapshot = $ this ->unwrap () ->toArray ();
214216 $ this ->isDirty = false ;
215217 }
216218
@@ -233,7 +235,7 @@ public function getSnapshot(): array
233235 */
234236 public function getDeleteDiff (): array
235237 {
236- $ collectionItems = $ this ->collection ->toArray ();
238+ $ collectionItems = $ this ->unwrap () ->toArray ();
237239
238240 return array_values (array_diff_key (
239241 array_combine (array_map ('spl_object_id ' , $ this ->snapshot ), $ this ->snapshot ),
@@ -249,7 +251,7 @@ public function getDeleteDiff(): array
249251 */
250252 public function getInsertDiff (): array
251253 {
252- $ collectionItems = $ this ->collection ->toArray ();
254+ $ collectionItems = $ this ->unwrap () ->toArray ();
253255
254256 return array_values (array_diff_key (
255257 array_combine (array_map ('spl_object_id ' , $ collectionItems ), $ collectionItems ),
@@ -322,8 +324,6 @@ public function setInitialized($bool): void
322324
323325 /**
324326 * {@inheritdoc}
325- *
326- * @return object
327327 */
328328 public function remove ($ key )
329329 {
@@ -387,7 +387,7 @@ public function containsKey($key): bool
387387 ) {
388388 $ persister = $ this ->em ->getUnitOfWork ()->getCollectionPersister ($ this ->association );
389389
390- return $ this ->collection ->containsKey ($ key ) || $ persister ->containsKey ($ this , $ key );
390+ return $ this ->unwrap () ->containsKey ($ key ) || $ persister ->containsKey ($ this , $ key );
391391 }
392392
393393 return parent ::containsKey ($ key );
@@ -401,7 +401,7 @@ public function contains($element): bool
401401 if (! $ this ->initialized && $ this ->association ['fetch ' ] === ClassMetadata::FETCH_EXTRA_LAZY ) {
402402 $ persister = $ this ->em ->getUnitOfWork ()->getCollectionPersister ($ this ->association );
403403
404- return $ this ->collection ->contains ($ element ) || $ persister ->contains ($ this , $ element );
404+ return $ this ->unwrap () ->contains ($ element ) || $ persister ->contains ($ this , $ element );
405405 }
406406
407407 return parent ::contains ($ element );
@@ -432,7 +432,7 @@ public function count(): int
432432 if (! $ this ->initialized && $ this ->association !== null && $ this ->association ['fetch ' ] === ClassMetadata::FETCH_EXTRA_LAZY ) {
433433 $ persister = $ this ->em ->getUnitOfWork ()->getCollectionPersister ($ this ->association );
434434
435- return $ persister ->count ($ this ) + ($ this ->isDirty ? $ this ->collection ->count () : 0 );
435+ return $ persister ->count ($ this ) + ($ this ->isDirty ? $ this ->unwrap () ->count () : 0 );
436436 }
437437
438438 return parent ::count ();
@@ -457,7 +457,7 @@ public function set($key, $value): void
457457 */
458458 public function add ($ value ): bool
459459 {
460- $ this ->collection ->add ($ value );
460+ $ this ->unwrap () ->add ($ value );
461461
462462 $ this ->changed ();
463463
@@ -514,13 +514,13 @@ public function offsetUnset($offset)
514514
515515 public function isEmpty (): bool
516516 {
517- return $ this ->collection ->isEmpty () && $ this ->count () === 0 ;
517+ return $ this ->unwrap () ->isEmpty () && $ this ->count () === 0 ;
518518 }
519519
520520 public function clear (): void
521521 {
522522 if ($ this ->initialized && $ this ->isEmpty ()) {
523- $ this ->collection ->clear ();
523+ $ this ->unwrap () ->clear ();
524524
525525 return ;
526526 }
@@ -536,12 +536,12 @@ public function clear(): void
536536 // hence for event listeners we need the objects in memory.
537537 $ this ->initialize ();
538538
539- foreach ($ this ->collection as $ element ) {
539+ foreach ($ this ->unwrap () as $ element ) {
540540 $ uow ->scheduleOrphanRemoval ($ element );
541541 }
542542 }
543543
544- $ this ->collection ->clear ();
544+ $ this ->unwrap () ->clear ();
545545
546546 $ this ->initialized = true ; // direct call, {@link initialize()} is too expensive
547547
@@ -633,7 +633,7 @@ public function matching(Criteria $criteria): Collection
633633 }
634634
635635 if ($ this ->initialized ) {
636- return $ this ->collection ->matching ($ criteria );
636+ return $ this ->unwrap () ->matching ($ criteria );
637637 }
638638
639639 if ($ this ->association ['type ' ] === ClassMetadata::MANY_TO_MANY ) {
@@ -665,6 +665,8 @@ public function matching(Criteria $criteria): Collection
665665 */
666666 public function unwrap (): Collection
667667 {
668+ assert ($ this ->collection !== null );
669+
668670 return $ this ->collection ;
669671 }
670672
@@ -674,10 +676,10 @@ protected function doInitialize(): void
674676 $ newlyAddedDirtyObjects = [];
675677
676678 if ($ this ->isDirty ) {
677- $ newlyAddedDirtyObjects = $ this ->collection ->toArray ();
679+ $ newlyAddedDirtyObjects = $ this ->unwrap () ->toArray ();
678680 }
679681
680- $ this ->collection ->clear ();
682+ $ this ->unwrap () ->clear ();
681683 $ this ->em ->getUnitOfWork ()->loadCollection ($ this );
682684 $ this ->takeSnapshot ();
683685
@@ -696,14 +698,14 @@ protected function doInitialize(): void
696698 */
697699 private function restoreNewObjectsInDirtyCollection (array $ newObjects ): void
698700 {
699- $ loadedObjects = $ this ->collection ->toArray ();
701+ $ loadedObjects = $ this ->unwrap () ->toArray ();
700702 $ newObjectsByOid = array_combine (array_map ('spl_object_id ' , $ newObjects ), $ newObjects );
701703 $ loadedObjectsByOid = array_combine (array_map ('spl_object_id ' , $ loadedObjects ), $ loadedObjects );
702704 $ newObjectsThatWereNotLoaded = array_diff_key ($ newObjectsByOid , $ loadedObjectsByOid );
703705
704706 if ($ newObjectsThatWereNotLoaded ) {
705707 // Reattach NEW objects added through add(), if any.
706- array_walk ($ newObjectsThatWereNotLoaded , [$ this ->collection , 'add ' ]);
708+ array_walk ($ newObjectsThatWereNotLoaded , [$ this ->unwrap () , 'add ' ]);
707709
708710 $ this ->isDirty = true ;
709711 }
0 commit comments