Skip to content

Commit

Permalink
fix(laravel): graphql fix relationship loading (#6857)
Browse files Browse the repository at this point in the history
fix loading relationships by only loading those related to the model

Closes: #6791

Signed-off-by: Tobias Oitzinger <tobiasoitzinger@gmail.com>
  • Loading branch information
toitzi authored Dec 13, 2024
1 parent f6f9d8c commit e0f8c38
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/GraphQl/State/Processor/NormalizeProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ private function serializePageBasedPaginatedCollection(iterable $collection, arr
}
$data['paginationInfo']['totalCount'] = $collection->getTotalItems();
}
if (isset($selection['paginationInfo']['currentPage'])) {
if (!($collection instanceof PartialPaginatorInterface)) {
throw new \LogicException(\sprintf('Collection returned by the collection data provider must implement %s to return currentPage field.', PartialPaginatorInterface::class));
}
$data['paginationInfo']['currentPage'] = $collection->getCurrentPage();
}
if (isset($selection['paginationInfo']['lastPage'])) {
if (!($collection instanceof PaginatorInterface)) {
throw new \LogicException(\sprintf('Collection returned by the collection data provider must implement %s to return lastPage field.', PaginatorInterface::class));
Expand Down
1 change: 1 addition & 0 deletions src/GraphQl/Type/TypeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ private function getPageBasedPaginationFields(GraphQLType $resourceType): array
'itemsPerPage' => GraphQLType::nonNull(GraphQLType::int()),
'lastPage' => GraphQLType::nonNull(GraphQLType::int()),
'totalCount' => GraphQLType::nonNull(GraphQLType::int()),
'currentPage' => GraphQLType::nonNull(GraphQLType::int()),
'hasNextPage' => GraphQLType::nonNull(GraphQLType::boolean()),
],
];
Expand Down
8 changes: 7 additions & 1 deletion src/Laravel/Eloquent/Paginator.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

namespace ApiPlatform\Laravel\Eloquent;

use ApiPlatform\State\Pagination\HasNextPagePaginatorInterface;
use ApiPlatform\State\Pagination\PaginatorInterface;
use Illuminate\Pagination\LengthAwarePaginator;
use IteratorAggregate;
Expand All @@ -21,7 +22,7 @@
* @implements IteratorAggregate<mixed,object>
* @implements PaginatorInterface<object>
*/
final class Paginator implements PaginatorInterface, \IteratorAggregate
final class Paginator implements PaginatorInterface, HasNextPagePaginatorInterface, \IteratorAggregate
{
/**
* @param LengthAwarePaginator<object> $paginator
Expand Down Expand Up @@ -60,4 +61,9 @@ public function getIterator(): \Traversable
{
return $this->paginator->getIterator();
}

public function hasNextPage(): bool
{
return $this->paginator->hasMorePages();
}
}
29 changes: 29 additions & 0 deletions src/Laravel/Tests/GraphQlTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,35 @@ public function testGetBooks(): void
$this->assertArrayNotHasKey('errors', $data);
}

public function testGetBooksWithSimplePagination(): void
{
BookFactory::new()->has(AuthorFactory::new())->count(9)->create();
$response = $this->postJson('/api/graphql', ['query' => '{
simplePaginationBooks(page: 1) {
collection {
id
},
paginationInfo {
itemsPerPage,
currentPage,
lastPage,
totalCount,
hasNextPage
}
}
}'], ['accept' => ['application/json']]);
$response->assertStatus(200);
$data = $response->json();
$this->assertArrayHasKey('data', $data);
$this->assertCount(3, $data['data']['simplePaginationBooks']['collection']);
$this->assertEquals(3, $data['data']['simplePaginationBooks']['paginationInfo']['itemsPerPage']);
$this->assertEquals(1, $data['data']['simplePaginationBooks']['paginationInfo']['currentPage']);
$this->assertEquals(3, $data['data']['simplePaginationBooks']['paginationInfo']['lastPage']);
$this->assertEquals(9, $data['data']['simplePaginationBooks']['paginationInfo']['totalCount']);
$this->assertTrue($data['data']['simplePaginationBooks']['paginationInfo']['hasNextPage']);
$this->assertArrayNotHasKey('errors', $data);
}

public function testGetBooksWithPaginationAndOrder(): void
{
BookFactory::new()->has(AuthorFactory::new())->count(10)->create();
Expand Down
5 changes: 5 additions & 0 deletions src/Laravel/workbench/app/Models/Book.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
new QueryParameter(key: 'order[:property]', filter: OrderFilter::class),
],
),
new QueryCollection(
paginationItemsPerPage: 3,
name: 'simplePagination',
paginationType: 'page',
),
new Mutation(name: 'create'),
]
)]
Expand Down

0 comments on commit e0f8c38

Please sign in to comment.