Completed
Push — master ( 1a1676...f7e1a1 )
by Thomas
04:58
created

ExtensionDomainTrait::create()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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