Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve LazyCriteriaCollection matching #10640

21 changes: 18 additions & 3 deletions lib/Doctrine/ORM/LazyCriteriaCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@

use Doctrine\Common\Collections\AbstractLazyCollection;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable;
use Doctrine\ORM\Persisters\Entity\EntityPersister;
use ReturnTypeWillChange;

use function array_filter;
use function array_merge;
use function assert;

/**
Expand Down Expand Up @@ -96,10 +99,22 @@ public function contains($element)
*/
public function matching(Criteria $criteria)
{
$this->initialize();
assert($this->collection instanceof Selectable);
if ($this->isInitialized()) {
assert($this->collection instanceof Selectable);

return $this->collection->matching($criteria);
}

$criteria = Criteria::create()
->andWhere(Criteria::expr()->andX(...array_filter([$this->criteria->getWhereExpression(), $criteria->getWhereExpression()])))
->orderBy(array_merge($this->criteria->getOrderings(), $criteria->getOrderings()))
->setFirstResult($criteria->getFirstResult() ?? $this->criteria->getFirstResult())
->setMaxResults($criteria->getMaxResults() ?? $this->criteria->getFirstResult());

/** @var Collection<TKey, TValue>&Selectable<TKey, TValue> $collection */
$collection = new self($this->entityPersister, $criteria);

return $this->collection->matching($criteria);
return $collection;
}

/**
Expand Down
17 changes: 12 additions & 5 deletions tests/Doctrine/Tests/ORM/LazyCriteriaCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Doctrine\Tests\ORM;

use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\LazyCriteriaCollection;
use Doctrine\ORM\Persisters\Entity\EntityPersister;
Expand Down Expand Up @@ -80,7 +79,6 @@ public function testMatchingUsesThePersisterOnlyOnce(): void
->persister
->expects(self::once())
->method('loadCriteria')
->with($this->criteria)
->will(self::returnValue([$foo, $bar, $baz]));

$criteria = new Criteria();
Expand All @@ -89,10 +87,19 @@ public function testMatchingUsesThePersisterOnlyOnce(): void

$filtered = $this->lazyCriteriaCollection->matching($criteria);

self::assertInstanceOf(Collection::class, $filtered);
self::assertEquals([$foo], $filtered->toArray());
self::assertInstanceOf(LazyCriteriaCollection::class, $filtered);
self::assertEquals([$foo, $bar, $baz], $filtered->toArray());

self::assertEquals([$foo], $filtered->matching($criteria)->toArray());
}

public function testMatchingWillNotInitializeCollection(): void
{
$this->persister->expects(self::never())->method('loadCriteria');

$this->lazyCriteriaCollection->matching(Criteria::create());

self::assertEquals([$foo], $this->lazyCriteriaCollection->matching($criteria)->toArray());
self::assertFalse($this->lazyCriteriaCollection->isInitialized());
}

public function testIsEmptyUsesCountWhenNotInitialized(): void
Expand Down