Passed
Pull Request — master (#652)
by Edoardo
03:00
created

CategoriesComponent::invalidateSchemaCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 1
1
<?php
2
namespace App\Controller\Component;
3
4
use App\Utility\CacheTools;
5
use BEdita\WebTools\ApiClientProvider;
6
use Cake\Cache\Cache;
7
use Cake\Controller\Component;
8
use Cake\Utility\Hash;
9
10
/**
11
 * Categories component
12
 */
13
class CategoriesComponent extends Component
14
{
15
    /**
16
     * Fetch categories list.
17
     *
18
     * @param string|null $objectType The object type filter for categories.
19
     * @param array|null $options Query options.
20
     * @return array The BEdita API response for the categories list.
21
     */
22
    public function index(?string $objectType = null, ?array $options = [])
23
    {
24
        $apiClient = ApiClientProvider::getApiClient();
25
26
        $options = $options + [
27
            'page_size' => 100,
28
        ];
29
        if (!empty($objectType)) {
30
            $options['filter'] = $options['filter'] ?? [];
31
            $options['filter']['type'] = $objectType;
32
        }
33
34
        return $apiClient->get('/model/categories', $options);
35
    }
36
37
    /**
38
     * Create a key/value map of categories from the BEdita categories list response.
39
     *
40
     * @param array $response The BEdita API response for the categories list.
41
     * @return array A map with the category ids as keys and the category attributes as values.
42
     */
43
    public function map(?array $response)
44
    {
45
        return (array)Hash::combine((array)$response['data'], '{n}.id', '{n}');
46
    }
47
48
    /**
49
     * Create an id-based categories tree.
50
     *
51
     * @param array $map The categories map returned by the map function.
52
     * @return array The categories tree.
53
     */
54
    public function tree(?array $map)
55
    {
56
        $tree = [
57
            '_' => [],
58
        ];
59
        foreach ($map as $category) {
60
            if (empty($category['attributes']['parent_id'])) {
61
                $tree['_'][] = $category['id'];
62
            } else {
63
                $tree[$category['attributes']['parent_id']][] = $category['id'];
64
            }
65
        }
66
67
        return $tree;
68
    }
69
70
    /**
71
     * Get an id/label map of available category roots.
72
     *
73
     * @param array $map The categories map returned by the map function.
74
     * @return array The list of available roots.
75
     */
76
    public function getAvailableRoots(?array $map)
77
    {
78
        $roots = ['' => '-'];
79
        foreach ($map as $category) {
80
            $label = empty($category['attributes']['label']) ? $category['attributes']['name'] : $category['attributes']['label'];
81
            if (empty($category['attributes']['parent_id'])) {
82
                $roots[$category['id']] = $label;
83
            }
84
        }
85
86
        return $roots;
87
    }
88
89
    /**
90
     * Save a category using the `/model/` API.
91
     *
92
     * @param array $data Data to save.
93
     * @return array The BEdita API response for the saved category.
94
     */
95
    public function save(array $data)
96
    {
97
        $id = Hash::get($data, 'id');
98
        $type = Hash::get($data, 'object_type_name');
99
        unset($data['id']);
100
        $body = [
101
            'data' => [
102
                'type' => 'categories',
103
                'attributes' => $data,
104
            ],
105
        ];
106
107
        $apiClient = ApiClientProvider::getApiClient();
108
        $endpoint = sprintf('/model/%s', 'categories');
109
        $response = null;
110
        if (empty($id)) {
111
            $response = $apiClient->post($endpoint, json_encode($body));
112
        } else {
113
            $body['data']['id'] = $id;
114
115
            $response = $apiClient->patch(sprintf('%s/%s', $endpoint, $id), json_encode($body));
116
        }
117
118
        if (!empty($type)) {
119
            $this->invalidateSchemaCache($type);
120
        }
121
122
        return $response;
123
    }
124
125
    /**
126
     * Delete a category using the `/model/` API.
127
     *
128
     * @param string|int $id The category id to delete.
129
     * @param string $type The object type name of the category.
130
     * @return array The BEdita API response for the deleted category.
131
     */
132
    public function delete(string $id, $type = null)
133
    {
134
        $apiClient = ApiClientProvider::getApiClient();
135
136
        $response = $apiClient->delete(sprintf('/model/%s/%s', 'categories', $id));
137
        if (!empty($type)) {
138
            $this->invalidateSchemaCache($type);
139
        }
140
141
        return $response;
142
    }
143
144
    /**
145
     * Invalidate schema cache for forms.
146
     *
147
     * @param string $type The object type name of the category.
148
     * @return void
149
     */
150
    private function invalidateSchemaCache(string $type): void
151
    {
152
        $key = CacheTools::cacheKey($type);
153
        Cache::delete($key, SchemaComponent::CACHE_CONFIG);
154
    }
155
}
156