Make PersistentCollection implement Selectable (#2982)

Implementing ReadableCollection without Selectable is deprecated

https://github.com/doctrine/collections/pull/518

* Update returned value in the mock to match the actual return type

* Fix return type to match the interface
This commit is contained in:
Jérôme Tamarelle
2026-01-16 18:27:51 +01:00
committed by GitHub
parent 0370e17b19
commit 8722216576
4 changed files with 46 additions and 2 deletions

View File

@@ -59,3 +59,8 @@ implement `closureToPHP()`.
The method `Doctrine\ODM\MongoDB\Types\Type::closureToMongo()` is not used,
and will be removed in MongoDB ODM 3.0. Don't call this method, but use
`convertToDatabaseValue()` instead.
## `PersistentCollection` implements `Selectable`
The `PersistentCollection` and all generated persistent collection classes
implement the `Doctrine\Common\Collections\Selectable::matching()` method.

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Doctrine\ODM\MongoDB\PersistentCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Selectable;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\MongoDBException;
use Doctrine\ODM\MongoDB\UnitOfWork;
@@ -21,8 +22,9 @@ use Doctrine\Persistence\Mapping\ClassMetadata;
* @template TKey of array-key
* @template T of object
* @template-extends Collection<TKey, T>
* @template-extends Selectable<TKey, T>
*/
interface PersistentCollectionInterface extends Collection
interface PersistentCollectionInterface extends Collection, Selectable
{
/**
* Sets the document manager and unit of work (used during merge operations).

View File

@@ -7,11 +7,15 @@ namespace Doctrine\ODM\MongoDB\PersistentCollection;
use BadMethodCallException;
use Closure;
use Doctrine\Common\Collections\Collection as BaseCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\ReadableCollection;
use Doctrine\Common\Collections\Selectable;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\MongoDBException;
use Doctrine\ODM\MongoDB\UnitOfWork;
use Doctrine\ODM\MongoDB\Utility\CollectionHelper;
use LogicException;
use ReturnTypeWillChange;
use Traversable;
@@ -775,4 +779,15 @@ trait PersistentCollectionTrait
return $this->coll->reduce($func, $initial);
}
public function matching(Criteria $criteria): ReadableCollection
{
$this->initialize();
if (! $this->coll instanceof Selectable) {
throw new LogicException('The backed collection must implement Selectable to use matching().');
}
return $this->coll->matching($criteria);
}
}

View File

@@ -7,6 +7,7 @@ namespace Doctrine\ODM\MongoDB\Tests;
use Closure;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
use Doctrine\ODM\MongoDB\MongoDBException;
use Doctrine\ODM\MongoDB\PersistentCollection;
@@ -29,7 +30,7 @@ class PersistentCollectionTest extends BaseTestCase
$collection->expects($this->once())
->method('slice')
->with($start, $limit)
->willReturn(true);
->willReturn([]);
$pCollection = new PersistentCollection($collection, $this->dm, $this->uow);
$pCollection->slice($start, $limit);
}
@@ -332,6 +333,27 @@ class PersistentCollectionTest extends BaseTestCase
self::assertTrue($pcoll->isEmpty());
}
public function testMatchingIsForwarded(): void
{
$criteria = new Criteria();
$criteria->where($criteria->expr()->eq('field', 'value'));
$expectedResult = new ArrayCollection([new stdClass()]);
// ArrayCollection implements both Collection and Selectable
// When doctrine/collections 2.6+ is required, we can mock Collection directly
$collection = $this->createMock(ArrayCollection::class);
$collection->expects($this->once())
->method('matching')
->with($criteria)
->willReturn($expectedResult);
$pcoll = new PersistentCollection($collection, $this->dm, $this->uow);
$result = $pcoll->matching($criteria);
self::assertSame($expectedResult, $result);
}
/** @return Collection<int, object>&MockObject */
private function getMockCollection()
{