Skip to content

Commit 399d4b3

Browse files
authored
Merge pull request #737 from soyuka/add-result-extension-item
Add QueryResultItemExtensionInterface
2 parents 796cd4f + 820b22c commit 399d4b3

File tree

8 files changed

+287
-26
lines changed

8 files changed

+287
-26
lines changed

src/Bridge/Doctrine/Orm/CollectionDataProvider.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
namespace ApiPlatform\Core\Bridge\Doctrine\Orm;
1313

1414
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
15-
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultExtensionInterface;
15+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultCollectionExtensionInterface;
1616
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
1717
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
1818
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
@@ -60,10 +60,8 @@ public function getCollection(string $resourceClass, string $operationName = nul
6060
foreach ($this->collectionExtensions as $extension) {
6161
$extension->applyToCollection($queryBuilder, $queryNameGenerator, $resourceClass, $operationName);
6262

63-
if ($extension instanceof QueryResultExtensionInterface) {
64-
if ($extension->supportsResult($resourceClass, $operationName)) {
65-
return $extension->getResult($queryBuilder);
66-
}
63+
if ($extension instanceof QueryResultCollectionExtensionInterface && $extension->supportsResult($resourceClass, $operationName)) {
64+
return $extension->getResult($queryBuilder);
6765
}
6866
}
6967

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* @author Kévin Dunglas <[email protected]>
2121
* @author Samuel ROZE <[email protected]>
2222
*/
23-
class OrderExtension implements QueryCollectionExtensionInterface
23+
final class OrderExtension implements QueryCollectionExtensionInterface
2424
{
2525
private $order;
2626

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* @author Kévin Dunglas <[email protected]>
2929
* @author Samuel ROZE <[email protected]>
3030
*/
31-
class PaginationExtension implements QueryResultExtensionInterface
31+
final class PaginationExtension implements QueryResultCollectionExtensionInterface
3232
{
3333
private $managerRegistry;
3434
private $requestStack;

src/Bridge/Doctrine/Orm/Extension/QueryResultExtensionInterface.php renamed to src/Bridge/Doctrine/Orm/Extension/QueryResultCollectionExtensionInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* @author Samuel ROZE <[email protected]>
2121
* @author Kévin Dunglas <[email protected]>
2222
*/
23-
interface QueryResultExtensionInterface extends QueryCollectionExtensionInterface
23+
interface QueryResultCollectionExtensionInterface extends QueryCollectionExtensionInterface
2424
{
2525
/**
2626
* @param string $resourceClass
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace ApiPlatform\Core\Bridge\Doctrine\Orm\Extension;
13+
14+
use Doctrine\ORM\QueryBuilder;
15+
16+
/**
17+
* Interface of Doctrine ORM query extensions that supports result production
18+
* for specific cases such as Query alteration.
19+
*
20+
* @author Antoine BLUCHET <[email protected]>
21+
*/
22+
interface QueryResultItemExtensionInterface extends QueryItemExtensionInterface
23+
{
24+
/**
25+
* @param string $resourceClass
26+
* @param string|null $operationName
27+
*
28+
* @return bool
29+
*/
30+
public function supportsResult(string $resourceClass, string $operationName = null) : bool;
31+
32+
/**
33+
* @param QueryBuilder $queryBuilder
34+
*
35+
* @return mixed
36+
*/
37+
public function getResult(QueryBuilder $queryBuilder);
38+
}

src/Bridge/Doctrine/Orm/ItemDataProvider.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212
namespace ApiPlatform\Core\Bridge\Doctrine\Orm;
1313

1414
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryItemExtensionInterface;
15+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultItemExtensionInterface;
1516
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGenerator;
1617
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
17-
use ApiPlatform\Core\Exception\InvalidArgumentException;
18+
use ApiPlatform\Core\Exception\PropertyNotFoundException;
1819
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
1920
use ApiPlatform\Core\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
2021
use ApiPlatform\Core\Metadata\Property\Factory\PropertyNameCollectionFactoryInterface;
@@ -74,6 +75,10 @@ public function getItem(string $resourceClass, $id, string $operationName = null
7475

7576
foreach ($this->itemExtensions as $extension) {
7677
$extension->applyToItem($queryBuilder, $queryNameGenerator, $resourceClass, $identifiers, $operationName);
78+
79+
if ($extension instanceof QueryResultItemExtensionInterface && $extension->supportsResult($resourceClass, $operationName)) {
80+
return $extension->getResult($queryBuilder);
81+
}
7782
}
7883

7984
return $queryBuilder->getQuery()->getOneOrNullResult();
@@ -87,10 +92,6 @@ public function getItem(string $resourceClass, $id, string $operationName = null
8792
*/
8893
private function addWhereForIdentifiers(array $identifiers, QueryBuilder $queryBuilder)
8994
{
90-
if (empty($identifiers)) {
91-
return;
92-
}
93-
9495
foreach ($identifiers as $identifier => $value) {
9596
$placeholder = ':id_'.$identifier;
9697
$expression = $queryBuilder->expr()->eq(
@@ -140,10 +141,10 @@ private function normalizeIdentifiers($id, ObjectManager $manager, string $resou
140141
continue;
141142
}
142143

143-
$identifier = $identifiersMap[$propertyName] ?? $identifierValues[$i] ?? null;
144+
$identifier = !isset($identifiersMap) ? $identifierValues[$i] ?? null : $identifiersMap[$propertyName] ?? null;
144145

145146
if (null === $identifier) {
146-
throw new InvalidArgumentException(sprintf('Invalid identifier "%s".', $id));
147+
throw new PropertyNotFoundException(sprintf('Invalid identifier "%s", "%s" has not been found.', $id, $propertyName));
147148
}
148149

149150
$identifiers[$propertyName] = $identifier;

tests/Bridge/Doctrine/Orm/CollectionDataProviderTest.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use ApiPlatform\Core\Bridge\Doctrine\Orm\CollectionDataProvider;
1515
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
16-
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultExtensionInterface;
16+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Extension\QueryResultCollectionExtensionInterface;
1717
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
1818
use ApiPlatform\Core\Tests\Fixtures\TestBundle\Entity\Dummy;
1919
use Doctrine\Common\Persistence\ManagerRegistry;
@@ -47,10 +47,10 @@ public function testGetCollection()
4747
$managerRegistryProphecy = $this->prophesize(ManagerRegistry::class);
4848
$managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled();
4949

50-
$exstensionProphecy = $this->prophesize(QueryCollectionExtensionInterface::class);
51-
$exstensionProphecy->applyToCollection($queryBuilder, Argument::type(QueryNameGeneratorInterface::class), Dummy::class, 'foo')->shouldBeCalled();
50+
$extensionProphecy = $this->prophesize(QueryCollectionExtensionInterface::class);
51+
$extensionProphecy->applyToCollection($queryBuilder, Argument::type(QueryNameGeneratorInterface::class), Dummy::class, 'foo')->shouldBeCalled();
5252

53-
$dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$exstensionProphecy->reveal()]);
53+
$dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extensionProphecy->reveal()]);
5454
$this->assertEquals([], $dataProvider->getCollection(Dummy::class, 'foo'));
5555
}
5656

@@ -68,12 +68,12 @@ public function testQueryResultExtension()
6868
$managerRegistryProphecy = $this->prophesize(ManagerRegistry::class);
6969
$managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn($managerProphecy->reveal())->shouldBeCalled();
7070

71-
$exstensionProphecy = $this->prophesize(QueryResultExtensionInterface::class);
72-
$exstensionProphecy->applyToCollection($queryBuilder, Argument::type(QueryNameGeneratorInterface::class), Dummy::class, 'foo')->shouldBeCalled();
73-
$exstensionProphecy->supportsResult(Dummy::class, 'foo')->willReturn(true)->shouldBeCalled();
74-
$exstensionProphecy->getResult($queryBuilder)->willReturn([])->shouldBeCalled();
71+
$extensionProphecy = $this->prophesize(QueryResultCollectionExtensionInterface::class);
72+
$extensionProphecy->applyToCollection($queryBuilder, Argument::type(QueryNameGeneratorInterface::class), Dummy::class, 'foo')->shouldBeCalled();
73+
$extensionProphecy->supportsResult(Dummy::class, 'foo')->willReturn(true)->shouldBeCalled();
74+
$extensionProphecy->getResult($queryBuilder)->willReturn([])->shouldBeCalled();
7575

76-
$dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$exstensionProphecy->reveal()]);
76+
$dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extensionProphecy->reveal()]);
7777
$this->assertEquals([], $dataProvider->getCollection(Dummy::class, 'foo'));
7878
}
7979

@@ -103,9 +103,9 @@ public function testThrowResourceClassNotSupportedException()
103103
$managerRegistryProphecy = $this->prophesize(ManagerRegistry::class);
104104
$managerRegistryProphecy->getManagerForClass(Dummy::class)->willReturn(null)->shouldBeCalled();
105105

106-
$extenstensionProphecy = $this->prophesize(QueryResultExtensionInterface::class);
106+
$extensionProphecy = $this->prophesize(QueryResultCollectionExtensionInterface::class);
107107

108-
$dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extenstensionProphecy->reveal()]);
108+
$dataProvider = new CollectionDataProvider($managerRegistryProphecy->reveal(), [$extensionProphecy->reveal()]);
109109
$dataProvider->getCollection(Dummy::class, 'foo');
110110
}
111111
}

0 commit comments

Comments
 (0)