Completed
Push — master ( 94e820...3f0fe0 )
by Thomas
10:39
created

GroupDomainTrait::updateActions()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 40
rs 8.439
cc 6
eloc 23
nc 10
nop 2
1
<?php
2
namespace keeko\core\domain\base;
3
4
use keeko\core\model\Group;
5
use keeko\core\model\GroupQuery;
6
use keeko\framework\service\ServiceContainer;
7
use keeko\framework\domain\payload\PayloadInterface;
8
use phootwork\collection\Map;
9
use keeko\framework\domain\payload\Found;
10
use keeko\framework\domain\payload\NotFound;
11
use keeko\framework\utils\Parameters;
12
use keeko\framework\utils\NameUtils;
13
use keeko\core\event\GroupEvent;
14
use keeko\framework\domain\payload\Created;
15
use keeko\framework\domain\payload\NotValid;
16
use keeko\framework\domain\payload\Updated;
17
use keeko\framework\domain\payload\NotUpdated;
18
use keeko\framework\domain\payload\Deleted;
19
use keeko\framework\domain\payload\NotDeleted;
20
use keeko\core\model\UserQuery;
21
use keeko\core\model\UserGroupQuery;
22
use keeko\core\model\ActionQuery;
23
use keeko\core\model\GroupActionQuery;
24
25
/**
26
 */
