Skip to content

Commit 1e0bc9d

Browse files
authored
fix(laravel): query extensions with item operations (#7001)
1 parent bbcbdd1 commit 1e0bc9d

File tree

5 files changed

+53
-3
lines changed

5 files changed

+53
-3
lines changed

src/Laravel/.php-cs-fixer.cache

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/Laravel/ApiPlatformProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ public function register(): void
448448
$this->app->singleton(ItemProvider::class, function (Application $app) {
449449
$tagged = iterator_to_array($app->tagged(LinksHandlerInterface::class));
450450

451-
return new ItemProvider(new LinksHandler($app, $app->make(ResourceMetadataCollectionFactoryInterface::class)), new ServiceLocator($tagged));
451+
return new ItemProvider(new LinksHandler($app, $app->make(ResourceMetadataCollectionFactoryInterface::class)), new ServiceLocator($tagged), $app->tagged(QueryExtensionInterface::class));
452452
});
453453
$this->app->singleton(CollectionProvider::class, function (Application $app) {
454454
$tagged = iterator_to_array($app->tagged(LinksHandlerInterface::class));

src/Laravel/Eloquent/Extension/FilterQueryExtension.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Laravel\Eloquent\Extension;
1515

1616
use ApiPlatform\Laravel\Eloquent\Filter\FilterInterface;
17+
use ApiPlatform\Metadata\CollectionOperationInterface;
1718
use ApiPlatform\Metadata\Operation;
1819
use ApiPlatform\State\ParameterNotFound;
1920
use Illuminate\Database\Eloquent\Builder;
@@ -36,6 +37,10 @@ public function __construct(
3637
*/
3738
public function apply(Builder $builder, array $uriVariables, Operation $operation, $context = []): Builder
3839
{
40+
if (!$operation instanceof CollectionOperationInterface) {
41+
return $builder;
42+
}
43+
3944
$context['uri_variables'] = $uriVariables;
4045
$context['operation'] = $operation;
4146

src/Laravel/Eloquent/State/ItemProvider.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
namespace ApiPlatform\Laravel\Eloquent\State;
1515

16+
use ApiPlatform\Laravel\Eloquent\Extension\QueryExtensionInterface;
1617
use ApiPlatform\Metadata\Operation;
1718
use ApiPlatform\State\ProviderInterface;
1819
use Illuminate\Database\Eloquent\Model;
@@ -26,11 +27,13 @@ final class ItemProvider implements ProviderInterface
2627
use LinksHandlerLocatorTrait;
2728

2829
/**
29-
* @param LinksHandlerInterface<Model> $linksHandler
30+
* @param LinksHandlerInterface<Model> $linksHandler
31+
* @param iterable<QueryExtensionInterface> $queryExtensions
3032
*/
3133
public function __construct(
3234
private readonly LinksHandlerInterface $linksHandler,
3335
?ContainerInterface $handleLinksLocator = null,
36+
private iterable $queryExtensions = [],
3437
) {
3538
$this->handleLinksLocator = $handleLinksLocator;
3639
}
@@ -45,6 +48,10 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
4548
$query = $this->linksHandler->handleLinks($model->query(), $uriVariables, ['operation' => $operation] + $context);
4649
}
4750

51+
foreach ($this->queryExtensions as $extension) {
52+
$query = $extension->apply($query, $uriVariables, $operation, $context);
53+
}
54+
4855
return $query->first();
4956
}
5057
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Laravel\Tests\Unit\State;
15+
16+
use ApiPlatform\Laravel\Eloquent\Extension\QueryExtensionInterface;
17+
use ApiPlatform\Laravel\Eloquent\State\ItemProvider;
18+
use ApiPlatform\Laravel\Eloquent\State\LinksHandlerInterface;
19+
use ApiPlatform\Metadata\Get;
20+
use Orchestra\Testbench\TestCase;
21+
use Psr\Container\ContainerInterface;
22+
use Workbench\App\Models\Book;
23+
24+
class ItemProviderTest extends TestCase
25+
{
26+
public function testItemProviderWithQueryExtension(): void
27+
{
28+
$linksHandler = $this->createMock(LinksHandlerInterface::class);
29+
$handleLinksLocator = $this->createMock(ContainerInterface::class);
30+
$queryExtension = $this->createMock(QueryExtensionInterface::class);
31+
$queryExtension->expects($this->once())->method('apply')->willReturnArgument(0);
32+
33+
$queryExtensions = [$queryExtension];
34+
$itemProvider = new ItemProvider($linksHandler, $handleLinksLocator, $queryExtensions);
35+
36+
$operation = new Get(class: Book::class);
37+
$itemProvider->provide($operation);
38+
}
39+
}

0 commit comments

Comments
 (0)