@@ -105,7 +105,7 @@ public function serialize($data)
105
105
* @param ResourceInterface $model
106
106
* @return array
107
107
*/
108
- protected function serializeModel (ResourceInterface $ model )
108
+ protected function serializeModel (ResourceInterface $ model, array $ included = null )
109
109
{
110
110
$ fields = $ this ->getRequestedFields ();
111
111
$ type = $ this ->pluralize ? Inflector::pluralize ($ model ->getType ()) : $ model ->getType ();
@@ -118,8 +118,7 @@ protected function serializeModel(ResourceInterface $model)
118
118
'attributes ' => $ attributes ,
119
119
]);
120
120
121
- $ included = $ this ->getIncluded ();
122
- $ relationships = $ model ->getResourceRelationships ();
121
+ $ relationships = $ model ->getResourceRelationships ($ included );
123
122
if (!empty ($ relationships )) {
124
123
foreach ($ relationships as $ name => $ items ) {
125
124
$ relationship = [];
@@ -132,17 +131,15 @@ protected function serializeModel(ResourceInterface $model)
132
131
} elseif ($ items instanceof ResourceIdentifierInterface) {
133
132
$ relationship = $ this ->serializeIdentifier ($ items );
134
133
}
134
+ $ memberName = $ this ->prepareMemberNames ([$ name ]);
135
+ $ memberName = reset ($ memberName );
135
136
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 );
146
143
}
147
144
}
148
145
}
@@ -164,11 +161,24 @@ protected function serializeResource(ResourceInterface $resource)
164
161
if ($ this ->request ->getIsHead ()) {
165
162
return null ;
166
163
} 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
+ ];
168
178
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 ;
172
182
}
173
183
174
184
return $ data ;
@@ -200,21 +210,39 @@ protected function serializeIdentifier(ResourceIdentifierInterface $identifier)
200
210
201
211
/**
202
212
* @param ResourceInterface|array $resources
213
+ * @param null|array $included
203
214
* @return array
204
215
*/
205
- protected function serializeIncluded ($ resources )
216
+ protected function serializeIncluded ($ resources, array $ included = null )
206
217
{
207
- $ included = $ this ->getIncluded ();
208
218
$ resources = is_array ($ resources ) ? $ resources : [$ resources ];
209
219
$ data = [];
210
220
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
+
211
239
foreach ($ resources as $ resource ) {
212
240
if (!$ resource instanceof ResourceInterface) {
213
241
continue ;
214
242
}
215
- $ relationships = $ resource ->getResourceRelationships ();
243
+ $ relationships = $ resource ->getResourceRelationships ($ linked );
216
244
foreach ($ relationships as $ name => $ relationship ) {
217
- if (! in_array ( $ name , $ included ) ) {
245
+ if ($ relationship === null ) {
218
246
continue ;
219
247
}
220
248
if (!is_array ($ relationship )) {
@@ -223,7 +251,10 @@ protected function serializeIncluded($resources)
223
251
foreach ($ relationship as $ model ) {
224
252
if ($ model instanceof ResourceInterface) {
225
253
$ 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
+ }
227
258
}
228
259
}
229
260
}
@@ -235,7 +266,7 @@ protected function serializeIncluded($resources)
235
266
/**
236
267
* Serializes a data provider.
237
268
* @param DataProviderInterface $dataProvider
238
- * @return array the array representation of the data provider.
269
+ * @return null| array the array representation of the data provider.
239
270
*/
240
271
protected function serializeDataProvider ($ dataProvider )
241
272
{
@@ -245,17 +276,18 @@ protected function serializeDataProvider($dataProvider)
245
276
$ models = $ dataProvider ->getModels ();
246
277
$ data = [];
247
278
279
+ $ included = $ this ->getIncluded ();
248
280
foreach ($ models as $ model ) {
249
281
if ($ model instanceof ResourceInterface) {
250
- $ data [] = $ this ->serializeModel ($ model );
282
+ $ data [] = $ this ->serializeModel ($ model, $ included );
251
283
}
252
284
}
253
285
254
286
$ result = ['data ' => $ data ];
255
287
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 ;
259
291
}
260
292
261
293
if (($ pagination = $ dataProvider ->getPagination ()) !== false ) {
@@ -321,9 +353,15 @@ protected function getRequestedFields()
321
353
return $ fields ;
322
354
}
323
355
356
+ /**
357
+ * @return array|null
358
+ */
324
359
protected function getIncluded ()
325
360
{
326
361
$ include = $ this ->request ->get ($ this ->expandParam );
362
+ if (!$ this ->request ->isGet ) {
363
+ return null ;
364
+ }
327
365
return is_string ($ include ) ? array_map ($ this ->formatMemberName , preg_split ('/\s*,\s*/ ' , $ include , -1 , PREG_SPLIT_NO_EMPTY )) : [];
328
366
}
329
367
0 commit comments