Make ReadableCollection extend Selectable

This commit is contained in:
Grégoire Paris
2026-01-15 19:45:52 +01:00
parent bcc1e1ce40
commit e07c7edde2
4 changed files with 9 additions and 45 deletions

View File

@@ -8,6 +8,12 @@ awareness about deprecated code.
# Upgrade to 3.0
## `ReadableCollection` now extends `Selectable`
The `Doctrine\Common\Collections\ReadableCollection` interface now extends
`Doctrine\Common\Collections\Selectable`. Any class implementing
`ReadableCollection` must also implement `Selectable`.
## Readonly classes
The following classes are now `readonly` classes, making all their properties immutable:

View File

@@ -5,7 +5,6 @@ declare(strict_types=1);
namespace Doctrine\Common\Collections;
use Closure;
use Doctrine\Deprecations\Deprecation;
use LogicException;
use Override;
use Traversable;
@@ -23,8 +22,7 @@ abstract class AbstractLazyCollection implements Collection, Selectable
/**
* The backed collection to use
*
* @phpstan-var Collection<TKey,T>|null
* @var Collection<mixed>|null
* @var Collection<TKey,T>|null
*/
protected Collection|null $collection;
@@ -321,18 +319,6 @@ abstract class AbstractLazyCollection implements Collection, Selectable
if ($this->collection === null) {
throw new LogicException('You must initialize the collection property in the doInitialize() method.');
}
if ($this->collection instanceof Selectable) {
return;
}
Deprecation::trigger(
'doctrine/collections',
'https://github.com/doctrine/collections/pull/518',
'Initializing %s with a collection that does not implement %s is deprecated and will throw an exception in 3.0.',
self::class,
Selectable::class,
);
}
/**
@@ -345,10 +331,6 @@ abstract class AbstractLazyCollection implements Collection, Selectable
{
$this->initialize();
if (! $this->collection instanceof Selectable) {
throw new LogicException('The backed collection must implement Selectable to use matching().');
}
return $this->collection->matching($criteria);
}
}

View File

@@ -12,8 +12,9 @@ use IteratorAggregate;
* @phpstan-template TKey of array-key
* @template-covariant T
* @template-extends IteratorAggregate<TKey, T>
* @template-extends Selectable<TKey, T>
*/
interface ReadableCollection extends Countable, IteratorAggregate
interface ReadableCollection extends Countable, IteratorAggregate, Selectable
{
/**
* Checks whether an element is contained in the collection.

View File

@@ -8,7 +8,6 @@ use Doctrine\Common\Collections\AbstractLazyCollection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
use LogicException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
@@ -23,8 +22,6 @@ use function is_string;
#[CoversClass(AbstractLazyCollection::class)]
class AbstractLazyCollectionTest extends CollectionTestCase
{
use VerifyDeprecations;
protected function setUp(): void
{
$this->collection = new LazyArrayCollection(new ArrayCollection());
@@ -139,26 +136,4 @@ class AbstractLazyCollectionTest extends CollectionTestCase
self::assertCount(2, $result);
self::assertSame($obj1, $result->first());
}
#[IgnoreDeprecations]
public function testMatchingThrowsExceptionWhenBackedCollectionNotSelectable(): void
{
$lazyCollection = new LazyArrayCollection($this->createStub(Collection::class));
$this->expectException(LogicException::class);
$this->expectExceptionMessage('The backed collection must implement Selectable to use matching().');
$lazyCollection->matching(Criteria::create(true));
}
#[IgnoreDeprecations]
public function testMatchingTriggersDeprecationWhenBackedCollectionNotSelectable(): void
{
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/collections/pull/518');
$lazyCollection = new LazyArrayCollection($this->createStub(Collection::class));
// Trigger initialization with any method - deprecation happens during initialize()
$lazyCollection->isEmpty();
}
}