Passed
Pull Request — master (#38)
by Dante
13:53
created

ApiFormatterComponent::extractFromIncluded()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 11
rs 10
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * API Formatter
6
 *
7
 * Copyright 2021 Atlas Srl
8
 */
9
namespace BEdita\WebTools\Controller\Component;
10
11
use Cake\Collection\Collection;
12
use Cake\Controller\Component;
13
use Cake\Utility\Hash;
14
15
/**
16
 * Component class to format API response data.
17
 */
18
class ApiFormatterComponent extends Component
19
{
20
    /**
21
     * Embed included data into relationships.
22
     *
23
     * @param array $response The response from API
24
     * @return array
25
     */
26
    public function embedIncluded(array $response): array
27
    {
28
        $data = (array)Hash::get($response, 'data');
29
        if (empty($data)) {
30
            return $response;
31
        }
32
33
        $included = (array)Hash::get($response, 'included');
34
        if (empty($included)) {
35
            return $response;
36
        }
37
38
        $included = collection($included);
39
        if (!Hash::numeric(array_keys($data))) {
40
            $response['data'] = $this->addIncluded($data, $included);
41
42
            return $response;
43
        }
44
45
        foreach ($data as &$d) {
46
            $d = $this->addIncluded($d, $included);
47
        }
48
        unset($d);
49
50
        $response['data'] = $data;
51
52
        return $response;
53
    }
54
55
    /**
56
     * Add included data to main resource.
57
     *
58
     * @param array $resource The resource.
59
     * @param \Cake\Collection\Collection $included The included collection.
60
     * @return array
61
     */
62
    protected function addIncluded(array $resource, Collection $included): array
63
    {
64
        foreach ($resource['relationships'] as &$relation) {
65
            if (empty($relation['data'])) {
66
                continue;
67
            }
68
69
            $relation['data'] = $this->extractFromIncluded($included, (array)$relation['data']);
70
        }
71
        unset($relation);
72
73
        return $resource;
74
    }
75
76
    /**
77
     * Extract items from included starting from $relationship data.
78
     *
79
     * @param \Cake\Collection\Collection $included The included collection
80
     * @param array $relationshipData Array of relationship data.
81
     *                                Every item must contain 'type' and 'id'.
82
     * @return array
83
     */
84
    protected function extractFromIncluded(Collection $included, array $relationshipData): array
85
    {
86
        foreach ($relationshipData as &$data) {
87
            $data = (array)$included->firstMatch([
88
                'type' => $data['type'],
89
                'id' => $data['id'],
90
            ]);
91
        }
92
        unset($data);
93
94
        return $relationshipData;
95
    }
96
}
97