1
|
|
|
<?php |
2
|
|
|
namespace keeko\core\domain\base; |
3
|
|
|
|
4
|
|
|
use keeko\core\event\ModuleEvent; |
5
|
|
|
use keeko\core\model\ActionQuery; |
6
|
|
|
use keeko\core\model\ModuleQuery; |
7
|
|
|
use keeko\core\model\Module; |
8
|
|
|
use keeko\framework\domain\payload\Created; |
9
|
|
|
use keeko\framework\domain\payload\Deleted; |
10
|
|
|
use keeko\framework\domain\payload\Found; |
11
|
|
|
use keeko\framework\domain\payload\NotDeleted; |
12
|
|
|
use keeko\framework\domain\payload\NotFound; |
13
|
|
|
use keeko\framework\domain\payload\NotUpdated; |
14
|
|
|
use keeko\framework\domain\payload\NotValid; |
15
|
|
|
use keeko\framework\domain\payload\PayloadInterface; |
16
|
|
|
use keeko\framework\domain\payload\Updated; |
17
|
|
|
use keeko\framework\exceptions\ErrorsException; |
18
|
|
|
use keeko\framework\service\ServiceContainer; |
19
|
|
|
use keeko\framework\utils\NameUtils; |
20
|
|
|
use keeko\framework\utils\Parameters; |
21
|
|
|
use phootwork\collection\Map; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
*/ |
25
|
|
|
trait ModuleDomainTrait { |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
*/ |
29
|
|
|
protected $pool; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Adds Actions to Module |
33
|
|
|
* |
34
|
|
|
* @param mixed $id |
35
|
|
|
* @param mixed $data |
36
|
|
|
* @return PayloadInterface |
37
|
|
|
*/ |
38
|
|
|
public function addActions($id, $data) { |
39
|
|
|
// find |
40
|
|
|
$model = $this->get($id); |
41
|
|
|
|
42
|
|
|
if ($model === null) { |
43
|
|
|
return new NotFound(['message' => 'Module not found.']); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
// pass add to internal logic |
47
|
|
|
try { |
48
|
|
|
$this->doAddActions($model, $data); |
49
|
|
|
} catch (ErrorsException $e) { |
|
|
|
|
50
|
|
|
return new NotValid(['errors' => $e->getErrors()]); |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
// save and dispatch events |
54
|
|
|
$event = new ModuleEvent($model); |
55
|
|
|
$this->dispatch(ModuleEvent::PRE_ACTIONS_ADD, $event); |
56
|
|
|
$this->dispatch(ModuleEvent::PRE_SAVE, $event); |
57
|
|
|
$rows = $model->save(); |
58
|
|
|
$this->dispatch(ModuleEvent::POST_ACTIONS_ADD, $event); |
59
|
|
|
$this->dispatch(ModuleEvent::POST_SAVE, $event); |
60
|
|
|
|
61
|
|
|
if ($rows > 0) { |
62
|
|
|
return Updated(['model' => $model]); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
return NotUpdated(['model' => $model]); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* Creates a new Module with the provided data |
70
|
|
|
* |
71
|
|
|
* @param mixed $data |
72
|
|
|
* @return PayloadInterface |
73
|
|
|
*/ |
74
|
|
|
public function create($data) { |
75
|
|
|
// hydrate |
76
|
|
|
$serializer = Module::getSerializer(); |
77
|
|
|
$model = $serializer->hydrate(new Module(), $data); |
78
|
|
|
$this->hydrateRelationships($model, $data); |
|
|
|
|
79
|
|
|
|
80
|
|
|
// validate |
81
|
|
|
$validator = $this->getValidator(); |
|
|
|
|
82
|
|
|
if ($validator !== null && !$validator->validate($model)) { |
83
|
|
|
return new NotValid([ |
84
|
|
|
'errors' => $validator->getValidationFailures() |
85
|
|
|
]); |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
// dispatch |
89
|
|
|
$event = new ModuleEvent($model); |
90
|
|
|
$this->dispatch(ModuleEvent::PRE_CREATE, $event); |
91
|
|
|
$this->dispatch(ModuleEvent::PRE_SAVE, $event); |
92
|
|
|
$model->save(); |
93
|
|
|
$this->dispatch(ModuleEvent::POST_CREATE, $event); |
94
|
|
|
$this->dispatch(ModuleEvent::POST_SAVE, $event); |
95
|
|
|
return new Created(['model' => $model]); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* Deletes a Module with the given id |
100
|
|
|
* |
101
|
|
|
* @param mixed $id |
102
|
|
|
* @return PayloadInterface |
103
|
|
|
*/ |
104
|
|
|
public function delete($id) { |
105
|
|
|
// find |
106
|
|
|
$model = $this->get($id); |
107
|
|
|
|
108
|
|
|
if ($model === null) { |
109
|
|
|
return new NotFound(['message' => 'Module not found.']); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
// delete |
113
|
|
|
$event = new ModuleEvent($model); |
114
|
|
|
$this->dispatch(ModuleEvent::PRE_DELETE, $event); |
115
|
|
|
$model->delete(); |
116
|
|
|
|
117
|
|
|
if ($model->isDeleted()) { |
118
|
|
|
$this->dispatch(ModuleEvent::POST_DELETE, $event); |
119
|
|
|
return new Deleted(['model' => $model]); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
return new NotDeleted(['message' => 'Could not delete Module']); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* Returns a paginated result |
127
|
|
|
* |
128
|
|
|
* @param Parameters $params |
129
|
|
|
* @return PayloadInterface |
130
|
|
|
*/ |
131
|
|
|
public function paginate(Parameters $params) { |
132
|
|
|
$sysPrefs = $this->getServiceContainer()->getPreferenceLoader()->getSystemPreferences(); |
133
|
|
|
$defaultSize = $sysPrefs->getPaginationSize(); |
134
|
|
|
$page = $params->getPage('number'); |
135
|
|
|
$size = $params->getPage('size', $defaultSize); |
136
|
|
|
|
137
|
|
|
$query = ModuleQuery::create(); |
138
|
|
|
|
139
|
|
|
// sorting |
140
|
|
|
$sort = $params->getSort(Module::getSerializer()->getSortFields()); |
141
|
|
|
foreach ($sort as $field => $order) { |
142
|
|
|
$method = 'orderBy' . NameUtils::toStudlyCase($field); |
143
|
|
|
$query->$method($order); |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
// filtering |
147
|
|
|
$filter = $params->getFilter(); |
148
|
|
|
if (!empty($filter)) { |
149
|
|
|
$this->applyFilter($query, $filter); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
// paginate |
153
|
|
|
$model = $query->paginate($page, $size); |
154
|
|
|
|
155
|
|
|
// run response |
156
|
|
|
return new Found(['model' => $model]); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Returns one Module with the given id |
161
|
|
|
* |
162
|
|
|
* @param mixed $id |
163
|
|
|
* @return PayloadInterface |
164
|
|
|
*/ |
165
|
|
|
public function read($id) { |
166
|
|
|
// read |
167
|
|
|
$model = $this->get($id); |
168
|
|
|
|
169
|
|
|
// check existence |
170
|
|
|
if ($model === null) { |
171
|
|
|
return new NotFound(['message' => 'Module not found.']); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
return new Found(['model' => $model]); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Removes Actions from Module |
179
|
|
|
* |
180
|
|
|
* @param mixed $id |
181
|
|
|
* @param mixed $data |
182
|
|
|
* @return PayloadInterface |
183
|
|
|
*/ |
184
|
|
|
public function removeActions($id, $data) { |
185
|
|
|
// find |
186
|
|
|
$model = $this->get($id); |
187
|
|
|
|
188
|
|
|
if ($model === null) { |
189
|
|
|
return new NotFound(['message' => 'Module not found.']); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
// pass remove to internal logic |
193
|
|
|
try { |
194
|
|
|
$this->doRemoveActions($model, $data); |
195
|
|
|
} catch (ErrorsException $e) { |
|
|
|
|
196
|
|
|
return new NotValid(['errors' => $e->getErrors()]); |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
// save and dispatch events |
200
|
|
|
$event = new ModuleEvent($model); |
201
|
|
|
$this->dispatch(ModuleEvent::PRE_ACTIONS_REMOVE, $event); |
202
|
|
|
$this->dispatch(ModuleEvent::PRE_SAVE, $event); |
203
|
|
|
$rows = $model->save(); |
204
|
|
|
$this->dispatch(ModuleEvent::POST_ACTIONS_REMOVE, $event); |
205
|
|
|
$this->dispatch(ModuleEvent::POST_SAVE, $event); |
206
|
|
|
|
207
|
|
|
if ($rows > 0) { |
208
|
|
|
return Updated(['model' => $model]); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
return NotUpdated(['model' => $model]); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* Updates a Module with the given idand the provided data |
216
|
|
|
* |
217
|
|
|
* @param mixed $id |
218
|
|
|
* @param mixed $data |
219
|
|
|
* @return PayloadInterface |
220
|
|
|
*/ |
221
|
|
|
public function update($id, $data) { |
222
|
|
|
// find |
223
|
|
|
$model = $this->get($id); |
224
|
|
|
|
225
|
|
|
if ($model === null) { |
226
|
|
|
return new NotFound(['message' => 'Module not found.']); |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
// hydrate |
230
|
|
|
$serializer = Module::getSerializer(); |
231
|
|
|
$model = $serializer->hydrate($model, $data); |
232
|
|
|
$this->hydrateRelationships($model, $data); |
|
|
|
|
233
|
|
|
|
234
|
|
|
// validate |
235
|
|
|
$validator = $this->getValidator(); |
|
|
|
|
236
|
|
|
if ($validator !== null && !$validator->validate($model)) { |
237
|
|
|
return new NotValid([ |
238
|
|
|
'errors' => $validator->getValidationFailures() |
239
|
|
|
]); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
// dispatch |
243
|
|
|
$event = new ModuleEvent($model); |
244
|
|
|
$this->dispatch(ModuleEvent::PRE_UPDATE, $event); |
245
|
|
|
$this->dispatch(ModuleEvent::PRE_SAVE, $event); |
246
|
|
|
$rows = $model->save(); |
247
|
|
|
$this->dispatch(ModuleEvent::POST_UPDATE, $event); |
248
|
|
|
$this->dispatch(ModuleEvent::POST_SAVE, $event); |
249
|
|
|
|
250
|
|
|
$payload = ['model' => $model]; |
251
|
|
|
|
252
|
|
|
if ($rows === 0) { |
253
|
|
|
return new NotUpdated($payload); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
return new Updated($payload); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Updates Actions on Module |
261
|
|
|
* |
262
|
|
|
* @param mixed $id |
263
|
|
|
* @param mixed $data |
264
|
|
|
* @return PayloadInterface |
265
|
|
|
*/ |
266
|
|
|
public function updateActions($id, $data) { |
267
|
|
|
// find |
268
|
|
|
$model = $this->get($id); |
269
|
|
|
|
270
|
|
|
if ($model === null) { |
271
|
|
|
return new NotFound(['message' => 'Module not found.']); |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
// pass update to internal logic |
275
|
|
|
try { |
276
|
|
|
$this->doUpdateActions($model, $data); |
277
|
|
|
} catch (ErrorsException $e) { |
|
|
|
|
278
|
|
|
return new NotValid(['errors' => $e->getErrors()]); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
// save and dispatch events |
282
|
|
|
$event = new ModuleEvent($model); |
283
|
|
|
$this->dispatch(ModuleEvent::PRE_ACTIONS_UPDATE, $event); |
284
|
|
|
$this->dispatch(ModuleEvent::PRE_SAVE, $event); |
285
|
|
|
$rows = $model->save(); |
286
|
|
|
$this->dispatch(ModuleEvent::POST_ACTIONS_UPDATE, $event); |
287
|
|
|
$this->dispatch(ModuleEvent::POST_SAVE, $event); |
288
|
|
|
|
289
|
|
|
if ($rows > 0) { |
290
|
|
|
return Updated(['model' => $model]); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
return NotUpdated(['model' => $model]); |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* @param mixed $query |
298
|
|
|
* @param mixed $filter |
299
|
|
|
* @return void |
300
|
|
|
*/ |
301
|
|
|
protected function applyFilter($query, $filter) { |
302
|
|
|
foreach ($filter as $column => $value) { |
303
|
|
|
$pos = strpos($column, '.'); |
304
|
|
|
if ($pos !== false) { |
305
|
|
|
$rel = NameUtils::toStudlyCase(substr($column, 0, $pos)); |
306
|
|
|
$col = substr($column, $pos + 1); |
307
|
|
|
$method = 'use' . $rel . 'Query'; |
308
|
|
|
if (method_exists($query, $method)) { |
309
|
|
|
$sub = $query->$method(); |
310
|
|
|
$this->applyFilter($sub, [$col => $value]); |
311
|
|
|
$sub->endUse(); |
312
|
|
|
} |
313
|
|
|
} else { |
314
|
|
|
$method = 'filterBy' . NameUtils::toStudlyCase($column); |
315
|
|
|
if (method_exists($query, $method)) { |
316
|
|
|
$query->$method($value); |
317
|
|
|
} |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* @param string $type |
324
|
|
|
* @param ModuleEvent $event |
325
|
|
|
*/ |
326
|
|
|
protected function dispatch($type, ModuleEvent $event) { |
327
|
|
|
$model = $event->getModule(); |
328
|
|
|
$methods = [ |
329
|
|
|
ModuleEvent::PRE_CREATE => 'preCreate', |
330
|
|
|
ModuleEvent::POST_CREATE => 'postCreate', |
331
|
|
|
ModuleEvent::PRE_UPDATE => 'preUpdate', |
332
|
|
|
ModuleEvent::POST_UPDATE => 'postUpdate', |
333
|
|
|
ModuleEvent::PRE_DELETE => 'preDelete', |
334
|
|
|
ModuleEvent::POST_DELETE => 'postDelete', |
335
|
|
|
ModuleEvent::PRE_SAVE => 'preSave', |
336
|
|
|
ModuleEvent::POST_SAVE => 'postSave' |
337
|
|
|
]; |
338
|
|
|
|
339
|
|
|
if (isset($methods[$type])) { |
340
|
|
|
$method = $methods[$type]; |
341
|
|
|
if (method_exists($this, $method)) { |
342
|
|
|
$this->$method($model); |
343
|
|
|
} |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
$dispatcher = $this->getServiceContainer()->getDispatcher(); |
347
|
|
|
$dispatcher->dispatch($type, $event); |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* Interal mechanism to add Actions to Module |
352
|
|
|
* |
353
|
|
|
* @param Module $model |
354
|
|
|
* @param mixed $data |
355
|
|
|
*/ |
356
|
|
|
protected function doAddActions(Module $model, $data) { |
357
|
|
|
$errors = []; |
358
|
|
|
foreach ($data as $entry) { |
359
|
|
|
if (!isset($entry['id'])) { |
360
|
|
|
$errors[] = 'Missing id for Action'; |
361
|
|
|
} else { |
362
|
|
|
$related = ActionQuery::create()->findOneById($entry['id']); |
363
|
|
|
$model->addAction($related); |
364
|
|
|
} |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
if (count($errors) > 0) { |
368
|
|
|
return new ErrorsException($errors); |
369
|
|
|
} |
370
|
|
|
} |
371
|
|
|
|
372
|
|
|
/** |
373
|
|
|
* Interal mechanism to remove Actions from Module |
374
|
|
|
* |
375
|
|
|
* @param Module $model |
376
|
|
|
* @param mixed $data |
377
|
|
|
*/ |
378
|
|
|
protected function doRemoveActions(Module $model, $data) { |
379
|
|
|
$errors = []; |
380
|
|
|
foreach ($data as $entry) { |
381
|
|
|
if (!isset($entry['id'])) { |
382
|
|
|
$errors[] = 'Missing id for Action'; |
383
|
|
|
} else { |
384
|
|
|
$related = ActionQuery::create()->findOneById($entry['id']); |
385
|
|
|
$model->removeAction($related); |
386
|
|
|
} |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
if (count($errors) > 0) { |
390
|
|
|
return new ErrorsException($errors); |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
/** |
395
|
|
|
* Internal update mechanism of Actions on Module |
396
|
|
|
* |
397
|
|
|
* @param Module $model |
398
|
|
|
* @param mixed $data |
399
|
|
|
*/ |
400
|
|
|
protected function doUpdateActions(Module $model, $data) { |
401
|
|
|
// remove all relationships before |
402
|
|
|
ActionQuery::create()->filterByModule($model)->delete(); |
403
|
|
|
|
404
|
|
|
// add them |
405
|
|
|
$errors = []; |
406
|
|
|
foreach ($data as $entry) { |
407
|
|
|
if (!isset($entry['id'])) { |
408
|
|
|
$errors[] = 'Missing id for Action'; |
409
|
|
|
} else { |
410
|
|
|
$related = ActionQuery::create()->findOneById($entry['id']); |
411
|
|
|
$model->addAction($related); |
412
|
|
|
} |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
if (count($errors) > 0) { |
416
|
|
|
throw new ErrorsException($errors); |
417
|
|
|
} |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* Returns one Module with the given id from cache |
422
|
|
|
* |
423
|
|
|
* @param mixed $id |
424
|
|
|
* @return Module|null |
425
|
|
|
*/ |
426
|
|
|
protected function get($id) { |
427
|
|
|
if ($this->pool === null) { |
428
|
|
|
$this->pool = new Map(); |
429
|
|
|
} else if ($this->pool->has($id)) { |
430
|
|
|
return $this->pool->get($id); |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
$model = ModuleQuery::create()->findOneById($id); |
434
|
|
|
$this->pool->set($id, $model); |
435
|
|
|
|
436
|
|
|
return $model; |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Returns the service container |
441
|
|
|
* |
442
|
|
|
* @return ServiceContainer |
443
|
|
|
*/ |
444
|
|
|
abstract protected function getServiceContainer(); |
445
|
|
|
} |
446
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.