20
20
use ApiPlatform \Metadata \Util \IriHelper ;
21
21
use ApiPlatform \State \Pagination \PaginatorInterface ;
22
22
use ApiPlatform \State \Pagination \PartialPaginatorInterface ;
23
+ use ApiPlatform \Hydra \State \Util \PaginationHelperTrait ;
24
+ use ApiPlatform \Hydra \PartialCollectionView ;
23
25
use Symfony \Component \PropertyAccess \PropertyAccess ;
24
26
use Symfony \Component \PropertyAccess \PropertyAccessorInterface ;
25
27
use Symfony \Component \Serializer \Exception \UnexpectedValueException ;
35
37
final class PartialCollectionViewNormalizer implements NormalizerInterface, NormalizerAwareInterface
36
38
{
37
39
use HydraPrefixTrait;
40
+ use PaginationHelperTrait;
38
41
private readonly PropertyAccessorInterface $ propertyAccessor ;
39
42
40
43
/**
@@ -60,21 +63,11 @@ public function normalize(mixed $object, ?string $format = null, array $context
60
63
throw new UnexpectedValueException ('Expected data to be an array ' );
61
64
}
62
65
63
- $ currentPage = $ lastPage = $ itemsPerPage = $ pageTotalItems = null ;
64
- if ($ paginated = ($ object instanceof PartialPaginatorInterface)) {
65
- if ($ object instanceof PaginatorInterface) {
66
- $ paginated = 1. !== $ lastPage = $ object ->getLastPage ();
67
- } else {
68
- $ itemsPerPage = $ object ->getItemsPerPage ();
69
- $ pageTotalItems = (float ) \count ($ object );
70
- }
71
-
72
- $ currentPage = $ object ->getCurrentPage ();
66
+ $ paginated = ($ object instanceof PartialPaginatorInterface);
67
+ if ($ paginated && $ object instanceof PaginatorInterface) {
68
+ $ paginated = 1. !== $ object ->getLastPage ();
73
69
}
74
70
75
- // TODO: This needs to be changed as well as I wrote in the CollectionFiltersNormalizer
76
- // We should not rely on the request_uri but instead rely on the UriTemplate
77
- // This needs that we implement the RFC and that we do more parsing before calling the serialization (MainController)
78
71
$ parsed = IriHelper::parseIri ($ context ['uri ' ] ?? $ context ['request_uri ' ] ?? '/ ' , $ this ->pageParameterName );
79
72
$ appliedFilters = $ parsed ['parameters ' ];
80
73
unset($ appliedFilters [$ this ->enabledParameterName ]);
@@ -94,18 +87,35 @@ public function normalize(mixed $object, ?string $format = null, array $context
94
87
$ isPaginatedWithCursor = (bool ) $ cursorPaginationAttribute ;
95
88
96
89
$ hydraPrefix = $ this ->getHydraPrefix ($ context + $ this ->defaultContext );
97
- $ data [$ hydraPrefix .'view ' ] = ['@id ' => null , '@type ' => $ hydraPrefix .'PartialCollectionView ' ];
98
90
99
91
if ($ isPaginatedWithCursor ) {
92
+ $ data [$ hydraPrefix .'view ' ] = ['@id ' => null , '@type ' => $ hydraPrefix .'PartialCollectionView ' ];
93
+
100
94
return $ this ->populateDataWithCursorBasedPagination ($ data , $ parsed , $ object , $ cursorPaginationAttribute , $ operation ?->getUrlGenerationStrategy() ?? $ this ->urlGenerationStrategy , $ hydraPrefix );
101
95
}
102
96
103
- $ data [$ hydraPrefix .'view ' ]['@id ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ paginated ? $ currentPage : null , $ operation ?->getUrlGenerationStrategy() ?? $ this ->urlGenerationStrategy );
97
+ $ partialCollectionView = $ this ->getPartialCollectionView ($ object , $ context ['uri ' ] ?? $ context ['request_uri ' ] ?? '/ ' , $ this ->pageParameterName , $ this ->enabledParameterName , $ operation ?->getUrlGenerationStrategy() ?? $ this ->urlGenerationStrategy );
98
+
99
+ $ view = [
100
+ '@id ' => $ partialCollectionView ->id ,
101
+ '@type ' => $ hydraPrefix .'PartialCollectionView ' ,
102
+ ];
103
+
104
+ if (null !== $ partialCollectionView ->first ) {
105
+ $ view [$ hydraPrefix .'first ' ] = $ partialCollectionView ->first ;
106
+ $ view [$ hydraPrefix .'last ' ] = $ partialCollectionView ->last ;
107
+ }
104
108
105
- if ($ paginated ) {
106
- return $ this -> populateDataWithPagination ( $ data , $ parsed , $ currentPage , $ lastPage , $ itemsPerPage , $ pageTotalItems , $ operation ?->getUrlGenerationStrategy() ?? $ this -> urlGenerationStrategy , $ hydraPrefix ) ;
109
+ if (null !== $ partialCollectionView -> previous ) {
110
+ $ view [ $ hydraPrefix . ' previous ' ] = $ partialCollectionView -> previous ;
107
111
}
108
112
113
+ if (null !== $ partialCollectionView ->next ) {
114
+ $ view [$ hydraPrefix .'next ' ] = $ partialCollectionView ->next ;
115
+ }
116
+
117
+ $ data [$ hydraPrefix .'view ' ] = $ view ;
118
+
109
119
return $ data ;
110
120
}
111
121
@@ -168,22 +178,4 @@ private function populateDataWithCursorBasedPagination(array $data, array $parse
168
178
169
179
return $ data ;
170
180
}
171
-
172
- private function populateDataWithPagination (array $ data , array $ parsed , ?float $ currentPage , ?float $ lastPage , ?float $ itemsPerPage , ?float $ pageTotalItems , ?int $ urlGenerationStrategy , string $ hydraPrefix ): array
173
- {
174
- if (null !== $ lastPage ) {
175
- $ data [$ hydraPrefix .'view ' ][$ hydraPrefix .'first ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , 1. , $ urlGenerationStrategy );
176
- $ data [$ hydraPrefix .'view ' ][$ hydraPrefix .'last ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ lastPage , $ urlGenerationStrategy );
177
- }
178
-
179
- if (1. !== $ currentPage ) {
180
- $ data [$ hydraPrefix .'view ' ][$ hydraPrefix .'previous ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ currentPage - 1. , $ urlGenerationStrategy );
181
- }
182
-
183
- if ((null !== $ lastPage && $ currentPage < $ lastPage ) || (null === $ lastPage && $ pageTotalItems >= $ itemsPerPage )) {
184
- $ data [$ hydraPrefix .'view ' ][$ hydraPrefix .'next ' ] = IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ currentPage + 1. , $ urlGenerationStrategy );
185
- }
186
-
187
- return $ data ;
188
- }
189
181
}
0 commit comments