[ERP-72] Paginer toutes les collections API + regle pagination obligatoire #28

Merged
tristan merged 8 commits from feature/ERP-72-backend-l-paginer-toutes-les-collections-api-exist into develop 2026-05-29 14:15:42 +00:00
Showing only changes of commit 08f8ff7788 - Show all commits
@@ -4,11 +4,14 @@ declare(strict_types=1);
namespace App\Module\Catalog\Infrastructure\ApiPlatform\State\Provider; namespace App\Module\Catalog\Infrastructure\ApiPlatform\State\Provider;
use ApiPlatform\Doctrine\Orm\Paginator;
use ApiPlatform\Metadata\CollectionOperationInterface; use ApiPlatform\Metadata\CollectionOperationInterface;
use ApiPlatform\Metadata\Operation; use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\Pagination\Pagination;
use ApiPlatform\State\ProviderInterface; use ApiPlatform\State\ProviderInterface;
use App\Module\Catalog\Domain\Entity\Category; use App\Module\Catalog\Domain\Entity\Category;
use App\Module\Catalog\Domain\Repository\CategoryRepositoryInterface; use App\Module\Catalog\Domain\Repository\CategoryRepositoryInterface;
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DependencyInjection\Attribute\Autowire;
/** /**
@@ -29,18 +32,32 @@ final class CategoryProvider implements ProviderInterface
public function __construct( public function __construct(
#[Autowire(service: 'App\Module\Catalog\Infrastructure\Doctrine\DoctrineCategoryRepository')] #[Autowire(service: 'App\Module\Catalog\Infrastructure\Doctrine\DoctrineCategoryRepository')]
private readonly CategoryRepositoryInterface $repository, private readonly CategoryRepositoryInterface $repository,
private readonly Pagination $pagination,
) {} ) {}
public function provide(Operation $operation, array $uriVariables = [], array $context = []): Category|iterable|null public function provide(Operation $operation, array $uriVariables = [], array $context = []): Category|iterable|Paginator|null
{ {
$includeDeleted = $this->readIncludeDeleted($context); $includeDeleted = $this->readIncludeDeleted($context);
if ($operation instanceof CollectionOperationInterface) { if ($operation instanceof CollectionOperationInterface) {
return $this->repository $qb = $this->repository->createListQueryBuilder($includeDeleted);
->createListQueryBuilder($includeDeleted)
->getQuery() // Echappatoire ?pagination=false : retourne la collection complete sans Paginator.
->getResult() // Utile pour les drawers Role/Permission/Site/CategoryType qui alimentent un <select>.
; if (!$this->pagination->isEnabled($operation, $context)) {
return $qb->getQuery()->getResult();
}
// Branche paginee standard : on applique offset/limit via Pagination,
// puis on enveloppe dans le Paginator ORM (fetchJoinCollection: true
// pour que Doctrine compte correctement avec les JOINs futurs).
$limit = $this->pagination->getLimit($operation, $context);
$page = max(1, $this->pagination->getPage($context));
$offset = ($page - 1) * $limit;
$qb->setFirstResult($offset)->setMaxResults($limit);
return new Paginator(new DoctrinePaginator($qb->getQuery(), fetchJoinCollection: true));
} }
// Get unitaire : recharger l'entite, puis appliquer le filtre soft-delete. // Get unitaire : recharger l'entite, puis appliquer le filtre soft-delete.