1515
1616use ApiPlatform \Metadata \HttpOperation ;
1717use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
18+ use ApiPlatform \Metadata \UrlGeneratorInterface ;
1819use ApiPlatform \Serializer \CacheableSupportsMethodInterface ;
1920use ApiPlatform \State \Pagination \PaginatorInterface ;
2021use ApiPlatform \State \Pagination \PartialPaginatorInterface ;
@@ -37,7 +38,7 @@ final class PartialCollectionViewNormalizer implements NormalizerInterface, Norm
3738{
3839 private readonly PropertyAccessorInterface $ propertyAccessor ;
3940
40- public function __construct (private readonly NormalizerInterface $ collectionNormalizer , private readonly string $ pageParameterName = 'page ' , private string $ enabledParameterName = 'pagination ' , private readonly ?ResourceMetadataCollectionFactoryInterface $ resourceMetadataFactory = null , ?PropertyAccessorInterface $ propertyAccessor = null )
41+ public function __construct (private readonly NormalizerInterface $ collectionNormalizer , private readonly string $ pageParameterName = 'page ' , private string $ enabledParameterName = 'pagination ' , private readonly ?ResourceMetadataCollectionFactoryInterface $ resourceMetadataFactory = null , ?PropertyAccessorInterface $ propertyAccessor = null , private readonly int $ urlGenerationStrategy = UrlGeneratorInterface:: ABS_PATH )
4142 {
4243 $ this ->propertyAccessor = $ propertyAccessor ?? PropertyAccess::createPropertyAccessor ();
4344 }
@@ -72,7 +73,7 @@ public function normalize(mixed $object, ?string $format = null, array $context
7273 // TODO: This needs to be changed as well as I wrote in the CollectionFiltersNormalizer
7374 // We should not rely on the request_uri but instead rely on the UriTemplate
7475 // This needs that we implement the RFC and that we do more parsing before calling the serialization (MainController)
75- $ parsed = IriHelper::parseIri ($ context ['request_uri ' ] ?? '/ ' , $ this ->pageParameterName );
76+ $ parsed = IriHelper::parseIri ($ context ['uri ' ] ?? $ context [ ' request_uri ' ] ?? '/ ' , $ this ->pageParameterName );
7677 $ appliedFilters = $ parsed ['parameters ' ];
7778 unset($ appliedFilters [$ this ->enabledParameterName ]);
7879
@@ -82,22 +83,24 @@ public function normalize(mixed $object, ?string $format = null, array $context
8283
8384 $ isPaginatedWithCursor = false ;
8485 $ cursorPaginationAttribute = null ;
85- if ( $ this -> resourceMetadataFactory && isset ( $ context ['resource_class ' ]) && $ paginated ) {
86- /** @var HttpOperation $operation */
86+ $ operation = $ context ['operation ' ] ?? null ;
87+ if (! $ operation && $ this -> resourceMetadataFactory && isset ( $ context [ ' resource_class ' ]) && $ paginated ) {
8788 $ operation = $ this ->resourceMetadataFactory ->create ($ context ['resource_class ' ])->getOperation ($ context ['operation_name ' ] ?? null );
88- $ isPaginatedWithCursor = [] !== $ cursorPaginationAttribute = ($ operation ->getPaginationViaCursor () ?? []);
8989 }
9090
91+ $ cursorPaginationAttribute = $ operation instanceof HttpOperation ? $ operation ->getPaginationViaCursor () : null ;
92+ $ isPaginatedWithCursor = (bool ) $ cursorPaginationAttribute ;
93+
9194 $ data ['hydra:view ' ] = ['@id ' => null , '@type ' => 'hydra:PartialCollectionView ' ];
9295
9396 if ($ isPaginatedWithCursor ) {
94- return $ this ->populateDataWithCursorBasedPagination ($ data , $ parsed , $ object , $ cursorPaginationAttribute );
97+ return $ this ->populateDataWithCursorBasedPagination ($ data , $ parsed , $ object , $ cursorPaginationAttribute, $ operation ?->getUrlGenerationStrategy() ?? $ this -> urlGenerationStrategy );
9598 }
9699
97- $ data ['hydra:view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ paginated ? $ currentPage : null );
100+ $ data ['hydra:view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ paginated ? $ currentPage : null , $ operation ?->getUrlGenerationStrategy() ?? $ this -> urlGenerationStrategy );
98101
99102 if ($ paginated ) {
100- return $ this ->populateDataWithPagination ($ data , $ parsed , $ currentPage , $ lastPage , $ itemsPerPage , $ pageTotalItems );
103+ return $ this ->populateDataWithPagination ($ data , $ parsed , $ currentPage , $ lastPage , $ itemsPerPage , $ pageTotalItems, $ operation ?->getUrlGenerationStrategy() ?? $ this -> urlGenerationStrategy );
101104 }
102105
103106 return $ data ;
@@ -165,38 +168,38 @@ private function cursorPaginationFields(array $fields, int $direction, $object):
165168 return $ paginationFilters ;
166169 }
167170
168- private function populateDataWithCursorBasedPagination (array $ data , array $ parsed , \Traversable $ object , ?array $ cursorPaginationAttribute ): array
171+ private function populateDataWithCursorBasedPagination (array $ data , array $ parsed , \Traversable $ object , ?array $ cursorPaginationAttribute, ? int $ urlGenerationStrategy ): array
169172 {
170173 $ objects = iterator_to_array ($ object );
171174 $ firstObject = current ($ objects );
172175 $ lastObject = end ($ objects );
173176
174- $ data ['hydra:view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ]);
177+ $ data ['hydra:view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], urlGenerationStrategy: $ urlGenerationStrategy );
175178
176179 if (false !== $ lastObject && \is_array ($ cursorPaginationAttribute )) {
177- $ data ['hydra:view ' ]['hydra:next ' ] = IriHelper::createIri ($ parsed ['parts ' ], array_merge ($ parsed ['parameters ' ], $ this ->cursorPaginationFields ($ cursorPaginationAttribute , 1 , $ lastObject )));
180+ $ data ['hydra:view ' ]['hydra:next ' ] = IriHelper::createIri ($ parsed ['parts ' ], array_merge ($ parsed ['parameters ' ], $ this ->cursorPaginationFields ($ cursorPaginationAttribute , 1 , $ lastObject )), urlGenerationStrategy: $ urlGenerationStrategy );
178181 }
179182
180183 if (false !== $ firstObject && \is_array ($ cursorPaginationAttribute )) {
181- $ data ['hydra:view ' ]['hydra:previous ' ] = IriHelper::createIri ($ parsed ['parts ' ], array_merge ($ parsed ['parameters ' ], $ this ->cursorPaginationFields ($ cursorPaginationAttribute , -1 , $ firstObject )));
184+ $ data ['hydra:view ' ]['hydra:previous ' ] = IriHelper::createIri ($ parsed ['parts ' ], array_merge ($ parsed ['parameters ' ], $ this ->cursorPaginationFields ($ cursorPaginationAttribute , -1 , $ firstObject )), urlGenerationStrategy: $ urlGenerationStrategy );
182185 }
183186
184187 return $ data ;
185188 }
186189
187- private function populateDataWithPagination (array $ data , array $ parsed , ?float $ currentPage , ?float $ lastPage , ?float $ itemsPerPage , ?float $ pageTotalItems ): array
190+ private function populateDataWithPagination (array $ data , array $ parsed , ?float $ currentPage , ?float $ lastPage , ?float $ itemsPerPage , ?float $ pageTotalItems, ? int $ urlGenerationStrategy ): array
188191 {
189192 if (null !== $ lastPage ) {
190- $ data ['hydra:view ' ]['hydra:first ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , 1. );
191- $ data ['hydra:view ' ]['hydra:last ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ lastPage );
193+ $ data ['hydra:view ' ]['hydra:first ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , 1. , $ urlGenerationStrategy );
194+ $ data ['hydra:view ' ]['hydra:last ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ lastPage, $ urlGenerationStrategy );
192195 }
193196
194197 if (1. !== $ currentPage ) {
195- $ data ['hydra:view ' ]['hydra:previous ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ currentPage - 1. );
198+ $ data ['hydra:view ' ]['hydra:previous ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ currentPage - 1. , $ urlGenerationStrategy );
196199 }
197200
198201 if ((null !== $ lastPage && $ currentPage < $ lastPage ) || (null === $ lastPage && $ pageTotalItems >= $ itemsPerPage )) {
199- $ data ['hydra:view ' ]['hydra:next ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ currentPage + 1. );
202+ $ data ['hydra:view ' ]['hydra:next ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ currentPage + 1. , $ urlGenerationStrategy );
200203 }
201204
202205 return $ data ;
0 commit comments