This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the League\Fractal package. |
||
5 | * |
||
6 | * (c) Phil Sturgeon <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace League\Fractal\Serializer; |
||
13 | |||
14 | use InvalidArgumentException; |
||
15 | use League\Fractal\Pagination\PaginatorInterface; |
||
16 | use League\Fractal\Resource\ResourceInterface; |
||
17 | |||
18 | class JsonApiSerializer extends ArraySerializer |
||
19 | { |
||
20 | protected $baseUrl; |
||
21 | protected $rootObjects; |
||
22 | |||
23 | /** |
||
24 | * JsonApiSerializer constructor. |
||
25 | * |
||
26 | * @param string $baseUrl |
||
27 | */ |
||
28 | 38 | public function __construct($baseUrl = null) |
|
29 | { |
||
30 | 38 | $this->baseUrl = $baseUrl; |
|
31 | 38 | $this->rootObjects = []; |
|
32 | 38 | } |
|
33 | |||
34 | /** |
||
35 | * Serialize a collection. |
||
36 | * |
||
37 | * @param string $resourceKey |
||
38 | * @param array $data |
||
39 | * |
||
40 | * @return array |
||
41 | */ |
||
42 | 24 | public function collection($resourceKey, array $data) |
|
43 | { |
||
44 | 24 | $resources = []; |
|
45 | |||
46 | 24 | foreach ($data as $resource) { |
|
47 | 23 | $resources[] = $this->item($resourceKey, $resource)['data']; |
|
48 | } |
||
49 | |||
50 | 24 | return ['data' => $resources]; |
|
51 | } |
||
52 | |||
53 | /** |
||
54 | * Serialize an item. |
||
55 | * |
||
56 | * @param string $resourceKey |
||
57 | * @param array $data |
||
58 | * |
||
59 | * @return array |
||
60 | */ |
||
61 | 38 | public function item($resourceKey, array $data) |
|
62 | { |
||
63 | 38 | $id = $this->getIdFromData($data); |
|
64 | |||
65 | $resource = [ |
||
66 | 'data' => [ |
||
67 | 37 | 'type' => $resourceKey, |
|
68 | 37 | 'id' => "$id", |
|
69 | 37 | 'attributes' => $data, |
|
70 | ], |
||
71 | ]; |
||
72 | |||
73 | 37 | unset($resource['data']['attributes']['id']); |
|
74 | |||
75 | 37 | View Code Duplication | if (isset($resource['data']['attributes']['links'])) { |
0 ignored issues
–
show
|
|||
76 | 2 | $custom_links = $data['links']; |
|
77 | 2 | unset($resource['data']['attributes']['links']); |
|
78 | } |
||
79 | |||
80 | 37 | View Code Duplication | if (isset($resource['data']['attributes']['meta'])) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
81 | 2 | $resource['data']['meta'] = $data['meta']; |
|
82 | 2 | unset($resource['data']['attributes']['meta']); |
|
83 | } |
||
84 | |||
85 | 37 | if (empty($resource['data']['attributes'])) { |
|
86 | 3 | $resource['data']['attributes'] = (object) []; |
|
87 | } |
||
88 | |||
89 | 37 | if ($this->shouldIncludeLinks()) { |
|
90 | 12 | $resource['data']['links'] = [ |
|
91 | 12 | 'self' => "{$this->baseUrl}/$resourceKey/$id", |
|
92 | ]; |
||
93 | 12 | if (isset($custom_links)) { |
|
94 | 2 | $resource['data']['links'] = array_merge($resource['data']['links'], $custom_links); |
|
95 | } |
||
96 | } |
||
97 | |||
98 | 37 | return $resource; |
|
99 | } |
||
100 | |||
101 | /** |
||
102 | * Serialize the paginator. |
||
103 | * |
||
104 | * @param PaginatorInterface $paginator |
||
105 | * |
||
106 | * @return array |
||
107 | */ |
||
108 | 3 | public function paginator(PaginatorInterface $paginator) |
|
109 | { |
||
110 | 3 | $currentPage = (int)$paginator->getCurrentPage(); |
|
111 | 3 | $lastPage = (int)$paginator->getLastPage(); |
|
112 | |||
113 | $pagination = [ |
||
114 | 3 | 'total' => (int)$paginator->getTotal(), |
|
115 | 3 | 'count' => (int)$paginator->getCount(), |
|
116 | 3 | 'per_page' => (int)$paginator->getPerPage(), |
|
117 | 3 | 'current_page' => $currentPage, |
|
118 | 3 | 'total_pages' => $lastPage, |
|
119 | ]; |
||
120 | |||
121 | 3 | $pagination['links'] = []; |
|
122 | |||
123 | 3 | $pagination['links']['self'] = $paginator->getUrl($currentPage); |
|
124 | 3 | $pagination['links']['first'] = $paginator->getUrl(1); |
|
125 | |||
126 | 3 | if ($currentPage > 1) { |
|
127 | 2 | $pagination['links']['prev'] = $paginator->getUrl($currentPage - 1); |
|
128 | } |
||
129 | |||
130 | 3 | if ($currentPage < $lastPage) { |
|
131 | 2 | $pagination['links']['next'] = $paginator->getUrl($currentPage + 1); |
|
132 | } |
||
133 | |||
134 | 3 | $pagination['links']['last'] = $paginator->getUrl($lastPage); |
|
135 | |||
136 | 3 | return ['pagination' => $pagination]; |
|
137 | } |
||
138 | |||
139 | /** |
||
140 | * Serialize the meta. |
||
141 | * |
||
142 | * @param array $meta |
||
143 | * |
||
144 | * @return array |
||
145 | */ |
||
146 | 37 | public function meta(array $meta) |
|
147 | { |
||
148 | 37 | if (empty($meta)) { |
|
149 | 31 | return []; |
|
150 | } |
||
151 | |||
152 | 7 | $result['meta'] = $meta; |
|
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.
Loading history...
|
|||
153 | |||
154 | 7 | if (array_key_exists('pagination', $result['meta'])) { |
|
155 | 3 | $result['links'] = $result['meta']['pagination']['links']; |
|
156 | 3 | unset($result['meta']['pagination']['links']); |
|
157 | } |
||
158 | |||
159 | 7 | return $result; |
|
160 | } |
||
161 | |||
162 | /** |
||
163 | * @return array |
||
164 | */ |
||
165 | 2 | public function null() |
|
166 | { |
||
167 | return [ |
||
168 | 2 | 'data' => null, |
|
169 | ]; |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Serialize the included data. |
||
174 | * |
||
175 | * @param ResourceInterface $resource |
||
176 | * @param array $data |
||
177 | * |
||
178 | * @return array |
||
179 | */ |
||
180 | 37 | public function includedData(ResourceInterface $resource, array $data) |
|
181 | { |
||
182 | 37 | list($serializedData, $linkedIds) = $this->pullOutNestedIncludedData($data); |
|
183 | |||
184 | 37 | foreach ($data as $value) { |
|
185 | 37 | foreach ($value as $includeObject) { |
|
186 | 22 | if ($this->isNull($includeObject) || $this->isEmpty($includeObject)) { |
|
187 | 4 | continue; |
|
188 | } |
||
189 | |||
190 | 20 | $includeObjects = $this->createIncludeObjects($includeObject); |
|
191 | 20 | list($serializedData, $linkedIds) = $this->serializeIncludedObjectsWithCacheKey($includeObjects, $linkedIds, $serializedData); |
|
192 | } |
||
193 | } |
||
194 | |||
195 | 37 | return empty($serializedData) ? [] : ['included' => $serializedData]; |
|
196 | } |
||
197 | |||
198 | /** |
||
199 | * Indicates if includes should be side-loaded. |
||
200 | * |
||
201 | * @return bool |
||
202 | */ |
||
203 | 38 | public function sideloadIncludes() |
|
204 | { |
||
205 | 38 | return true; |
|
206 | } |
||
207 | |||
208 | /** |
||
209 | * @param array $data |
||
210 | * @param array $includedData |
||
211 | * |
||
212 | * @return array |
||
213 | */ |
||
214 | 37 | public function injectData($data, $includedData) |
|
215 | { |
||
216 | 37 | $relationships = $this->parseRelationships($includedData); |
|
217 | |||
218 | 37 | if (!empty($relationships)) { |
|
219 | 22 | $data = $this->fillRelationships($data, $relationships); |
|
220 | } |
||
221 | |||
222 | 37 | return $data; |
|
223 | } |
||
224 | |||
225 | /** |
||
226 | * Hook to manipulate the final sideloaded includes. |
||
227 | * The JSON API specification does not allow the root object to be included |
||
228 | * into the sideloaded `included`-array. We have to make sure it is |
||
229 | * filtered out, in case some object links to the root object in a |
||
230 | * relationship. |
||
231 | * |
||
232 | * @param array $includedData |
||
233 | * @param array $data |
||
234 | * |
||
235 | * @return array |
||
236 | */ |
||
237 | 37 | public function filterIncludes($includedData, $data) |
|
238 | { |
||
239 | 37 | if (!isset($includedData['included'])) { |
|
240 | 19 | return $includedData; |
|
241 | } |
||
242 | |||
243 | // Create the RootObjects |
||
244 | 18 | $this->createRootObjects($data); |
|
245 | |||
246 | // Filter out the root objects |
||
247 | 18 | $filteredIncludes = array_filter($includedData['included'], [$this, 'filterRootObject']); |
|
248 | |||
249 | // Reset array indizes |
||
250 | 18 | $includedData['included'] = array_merge([], $filteredIncludes); |
|
251 | |||
252 | 18 | return $includedData; |
|
253 | } |
||
254 | |||
255 | /** |
||
256 | * Get the mandatory fields for the serializer |
||
257 | * |
||
258 | * @return array |
||
259 | */ |
||
260 | 4 | public function getMandatoryFields() |
|
261 | { |
||
262 | 4 | return ['id']; |
|
263 | } |
||
264 | |||
265 | /** |
||
266 | * Filter function to delete root objects from array. |
||
267 | * |
||
268 | * @param array $object |
||
269 | * |
||
270 | * @return bool |
||
271 | */ |
||
272 | 18 | protected function filterRootObject($object) |
|
273 | { |
||
274 | 18 | return !$this->isRootObject($object); |
|
275 | } |
||
276 | |||
277 | /** |
||
278 | * Set the root objects of the JSON API tree. |
||
279 | * |
||
280 | * @param array $objects |
||
281 | */ |
||
282 | 18 | protected function setRootObjects(array $objects = []) |
|
283 | { |
||
284 | $this->rootObjects = array_map(function ($object) { |
||
285 | 18 | return "{$object['type']}:{$object['id']}"; |
|
286 | 18 | }, $objects); |
|
287 | 18 | } |
|
288 | |||
289 | /** |
||
290 | * Determines whether an object is a root object of the JSON API tree. |
||
291 | * |
||
292 | * @param array $object |
||
293 | * |
||
294 | * @return bool |
||
295 | */ |
||
296 | 18 | protected function isRootObject($object) |
|
297 | { |
||
298 | 18 | $objectKey = "{$object['type']}:{$object['id']}"; |
|
299 | 18 | return in_array($objectKey, $this->rootObjects); |
|
300 | } |
||
301 | |||
302 | /** |
||
303 | * @param array|null $data |
||
304 | * |
||
305 | * @return bool |
||
306 | */ |
||
307 | 30 | View Code Duplication | protected function isCollection($data) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
308 | { |
||
309 | 30 | if ($data === null) { |
|
310 | return false; |
||
311 | } |
||
312 | |||
313 | 30 | return array_key_exists('data', $data) && |
|
314 | 30 | array_key_exists(0, $data['data']); |
|
315 | } |
||
316 | |||
317 | /** |
||
318 | * @param array|null $data |
||
319 | * |
||
320 | * @return bool |
||
321 | */ |
||
322 | 22 | View Code Duplication | protected function isNull($data) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
323 | { |
||
324 | 22 | if ($data === null) { |
|
325 | return true; |
||
326 | } |
||
327 | |||
328 | 22 | return array_key_exists('data', $data) && $data['data'] === null; |
|
329 | } |
||
330 | |||
331 | /** |
||
332 | * @param array|null $data |
||
333 | * |
||
334 | * @return bool |
||
335 | */ |
||
336 | 21 | View Code Duplication | protected function isEmpty($data) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
337 | { |
||
338 | 21 | if ($data === null) { |
|
339 | return true; |
||
340 | } |
||
341 | |||
342 | 21 | return array_key_exists('data', $data) && $data['data'] === []; |
|
343 | } |
||
344 | |||
345 | /** |
||
346 | * @param array $data |
||
347 | * @param array $relationships |
||
348 | * |
||
349 | * @return array |
||
350 | */ |
||
351 | 22 | protected function fillRelationships($data, $relationships) |
|
352 | { |
||
353 | 22 | if ($this->isCollection($data)) { |
|
354 | 9 | foreach ($relationships as $key => $relationship) { |
|
355 | 9 | $data = $this->fillRelationshipAsCollection($data, $relationship, $key); |
|
356 | } |
||
357 | } else { // Single resource |
||
358 | 15 | foreach ($relationships as $key => $relationship) { |
|
359 | 15 | $data = $this->fillRelationshipAsSingleResource($data, $relationship, $key); |
|
360 | } |
||
361 | } |
||
362 | |||
363 | 22 | return $data; |
|
364 | } |
||
365 | |||
366 | /** |
||
367 | * @param array $includedData |
||
368 | * |
||
369 | * @return array |
||
370 | */ |
||
371 | 37 | protected function parseRelationships($includedData) |
|
372 | { |
||
373 | 37 | $relationships = []; |
|
374 | |||
375 | 37 | foreach ($includedData as $key => $inclusion) { |
|
376 | 37 | foreach ($inclusion as $includeKey => $includeObject) { |
|
377 | 22 | $relationships = $this->buildRelationships($includeKey, $relationships, $includeObject, $key); |
|
378 | 22 | if (isset($includedData[0][$includeKey]['meta'])) { |
|
379 | 1 | $relationships[$includeKey][0]['meta'] = $includedData[0][$includeKey]['meta']; |
|
380 | } |
||
381 | } |
||
382 | } |
||
383 | |||
384 | 37 | return $relationships; |
|
385 | } |
||
386 | |||
387 | /** |
||
388 | * @param array $data |
||
389 | * |
||
390 | * @return integer |
||
391 | */ |
||
392 | 38 | protected function getIdFromData(array $data) |
|
393 | { |
||
394 | 38 | if (!array_key_exists('id', $data)) { |
|
395 | 1 | throw new InvalidArgumentException( |
|
396 | 1 | 'JSON API resource objects MUST have a valid id' |
|
397 | ); |
||
398 | } |
||
399 | 37 | return $data['id']; |
|
400 | } |
||
401 | |||
402 | /** |
||
403 | * Keep all sideloaded inclusion data on the top level. |
||
404 | * |
||
405 | * @param array $data |
||
406 | * |
||
407 | * @return array |
||
408 | */ |
||
409 | 37 | protected function pullOutNestedIncludedData(array $data) |
|
410 | { |
||
411 | 37 | $includedData = []; |
|
412 | 37 | $linkedIds = []; |
|
413 | |||
414 | 37 | foreach ($data as $value) { |
|
415 | 37 | foreach ($value as $includeObject) { |
|
416 | 22 | if (isset($includeObject['included'])) { |
|
417 | 4 | list($includedData, $linkedIds) = $this->serializeIncludedObjectsWithCacheKey($includeObject['included'], $linkedIds, $includedData); |
|
418 | } |
||
419 | } |
||
420 | } |
||
421 | |||
422 | 37 | return [$includedData, $linkedIds]; |
|
423 | } |
||
424 | |||
425 | /** |
||
426 | * Whether or not the serializer should include `links` for resource objects. |
||
427 | * |
||
428 | * @return bool |
||
429 | */ |
||
430 | 37 | protected function shouldIncludeLinks() |
|
431 | { |
||
432 | 37 | return $this->baseUrl !== null; |
|
433 | } |
||
434 | |||
435 | /** |
||
436 | * Check if the objects are part of a collection or not |
||
437 | * |
||
438 | * @param array $includeObject |
||
439 | * |
||
440 | * @return array |
||
441 | */ |
||
442 | 20 | private function createIncludeObjects($includeObject) |
|
443 | { |
||
444 | 20 | if ($this->isCollection($includeObject)) { |
|
445 | 11 | $includeObjects = $includeObject['data']; |
|
446 | |||
447 | 11 | return $includeObjects; |
|
448 | } else { |
||
449 | 13 | $includeObjects = [$includeObject['data']]; |
|
450 | |||
451 | 13 | return $includeObjects; |
|
452 | } |
||
453 | } |
||
454 | |||
455 | /** |
||
456 | * Sets the RootObjects, either as collection or not. |
||
457 | * |
||
458 | * @param array $data |
||
459 | */ |
||
460 | 18 | private function createRootObjects($data) |
|
461 | { |
||
462 | 18 | if ($this->isCollection($data)) { |
|
463 | 8 | $this->setRootObjects($data['data']); |
|
464 | } else { |
||
465 | 10 | $this->setRootObjects([$data['data']]); |
|
466 | } |
||
467 | 18 | } |
|
468 | |||
469 | |||
470 | /** |
||
471 | * Loops over the relationships of the provided data and formats it |
||
472 | * |
||
473 | * @param array $data |
||
474 | * @param array $relationship |
||
475 | * @param string $key |
||
476 | * |
||
477 | * @return array |
||
478 | */ |
||
479 | 9 | private function fillRelationshipAsCollection($data, $relationship, $key) |
|
480 | { |
||
481 | 9 | foreach ($relationship as $index => $relationshipData) { |
|
482 | 9 | $data['data'][$index]['relationships'][$key] = $relationshipData; |
|
483 | } |
||
484 | |||
485 | 9 | return $data; |
|
486 | } |
||
487 | |||
488 | |||
489 | /** |
||
490 | * @param array $data |
||
491 | * @param array $relationship |
||
492 | * @param string $key |
||
493 | * |
||
494 | * @return array |
||
495 | */ |
||
496 | 15 | private function fillRelationshipAsSingleResource($data, $relationship, $key) |
|
497 | { |
||
498 | 15 | $data['data']['relationships'][$key] = $relationship[0]; |
|
499 | |||
500 | 15 | return $data; |
|
501 | } |
||
502 | |||
503 | /** |
||
504 | * @param mixed $includeKey |
||
505 | * @param array $relationships |
||
506 | * @param array|null $includeObject |
||
507 | * @param string $key |
||
508 | * |
||
509 | * @return array |
||
510 | */ |
||
511 | 22 | private function buildRelationships($includeKey, $relationships, $includeObject, $key) |
|
512 | { |
||
513 | 22 | $relationships = $this->addIncludekeyToRelationsIfNotSet($includeKey, $relationships); |
|
514 | |||
515 | 22 | if ($this->isNull($includeObject)) { |
|
516 | 2 | $relationship = $this->null(); |
|
517 | 21 | } elseif ($this->isEmpty($includeObject)) { |
|
518 | $relationship = [ |
||
519 | 2 | 'data' => [], |
|
520 | ]; |
||
521 | 20 | } elseif ($includeObject && $this->isCollection($includeObject)) { |
|
522 | 11 | $relationship = ['data' => []]; |
|
523 | 11 | $relationship = $this->addIncludedDataToRelationship($includeObject, $relationship); |
|
524 | } else { |
||
525 | $relationship = [ |
||
526 | 'data' => [ |
||
527 | 13 | 'type' => $includeObject['data']['type'], |
|
528 | 13 | 'id' => $includeObject['data']['id'], |
|
529 | ], |
||
530 | ]; |
||
531 | } |
||
532 | |||
533 | 22 | $relationships[$includeKey][$key] = $relationship; |
|
534 | |||
535 | 22 | return $relationships; |
|
536 | } |
||
537 | |||
538 | /** |
||
539 | * @param mixed $includeKey |
||
540 | * @param array $relationships |
||
541 | * |
||
542 | * @return array |
||
543 | */ |
||
544 | 22 | private function addIncludekeyToRelationsIfNotSet($includeKey, $relationships) |
|
545 | { |
||
546 | 22 | if (!array_key_exists($includeKey, $relationships)) { |
|
547 | 22 | $relationships[$includeKey] = []; |
|
548 | 22 | return $relationships; |
|
549 | } |
||
550 | |||
551 | 9 | return $relationships; |
|
552 | } |
||
553 | |||
554 | /** |
||
555 | * @param array $includeObject |
||
556 | * @param array $relationship |
||
557 | * |
||
558 | * @return array |
||
559 | */ |
||
560 | 11 | private function addIncludedDataToRelationship($includeObject, $relationship) |
|
561 | { |
||
562 | 11 | foreach ($includeObject['data'] as $object) { |
|
563 | 11 | $relationship['data'][] = [ |
|
564 | 11 | 'type' => $object['type'], |
|
565 | 11 | 'id' => $object['id'], |
|
566 | ]; |
||
567 | } |
||
568 | |||
569 | 11 | return $relationship; |
|
570 | } |
||
571 | |||
572 | /** |
||
573 | * {@inheritdoc} |
||
574 | */ |
||
575 | 36 | public function injectAvailableIncludeData($data, $availableIncludes) |
|
576 | { |
||
577 | 36 | if (!$this->shouldIncludeLinks()) { |
|
578 | 24 | return $data; |
|
579 | } |
||
580 | |||
581 | 12 | if ($this->isCollection($data)) { |
|
582 | $data['data'] = array_map(function ($resource) use ($availableIncludes) { |
||
583 | 7 | foreach ($availableIncludes as $relationshipKey) { |
|
584 | 7 | $resource = $this->addRelationshipLinks($resource, $relationshipKey); |
|
585 | } |
||
586 | 7 | return $resource; |
|
587 | 7 | }, $data['data']); |
|
588 | } else { |
||
589 | 7 | foreach ($availableIncludes as $relationshipKey) { |
|
590 | 7 | $data['data'] = $this->addRelationshipLinks($data['data'], $relationshipKey); |
|
591 | } |
||
592 | } |
||
593 | |||
594 | 12 | return $data; |
|
595 | } |
||
596 | |||
597 | /** |
||
598 | * Adds links for all available includes to a single resource. |
||
599 | * |
||
600 | * @param array $resource The resource to add relationship links to |
||
601 | * @param string $relationshipKey The resource key of the relationship |
||
602 | */ |
||
603 | 12 | private function addRelationshipLinks($resource, $relationshipKey) |
|
604 | { |
||
605 | 12 | if (!isset($resource['relationships']) || !isset($resource['relationships'][$relationshipKey])) { |
|
606 | 12 | $resource['relationships'][$relationshipKey] = []; |
|
607 | } |
||
608 | |||
609 | 12 | $resource['relationships'][$relationshipKey] = array_merge( |
|
610 | [ |
||
611 | 'links' => [ |
||
612 | 12 | 'self' => "{$this->baseUrl}/{$resource['type']}/{$resource['id']}/relationships/{$relationshipKey}", |
|
613 | 12 | 'related' => "{$this->baseUrl}/{$resource['type']}/{$resource['id']}/{$relationshipKey}", |
|
614 | ] |
||
615 | ], |
||
616 | 12 | $resource['relationships'][$relationshipKey] |
|
617 | ); |
||
618 | |||
619 | 12 | return $resource; |
|
620 | } |
||
621 | |||
622 | /** |
||
623 | * @param array $includeObjects |
||
624 | * @param array $linkedIds |
||
625 | * @param array $serializedData |
||
626 | * |
||
627 | * @return array |
||
628 | */ |
||
629 | 20 | private function serializeIncludedObjectsWithCacheKey($includeObjects, $linkedIds, $serializedData) |
|
630 | { |
||
631 | 20 | foreach ($includeObjects as $object) { |
|
632 | 20 | $includeType = $object['type']; |
|
633 | 20 | $includeId = $object['id']; |
|
634 | 20 | $cacheKey = "$includeType:$includeId"; |
|
635 | 20 | if (!array_key_exists($cacheKey, $linkedIds)) { |
|
636 | 20 | $serializedData[] = $object; |
|
637 | 20 | $linkedIds[$cacheKey] = $object; |
|
638 | } |
||
639 | } |
||
640 | 20 | return [$serializedData, $linkedIds]; |
|
641 | } |
||
642 | } |
||
643 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.