Completed
Push — master ( e8b3d2...889b57 )
by Thomas
14:29
created

PreferenceDomainTrait::dispatch()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 23
rs 9.0856
cc 3
eloc 17
nc 3
nop 2
1
<?php
2
namespace keeko\core\domain\base;
3
4
use keeko\core\event\PreferenceEvent;
5
use keeko\core\model\PreferenceQuery;
6
use keeko\core\model\Preference;
7
use keeko\framework\domain\payload\Created;
8
use keeko\framework\domain\payload\Deleted;
9
use keeko\framework\domain\payload\Found;
10
use keeko\framework\domain\payload\NotDeleted;
11
use keeko\framework\domain\payload\NotFound;
12
use keeko\framework\domain\payload\NotUpdated;
13
use keeko\framework\domain\payload\NotValid;
14
use keeko\framework\domain\payload\PayloadInterface;
15
use keeko\framework\domain\payload\Updated;
16
use keeko\framework\service\ServiceContainer;
17
use keeko\framework\utils\NameUtils;
18
use keeko\framework\utils\Parameters;
19
use phootwork\collection\Map;
20
21
/**
22
 */
23
trait PreferenceDomainTrait {
24
25
	/**
26
	 */
27
	protected $pool;
28
29
	/**
30
	 * Creates a new Preference with the provided data
31
	 * 
32
	 * @param mixed $data
33
	 * @return PayloadInterface
34
	 */
35
	public function create($data) {
36
		// hydrate
37
		$serializer = Preference::getSerializer();
38
		$model = $serializer->hydrate(new Preference(), $data);
39
		$this->hydrateRelationships($model, $data);
0 ignored issues
show
Bug introduced by
It seems like hydrateRelationships() 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...
40
41
		// validate
42
		$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...
43
		if ($validator !== null && !$validator->validate($model)) {
44
			return new NotValid([
45
				'errors' => $validator->getValidationFailures()
46
			]);
47
		}
48
49
		// dispatch
50
		$event = new PreferenceEvent($model);
51
		$this->dispatch(PreferenceEvent::PRE_CREATE, $event);
52
		$this->dispatch(PreferenceEvent::PRE_SAVE, $event);
53
		$model->save();
54
		$this->dispatch(PreferenceEvent::POST_CREATE, $event);
55
		$this->dispatch(PreferenceEvent::POST_SAVE, $event);
56
		return new Created(['model' => $model]);
57
	}
58
59
	/**
60
	 * Deletes a Preference with the given id
61
	 * 
62
	 * @param mixed $id
63
	 * @return PayloadInterface
64
	 */
65
	public function delete($id) {
66
		// find
67
		$model = $this->get($id);
68
69
		if ($model === null) {
70
			return new NotFound(['message' => 'Preference not found.']);
71
		}
72
73
		// delete
74
		$event = new PreferenceEvent($model);
75
		$this->dispatch(PreferenceEvent::PRE_DELETE, $event);
76
		$model->delete();
77
78
		if ($model->isDeleted()) {
79
			$this->dispatch(PreferenceEvent::POST_DELETE, $event);
80
			return new Deleted(['model' => $model]);
81
		}
82
83
		return new NotDeleted(['message' => 'Could not delete Preference']);
84
	}
85
86
	/**
87
	 * Returns a paginated result
88
	 * 
89
	 * @param Parameters $params
90
	 * @return PayloadInterface
91
	 */
92
	public function paginate(Parameters $params) {
93
		$sysPrefs = $this->getServiceContainer()->getPreferenceLoader()->getSystemPreferences();
94
		$defaultSize = $sysPrefs->getPaginationSize();
95
		$page = $params->getPage('number');
96
		$size = $params->getPage('size', $defaultSize);
97
98
		$query = PreferenceQuery::create();
99
100
		// sorting
101
		$sort = $params->getSort(Preference::getSerializer()->getSortFields());
102
		foreach ($sort as $field => $order) {
103
			$method = 'orderBy' . NameUtils::toStudlyCase($field);
104
			$query->$method($order);
105
		}
106
107
		// filtering
108
		$filter = $params->getFilter();
109
		if (!empty($filter)) {
110
			$this->applyFilter($query, $filter);
111
		}
112
113
		// paginate
114
		$model = $query->paginate($page, $size);
115
116
		// run response
117
		return new Found(['model' => $model]);
118
	}
119
120
	/**
121
	 * Returns one Preference with the given id
122
	 * 
123
	 * @param mixed $id
124
	 * @return PayloadInterface
125
	 */
126
	public function read($id) {
127
		// read
128
		$model = $this->get($id);
129
130
		// check existence
131
		if ($model === null) {
132
			return new NotFound(['message' => 'Preference not found.']);
133
		}
134
135
		return new Found(['model' => $model]);
136
	}
137
138
	/**
139
	 * Updates a Preference with the given idand the provided data
140
	 * 
141
	 * @param mixed $id
142
	 * @param mixed $data
143
	 * @return PayloadInterface
144
	 */
145
	public function update($id, $data) {
146
		// find
147
		$model = $this->get($id);
148
149
		if ($model === null) {
150
			return new NotFound(['message' => 'Preference not found.']);
151
		}
152
153
		// hydrate
154
		$serializer = Preference::getSerializer();
155
		$model = $serializer->hydrate($model, $data);
156
		$this->hydrateRelationships($model, $data);
0 ignored issues
show
Bug introduced by
It seems like hydrateRelationships() 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...
157
158
		// validate
159
		$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...
160
		if ($validator !== null && !$validator->validate($model)) {
161
			return new NotValid([
162
				'errors' => $validator->getValidationFailures()
163
			]);
164
		}
165
166
		// dispatch
167
		$event = new PreferenceEvent($model);
168
		$this->dispatch(PreferenceEvent::PRE_UPDATE, $event);
169
		$this->dispatch(PreferenceEvent::PRE_SAVE, $event);
170
		$rows = $model->save();
171
		$this->dispatch(PreferenceEvent::POST_UPDATE, $event);
172
		$this->dispatch(PreferenceEvent::POST_SAVE, $event);
173
174
		$payload = ['model' => $model];
175
176
		if ($rows === 0) {
177
			return new NotUpdated($payload);
178
		}
179
180
		return new Updated($payload);
181
	}
182
183
	/**
184
	 * @param mixed $query
185
	 * @param mixed $filter
186
	 * @return void
187
	 */
188
	protected function applyFilter($query, $filter) {
189
		foreach ($filter as $column => $value) {
190
			$pos = strpos($column, '.');
191
			if ($pos !== false) {
192
				$rel = NameUtils::toStudlyCase(substr($column, 0, $pos));
193
				$col = substr($column, $pos + 1);
194
				$method = 'use' . $rel . 'Query';
195
				if (method_exists($query, $method)) {
196
					$sub = $query->$method();
197
					$this->applyFilter($sub, [$col => $value]);
198
					$sub->endUse();
199
				}
200
			} else {
201
				$method = 'filterBy' . NameUtils::toStudlyCase($column);
202
				if (method_exists($query, $method)) {
203
					$query->$method($value);
204
				}
205
			}
206
		}
207
	}
208
209
	/**
210
	 * @param string $type
211
	 * @param PreferenceEvent $event
212
	 */
213
	protected function dispatch($type, PreferenceEvent $event) {
214
		$model = $event->getPreference();
215
		$methods = [
216
			PreferenceEvent::PRE_CREATE => 'preCreate',
217
			PreferenceEvent::POST_CREATE => 'postCreate',
218
			PreferenceEvent::PRE_UPDATE => 'preUpdate',
219
			PreferenceEvent::POST_UPDATE => 'postUpdate',
220
			PreferenceEvent::PRE_DELETE => 'preDelete',
221
			PreferenceEvent::POST_DELETE => 'postDelete',
222
			PreferenceEvent::PRE_SAVE => 'preSave',
223
			PreferenceEvent::POST_SAVE => 'postSave'
224
		];
225
226
		if (isset($methods[$type])) {
227
			$method = $methods[$type];
228
			if (method_exists($this, $method)) {
229
				$this->$method($model);
230
			}
231
		}
232
233
		$dispatcher = $this->getServiceContainer()->getDispatcher();
234
		$dispatcher->dispatch($type, $event);
235
	}
236
237
	/**
238
	 * Returns one Preference with the given id from cache
239
	 * 
240
	 * @param mixed $id
241
	 * @return Preference|null
242
	 */
243
	protected function get($id) {
244
		if ($this->pool === null) {
245
			$this->pool = new Map();
246
		} else if ($this->pool->has($id)) {
247
			return $this->pool->get($id);
248
		}
249
250
		$model = PreferenceQuery::create()->findOneById($id);
251
		$this->pool->set($id, $model);
252
253
		return $model;
254
	}
255
256
	/**
257
	 * Returns the service container
258
	 * 
259
	 * @return ServiceContainer
260
	 */
261
	abstract protected function getServiceContainer();
262
}
263