1 | <?php |
||
34 | final class PaginationExtension implements QueryResultCollectionExtensionInterface |
||
35 | { |
||
36 | private $managerRegistry; |
||
37 | private $requestStack; |
||
38 | private $resourceMetadataFactory; |
||
39 | private $enabled; |
||
40 | private $clientEnabled; |
||
41 | private $clientItemsPerPage; |
||
42 | private $itemsPerPage; |
||
43 | private $pageParameterName; |
||
44 | private $enabledParameterName; |
||
45 | private $itemsPerPageParameterName; |
||
46 | private $maximumItemPerPage; |
||
47 | |||
48 | public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack, ResourceMetadataFactoryInterface $resourceMetadataFactory, bool $enabled = true, bool $clientEnabled = false, bool $clientItemsPerPage = false, int $itemsPerPage = 30, string $pageParameterName = 'page', string $enabledParameterName = 'pagination', string $itemsPerPageParameterName = 'itemsPerPage', int $maximumItemPerPage = null) |
||
62 | |||
63 | /** |
||
64 | * {@inheritdoc} |
||
65 | */ |
||
66 | public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null) |
||
67 | { |
||
68 | $request = $this->requestStack->getCurrentRequest(); |
||
69 | if (null === $request) { |
||
70 | return; |
||
71 | } |
||
72 | |||
73 | $resourceMetadata = $this->resourceMetadataFactory->create($resourceClass); |
||
74 | if (!$this->isPaginationEnabled($request, $resourceMetadata, $operationName)) { |
||
75 | return; |
||
76 | } |
||
77 | |||
78 | $itemsPerPage = $resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_items_per_page', $this->itemsPerPage, true); |
||
79 | if ($resourceMetadata->getCollectionOperationAttribute($operationName, 'pagination_client_items_per_page', $this->clientItemsPerPage, true)) { |
||
80 | $itemsPerPage = (int) $request->query->get($this->itemsPerPageParameterName, $itemsPerPage); |
||
81 | $itemsPerPage = (null !== $this->maximumItemPerPage && $itemsPerPage >= $this->maximumItemPerPage ? $this->maximumItemPerPage : $itemsPerPage); |
||
82 | } |
||
83 | |||
84 | if (0 > $itemsPerPage) { |
||
85 | throw new InvalidArgumentException('Item per page parameter should not be less than 0'); |
||
86 | } |
||
87 | |||
88 | $page = $request->query->get($this->pageParameterName, 1); |
||
89 | |||
90 | if (0 === $itemsPerPage && 1 < $page) { |
||
91 | throw new InvalidArgumentException('Page should not be greater than 1 if itemsPegPage is equal to 0'); |
||
92 | } |
||
93 | |||
94 | $queryBuilder |
||
95 | ->setFirstResult(($page - 1) * $itemsPerPage) |
||
96 | ->setMaxResults($itemsPerPage); |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * {@inheritdoc} |
||
101 | */ |
||
102 | public function supportsResult(string $resourceClass, string $operationName = null): bool |
||
113 | |||
114 | /** |
||
115 | * {@inheritdoc} |
||
116 | */ |
||
117 | public function getResult(QueryBuilder $queryBuilder) |
||
124 | |||
125 | private function isPaginationEnabled(Request $request, ResourceMetadata $resourceMetadata, string $operationName = null): bool |
||
136 | |||
137 | /** |
||
138 | * Determines whether the Paginator should fetch join collections, if the root entity uses composite identifiers it should not. |
||
139 | * |
||
140 | * @see https://github.com/doctrine/doctrine2/issues/2910 |
||
141 | * |
||
142 | * @param QueryBuilder $queryBuilder |
||
143 | * |
||
144 | * @return bool |
||
145 | */ |
||
146 | private function useFetchJoinCollection(QueryBuilder $queryBuilder): bool |
||
150 | |||
151 | /** |
||
152 | * Determines whether output walkers should be used. |
||
153 | * |
||
154 | * @param QueryBuilder $queryBuilder |
||
155 | * |
||
156 | * @return bool |
||
157 | */ |
||
158 | private function useOutputWalkers(QueryBuilder $queryBuilder): bool |
||
200 | } |
||
201 |