1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* BEdita, API-first content management framework |
4
|
|
|
* Copyright 2018 ChannelWeb Srl, Chialab Srl |
5
|
|
|
* |
6
|
|
|
* This file is part of BEdita: you can redistribute it and/or modify |
7
|
|
|
* it under the terms of the GNU Lesser General Public License as published |
8
|
|
|
* by the Free Software Foundation, either version 3 of the License, or |
9
|
|
|
* (at your option) any later version. |
10
|
|
|
* |
11
|
|
|
* See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details. |
12
|
|
|
*/ |
13
|
|
|
namespace App\Controller; |
14
|
|
|
|
15
|
|
|
use BEdita\SDK\BEditaClientException; |
16
|
|
|
use Cake\Event\Event; |
17
|
|
|
use Cake\Http\Exception\BadRequestException; |
18
|
|
|
use Cake\Http\Exception\UnauthorizedException; |
19
|
|
|
use Cake\Http\Response; |
20
|
|
|
use Psr\Log\LogLevel; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Model controller: list, add, edit, remove modeling related resources |
24
|
|
|
* |
25
|
|
|
* Object types, relations, properties and property_types |
26
|
|
|
* |
27
|
|
|
* @property \App\Controller\Component\PropertiesComponent $Properties |
28
|
|
|
*/ |
29
|
|
|
class ModelController extends AppController |
30
|
|
|
{ |
31
|
|
|
/** |
32
|
|
|
* Resource type currently used |
33
|
|
|
* |
34
|
|
|
* @var string |
35
|
|
|
*/ |
36
|
|
|
protected $resourceType = null; |
37
|
|
|
|
38
|
|
|
/** |
39
|
|
|
* {@inheritDoc} |
40
|
|
|
*/ |
41
|
|
|
public function initialize() : void |
42
|
|
|
{ |
43
|
|
|
parent::initialize(); |
44
|
|
|
|
45
|
|
|
$this->loadComponent('Properties'); |
46
|
|
|
|
47
|
|
|
$this->resourceType = $this->request->getParam('resource_type', 'object_types'); |
48
|
|
|
$this->Schema->setConfig([ |
49
|
|
|
'type' => $this->resourceType, |
50
|
|
|
'internalSchema' => true, |
51
|
|
|
]); |
52
|
|
|
|
53
|
|
|
$this->Security->setConfig('unlockedActions', ['savePropertyTypesJson']); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* {@inheritDoc} |
58
|
|
|
*/ |
59
|
|
|
public function beforeFilter(Event $event) : ?Response |
60
|
|
|
{ |
61
|
|
|
$roles = $this->Auth->user('roles'); |
62
|
|
|
if (empty($roles) || !in_array('admin', $roles)) { |
63
|
|
|
throw new UnauthorizedException(__('Module access not authorized')); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
return parent::beforeFilter($event); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* {@inheritDoc} |
71
|
|
|
*/ |
72
|
|
|
public function beforeRender(Event $event) : ?Response |
73
|
|
|
{ |
74
|
|
|
$this->set('resourceType', $this->resourceType); |
75
|
|
|
$this->set('moduleLink', ['_name' => 'model:list', 'resource_type' => 'object_types']); |
76
|
|
|
|
77
|
|
|
return parent::beforeRender($event); |
|
|
|
|
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Display resources list. |
82
|
|
|
* |
83
|
|
|
* @return \Cake\Http\Response|null |
84
|
|
|
*/ |
85
|
|
|
public function index() : ?Response |
86
|
|
|
{ |
87
|
|
|
$this->request->allowMethod(['get']); |
88
|
|
|
|
89
|
|
|
try { |
90
|
|
|
$response = $this->apiClient->get( |
91
|
|
|
sprintf('/model/%s', $this->resourceType), |
92
|
|
|
$this->request->getQueryParams() |
93
|
|
|
); |
94
|
|
|
} catch (BEditaClientException $e) { |
95
|
|
|
$this->log($e, LogLevel::ERROR); |
96
|
|
|
$this->Flash->error($e->getMessage(), ['params' => $e]); |
97
|
|
|
|
98
|
|
|
return $this->redirect(['_name' => 'dashboard']); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
$this->set('resources', (array)$response['data']); |
102
|
|
|
$this->set('meta', (array)$response['meta']); |
103
|
|
|
$this->set('links', (array)$response['links']); |
104
|
|
|
|
105
|
|
|
$this->set('properties', $this->Properties->indexList($this->resourceType)); |
106
|
|
|
|
107
|
|
|
return null; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* View single resource. |
112
|
|
|
* |
113
|
|
|
* @param string|int $id Resource ID. |
114
|
|
|
* |
115
|
|
|
* @return \Cake\Http\Response|null |
116
|
|
|
*/ |
117
|
|
|
public function view($id) : ?Response |
118
|
|
|
{ |
119
|
|
|
$this->request->allowMethod(['get']); |
120
|
|
|
|
121
|
|
|
try { |
122
|
|
|
$response = $this->apiClient->get(sprintf('/model/%s/%s', $this->resourceType, $id)); |
123
|
|
|
} catch (BEditaClientException $e) { |
124
|
|
|
$this->log($e, LogLevel::ERROR); |
125
|
|
|
$this->Flash->error($e->getMessage(), ['params' => $e]); |
126
|
|
|
|
127
|
|
|
return $this->redirect(['_name' => 'model:list', 'resource_type' => $this->resourceType]); |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
$resource = (array)$response['data']; |
131
|
|
|
$this->set(compact('resource')); |
132
|
|
|
$this->set('schema', $this->Schema->getSchema()); |
133
|
|
|
$this->set('properties', $this->Properties->viewGroups($resource, $this->resourceType)); |
134
|
|
|
|
135
|
|
|
return null; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
/** |
139
|
|
|
* save property types (add/edit/delete) |
140
|
|
|
* |
141
|
|
|
* @return void |
142
|
|
|
*/ |
143
|
|
|
public function savePropertyTypesJson() : void |
144
|
|
|
{ |
145
|
|
|
$payload = $this->request->getData(); |
146
|
|
|
|
147
|
|
|
$this->request->allowMethod(['post']); |
148
|
|
|
$response = []; |
149
|
|
|
|
150
|
|
|
try { |
151
|
|
|
if (empty($payload)) { |
152
|
|
|
throw new BadRequestException('empty request'); |
153
|
|
|
} |
154
|
|
|
$response['saved'] = []; |
155
|
|
|
$response['edited'] = []; |
156
|
|
|
$response['removed'] = []; |
157
|
|
|
|
158
|
|
|
// save newly added property types |
159
|
|
|
if (!empty($payload['addPropertyTypes'])) { |
160
|
|
|
$addPropertyTypes = $payload['addPropertyTypes']; |
161
|
|
|
// dd($addPropertyTypes); |
162
|
|
|
foreach ($addPropertyTypes as $addPropertyType) { |
163
|
|
|
if (isset($addPropertyType['params'])) { |
164
|
|
|
$params = json_decode($addPropertyType['params'], true); |
165
|
|
|
$addPropertyType['params'] = $params; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
$body = [ |
169
|
|
|
'data' => [ |
170
|
|
|
'type' => $this->resourceType, |
171
|
|
|
'attributes' => $addPropertyType, |
172
|
|
|
], |
173
|
|
|
]; |
174
|
|
|
|
175
|
|
|
$resp = $this->apiClient->post(sprintf('/model/%s', $this->resourceType), json_encode($body)); |
176
|
|
|
unset($resp['data']['relationships']); |
177
|
|
|
|
178
|
|
|
$response['saved'][] = $resp['data']; |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
// edit property types |
183
|
|
|
if (!empty($payload['editPropertyTypes'])) { |
184
|
|
|
$editPropertyTypes = $payload['editPropertyTypes']; |
185
|
|
|
foreach ($editPropertyTypes as $editPropertyType) { |
186
|
|
|
$id = (string)$editPropertyType['id']; |
187
|
|
|
$type = $this->resourceType; |
188
|
|
|
$body = [ |
189
|
|
|
'data' => [ |
190
|
|
|
'id' => $id, |
191
|
|
|
'type' => $type, |
192
|
|
|
'attributes' => $editPropertyType['attributes'], |
193
|
|
|
], |
194
|
|
|
]; |
195
|
|
|
$resp = $this->apiClient->patch(sprintf('/model/%s/%s', $type, $id), json_encode($body)); |
196
|
|
|
unset($resp['data']['relationships']); |
197
|
|
|
|
198
|
|
|
$response['edited'][] = $resp['data']; |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
// remove property types |
203
|
|
|
if (!empty($payload['removePropertyTypes'])) { |
204
|
|
|
$removePropertyTypes = $payload['removePropertyTypes']; |
205
|
|
|
foreach ($removePropertyTypes as $removePropertyTypeId) { |
206
|
|
|
$this->apiClient->delete(sprintf('/model/%s/%s', $this->resourceType, $removePropertyTypeId), null); |
207
|
|
|
$response['removed'][] = $removePropertyTypeId; |
208
|
|
|
} |
209
|
|
|
} |
210
|
|
|
} catch (BEditaClientException $error) { |
211
|
|
|
$this->log($error, LogLevel::ERROR); |
212
|
|
|
|
213
|
|
|
$this->set([ |
214
|
|
|
'error' => $error->getMessage(), |
215
|
|
|
'_serialize' => ['error'], |
216
|
|
|
]); |
217
|
|
|
|
218
|
|
|
return; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
$this->set((array)$response); |
222
|
|
|
$this->set('_serialize', true); |
223
|
|
|
} |
224
|
|
|
} |
225
|
|
|
|
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()
can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.