15
15
16
16
use ApiPlatform \Metadata \HttpOperation ;
17
17
use ApiPlatform \Metadata \Resource \Factory \ResourceMetadataCollectionFactoryInterface ;
18
+ use ApiPlatform \Metadata \UrlGeneratorInterface ;
18
19
use ApiPlatform \Serializer \CacheableSupportsMethodInterface ;
19
20
use ApiPlatform \State \Pagination \PaginatorInterface ;
20
21
use ApiPlatform \State \Pagination \PartialPaginatorInterface ;
@@ -37,7 +38,7 @@ final class PartialCollectionViewNormalizer implements NormalizerInterface, Norm
37
38
{
38
39
private readonly PropertyAccessorInterface $ propertyAccessor ;
39
40
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 )
41
42
{
42
43
$ this ->propertyAccessor = $ propertyAccessor ?? PropertyAccess::createPropertyAccessor ();
43
44
}
@@ -72,7 +73,7 @@ public function normalize(mixed $object, ?string $format = null, array $context
72
73
// TODO: This needs to be changed as well as I wrote in the CollectionFiltersNormalizer
73
74
// We should not rely on the request_uri but instead rely on the UriTemplate
74
75
// 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 );
76
77
$ appliedFilters = $ parsed ['parameters ' ];
77
78
unset($ appliedFilters [$ this ->enabledParameterName ]);
78
79
@@ -82,22 +83,24 @@ public function normalize(mixed $object, ?string $format = null, array $context
82
83
83
84
$ isPaginatedWithCursor = false ;
84
85
$ 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 ) {
87
88
$ operation = $ this ->resourceMetadataFactory ->create ($ context ['resource_class ' ])->getOperation ($ context ['operation_name ' ] ?? null );
88
- $ isPaginatedWithCursor = [] !== $ cursorPaginationAttribute = ($ operation ->getPaginationViaCursor () ?? []);
89
89
}
90
90
91
+ $ cursorPaginationAttribute = $ operation instanceof HttpOperation ? $ operation ->getPaginationViaCursor () : null ;
92
+ $ isPaginatedWithCursor = (bool ) $ cursorPaginationAttribute ;
93
+
91
94
$ data ['hydra:view ' ] = ['@id ' => null , '@type ' => 'hydra:PartialCollectionView ' ];
92
95
93
96
if ($ isPaginatedWithCursor ) {
94
- return $ this ->populateDataWithCursorBasedPagination ($ data , $ parsed , $ object , $ cursorPaginationAttribute );
97
+ return $ this ->populateDataWithCursorBasedPagination ($ data , $ parsed , $ object , $ cursorPaginationAttribute, $ operation ?->getUrlGenerationStrategy() ?? $ this -> urlGenerationStrategy );
95
98
}
96
99
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 );
98
101
99
102
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 );
101
104
}
102
105
103
106
return $ data ;
@@ -165,38 +168,38 @@ private function cursorPaginationFields(array $fields, int $direction, $object):
165
168
return $ paginationFilters ;
166
169
}
167
170
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
169
172
{
170
173
$ objects = iterator_to_array ($ object );
171
174
$ firstObject = current ($ objects );
172
175
$ lastObject = end ($ objects );
173
176
174
- $ data ['hydra:view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ]);
177
+ $ data ['hydra:view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], urlGenerationStrategy: $ urlGenerationStrategy );
175
178
176
179
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 );
178
181
}
179
182
180
183
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 );
182
185
}
183
186
184
187
return $ data ;
185
188
}
186
189
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
188
191
{
189
192
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 );
192
195
}
193
196
194
197
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 );
196
199
}
197
200
198
201
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 );
200
203
}
201
204
202
205
return $ data ;
0 commit comments