Passed
Pull Request — master (#38)
by Dante
12:06 queued 03:22
created

ApiFormatterComponent::addIncluded()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 12
rs 10
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2021 Atlas Srl, ChannelWeb Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
16
namespace BEdita\WebTools\Controller\Component;
17
18
use Cake\Collection\Collection;
19
use Cake\Controller\Component;
20
use Cake\Utility\Hash;
21
22
/**
23
 * Component class to format API response data.
24
 */
25
class ApiFormatterComponent extends Component
26
{
27
    /**
28
     * Embed included data into relationships.
29
     *
30
     * @param array $response The response from API
31
     * @return array
32
     */
33
    public function embedIncluded(array $response): array
34
    {
35
        $data = (array)Hash::get($response, 'data');
36
        if (empty($data)) {
37
            return $response;
38
        }
39
40
        $included = (array)Hash::get($response, 'included');
41
        if (empty($included)) {
42
            return $response;
43
        }
44
45
        $included = collection($included);
46
        if (!Hash::numeric(array_keys($data))) {
47
            $response['data'] = $this->addIncluded($data, $included);
48
49
            return $response;
50
        }
51
52
        foreach ($data as &$d) {
53
            $d = $this->addIncluded($d, $included);
54
        }
55
        unset($d);
56
57
        $response['data'] = $data;
58
59
        return $response;
60
    }
61
62
    /**
63
     * Add included data to main resource.
64
     *
65
     * @param array $resource The resource.
66
     * @param \Cake\Collection\Collection $included The included collection.
67
     * @return array
68
     */
69
    protected function addIncluded(array $resource, Collection $included): array
70
    {
71
        foreach ($resource['relationships'] as &$relation) {
72
            if (empty($relation['data'])) {
73
                continue;
74
            }
75
76
            $relation['data'] = $this->extractFromIncluded($included, (array)$relation['data']);
77
        }
78
        unset($relation);
79
80
        return $resource;
81
    }
82
83
    /**
84
     * Extract items from included starting from $relationship data.
85
     *
86
     * @param \Cake\Collection\Collection $included The included collection
87
     * @param array $relationshipData Array of relationship data.
88
     *                                Every item must contain 'type' and 'id'.
89
     * @return array
90
     */
91
    protected function extractFromIncluded(Collection $included, array $relationshipData): array
92
    {
93
        foreach ($relationshipData as &$data) {
94
            $data = (array)$included->firstMatch([
95
                'type' => $data['type'],
96
                'id' => $data['id'],
97
            ]);
98
        }
99
        unset($data);
100
101
        return $relationshipData;
102
    }
103
}
104