44
55namespace Doctrine \ODM \MongoDB \PersistentCollection ;
66
7- use BadMethodCallException ;
87use Closure ;
98use Doctrine \Common \Collections \Collection as BaseCollection ;
109use Doctrine \Common \Collections \Criteria ;
11- use Doctrine \Common \Collections \ReadableCollection ;
1210use Doctrine \Common \Collections \Selectable ;
1311use Doctrine \ODM \MongoDB \DocumentManager ;
1412use Doctrine \ODM \MongoDB \Mapping \ClassMetadata ;
2523use function array_values ;
2624use function count ;
2725use function is_object ;
28- use function method_exists ;
26+ use function sprintf ;
2927
3028/**
3129 * Trait with methods needed to implement PersistentCollectionInterface.
@@ -437,8 +435,15 @@ public function set(string|int $key, mixed $value): void
437435 $ this ->doSet ($ key , $ value , false );
438436 }
439437
440- /** @param T $element */
441- public function add (mixed $ element ): bool
438+ /**
439+ * Adds an element at the end of the collection.
440+ *
441+ * @param mixed $element The element to add.
442+ * @phpstan-param T $element
443+ *
444+ * @return true The return value is kept for BC reasons, but will be void in doctrine/mongodb-odm 3.0.
445+ */
446+ public function add ($ element ): bool
442447 {
443448 return $ this ->doAdd ($ element , false );
444449 }
@@ -750,10 +755,6 @@ private function isOrphanRemovalEnabled(): bool
750755 */
751756 public function findFirst (Closure $ p ): ?object
752757 {
753- if (! method_exists ($ this ->coll , 'findFirst ' )) {
754- throw new BadMethodCallException ('findFirst() is only available since doctrine/collections v2 ' );
755- }
756-
757758 return $ this ->coll ->findFirst ($ p );
758759 }
759760
@@ -768,21 +769,24 @@ public function findFirst(Closure $p): ?object
768769 */
769770 public function reduce (Closure $ func , mixed $ initial = null ): mixed
770771 {
771- if (! method_exists ($ this ->coll , 'reduce ' )) {
772- throw new BadMethodCallException ('reduce() is only available since doctrine/collections v2 ' );
773- }
774-
775772 return $ this ->coll ->reduce ($ func , $ initial );
776773 }
777774
778- public function matching (Criteria $ criteria ): ReadableCollection
775+ /** @return BaseCollection<TKey, T> */
776+ public function matching (Criteria $ criteria ): BaseCollection
779777 {
780778 $ this ->initialize ();
781779
782780 if (! $ this ->coll instanceof Selectable) {
783781 throw new LogicException ('The backed collection must implement Selectable to use matching(). ' );
784782 }
785783
786- return $ this ->coll ->matching ($ criteria );
784+ $ coll = $ this ->coll ->matching ($ criteria );
785+
786+ if (! $ coll instanceof BaseCollection) {
787+ throw new LogicException (sprintf ('The matching() method of the backed collection must return an instance of "%s". ' , BaseCollection::class));
788+ }
789+
790+ return $ coll ;
787791 }
788792}
0 commit comments