Completed
Push — master ( 061e94...8714ce )
by Thomas
06:16
created

GroupDomainTrait::addUser()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 30
rs 8.439
cc 6
eloc 16
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 Tobscure\JsonApi\Parameters;
12
use keeko\framework\utils\NameUtils;
13
use keeko\framework\domain\payload\Created;
14
use keeko\framework\domain\payload\Updated;
15
use keeko\framework\domain\payload\NotUpdated;
16
use keeko\framework\domain\payload\NotValid;
17
use keeko\framework\domain\payload\Deleted;
18
use keeko\framework\domain\payload\NotDeleted;
19
use keeko\core\model\UserQuery;
20
use keeko\core\model\UserGroupQuery;
21
22
/**
23
 */
24
trait GroupDomainTrait {
25
26
	/**
27
	 * Adds User to Group
28
	 * 
29
	 * @param mixed $id
30
	 * @param mixed $data
31
	 * @return PayloadInterface
32
	 */
33
	public function addUser($id, $data) {
34
		// find
35
		$group = $this->get($id);
36
37
		if ($group === null) {
38
			return new NotFound(['message' => 'Group not found.']);
39
		}
40
		 
41
		// update
42
		$errors = [];
43
		foreach ($data as $entry) {
44
			if (!isset($entry['id'])) {
45
				$errors[] = 'Missing id for User';
46
			}
47
			$user = UserQuery::create()->findOneById($entry['id']);
48
			$group->addUser($user);
49
		}
50
51
		if (count($errors) > 0) {
52
			return new NotValid(['errors' => $errors]);
53
		}
54
55
		$rows = $group->save();
56
57
		if ($rows > 0) {
58
			return Updated(['model' => $group]);
59
		}
60
61
		return NotUpdated(['model' => $group]);
62
	}
63
64
	/**
65
	 * Creates a new Group with the provided data
66
	 * 
67
	 * @param mixed $data
68
	 * @return PayloadInterface
69
	 */
70
	public function create($data) {
71
		// hydrate
72
		$serializer = Group::getSerializer();
73
		$group = $serializer->hydrate(new Group(), $data);
74
75
		// validate
76
		if (!$group->validate()) {
77
			return new NotValid([
78
				'errors' => $group->getValidationFailures()
79
			]);
80
		}
81
82
		$group->save();
83
		return new Created(['model' => $group]);
84
	}
85
86
	/**
87
	 * Deletes a Group with the given id
88
	 * 
89
	 * @param mixed $id
90
	 * @return PayloadInterface
91
	 */
92
	public function delete($id) {
93
		// find
94
		$group = $this->get($id);
95
96
		if ($group === null) {
97
			return new NotFound(['message' => 'Group not found.']);
98
		}
99
100
		// delete
101
		$group->delete();
102
103
		if ($group->isDeleted()) {
104
			return new Deleted(['model' => $group]);
105
		}
106
107
		return new NotDeleted(['message' => 'Could not delete Group']);
108
	}
109
110
	/**
111
	 * Returns a paginated result
112
	 * 
113
	 * @param Parameters $params
114
	 * @return PayloadInterface
115
	 */
116
	public function paginate(Parameters $params) {
117
		$sysPrefs = $this->getServiceContainer()->getPreferenceLoader()->getSystemPreferences();
118
		$defaultSize = $sysPrefs->getPaginationSize();
119
		$page = $params->getPage('number');
0 ignored issues
show
Bug introduced by
The method getPage() cannot be called from this context as it is declared protected in class Tobscure\JsonApi\Parameters.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
120
		$size = $params->getPage('size', $defaultSize);
0 ignored issues
show
Bug introduced by
The method getPage() cannot be called from this context as it is declared protected in class Tobscure\JsonApi\Parameters.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
Unused Code introduced by
The call to Parameters::getPage() has too many arguments starting with $defaultSize.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
121
122
		$query = GroupQuery::create();
123
124
		// sorting
125
		$sort = $params->getSort(Group::getSerializer()->getSortFields());
126
		foreach ($sort as $field => $order) {
127
			$method = 'orderBy' . NameUtils::toStudlyCase($field);
128
			$query->$method($order);
129
		}
130
131
		// filtering
132
		$filter = $params->getFilter();
133
		if (!empty($filter)) {
134
			$this->applyFilter($query, $filter);
135
		}
136
137
		// paginate
138
		$group = $query->paginate($page, $size);
139
140
		// run response
141
		return new Found(['model' => $group]);
142
	}
143
144
	/**
145
	 * Returns one Group with the given id
146
	 * 
147
	 * @param mixed $id
148
	 * @return PayloadInterface
149
	 */
150
	public function read($id) {
151
		// read
152
		$group = $this->get($id);
153
154
		// check existence
155
		if ($group === null) {
156
			return new NotFound(['message' => 'Group not found.']);
157
		}
158
159
		return new Found(['model' => $group]);
160
	}
161
162
	/**
163
	 * Removes User from Group
164
	 * 
165
	 * @param mixed $id
166
	 * @param mixed $data
167
	 * @return PayloadInterface
168
	 */
169
	public function removeUser($id, $data) {
170
		// find
171
		$group = $this->get($id);
172
173
		if ($group === null) {
174
			return new NotFound(['message' => 'Group not found.']);
175
		}
176
177
		// remove them
178
		$errors = [];
179
		foreach ($data as $entry) {
180
			if (!isset($entry['id'])) {
181
				$errors[] = 'Missing id for User';
182
			}
183
			$user = UserQuery::create()->findOneById($entry['id']);
184
			$group->removeUser($user);
185
		}
186
187
		if (count($errors) > 0) {
188
			return new NotValid(['errors' => $errors]);
189
		}
190
191
		$rows = $group->save();
192
193
		if ($rows > 0) {
194
			return Updated(['model' => $group]);
195
		}
196
197
		return NotUpdated(['model' => $group]);
198
	}
199
200
	/**
201
	 * Updates a Group with the given idand the provided data
202
	 * 
203
	 * @param mixed $id
204
	 * @param mixed $data
205
	 * @return PayloadInterface
206
	 */
207
	public function update($id, $data) {
208
		// find
209
		$group = $this->get($id);
210
211
		if ($group === null) {
212
			return new NotFound(['message' => 'Group not found.']);
213
		}
214
215
		// hydrate
216
		$serializer = Group::getSerializer();
217
		$group = $serializer->hydrate($group, $data);
218
219
		// validate
220
		if (!$group->validate()) {
221
			return new NotValid([
222
				'errors' => $group->getValidationFailures()
223
			]);
224
		}
225
226
		$rows = $group->save();
227
		$payload = ['model' => $group];
228
229
		if ($rows === 0) {
230
			return new NotUpdated($payload);
231
		}
232
233
		return new Updated($payload);
234
	}
235
236
	/**
237
	 * Updates User on Group
238
	 * 
239
	 * @param mixed $id
240
	 * @param mixed $data
241
	 * @return PayloadInterface
242
	 */
243
	public function updateUser($id, $data) {
244
		// find
245
		$group = $this->get($id);
246
247
		if ($group === null) {
248
			return new NotFound(['message' => 'Group not found.']);
249
		}
250
251
		// remove all relationships before
252
		UserGroupQuery::create()->filterByGroup($group)->delete();
253
254
		// add them
255
		$errors = [];
256
		foreach ($data as $entry) {
257
			if (!isset($entry['id'])) {
258
				$errors[] = 'Missing id for User';
259
			}
260
			$user = UserQuery::create()->findOneById($entry['id']);
261
			$group->addUser($user);
262
		}
263
264
		if (count($errors) > 0) {
265
			return new NotValid(['errors' => $errors]);
266
		}
267
268
		$rows = $group->save();
269
270
		if ($rows > 0) {
271
			return Updated(['model' => $group]);
272
		}
273
274
		return NotUpdated(['model' => $group]);
275
	}
276
277
	/**
278
	 * Implement this functionality at keeko\core\domain\GroupDomain
279
	 * 
280
	 * @param GroupQuery $query
281
	 * @param mixed $filter
282
	 */
283
	abstract protected function applyFilter(GroupQuery $query, $filter);
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
284
285
	/**
286
	 * Returns one Group with the given id from cache
287
	 * 
288
	 * @param mixed $id
289
	 * @return Group|null
290
	 */
291
	protected function get($id) {
292
		if ($this->pool === null) {
293
			$this->pool = new Map();
0 ignored issues
show
Bug introduced by
The property pool does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
294
		} else if ($this->pool->has($id)) {
295
			return $this->pool->get($id);
296
		}
297
298
		$group = GroupQuery::create()->findOneById($id);
299
		$this->pool->set($id, $group);
300
301
		return $group;
302
	}
303
304
	/**
305
	 * Returns the service container
306
	 * 
307
	 * @return ServiceContainer
308
	 */
309
	abstract protected function getServiceContainer();
310
}
311