1313
1414namespace ApiPlatform \Core \JsonApi \Serializer ;
1515
16- use ApiPlatform \Core \Api \ResourceClassResolverInterface ;
17- use ApiPlatform \Core \DataProvider \PaginatorInterface ;
18- use ApiPlatform \Core \DataProvider \PartialPaginatorInterface ;
19- use ApiPlatform \Core \Exception \RuntimeException ;
20- use ApiPlatform \Core \Serializer \ContextTrait ;
16+ use ApiPlatform \Core \Exception \InvalidArgumentException ;
17+ use ApiPlatform \Core \Serializer \AbstractCollectionNormalizer ;
2118use ApiPlatform \Core \Util \IriHelper ;
22- use Symfony \Component \Serializer \Normalizer \NormalizerAwareInterface ;
23- use Symfony \Component \Serializer \Normalizer \NormalizerAwareTrait ;
24- use Symfony \Component \Serializer \Normalizer \NormalizerInterface ;
2519
2620/**
2721 * Normalizes collections in the JSON API format.
3024 * @author Hamza Amrouche <hamza@les-tilleuls.coop>
3125 * @author Baptiste Meyer <baptiste.meyer@gmail.com>
3226 */
33- final class CollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface
27+ final class CollectionNormalizer extends AbstractCollectionNormalizer
3428{
35- use ContextTrait;
36- use NormalizerAwareTrait;
37-
3829 const FORMAT = 'jsonapi ' ;
3930
40- private $ resourceClassResolver ;
41- private $ pageParameterName ;
42-
43- public function __construct (ResourceClassResolverInterface $ resourceClassResolver , string $ pageParameterName )
44- {
45- $ this ->resourceClassResolver = $ resourceClassResolver ;
46- $ this ->pageParameterName = $ pageParameterName ;
47- }
48-
49- /**
50- * {@inheritdoc}
51- */
52- public function supportsNormalization ($ data , $ format = null )
53- {
54- return self ::FORMAT === $ format && (is_array ($ data ) || ($ data instanceof \Traversable));
55- }
56-
5731 /**
5832 * {@inheritdoc}
5933 */
60- public function normalize ($ object , $ format = null , array $ context = [])
34+ protected function getPaginationData ($ object , array $ context = []): array
6135 {
62- $ data = [];
63- if (isset ($ context ['api_sub_level ' ])) {
64- foreach ($ object as $ index => $ obj ) {
65- $ data [$ index ] = $ this ->normalizer ->normalize ($ obj , $ format , $ context );
66- }
67-
68- return $ data ;
69- }
70-
71- $ resourceClass = $ this ->resourceClassResolver ->getResourceClass ($ object , $ context ['resource_class ' ] ?? null , true );
72- $ context = $ this ->initContext ($ resourceClass , $ context );
36+ list ($ paginator , $ paginated , $ currentPage , $ itemsPerPage , $ lastPage , $ pageTotalItems , $ totalItems ) = $ this ->getPaginationConfig ($ object , $ context );
7337 $ parsed = IriHelper::parseIri ($ context ['request_uri ' ] ?? '/ ' , $ this ->pageParameterName );
7438
75- $ currentPage = $ lastPage = $ itemsPerPage = $ pageTotalItems = null ;
76- if ($ paginated = $ isPaginator = $ object instanceof PartialPaginatorInterface) {
77- if ($ object instanceof PaginatorInterface) {
78- $ paginated = 1. !== $ lastPage = $ object ->getLastPage ();
79- } else {
80- $ pageTotalItems = (float ) count ($ object );
81- }
82-
83- $ currentPage = $ object ->getCurrentPage ();
84- $ itemsPerPage = $ object ->getItemsPerPage ();
85- }
86-
8739 $ data = [
88- 'data ' => [],
8940 'links ' => [
9041 'self ' => IriHelper::createIri ($ parsed ['parts ' ], $ parsed ['parameters ' ], $ this ->pageParameterName , $ paginated ? $ currentPage : null ),
9142 ],
@@ -106,29 +57,39 @@ public function normalize($object, $format = null, array $context = [])
10657 }
10758 }
10859
60+ if (null !== $ totalItems ) {
61+ $ data ['meta ' ]['totalItems ' ] = $ totalItems ;
62+ }
63+
64+ if ($ paginator ) {
65+ $ data ['meta ' ]['itemsPerPage ' ] = (int ) $ itemsPerPage ;
66+ $ data ['meta ' ]['currentPage ' ] = (int ) $ currentPage ;
67+ }
68+
69+ return $ data ;
70+ }
71+
72+ /**
73+ * {@inheritdoc}
74+ *
75+ * @throws InvalidArgumentException
76+ */
77+ protected function getItemsData ($ object , string $ format = null , array $ context = []): array
78+ {
79+ $ data = [
80+ 'data ' => [],
81+ ];
82+
10983 foreach ($ object as $ obj ) {
11084 $ item = $ this ->normalizer ->normalize ($ obj , $ format , $ context );
11185
11286 if (!isset ($ item ['data ' ])) {
113- throw new RuntimeException ('The JSON API document must contain a "data" key. ' );
87+ throw new InvalidArgumentException ('The JSON API document must contain a "data" key. ' );
11488 }
11589
11690 $ data ['data ' ][] = $ item ['data ' ];
11791 }
11892
119- if (
120- is_array ($ object ) ||
121- ($ paginated = $ object instanceof PaginatorInterface) ||
122- $ object instanceof \Countable && !$ object instanceof PartialPaginatorInterface
123- ) {
124- $ data ['meta ' ]['totalItems ' ] = $ paginated ? (int ) $ object ->getTotalItems () : count ($ object );
125- }
126-
127- if ($ isPaginator ) {
128- $ data ['meta ' ]['itemsPerPage ' ] = (int ) $ itemsPerPage ;
129- $ data ['meta ' ]['currentPage ' ] = (int ) $ currentPage ;
130- }
131-
13293 return $ data ;
13394 }
13495}
0 commit comments