@@ -105,7 +105,7 @@ public function serialize($data)
105105 * @param ResourceInterface $model
106106 * @return array
107107 */
108- protected function serializeModel (ResourceInterface $ model )
108+ protected function serializeModel (ResourceInterface $ model, array $ included = null )
109109 {
110110 $ fields = $ this ->getRequestedFields ();
111111 $ type = $ this ->pluralize ? Inflector::pluralize ($ model ->getType ()) : $ model ->getType ();
@@ -118,8 +118,7 @@ protected function serializeModel(ResourceInterface $model)
118118 'attributes ' => $ attributes ,
119119 ]);
120120
121- $ included = $ this ->getIncluded ();
122- $ relationships = $ model ->getResourceRelationships ();
121+ $ relationships = $ model ->getResourceRelationships ($ included );
123122 if (!empty ($ relationships )) {
124123 foreach ($ relationships as $ name => $ items ) {
125124 $ relationship = [];
@@ -132,17 +131,15 @@ protected function serializeModel(ResourceInterface $model)
132131 } elseif ($ items instanceof ResourceIdentifierInterface) {
133132 $ relationship = $ this ->serializeIdentifier ($ items );
134133 }
134+ $ memberName = $ this ->prepareMemberNames ([$ name ]);
135+ $ memberName = reset ($ memberName );
135136 if (!empty ($ relationship )) {
136- $ memberName = $ this ->prepareMemberNames ([$ name ]);
137- $ memberName = reset ($ memberName );
138- if (in_array ($ name , $ included )) {
139- $ data ['relationships ' ][$ memberName ]['data ' ] = $ relationship ;
140- }
141- if ($ model instanceof LinksInterface) {
142- $ links = $ model ->getRelationshipLinks ($ memberName );
143- if (!empty ($ links )) {
144- $ data ['relationships ' ][$ memberName ]['links ' ] = Link::serialize ($ links );
145- }
137+ $ data ['relationships ' ][$ memberName ]['data ' ] = $ relationship ;
138+ }
139+ if ($ model instanceof LinksInterface) {
140+ $ links = $ model ->getRelationshipLinks ($ memberName );
141+ if (!empty ($ links )) {
142+ $ data ['relationships ' ][$ memberName ]['links ' ] = Link::serialize ($ links );
146143 }
147144 }
148145 }
@@ -164,11 +161,24 @@ protected function serializeResource(ResourceInterface $resource)
164161 if ($ this ->request ->getIsHead ()) {
165162 return null ;
166163 } else {
167- $ data = ['data ' => $ this ->serializeModel ($ resource )];
164+ $ included = $ topLevel = $ this ->getIncluded ();
165+
166+ if ($ included !== null ) {
167+ $ topLevel = array_map (function ($ item ) {
168+ if (($ pos = strrpos ($ item , '. ' )) !== false ) {
169+ return substr ($ item , 0 , $ pos );
170+ }
171+ return $ item ;
172+ }, $ included );
173+ }
174+
175+ $ data = [
176+ 'data ' => $ this ->serializeModel ($ resource , $ topLevel )
177+ ];
168178
169- $ included = $ this ->serializeIncluded ($ resource );
170- if (!empty ($ included )) {
171- $ data ['included ' ] = $ included ;
179+ $ relatedResources = $ this ->serializeIncluded ($ resource, $ included );
180+ if (!empty ($ relatedResources )) {
181+ $ data ['included ' ] = $ relatedResources ;
172182 }
173183
174184 return $ data ;
@@ -200,21 +210,39 @@ protected function serializeIdentifier(ResourceIdentifierInterface $identifier)
200210
201211 /**
202212 * @param ResourceInterface|array $resources
213+ * @param null|array $included
203214 * @return array
204215 */
205- protected function serializeIncluded ($ resources )
216+ protected function serializeIncluded ($ resources, array $ included = null )
206217 {
207- $ included = $ this ->getIncluded ();
208218 $ resources = is_array ($ resources ) ? $ resources : [$ resources ];
209219 $ data = [];
210220
221+ if ($ included === null ) {
222+ return [];
223+ }
224+
225+ $ inclusion = [];
226+ $ linked = [];
227+ foreach ($ included as $ path ) {
228+ if (($ pos = strrpos ($ path , '. ' )) === false ) {
229+ $ linked [] = $ path ;
230+ $ inclusion [$ path ] = [];
231+ continue ;
232+ }
233+ $ name = substr ($ path , $ pos + 1 );
234+ $ key = substr ($ path , 0 , $ pos );
235+ $ inclusion [$ key ][] = $ name ;
236+ $ linked [] = $ key ;
237+ }
238+
211239 foreach ($ resources as $ resource ) {
212240 if (!$ resource instanceof ResourceInterface) {
213241 continue ;
214242 }
215- $ relationships = $ resource ->getResourceRelationships ();
243+ $ relationships = $ resource ->getResourceRelationships ($ linked );
216244 foreach ($ relationships as $ name => $ relationship ) {
217- if (! in_array ( $ name , $ included ) ) {
245+ if ($ relationship === null ) {
218246 continue ;
219247 }
220248 if (!is_array ($ relationship )) {
@@ -223,7 +251,10 @@ protected function serializeIncluded($resources)
223251 foreach ($ relationship as $ model ) {
224252 if ($ model instanceof ResourceInterface) {
225253 $ uniqueKey = $ model ->getType () . '/ ' . $ model ->getId ();
226- $ data [$ uniqueKey ] = $ this ->serializeModel ($ model );
254+ $ data [$ uniqueKey ] = $ this ->serializeModel ($ model , $ inclusion [$ name ]);
255+ if (!empty ($ inclusion [$ name ])) {
256+ $ data = array_merge ($ data , $ this ->serializeIncluded ($ model , $ inclusion [$ name ]));
257+ }
227258 }
228259 }
229260 }
@@ -235,7 +266,7 @@ protected function serializeIncluded($resources)
235266 /**
236267 * Serializes a data provider.
237268 * @param DataProviderInterface $dataProvider
238- * @return array the array representation of the data provider.
269+ * @return null| array the array representation of the data provider.
239270 */
240271 protected function serializeDataProvider ($ dataProvider )
241272 {
@@ -245,17 +276,18 @@ protected function serializeDataProvider($dataProvider)
245276 $ models = $ dataProvider ->getModels ();
246277 $ data = [];
247278
279+ $ included = $ this ->getIncluded ();
248280 foreach ($ models as $ model ) {
249281 if ($ model instanceof ResourceInterface) {
250- $ data [] = $ this ->serializeModel ($ model );
282+ $ data [] = $ this ->serializeModel ($ model, $ included );
251283 }
252284 }
253285
254286 $ result = ['data ' => $ data ];
255287
256- $ included = $ this ->serializeIncluded ($ models );
257- if (!empty ($ included )) {
258- $ result ['included ' ] = $ included ;
288+ $ relatedResources = $ this ->serializeIncluded ($ models, $ included );
289+ if (!empty ($ relatedResources )) {
290+ $ result ['included ' ] = $ relatedResources ;
259291 }
260292
261293 if (($ pagination = $ dataProvider ->getPagination ()) !== false ) {
@@ -321,9 +353,15 @@ protected function getRequestedFields()
321353 return $ fields ;
322354 }
323355
356+ /**
357+ * @return array|null
358+ */
324359 protected function getIncluded ()
325360 {
326361 $ include = $ this ->request ->get ($ this ->expandParam );
362+ if (!$ this ->request ->isGet ) {
363+ return null ;
364+ }
327365 return is_string ($ include ) ? array_map ($ this ->formatMemberName , preg_split ('/\s*,\s*/ ' , $ include , -1 , PREG_SPLIT_NO_EMPTY )) : [];
328366 }
329367
0 commit comments