glaphire
@glaphire
PHP developer

Как правильно сериализовать коллекцию элементов с данными пагинации?

Есть 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 до сериализации

5f3041ffce1cb849175598.png

Коллекция формируется корректная, в ней есть все элементы сущности для страницы и ссылки пагинации, но сериализация не работает - выводит пустой массив (и через стандартный symfony serializer component, и через json_encode).

Нужно писать кастомный сериалайзер для PaginatedCollection?
  • Вопрос задан
  • 221 просмотр
Решения вопроса 1
glaphire
@glaphire Автор вопроса
PHP developer
Нужно было имплементировать JsonSerializable в классе PaginatedCollection, чтобы сериализатор начал с этим классом работать
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы