Skip to content

Commit

Permalink
fix api-platform/#360 QueryChecker with class join
Browse files Browse the repository at this point in the history
  • Loading branch information
abluchet committed Aug 4, 2017
1 parent e0c8465 commit b40c191
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/Bridge/Doctrine/Orm/Util/QueryChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,35 @@ public static function hasOrderByOnToManyJoin(QueryBuilder $queryBuilder, Manage

if (isset($orderByAliases[$alias])) {
$relationship = QueryJoinParser::getJoinRelationship($join);
list($parentAlias, $association) = explode('.', $relationship);

$parentMetadata = QueryJoinParser::getClassMetadataFromJoinAlias($parentAlias, $queryBuilder, $managerRegistry);
if (!class_exists($relationship)) {
list($parentAlias, $association) = explode('.', $relationship);

if ($parentMetadata->isCollectionValuedAssociation($association)) {
return true;
$parentMetadata = QueryJoinParser::getClassMetadataFromJoinAlias($parentAlias, $queryBuilder, $managerRegistry);

if ($parentMetadata->isCollectionValuedAssociation($association)) {
return true;
}

continue;
}

$parentMetadata = $managerRegistry->getManagerForClass($relationship)->getClassMetadata($relationship);

foreach ($queryBuilder->getRootEntities() as $rootEntity) {
$rootMetadata = $managerRegistry
->getManagerForClass($rootEntity)
->getClassMetadata($rootEntity);

if (!($rootMetadata instanceof ClassMetadata)) {
continue;
}

foreach ($rootMetadata->getAssociationsByTargetClass($relationship) as $association => $mapping) {
if ($parentMetadata->isCollectionValuedAssociation($association)) {
return true;
}
}
}
}
}
Expand Down
22 changes: 22 additions & 0 deletions tests/Bridge/Doctrine/Orm/Util/QueryCheckerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace ApiPlatform\Core\Tests\Bridge\Doctrine\Orm\Util;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryChecker;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\Mapping\ClassMetadata;
Expand Down Expand Up @@ -153,4 +154,25 @@ public function testHasOrderByOnToManyJoinWithoutJoinAndWithoutOrderBy()

$this->assertFalse(QueryChecker::hasOrderByOnToManyJoin($queryBuilder->reveal(), $managerRegistry->reveal()));
}

public function testHasOrderByOnToManyJoinWithClassLeftJoin()
{
$queryBuilder = $this->prophesize(QueryBuilder::class);
$queryBuilder->getRootEntities()->willReturn(['Dummy']);
$queryBuilder->getRootAliases()->willReturn(['d']);
$queryBuilder->getDQLPart('join')->willReturn(['a_1' => [new Join('LEFT_JOIN', RelatedDummy::class, 'a_1', null, 'a_1.name = d.name')]]);
$queryBuilder->getDQLPart('orderBy')->willReturn(['a_1.name' => new OrderBy('a_1.name', 'asc')]);
$classMetadata = $this->prophesize(ClassMetadata::class);
$classMetadata->getAssociationsByTargetClass(RelatedDummy::class)->willReturn(['relatedDummy' => ['targetEntity' => RelatedDummy::class]]);
$relatedClassMetadata = $this->prophesize(ClassMetadata::class);
$relatedClassMetadata->isCollectionValuedAssociation('relatedDummy')->willReturn(true);
$objectManager = $this->prophesize(ObjectManager::class);
$objectManager->getClassMetadata('Dummy')->willReturn($classMetadata->reveal());
$objectManager->getClassMetadata(RelatedDummy::class)->willReturn($relatedClassMetadata->reveal());
$managerRegistry = $this->prophesize(ManagerRegistry::class);
$managerRegistry->getManagerForClass('Dummy')->willReturn($objectManager->reveal());
$managerRegistry->getManagerForClass(RelatedDummy::class)->willReturn($objectManager->reveal());

$this->assertTrue(QueryChecker::hasOrderByOnToManyJoin($queryBuilder->reveal(), $managerRegistry->reveal()));
}
}
13 changes: 13 additions & 0 deletions tests/Bridge/Doctrine/Orm/Util/QueryJoinParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace ApiPlatform\Core\Tests\Bridge\Doctrine\Orm\Util;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryJoinParser;
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\RelatedDummy;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\ORM\Mapping\ClassMetadata;
Expand Down Expand Up @@ -47,6 +48,12 @@ public function testGetJoinRelationshipWithJoin()
$this->assertEquals('relatedDummy', QueryJoinParser::getJoinRelationship($join));
}

public function testGetJoinRelationshipWithClassJoin()
{
$join = new Join('INNER_JOIN', RelatedDummy::class, 'a_1', null, 'a_1.name = r.name');
$this->assertEquals(RelatedDummy::class, QueryJoinParser::getJoinRelationship($join));
}

public function testGetJoinRelationshipWithReflection()
{
$methodExist = $this->getFunctionMock('ApiPlatform\Core\Bridge\Doctrine\Orm\Util', 'method_exists');
Expand All @@ -61,6 +68,12 @@ public function testGetJoinAliasWithJoin()
$this->assertEquals('a_1', QueryJoinParser::getJoinAlias($join));
}

public function testGetJoinAliasWithClassJoin()
{
$join = new Join('LEFT_JOIN', RelatedDummy::class, 'a_1', null, 'a_1.name = r.name');
$this->assertEquals('a_1', QueryJoinParser::getJoinAlias($join));
}

public function testGetJoinAliasWithReflection()
{
$methodExist = $this->getFunctionMock('ApiPlatform\Core\Bridge\Doctrine\Orm\Util', 'method_exists');
Expand Down

0 comments on commit b40c191

Please sign in to comment.