27
trait GroupDomainTrait {
28
29
	/**
30
	 */
31
	protected $pool;
32
33
	/**
34
	 * Adds Actions to Group
35
	 * 
36
	 * @param mixed $id
37
	 * @param mixed $data
38
	 * @return PayloadInterface
39
	 */
40
	public function addActions($id, $data) {
41
		// find
42
		$group = $this->get($id);
43
44
		if ($group === null) {
45
			return new NotFound(['message' => 'Group not found.']);
46
		}
47
		 
48
		// update
49
		$errors = [];
50
		foreach ($data as $entry) {
51
			if (!isset($entry['id'])) {
52
				$errors[] = 'Missing id for Action';
53
			}
54
			$action = ActionQuery::create()->findOneById($entry['id']);
55
			$group->addAction($action);
56
		}
57
58
		if (count($errors) > 0) {
59
			return new NotValid(['errors' => $errors]);
60
		}
61
62
		// save and dispatch events
63
		$event = new GroupEvent($group);
64
		$dispatcher = $this->getServiceContainer()->getDispatcher();
65
		$dispatcher->dispatch(GroupEvent::PRE_ACTIONS_ADD, $event);
66
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
67
		$rows = $group->save();
68
		$dispatcher->dispatch(GroupEvent::POST_ACTIONS_ADD, $event);
69
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
70
71
		if ($rows > 0) {
72
			return Updated(['model' => $group]);
73
		}
74
75
		return NotUpdated(['model' => $group]);
76
	}
77
78
	/**
79
	 * Adds Users to Group
80
	 * 
81
	 * @param mixed $id
82
	 * @param mixed $data
83
	 * @return PayloadInterface
84
	 */
85
	public function addUsers($id, $data) {
86
		// find
87
		$group = $this->get($id);
88
89
		if ($group === null) {
90
			return new NotFound(['message' => 'Group not found.']);
91
		}
92
		 
93
		// update
94
		$errors = [];
95
		foreach ($data as $entry) {
96
			if (!isset($entry['id'])) {
97
				$errors[] = 'Missing id for User';
98
			}
99
			$user = UserQuery::create()->findOneById($entry['id']);
100
			$group->addUser($user);
101
		}
102
103
		if (count($errors) > 0) {
104
			return new NotValid(['errors' => $errors]);
105
		}
106
107
		// save and dispatch events
108
		$event = new GroupEvent($group);
109
		$dispatcher = $this->getServiceContainer()->getDispatcher();
110
		$dispatcher->dispatch(GroupEvent::PRE_USERS_ADD, $event);
111
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
112
		$rows = $group->save();
113
		$dispatcher->dispatch(GroupEvent::POST_USERS_ADD, $event);
114
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
115
116
		if ($rows > 0) {
117
			return Updated(['model' => $group]);
118
		}
119
120
		return NotUpdated(['model' => $group]);
121
	}
122
123
	/**
124
	 * Creates a new Group with the provided data
125
	 * 
126
	 * @param mixed $data
127
	 * @return PayloadInterface
128
	 */
129
	public function create($data) {
130
		// hydrate
131
		$serializer = Group::getSerializer();
132
		$group = $serializer->hydrate(new Group(), $data);
133
134
		// validate
135
		$validator = $this->getValidator();
0 ignored issues
show
Bug introduced by
It seems like getValidator() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
136
		if ($validator !== null && !$validator->validate($group)) {
137
			return new NotValid([
138
				'errors' => $validator->getValidationFailures()
139
			]);
140
		}
141
142
		// dispatch
143
		$event = new GroupEvent($group);
144
		$dispatcher = $this->getServiceContainer()->getDispatcher();
145
		$dispatcher->dispatch(GroupEvent::PRE_CREATE, $event);
146
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
147
		$group->save();
148
		$dispatcher->dispatch(GroupEvent::POST_CREATE, $event);
149
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
150
		return new Created(['model' => $group]);
151
	}
152
153
	/**
154
	 * Deletes a Group with the given id
155
	 * 
156
	 * @param mixed $id
157
	 * @return PayloadInterface
158
	 */
159
	public function delete($id) {
160
		// find
161
		$group = $this->get($id);
162
163
		if ($group === null) {
164
			return new NotFound(['message' => 'Group not found.']);
165
		}
166
167
		// delete
168
		$event = new GroupEvent($group);
169
		$dispatcher = $this->getServiceContainer()->getDispatcher();
170
		$dispatcher->dispatch(GroupEvent::PRE_DELETE, $event);
171
		$group->delete();
172
173
		if ($group->isDeleted()) {
174
			$dispatcher->dispatch(GroupEvent::POST_DELETE, $event);
175
			return new Deleted(['model' => $group]);
176
		}
177
178
		return new NotDeleted(['message' => 'Could not delete Group']);
179
	}
180
181
	/**
182
	 * Returns a paginated result
183
	 * 
184
	 * @param Parameters $params
185
	 * @return PayloadInterface
186
	 */
187
	public function paginate(Parameters $params) {
188
		$sysPrefs = $this->getServiceContainer()->getPreferenceLoader()->getSystemPreferences();
189
		$defaultSize = $sysPrefs->getPaginationSize();
190
		$page = $params->getPage('number');
191
		$size = $params->getPage('size', $defaultSize);
192
193
		$query = GroupQuery::create();
194
195
		// sorting
196
		$sort = $params->getSort(Group::getSerializer()->getSortFields());
197
		foreach ($sort as $field => $order) {
198
			$method = 'orderBy' . NameUtils::toStudlyCase($field);
199
			$query->$method($order);
200
		}
201
202
		// filtering
203
		$filter = $params->getFilter();
204
		if (!empty($filter)) {
205
			$this->applyFilter($query, $filter);
206
		}
207
208
		// paginate
209
		$group = $query->paginate($page, $size);
210
211
		// run response
212
		return new Found(['model' => $group]);
213
	}
214
215
	/**
216
	 * Returns one Group with the given id
217
	 * 
218
	 * @param mixed $id
219
	 * @return PayloadInterface
220
	 */
221
	public function read($id) {
222
		// read
223
		$group = $this->get($id);
224
225
		// check existence
226
		if ($group === null) {
227
			return new NotFound(['message' => 'Group not found.']);
228
		}
229
230
		return new Found(['model' => $group]);
231
	}
232
233
	/**
234
	 * Removes Actions from Group
235
	 * 
236
	 * @param mixed $id
237
	 * @param mixed $data
238
	 * @return PayloadInterface
239
	 */
240
	public function removeActions($id, $data) {
241
		// find
242
		$group = $this->get($id);
243
244
		if ($group === null) {
245
			return new NotFound(['message' => 'Group not found.']);
246
		}
247
248
		// remove them
249
		$errors = [];
250
		foreach ($data as $entry) {
251
			if (!isset($entry['id'])) {
252
				$errors[] = 'Missing id for Action';
253
			}
254
			$action = ActionQuery::create()->findOneById($entry['id']);
255
			$group->removeAction($action);
256
		}
257
258
		if (count($errors) > 0) {
259
			return new NotValid(['errors' => $errors]);
260
		}
261
262
		// save and dispatch events
263
		$event = new GroupEvent($group);
264
		$dispatcher = $this->getServiceContainer()->getDispatcher();
265
		$dispatcher->dispatch(GroupEvent::PRE_ACTIONS_REMOVE, $event);
266
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
267
		$rows = $group->save();
268
		$dispatcher->dispatch(GroupEvent::POST_ACTIONS_REMOVE, $event);
269
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
270
271
		if ($rows > 0) {
272
			return Updated(['model' => $group]);
273
		}
274
275
		return NotUpdated(['model' => $group]);
276
	}
277
278
	/**
279
	 * Removes Users from Group
280
	 * 
281
	 * @param mixed $id
282
	 * @param mixed $data
283
	 * @return PayloadInterface
284
	 */
285
	public function removeUsers($id, $data) {
286
		// find
287
		$group = $this->get($id);
288
289
		if ($group === null) {
290
			return new NotFound(['message' => 'Group not found.']);
291
		}
292
293
		// remove them
294
		$errors = [];
295
		foreach ($data as $entry) {
296
			if (!isset($entry['id'])) {
297
				$errors[] = 'Missing id for User';
298
			}
299
			$user = UserQuery::create()->findOneById($entry['id']);
300
			$group->removeUser($user);
301
		}
302
303
		if (count($errors) > 0) {
304
			return new NotValid(['errors' => $errors]);
305
		}
306
307
		// save and dispatch events
308
		$event = new GroupEvent($group);
309
		$dispatcher = $this->getServiceContainer()->getDispatcher();
310
		$dispatcher->dispatch(GroupEvent::PRE_USERS_REMOVE, $event);
311
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
312
		$rows = $group->save();
313
		$dispatcher->dispatch(GroupEvent::POST_USERS_REMOVE, $event);
314
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
315
316
		if ($rows > 0) {
317
			return Updated(['model' => $group]);
318
		}
319
320
		return NotUpdated(['model' => $group]);
321
	}
322
323
	/**
324
	 * Updates a Group with the given idand the provided data
325
	 * 
326
	 * @param mixed $id
327
	 * @param mixed $data
328
	 * @return PayloadInterface
329
	 */
330
	public function update($id, $data) {
331
		// find
332
		$group = $this->get($id);
333
334
		if ($group === null) {
335
			return new NotFound(['message' => 'Group not found.']);
336
		}
337
338
		// hydrate
339
		$serializer = Group::getSerializer();
340
		$group = $serializer->hydrate($group, $data);
341
342
		// validate
343
		$validator = $this->getValidator();
0 ignored issues
show
Bug introduced by
It seems like getValidator() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
344
		if ($validator !== null && !$validator->validate($group)) {
345
			return new NotValid([
346
				'errors' => $validator->getValidationFailures()
347
			]);
348
		}
349
350
		// dispatch
351
		$event = new GroupEvent($group);
352
		$dispatcher = $this->getServiceContainer()->getDispatcher();
353
		$dispatcher->dispatch(GroupEvent::PRE_UPDATE, $event);
354
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
355
		$rows = $group->save();
356
		$dispatcher->dispatch(GroupEvent::POST_UPDATE, $event);
357
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
358
359
		$payload = ['model' => $group];
360
361
		if ($rows === 0) {
362
			return new NotUpdated($payload);
363
		}
364
365
		return new Updated($payload);
366
	}
367
368
	/**
369
	 * Updates Actions on Group
370
	 * 
371
	 * @param mixed $id
372
	 * @param mixed $data
373
	 * @return PayloadInterface
374
	 */
375
	public function updateActions($id, $data) {
376
		// find
377
		$group = $this->get($id);
378
379
		if ($group === null) {
380
			return new NotFound(['message' => 'Group not found.']);
381
		}
382
383
		// remove all relationships before
384
		GroupActionQuery::create()->filterByGroup($group)->delete();
385
386
		// add them
387
		$errors = [];
388
		foreach ($data as $entry) {
389
			if (!isset($entry['id'])) {
390
				$errors[] = 'Missing id for Action';
391
			}
392
			$action = ActionQuery::create()->findOneById($entry['id']);
393
			$group->addAction($action);
394
		}
395
396
		if (count($errors) > 0) {
397
			return new NotValid(['errors' => $errors]);
398
		}
399
400
		// save and dispatch events
401
		$event = new GroupEvent($group);
402
		$dispatcher = $this->getServiceContainer()->getDispatcher();
403
		$dispatcher->dispatch(GroupEvent::PRE_ACTIONS_UPDATE, $event);
404
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
405
		$rows = $group->save();
406
		$dispatcher->dispatch(GroupEvent::POST_ACTIONS_UPDATE, $event);
407
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
408
409
		if ($rows > 0) {
410
			return Updated(['model' => $group]);
411
		}
412
413
		return NotUpdated(['model' => $group]);
414
	}
415
416
	/**
417
	 * Updates Users on Group
418
	 * 
419
	 * @param mixed $id
420
	 * @param mixed $data
421
	 * @return PayloadInterface
422
	 */
423
	public function updateUsers($id, $data) {
424
		// find
425
		$group = $this->get($id);
426
427
		if ($group === null) {
428
			return new NotFound(['message' => 'Group not found.']);
429
		}
430
431
		// remove all relationships before
432
		UserGroupQuery::create()->filterByGroup($group)->delete();
433
434
		// add them
435
		$errors = [];
436
		foreach ($data as $entry) {
437
			if (!isset($entry['id'])) {
438
				$errors[] = 'Missing id for User';
439
			}
440
			$user = UserQuery::create()->findOneById($entry['id']);
441
			$group->addUser($user);
442
		}
443
444
		if (count($errors) > 0) {
445
			return new NotValid(['errors' => $errors]);
446
		}
447
448
		// save and dispatch events
449
		$event = new GroupEvent($group);
450
		$dispatcher = $this->getServiceContainer()->getDispatcher();
451
		$dispatcher->dispatch(GroupEvent::PRE_USERS_UPDATE, $event);
452
		$dispatcher->dispatch(GroupEvent::PRE_SAVE, $event);
453
		$rows = $group->save();
454
		$dispatcher->dispatch(GroupEvent::POST_USERS_UPDATE, $event);
455
		$dispatcher->dispatch(GroupEvent::POST_SAVE, $event);
456
457
		if ($rows > 0) {
458
			return Updated(['model' => $group]);
459
		}
460
461
		return NotUpdated(['model' => $group]);
462
	}
463
464
	/**
465
	 * Implement this functionality at keeko\core\domain\GroupDomain
466
	 * 
467
	 * @param GroupQuery $query
468
	 * @param mixed $filter
469
	 * @return void
470
	 */
471
	abstract protected function applyFilter(GroupQuery $query, $filter);
472
473
	/**
474
	 * Returns one Group with the given id from cache
475
	 * 
476
	 * @param mixed $id
477
	 * @return Group|null
478
	 */
479
	protected function get($id) {
480
		if ($this->pool === null) {
481
			$this->pool = new Map();
482
		} else if ($this->pool->has($id)) {
483
			return $this->pool->get($id);
484
		}
485
486
		$group = GroupQuery::create()->findOneById($id);
487
		$this->pool->set($id, $group);
488
489
		return $group;
490
	}
491
492
	/**
493
	 * Returns the service container
494
	 * 
495
	 * @return ServiceContainer
496
	 */
497
	abstract protected function getServiceContainer();
498
}
499