Есть Symfony 5, нужно создать пару эндпоинтов, которые отдают список элементов с пагинацией.
Решила использовать FosRestBundle +
babdev/pagerfanta-bundle, потому что в документации API Platform половина непонятна и трудно ее адаптировать под себя, не переписывая треть проекта.
Пагинацию решила сделать по примеру
урока SymfonyCasts (адаптировала под современную версию).
Источник:
src/AppBundle/Pagination/PaginationFactory.php
<?php
namespace AppBundle\Pagination;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
class PaginationFactory
{
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function createCollection(QueryBuilder $qb, Request $request, $route, array $routeParams = array())
{
$page = $request->query->get('page', 1);
$adapter = new DoctrineORMAdapter($qb);
$pagerfanta = new Pagerfanta($adapter);
$pagerfanta->setMaxPerPage(10);
$pagerfanta->setCurrentPage($page);
$programmers = [];
foreach ($pagerfanta->getCurrentPageResults() as $result) {
$programmers[] = $result;
}
$paginatedCollection = new PaginatedCollection($programmers, $pagerfanta->getNbResults());
$createLinkUrl = function($targetPage) use ($route, $routeParams) {
return $this->router->generate($route, array_merge(
$routeParams,
array('page' => $targetPage)
));
};
$paginatedCollection->addLink('self', $createLinkUrl($page));
$paginatedCollection->addLink('first', $createLinkUrl(1));
$paginatedCollection->addLink('last', $createLinkUrl($pagerfanta->getNbPages()));
if ($pagerfanta->hasNextPage()) {
$paginatedCollection->addLink('next', $createLinkUrl($pagerfanta->getNextPage()));
}
if ($pagerfanta->hasPreviousPage()) {
$paginatedCollection->addLink('prev', $createLinkUrl($pagerfanta->getPreviousPage()));
}
return $paginatedCollection;
}
}
Экшен контроллера из урока
public function listAction(Request $request)
{
$qb = $this->getDoctrine()
->getRepository('AppBundle:Programmer')
->findAllQueryBuilder();
$paginatedCollection = $this->get('pagination_factory')
->createCollection($qb, $request, 'api_programmers_collection');
$response = $this->createApiResponse($paginatedCollection, 200);
return $response;
}
Мой объект PaginatedCollection до сериализации
Коллекция формируется корректная, в ней есть все элементы сущности для страницы и ссылки пагинации, но сериализация не работает - выводит пустой массив (и через стандартный symfony serializer component, и через json_encode).
Нужно писать кастомный сериалайзер для PaginatedCollection?