[...], 'pagination' => [...]] в едином формате для новых list-контрактов. */ final class Paginator { public const DEFAULT_PER_PAGE = 50; public const MAX_PER_PAGE = 500; /** * @return array{data: list, pagination: array} */ public function paginate( QueryBuilder $qb, Request $request, int $defaultPerPage = self::DEFAULT_PER_PAGE, int $maxPerPage = self::MAX_PER_PAGE, ): array { $page = max(1, $request->query->getInt('page', 1)); $perPage = min( max(1, $request->query->getInt('perPage', $defaultPerPage)), $maxPerPage, ); $pagerfanta = (new Pagerfanta(new QueryAdapter($qb))) ->setMaxPerPage($perPage); try { $pagerfanta->setCurrentPage($page); } catch (NotValidCurrentPageException) { // выходим за пределы — возвращаем пустую страницу с корректным total $pagerfanta->setCurrentPage(max(1, $pagerfanta->getNbPages())); } $data = iterator_to_array($pagerfanta->getCurrentPageResults(), false); return [ 'data' => $data, 'pagination' => [ 'total' => $pagerfanta->getNbResults(), 'count' => count($data), 'per_page' => $pagerfanta->getMaxPerPage(), 'current_page' => $pagerfanta->getCurrentPage(), 'total_pages' => $pagerfanta->getNbPages(), 'has_previous_page' => $pagerfanta->hasPreviousPage(), 'has_next_page' => $pagerfanta->hasNextPage(), ], ]; } /** * Legacy-формат для ArticleController. * * Старый контракт /article/list уже использовался клиентами: * - размер страницы приходит в query-параметре limit; * - метаданные лежат в ключе meta; * - поля называются total/page/limit/totalPages. * * @return array{data: list, meta: array{total: int, page: int, limit: int, totalPages: int}} */ public function paginateWithLegacyMeta( QueryBuilder $qb, Request $request, int $defaultLimit = 20, int $maxLimit = 100, ): array { $page = max(1, $request->query->getInt('page', 1)); $limit = min( max(1, $request->query->getInt('limit', $defaultLimit)), $maxLimit, ); $pagerfanta = (new Pagerfanta(new QueryAdapter($qb))) ->setMaxPerPage($limit); try { $pagerfanta->setCurrentPage($page); } catch (NotValidCurrentPageException) { $pagerfanta->setCurrentPage(max(1, $pagerfanta->getNbPages())); } return [ 'data' => iterator_to_array($pagerfanta->getCurrentPageResults(), false), 'meta' => [ 'total' => $pagerfanta->getNbResults(), 'page' => $pagerfanta->getCurrentPage(), 'limit' => $pagerfanta->getMaxPerPage(), 'totalPages' => $pagerfanta->getNbPages(), ], ]; } }