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

ActivityObjectDomainTrait::removeActivities()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 37
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 37
rs 8.439
cc 6
eloc 22
nc 10
nop 2
1
<?php
2
namespace keeko\core\domain\base;
3
4
use keeko\core\model\ActivityObject;
5
use keeko\core\model\ActivityObjectQuery;
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\ActivityObjectEvent;
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\ActivityQuery;
21
22
/**
23
 */
24
trait ActivityObjectDomainTrait {
25
26
	/**
27
	 */
28
	protected $pool;
29
30
	/**
31
	 * Adds Activities to ActivityObject
32
	 * 
33
	 * @param mixed $id
34
	 * @param mixed $data
35
	 * @return PayloadInterface
36
	 */
37
	public function addActivities($id, $data) {
38
		// find
39
		$activityObject = $this->get($id);
40
41
		if ($activityObject === null) {
42
			return new NotFound(['message' => 'ActivityObject not found.']);
43
		}
44
		 
45
		// update
46
		$errors = [];
47
		foreach ($data as $entry) {
48
			if (!isset($entry['id'])) {
49
				$errors[] = 'Missing id for Activity';
50
			}
51
			$activity = ActivityQuery::create()->findOneById($entry['id']);
52
			$activityObject->addActivity($activity);
53
		}
54
55
		if (count($errors) > 0) {
56
			return new NotValid(['errors' => $errors]);
57
		}
58
59
		// save and dispatch events
60
		$event = new ActivityObjectEvent($activityObject);
61
		$dispatcher = $this->getServiceContainer()->getDispatcher();
62
		$dispatcher->dispatch(ActivityObjectEvent::PRE_ACTIVITIES_ADD, $event);
63
		$dispatcher->dispatch(ActivityObjectEvent::PRE_SAVE, $event);
64
		$rows = $activityObject->save();
65
		$dispatcher->dispatch(ActivityObjectEvent::POST_ACTIVITIES_ADD, $event);
66
		$dispatcher->dispatch(ActivityObjectEvent::POST_SAVE, $event);
67
68
		if ($rows > 0) {
69
			return Updated(['model' => $activityObject]);
70
		}
71
72
		return NotUpdated(['model' => $activityObject]);
73
	}
74
75
	/**
76
	 * Creates a new ActivityObject with the provided data
77
	 * 
78
	 * @param mixed $data
79
	 * @return PayloadInterface
80
	 */
81
	public function create($data) {
82
		// hydrate
83
		$serializer = ActivityObject::getSerializer();
84
		$activityObject = $serializer->hydrate(new ActivityObject(), $data);
85
86
		// validate
87
		$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...
88
		if ($validator !== null && !$validator->validate($activityObject)) {
89
			return new NotValid([
90
				'errors' => $validator->getValidationFailures()
91
			]);
92
		}
93
94
		// dispatch
95
		$event = new ActivityObjectEvent($activityObject);
96
		$dispatcher = $this->getServiceContainer()->getDispatcher();
97
		$dispatcher->dispatch(ActivityObjectEvent::PRE_CREATE, $event);
98
		$dispatcher->dispatch(ActivityObjectEvent::PRE_SAVE, $event);
99
		$activityObject->save();
100
		$dispatcher->dispatch(ActivityObjectEvent::POST_CREATE, $event);
101
		$dispatcher->dispatch(ActivityObjectEvent::POST_SAVE, $event);
102
		return new Created(['model' => $activityObject]);
103
	}
104
105
	/**
106
	 * Deletes a ActivityObject with the given id
107
	 * 
108
	 * @param mixed $id
109
	 * @return PayloadInterface
110
	 */
111
	public function delete($id) {
112
		// find
113
		$activityObject = $this->get($id);
114
115
		if ($activityObject === null) {
116
			return new NotFound(['message' => 'ActivityObject not found.']);
117
		}
118
119
		// delete
120
		$event = new ActivityObjectEvent($activityObject);
121
		$dispatcher = $this->getServiceContainer()->getDispatcher();
122
		$dispatcher->dispatch(ActivityObjectEvent::PRE_DELETE, $event);
123
		$activityObject->delete();
124
125
		if ($activityObject->isDeleted()) {
126
			$dispatcher->dispatch(ActivityObjectEvent::POST_DELETE, $event);
127
			return new Deleted(['model' => $activityObject]);
128
		}
129
130
		return new NotDeleted(['message' => 'Could not delete ActivityObject']);
131
	}
132
133
	/**
134
	 * Returns a paginated result
135
	 * 
136
	 * @param Parameters $params
137
	 * @return PayloadInterface
138
	 */
139
	public function paginate(Parameters $params) {
140
		$sysPrefs = $this->getServiceContainer()->getPreferenceLoader()->getSystemPreferences();
141
		$defaultSize = $sysPrefs->getPaginationSize();
142
		$page = $params->getPage('number');
143
		$size = $params->getPage('size', $defaultSize);
144
145
		$query = ActivityObjectQuery::create();
146
147
		// sorting
148
		$sort = $params->getSort(ActivityObject::getSerializer()->getSortFields());
149
		foreach ($sort as $field => $order) {
150
			$method = 'orderBy' . NameUtils::toStudlyCase($field);
151
			$query->$method($order);
152
		}
153
154
		// filtering
155
		$filter = $params->getFilter();
156
		if (!empty($filter)) {
157
			$this->applyFilter($query, $filter);
158
		}
159
160
		// paginate
161
		$activityObject = $query->paginate($page, $size);
162
163
		// run response
164
		return new Found(['model' => $activityObject]);
165
	}
166
167
	/**
168
	 * Returns one ActivityObject with the given id
169
	 * 
170
	 * @param mixed $id
171
	 * @return PayloadInterface
172
	 */
173
	public function read($id) {
174
		// read
175
		$activityObject = $this->get($id);
176
177
		// check existence
178
		if ($activityObject === null) {
179
			return new NotFound(['message' => 'ActivityObject not found.']);
180
		}
181
182
		return new Found(['model' => $activityObject]);
183
	}
184
185
	/**
186
	 * Removes Activities from ActivityObject
187
	 * 
188
	 * @param mixed $id
189
	 * @param mixed $data
190
	 * @return PayloadInterface
191
	 */
192
	public function removeActivities($id, $data) {
193
		// find
194
		$activityObject = $this->get($id);
195
196
		if ($activityObject === null) {
197
			return new NotFound(['message' => 'ActivityObject not found.']);
198
		}
199
200
		// remove them
201
		$errors = [];
202
		foreach ($data as $entry) {
203
			if (!isset($entry['id'])) {
204
				$errors[] = 'Missing id for Activity';
205
			}
206
			$activity = ActivityQuery::create()->findOneById($entry['id']);
207
			$activityObject->removeActivity($activity);
208
		}
209
210
		if (count($errors) > 0) {
211
			return new NotValid(['errors' => $errors]);
212
		}
213
214
		// save and dispatch events
215
		$event = new ActivityObjectEvent($activityObject);
216
		$dispatcher = $this->getServiceContainer()->getDispatcher();
217
		$dispatcher->dispatch(ActivityObjectEvent::PRE_ACTIVITIES_REMOVE, $event);
218
		$dispatcher->dispatch(ActivityObjectEvent::PRE_SAVE, $event);
219
		$rows = $activityObject->save();
220
		$dispatcher->dispatch(ActivityObjectEvent::POST_ACTIVITIES_REMOVE, $event);
221
		$dispatcher->dispatch(ActivityObjectEvent::POST_SAVE, $event);
222
223
		if ($rows > 0) {
224
			return Updated(['model' => $activityObject]);
225
		}
226
227
		return NotUpdated(['model' => $activityObject]);
228
	}
229
230
	/**
231
	 * Updates a ActivityObject with the given idand the provided data
232
	 * 
233
	 * @param mixed $id
234
	 * @param mixed $data
235
	 * @return PayloadInterface
236
	 */
237
	public function update($id, $data) {
238
		// find
239
		$activityObject = $this->get($id);
240
241
		if ($activityObject === null) {
242
			return new NotFound(['message' => 'ActivityObject not found.']);
243
		}
244
245
		// hydrate
246
		$serializer = ActivityObject::getSerializer();
247
		$activityObject = $serializer->hydrate($activityObject, $data);
248
249
		// validate
250
		$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...
251
		if ($validator !== null && !$validator->validate($activityObject)) {
252
			return new NotValid([
253
				'errors' => $validator->getValidationFailures()
254
			]);
255
		}
256
257
		// dispatch
258
		$event = new ActivityObjectEvent($activityObject);
259
		$dispatcher = $this->getServiceContainer()->getDispatcher();
260
		$dispatcher->dispatch(ActivityObjectEvent::PRE_UPDATE, $event);
261
		$dispatcher->dispatch(ActivityObjectEvent::PRE_SAVE, $event);
262
		$rows = $activityObject->save();
263
		$dispatcher->dispatch(ActivityObjectEvent::POST_UPDATE, $event);
264
		$dispatcher->dispatch(ActivityObjectEvent::POST_SAVE, $event);
265
266
		$payload = ['model' => $activityObject];
267
268
		if ($rows === 0) {
269
			return new NotUpdated($payload);
270
		}
271
272
		return new Updated($payload);
273
	}
274
275
	/**
276
	 * Updates Activities on ActivityObject
277
	 * 
278
	 * @param mixed $id
279
	 * @param mixed $data
280
	 * @return PayloadInterface
281
	 */
282
	public function updateActivities($id, $data) {
283
		// find
284
		$activityObject = $this->get($id);
285
286
		if ($activityObject === null) {
287
			return new NotFound(['message' => 'ActivityObject not found.']);
288
		}
289
290
		// remove all relationships before
291
		ActivityQuery::create()->filterByTarget($activityObject)->delete();
292
293
		// add 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
			$activityObject->addActivity($activity);
301
		}
302
303
		if (count($errors) > 0) {
304
			return new NotValid(['errors' => $errors]);
305
		}
306
307
		// save and dispatch events
308
		$event = new ActivityObjectEvent($activityObject);
309
		$dispatcher = $this->getServiceContainer()->getDispatcher();
310
		$dispatcher->dispatch(ActivityObjectEvent::PRE_ACTIVITIES_UPDATE, $event);
311
		$dispatcher->dispatch(ActivityObjectEvent::PRE_SAVE, $event);
312
		$rows = $activityObject->save();
313
		$dispatcher->dispatch(ActivityObjectEvent::POST_ACTIVITIES_UPDATE, $event);
314
		$dispatcher->dispatch(ActivityObjectEvent::POST_SAVE, $event);
315
316
		if ($rows > 0) {
317
			return Updated(['model' => $activityObject]);
318
		}
319
320
		return NotUpdated(['model' => $activityObject]);
321
	}
322
323
	/**
324
	 * Implement this functionality at keeko\core\domain\ActivityObjectDomain
325
	 * 
326
	 * @param ActivityObjectQuery $query
327
	 * @param mixed $filter
328
	 * @return void
329
	 */
330
	abstract protected function applyFilter(ActivityObjectQuery $query, $filter);
331
332
	/**
333
	 * Returns one ActivityObject with the given id from cache
334
	 * 
335
	 * @param mixed $id
336
	 * @return ActivityObject|null
337
	 */
338
	protected function get($id) {
339
		if ($this->pool === null) {
340
			$this->pool = new Map();
341
		} else if ($this->pool->has($id)) {
342
			return $this->pool->get($id);
343
		}
344
345
		$activityObject = ActivityObjectQuery::create()->findOneById($id);
346
		$this->pool->set($id, $activityObject);
347
348
		return $activityObject;
349
	}
350
351
	/**
352
	 * Returns the service container
353
	 * 
354
	 * @return ServiceContainer
355
	 */
356
	abstract protected function getServiceContainer();
357
}
358