Skip to content

Commit

Permalink
Eloquent pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
romainallanot committed Oct 20, 2023
1 parent c974989 commit b20c554
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 5 deletions.
42 changes: 39 additions & 3 deletions src/Laravel/ApiPlatformProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
use ApiPlatform\Serializer\SerializerContextBuilderInterface;
use ApiPlatform\State\CallableProcessor;
use ApiPlatform\State\CallableProvider;
use ApiPlatform\State\Pagination\Pagination;
use ApiPlatform\State\Pagination\PaginationOptions;
use ApiPlatform\State\Processor\AddLinkHeaderProcessor;
use ApiPlatform\State\Processor\RespondProcessor;
use ApiPlatform\State\Processor\SerializeProcessor;
Expand Down Expand Up @@ -149,6 +151,21 @@ public function register(): void
'jsonproblem' => ['application/problem+json'],
];

$pagination = config('apî-platform.collection.pagination') ?? [
'enabled' => true,
'partial' => false,
'client_enabled' => false,
'client_items_per_page' => false,
'client_partial' => false,
'items_per_page' => 30,
'maximum_items_per_page' => null,
'page_parameter_name' => 'page',
'enabled_parameter_name' => 'pagination',
'items_per_page_parameter_name' => 'itemsPerPage',
'partial_parameter_name' => 'partial',
];
$graphqlPagination = [];

// $configuration = [
// 'collection' => [
// 'pagination' => [
Expand Down Expand Up @@ -436,6 +453,26 @@ public function register(): void
return new EntrypointAction($app->make(ResourceNameCollectionFactoryInterface::class), $app->make(ProviderInterface::class), $app->make(ProcessorInterface::class), ['jsonld' => ['application/ld+json']]);
});

$this->app->singleton(Pagination::class, function () use ($pagination, $graphqlPagination) {
return new Pagination($pagination, $graphqlPagination);
});

$this->app->singleton(PaginationOptions::class, function () use ($pagination) {
return new PaginationOptions(
$pagination['enabled'],
$pagination['page_parameter_name'],
$pagination['client_items_per_page'],
$pagination['items_per_page_parameter_name'],
$pagination['client_enabled'],
$pagination['enabled_parameter_name'],
$pagination['items_per_page'],
$pagination['maximum_items_per_page'],
$pagination['partial'],
$pagination['client_partial'],
$pagination['partial_parameter_name'],
);
});

$this->app->bind(OpenApiFactoryInterface::class, OpenApiFactory::class);
$this->app->singleton(OpenApiFactory::class, function (Application $app) use ($formats) {
return new OpenApiFactory(
Expand All @@ -447,9 +484,8 @@ public function register(): void
$app->make(TypeFactoryInterface::class),
$app->make(FilterLocator::class),
$formats,
// array $formats = [],
// ?Options $openApiOptions = null,
// ?PaginationOptions $paginationOptions = null,
null, // ?Options $openApiOptions = null,
$app->make(PaginationOptions::class), // ?PaginationOptions $paginationOptions = null,
// ?RouterInterface $router = null
);
});
Expand Down
44 changes: 44 additions & 0 deletions src/Laravel/Eloquent/Paginator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

declare(strict_types=1);

namespace ApiPlatform\Laravel\Eloquent;

use ApiPlatform\State\Pagination\PaginatorInterface;
use Illuminate\Pagination\LengthAwarePaginator;

final class Paginator implements PaginatorInterface, \IteratorAggregate
{
public function __construct(protected LengthAwarePaginator $paginator) {
}

public function count(): int
{
return $this->paginator->count();
}

public function getLastPage(): float
{
return $this->paginator->lastPage();
}

public function getTotalItems(): float
{
return $this->paginator->total();
}

public function getCurrentPage(): float
{
return $this->paginator->currentPage();
}

public function getItemsPerPage(): float
{
return $this->paginator->perPage();
}

public function getIterator(): \Traversable
{
return $this->paginator->getIterator();
}
}
19 changes: 17 additions & 2 deletions src/Laravel/Eloquent/State/CollectionProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,33 @@

namespace ApiPlatform\Laravel\Eloquent\State;

use ApiPlatform\Laravel\Eloquent\Paginator;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\Pagination\Pagination;
use ApiPlatform\State\ProviderInterface;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Application;

class CollectionProvider implements ProviderInterface
{
public function __construct(private readonly Application $application)
public function __construct(private readonly Application $application, private readonly Pagination $pagination)
{
}

public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
{
return $this->application->make($operation->getClass())::all();
/** @var Model $model */
$model = $this->application->make($operation->getClass());

if (false === $this->pagination->isEnabled($operation, $context)) {
return $model::all();
}

return new Paginator($model::query()
->paginate(
perPage: $this->pagination->getLimit($operation, $context),
page: $this->pagination->getPage($context),
)
);
}
}
16 changes: 16 additions & 0 deletions src/Laravel/config/api-platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,20 @@
'error_formats' => [
'jsonproblem' => ['application/problem+json'],
],

'collection' => [
'pagination' => [
'enabled' => true,
'partial' => false,
'client_enabled' => false,
'client_items_per_page' => false,
'client_partial' => false,
'items_per_page' => 30,
'maximum_items_per_page' => null,
'page_parameter_name' => 'page',
'enabled_parameter_name' => 'pagination',
'items_per_page_parameter_name' => 'itemsPerPage',
'partial_parameter_name' => 'partial',
],
],
];

0 comments on commit b20c554

Please sign in to comment.