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

UserDomainTrait::getServiceContainer()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 1
nc 1
1
<?php
2
namespace keeko\core\domain\base;
3
4
use keeko\core\model\User;
5
use keeko\core\model\UserQuery;
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\UserEvent;
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\SessionQuery;
21
use keeko\core\model\GroupQuery;
22
use keeko\core\model\UserGroupQuery;
23
use keeko\core\model\ActivityQuery;
24
25
/**
26
 */
27
trait UserDomainTrait {
28
29
	/**
30
	 */
31
	protected $pool;
32
33
	/**
34
	 * Adds Activities to User
35
	 * 
36
	 * @param mixed $id
37
	 * @param mixed $data
38
	 * @return PayloadInterface
39
	 */
40
	public function addActivities($id, $data) {
41
		// find
42
		$user = $this->get($id);
43
44
		if ($user === null) {
45
			return new NotFound(['message' => 'User not found.']);
46
		}
47
		 
48
		// update
49
		$errors = [];
50
		foreach ($data as $entry) {
51
			if (!isset($entry['id'])) {
52
				$errors[] = 'Missing id for Activity';
53
			}
54
			$activity = ActivityQuery::create()->findOneById($entry['id']);
55
			$user->addActivity($activity);
56
		}
57
58
		if (count($errors) > 0) {
59
			return new NotValid(['errors' => $errors]);
60
		}
61
62
		// save and dispatch events
63
		$event = new UserEvent($user);
64
		$dispatcher = $this->getServiceContainer()->getDispatcher();
65
		$dispatcher->dispatch(UserEvent::PRE_ACTIVITIES_ADD, $event);
66
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
67
		$rows = $user->save();
68
		$dispatcher->dispatch(UserEvent::POST_ACTIVITIES_ADD, $event);
69
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
70
71
		if ($rows > 0) {
72
			return Updated(['model' => $user]);
73
		}
74
75
		return NotUpdated(['model' => $user]);
76
	}
77
78
	/**
79
	 * Adds Groups to User
80
	 * 
81
	 * @param mixed $id
82
	 * @param mixed $data
83
	 * @return PayloadInterface
84
	 */
85
	public function addGroups($id, $data) {
86
		// find
87
		$user = $this->get($id);
88
89
		if ($user === null) {
90
			return new NotFound(['message' => 'User not found.']);
91
		}
92
		 
93
		// update
94
		$errors = [];
95
		foreach ($data as $entry) {
96
			if (!isset($entry['id'])) {
97
				$errors[] = 'Missing id for Group';
98
			}
99
			$group = GroupQuery::create()->findOneById($entry['id']);
100
			$user->addGroup($group);
101
		}
102
103
		if (count($errors) > 0) {
104
			return new NotValid(['errors' => $errors]);
105
		}
106
107
		// save and dispatch events
108
		$event = new UserEvent($user);
109
		$dispatcher = $this->getServiceContainer()->getDispatcher();
110
		$dispatcher->dispatch(UserEvent::PRE_GROUPS_ADD, $event);
111
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
112
		$rows = $user->save();
113
		$dispatcher->dispatch(UserEvent::POST_GROUPS_ADD, $event);
114
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
115
116
		if ($rows > 0) {
117
			return Updated(['model' => $user]);
118
		}
119
120
		return NotUpdated(['model' => $user]);
121
	}
122
123
	/**
124
	 * Adds Sessions to User
125
	 * 
126
	 * @param mixed $id
127
	 * @param mixed $data
128
	 * @return PayloadInterface
129
	 */
130
	public function addSessions($id, $data) {
131
		// find
132
		$user = $this->get($id);
133
134
		if ($user === null) {
135
			return new NotFound(['message' => 'User not found.']);
136
		}
137
		 
138
		// update
139
		$errors = [];
140
		foreach ($data as $entry) {
141
			if (!isset($entry['id'])) {
142
				$errors[] = 'Missing id for Session';
143
			}
144
			$session = SessionQuery::create()->findOneById($entry['id']);
145
			$user->addSession($session);
146
		}
147
148
		if (count($errors) > 0) {
149
			return new NotValid(['errors' => $errors]);
150
		}
151
152
		// save and dispatch events
153
		$event = new UserEvent($user);
154
		$dispatcher = $this->getServiceContainer()->getDispatcher();
155
		$dispatcher->dispatch(UserEvent::PRE_SESSIONS_ADD, $event);
156
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
157
		$rows = $user->save();
158
		$dispatcher->dispatch(UserEvent::POST_SESSIONS_ADD, $event);
159
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
160
161
		if ($rows > 0) {
162
			return Updated(['model' => $user]);
163
		}
164
165
		return NotUpdated(['model' => $user]);
166
	}
167
168
	/**
169
	 * Creates a new User with the provided data
170
	 * 
171
	 * @param mixed $data
172
	 * @return PayloadInterface
173
	 */
174
	public function create($data) {
175
		// hydrate
176
		$serializer = User::getSerializer();
177
		$user = $serializer->hydrate(new User(), $data);
178
179
		// validate
180
		$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...
181
		if ($validator !== null && !$validator->validate($user)) {
182
			return new NotValid([
183
				'errors' => $validator->getValidationFailures()
184
			]);
185
		}
186
187
		// dispatch
188
		$event = new UserEvent($user);
189
		$dispatcher = $this->getServiceContainer()->getDispatcher();
190
		$dispatcher->dispatch(UserEvent::PRE_CREATE, $event);
191
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
192
		$user->save();
193
		$dispatcher->dispatch(UserEvent::POST_CREATE, $event);
194
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
195
		return new Created(['model' => $user]);
196
	}
197
198
	/**
199
	 * Deletes a User with the given id
200
	 * 
201
	 * @param mixed $id
202
	 * @return PayloadInterface
203
	 */
204
	public function delete($id) {
205
		// find
206
		$user = $this->get($id);
207
208
		if ($user === null) {
209
			return new NotFound(['message' => 'User not found.']);
210
		}
211
212
		// delete
213
		$event = new UserEvent($user);
214
		$dispatcher = $this->getServiceContainer()->getDispatcher();
215
		$dispatcher->dispatch(UserEvent::PRE_DELETE, $event);
216
		$user->delete();
217
218
		if ($user->isDeleted()) {
219
			$dispatcher->dispatch(UserEvent::POST_DELETE, $event);
220
			return new Deleted(['model' => $user]);
221
		}
222
223
		return new NotDeleted(['message' => 'Could not delete User']);
224
	}
225
226
	/**
227
	 * Returns a paginated result
228
	 * 
229
	 * @param Parameters $params
230
	 * @return PayloadInterface
231
	 */
232
	public function paginate(Parameters $params) {
233
		$sysPrefs = $this->getServiceContainer()->getPreferenceLoader()->getSystemPreferences();
234
		$defaultSize = $sysPrefs->getPaginationSize();
235
		$page = $params->getPage('number');
236
		$size = $params->getPage('size', $defaultSize);
237
238
		$query = UserQuery::create();
239
240
		// sorting
241
		$sort = $params->getSort(User::getSerializer()->getSortFields());
242
		foreach ($sort as $field => $order) {
243
			$method = 'orderBy' . NameUtils::toStudlyCase($field);
244
			$query->$method($order);
245
		}
246
247
		// filtering
248
		$filter = $params->getFilter();
249
		if (!empty($filter)) {
250
			$this->applyFilter($query, $filter);
251
		}
252
253
		// paginate
254
		$user = $query->paginate($page, $size);
255
256
		// run response
257
		return new Found(['model' => $user]);
258
	}
259
260
	/**
261
	 * Returns one User with the given id
262
	 * 
263
	 * @param mixed $id
264
	 * @return PayloadInterface
265
	 */
266
	public function read($id) {
267
		// read
268
		$user = $this->get($id);
269
270
		// check existence
271
		if ($user === null) {
272
			return new NotFound(['message' => 'User not found.']);
273
		}
274
275
		return new Found(['model' => $user]);
276
	}
277
278
	/**
279
	 * Removes Activities from User
280
	 * 
281
	 * @param mixed $id
282
	 * @param mixed $data
283
	 * @return PayloadInterface
284
	 */
285
	public function removeActivities($id, $data) {
286
		// find
287
		$user = $this->get($id);
288
289
		if ($user === null) {
290
			return new NotFound(['message' => 'User not found.']);
291
		}
292
293
		// remove them
294
		$errors = [];
295
		foreach ($data as $entry) {
296
			if (!isset($entry['id'])) {
297
				$errors[] = 'Missing id for Activity';
298
			}
299
			$activity = ActivityQuery::create()->findOneById($entry['id']);
300
			$user->removeActivity($activity);
301
		}
302
303
		if (count($errors) > 0) {
304
			return new NotValid(['errors' => $errors]);
305
		}
306
307
		// save and dispatch events
308
		$event = new UserEvent($user);
309
		$dispatcher = $this->getServiceContainer()->getDispatcher();
310
		$dispatcher->dispatch(UserEvent::PRE_ACTIVITIES_REMOVE, $event);
311
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
312
		$rows = $user->save();
313
		$dispatcher->dispatch(UserEvent::POST_ACTIVITIES_REMOVE, $event);
314
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
315
316
		if ($rows > 0) {
317
			return Updated(['model' => $user]);
318
		}
319
320
		return NotUpdated(['model' => $user]);
321
	}
322
323
	/**
324
	 * Removes Groups from User
325
	 * 
326
	 * @param mixed $id
327
	 * @param mixed $data
328
	 * @return PayloadInterface
329
	 */
330
	public function removeGroups($id, $data) {
331
		// find
332
		$user = $this->get($id);
333
334
		if ($user === null) {
335
			return new NotFound(['message' => 'User not found.']);
336
		}
337
338
		// remove them
339
		$errors = [];
340
		foreach ($data as $entry) {
341
			if (!isset($entry['id'])) {
342
				$errors[] = 'Missing id for Group';
343
			}
344
			$group = GroupQuery::create()->findOneById($entry['id']);
345
			$user->removeGroup($group);
346
		}
347
348
		if (count($errors) > 0) {
349
			return new NotValid(['errors' => $errors]);
350
		}
351
352
		// save and dispatch events
353
		$event = new UserEvent($user);
354
		$dispatcher = $this->getServiceContainer()->getDispatcher();
355
		$dispatcher->dispatch(UserEvent::PRE_GROUPS_REMOVE, $event);
356
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
357
		$rows = $user->save();
358
		$dispatcher->dispatch(UserEvent::POST_GROUPS_REMOVE, $event);
359
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
360
361
		if ($rows > 0) {
362
			return Updated(['model' => $user]);
363
		}
364
365
		return NotUpdated(['model' => $user]);
366
	}
367
368
	/**
369
	 * Removes Sessions from User
370
	 * 
371
	 * @param mixed $id
372
	 * @param mixed $data
373
	 * @return PayloadInterface
374
	 */
375
	public function removeSessions($id, $data) {
376
		// find
377
		$user = $this->get($id);
378
379
		if ($user === null) {
380
			return new NotFound(['message' => 'User not found.']);
381
		}
382
383
		// remove them
384
		$errors = [];
385
		foreach ($data as $entry) {
386
			if (!isset($entry['id'])) {
387
				$errors[] = 'Missing id for Session';
388
			}
389
			$session = SessionQuery::create()->findOneById($entry['id']);
390
			$user->removeSession($session);
391
		}
392
393
		if (count($errors) > 0) {
394
			return new NotValid(['errors' => $errors]);
395
		}
396
397
		// save and dispatch events
398
		$event = new UserEvent($user);
399
		$dispatcher = $this->getServiceContainer()->getDispatcher();
400
		$dispatcher->dispatch(UserEvent::PRE_SESSIONS_REMOVE, $event);
401
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
402
		$rows = $user->save();
403
		$dispatcher->dispatch(UserEvent::POST_SESSIONS_REMOVE, $event);
404
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
405
406
		if ($rows > 0) {
407
			return Updated(['model' => $user]);
408
		}
409
410
		return NotUpdated(['model' => $user]);
411
	}
412
413
	/**
414
	 * Updates a User with the given idand the provided data
415
	 * 
416
	 * @param mixed $id
417
	 * @param mixed $data
418
	 * @return PayloadInterface
419
	 */
420
	public function update($id, $data) {
421
		// find
422
		$user = $this->get($id);
423
424
		if ($user === null) {
425
			return new NotFound(['message' => 'User not found.']);
426
		}
427
428
		// hydrate
429
		$serializer = User::getSerializer();
430
		$user = $serializer->hydrate($user, $data);
431
432
		// validate
433
		$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...
434
		if ($validator !== null && !$validator->validate($user)) {
435
			return new NotValid([
436
				'errors' => $validator->getValidationFailures()
437
			]);
438
		}
439
440
		// dispatch
441
		$event = new UserEvent($user);
442
		$dispatcher = $this->getServiceContainer()->getDispatcher();
443
		$dispatcher->dispatch(UserEvent::PRE_UPDATE, $event);
444
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
445
		$rows = $user->save();
446
		$dispatcher->dispatch(UserEvent::POST_UPDATE, $event);
447
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
448
449
		$payload = ['model' => $user];
450
451
		if ($rows === 0) {
452
			return new NotUpdated($payload);
453
		}
454
455
		return new Updated($payload);
456
	}
457
458
	/**
459
	 * Updates Activities on User
460
	 * 
461
	 * @param mixed $id
462
	 * @param mixed $data
463
	 * @return PayloadInterface
464
	 */
465
	public function updateActivities($id, $data) {
466
		// find
467
		$user = $this->get($id);
468
469
		if ($user === null) {
470
			return new NotFound(['message' => 'User not found.']);
471
		}
472
473
		// remove all relationships before
474
		ActivityQuery::create()->filterByActor($user)->delete();
475
476
		// add them
477
		$errors = [];
478
		foreach ($data as $entry) {
479
			if (!isset($entry['id'])) {
480
				$errors[] = 'Missing id for Activity';
481
			}
482
			$activity = ActivityQuery::create()->findOneById($entry['id']);
483
			$user->addActivity($activity);
484
		}
485
486
		if (count($errors) > 0) {
487
			return new NotValid(['errors' => $errors]);
488
		}
489
490
		// save and dispatch events
491
		$event = new UserEvent($user);
492
		$dispatcher = $this->getServiceContainer()->getDispatcher();
493
		$dispatcher->dispatch(UserEvent::PRE_ACTIVITIES_UPDATE, $event);
494
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
495
		$rows = $user->save();
496
		$dispatcher->dispatch(UserEvent::POST_ACTIVITIES_UPDATE, $event);
497
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
498
499
		if ($rows > 0) {
500
			return Updated(['model' => $user]);
501
		}
502
503
		return NotUpdated(['model' => $user]);
504
	}
505
506
	/**
507
	 * Updates Groups on User
508
	 * 
509
	 * @param mixed $id
510
	 * @param mixed $data
511
	 * @return PayloadInterface
512
	 */
513
	public function updateGroups($id, $data) {
514
		// find
515
		$user = $this->get($id);
516
517
		if ($user === null) {
518
			return new NotFound(['message' => 'User not found.']);
519
		}
520
521
		// remove all relationships before
522
		UserGroupQuery::create()->filterByUser($user)->delete();
523
524
		// add them
525
		$errors = [];
526
		foreach ($data as $entry) {
527
			if (!isset($entry['id'])) {
528
				$errors[] = 'Missing id for Group';
529
			}
530
			$group = GroupQuery::create()->findOneById($entry['id']);
531
			$user->addGroup($group);
532
		}
533
534
		if (count($errors) > 0) {
535
			return new NotValid(['errors' => $errors]);
536
		}
537
538
		// save and dispatch events
539
		$event = new UserEvent($user);
540
		$dispatcher = $this->getServiceContainer()->getDispatcher();
541
		$dispatcher->dispatch(UserEvent::PRE_GROUPS_UPDATE, $event);
542
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
543
		$rows = $user->save();
544
		$dispatcher->dispatch(UserEvent::POST_GROUPS_UPDATE, $event);
545
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
546
547
		if ($rows > 0) {
548
			return Updated(['model' => $user]);
549
		}
550
551
		return NotUpdated(['model' => $user]);
552
	}
553
554
	/**
555
	 * Updates Sessions on User
556
	 * 
557
	 * @param mixed $id
558
	 * @param mixed $data
559
	 * @return PayloadInterface
560
	 */
561
	public function updateSessions($id, $data) {
562
		// find
563
		$user = $this->get($id);
564
565
		if ($user === null) {
566
			return new NotFound(['message' => 'User not found.']);
567
		}
568
569
		// remove all relationships before
570
		SessionQuery::create()->filterByUser($user)->delete();
571
572
		// add them
573
		$errors = [];
574
		foreach ($data as $entry) {
575
			if (!isset($entry['id'])) {
576
				$errors[] = 'Missing id for Session';
577
			}
578
			$session = SessionQuery::create()->findOneById($entry['id']);
579
			$user->addSession($session);
580
		}
581
582
		if (count($errors) > 0) {
583
			return new NotValid(['errors' => $errors]);
584
		}
585
586
		// save and dispatch events
587
		$event = new UserEvent($user);
588
		$dispatcher = $this->getServiceContainer()->getDispatcher();
589
		$dispatcher->dispatch(UserEvent::PRE_SESSIONS_UPDATE, $event);
590
		$dispatcher->dispatch(UserEvent::PRE_SAVE, $event);
591
		$rows = $user->save();
592
		$dispatcher->dispatch(UserEvent::POST_SESSIONS_UPDATE, $event);
593
		$dispatcher->dispatch(UserEvent::POST_SAVE, $event);
594
595
		if ($rows > 0) {
596
			return Updated(['model' => $user]);
597
		}
598
599
		return NotUpdated(['model' => $user]);
600
	}
601
602
	/**
603
	 * Implement this functionality at keeko\core\domain\UserDomain
604
	 * 
605
	 * @param UserQuery $query
606
	 * @param mixed $filter
607
	 * @return void
608
	 */
609
	abstract protected function applyFilter(UserQuery $query, $filter);
610
611
	/**
612
	 * Returns one User with the given id from cache
613
	 * 
614
	 * @param mixed $id
615
	 * @return User|null
616
	 */
617
	protected function get($id) {
618
		if ($this->pool === null) {
619
			$this->pool = new Map();
620
		} else if ($this->pool->has($id)) {
621
			return $this->pool->get($id);
622
		}
623
624
		$user = UserQuery::create()->findOneById($id);
625
		$this->pool->set($id, $user);
626
627
		return $user;
628
	}
629
630
	/**
631
	 * Returns the service container
632
	 * 
633
	 * @return ServiceContainer
634
	 */
635
	abstract protected function getServiceContainer();
636
}
637