Skip to content

Commit 46e1519

Browse files
authored
Merge pull request #1636 from soyuka/hotfix/filter-eager-loading-ext
fix FilterEagerLoadingExtension do not remove where clause if it did …
2 parents 0f57e94 + 776f62d commit 46e1519

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

src/Bridge/Doctrine/Orm/Extension/FilterEagerLoadingExtension.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,14 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator
6262

6363
$queryBuilderClone = clone $queryBuilder;
6464
$queryBuilderClone->resetDQLPart('where');
65+
$changedWhereClause = false;
6566

6667
if (!$classMetadata->isIdentifierComposite) {
6768
$replacementAlias = $queryNameGenerator->generateJoinAlias($originAlias);
6869
$in = $this->getQueryBuilderWithNewAliases($queryBuilder, $queryNameGenerator, $originAlias, $replacementAlias);
6970
$in->select($replacementAlias);
7071
$queryBuilderClone->andWhere($queryBuilderClone->expr()->in($originAlias, $in->getDQL()));
72+
$changedWhereClause = true;
7173
} else {
7274
// Because Doctrine doesn't support WHERE ( foo, bar ) IN () (https://github.com/doctrine/doctrine2/issues/5238), we are building as many subqueries as they are identifiers
7375
foreach ($classMetadata->getIdentifier() as $identifier) {
@@ -79,9 +81,14 @@ public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGenerator
7981
$in = $this->getQueryBuilderWithNewAliases($queryBuilder, $queryNameGenerator, $originAlias, $replacementAlias);
8082
$in->select("IDENTITY($replacementAlias.$identifier)");
8183
$queryBuilderClone->andWhere($queryBuilderClone->expr()->in("$originAlias.$identifier", $in->getDQL()));
84+
$changedWhereClause = true;
8285
}
8386
}
8487

88+
if (false === $changedWhereClause) {
89+
return;
90+
}
91+
8592
$queryBuilder->resetDQLPart('where');
8693
$queryBuilder->add('where', $queryBuilderClone->getDQLPart('where'));
8794
}

tests/Bridge/Doctrine/Orm/Extension/FilterEagerLoadingExtensionTest.php

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ public function testFetchEagerWithNoForceEager()
358358
$this->assertEquals($this->toDQLString($expected), $qb->getDQL());
359359
}
360360

361-
public function testCompositeIdentifiersWithoutAssociation()
361+
public function testCompositeIdentifiersWithAssociation()
362362
{
363363
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
364364
$resourceMetadataFactoryProphecy->create(CompositeRelation::class)->willReturn(new ResourceMetadata(CompositeRelation::class));
@@ -416,6 +416,48 @@ public function testCompositeIdentifiersWithoutAssociation()
416416
$this->assertEquals($this->toDQLString($expected), $qb->getDQL());
417417
}
418418

419+
public function testCompositeIdentifiersWithoutAssociation()
420+
{
421+
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
422+
$resourceMetadataFactoryProphecy->create(CompositeRelation::class)->willReturn(new ResourceMetadata(CompositeRelation::class));
423+
424+
$classMetadataProphecy = $this->prophesize(ClassMetadataInfo::class);
425+
$classMetadataProphecy->getIdentifier()->willReturn(['foo', 'bar']);
426+
$classMetadataProphecy->getAssociationMappings()->willReturn(['item' => ['fetch' => ClassMetadataInfo::FETCH_EAGER]]);
427+
$classMetadataProphecy->hasAssociation('foo')->shouldBeCalled()->willReturn(false);
428+
$classMetadataProphecy->hasAssociation('bar')->shouldBeCalled()->willReturn(false);
429+
430+
$classMetadata = $classMetadataProphecy->reveal();
431+
$classMetadata->isIdentifierComposite = true;
432+
433+
$em = $this->prophesize(EntityManager::class);
434+
$em->getClassMetadata(CompositeRelation::class)->shouldBeCalled()->willReturn($classMetadata);
435+
436+
$qb = new QueryBuilder($em->reveal());
437+
438+
$qb->select('o')
439+
->from(CompositeRelation::class, 'o')
440+
->innerJoin('o.compositeItem', 'item')
441+
->innerJoin('o.compositeLabel', 'label')
442+
->where('item.field1 = :foo AND o.bar = :bar')
443+
->setParameter('foo', 1)
444+
->setParameter('bar', 2);
445+
446+
$queryNameGenerator = $this->prophesize(QueryNameGeneratorInterface::class);
447+
$filterEagerLoadingExtension = new FilterEagerLoadingExtension($resourceMetadataFactoryProphecy->reveal(), true);
448+
$filterEagerLoadingExtension->applyToCollection($qb, $queryNameGenerator->reveal(), CompositeRelation::class, 'get');
449+
450+
$expected = <<<SQL
451+
SELECT o
452+
FROM ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\CompositeRelation o
453+
INNER JOIN o.compositeItem item
454+
INNER JOIN o.compositeLabel label
455+
WHERE item.field1 = :foo AND o.bar = :bar
456+
SQL;
457+
458+
$this->assertEquals($this->toDQLString($expected), $qb->getDQL());
459+
}
460+
419461
private function toDQLString(string $dql): string
420462
{
421463
return preg_replace(['/\s+/', '/\(\s/', '/\s\)/'], [' ', '(', ')'], $dql);

0 commit comments

Comments
 (0)