Passed
Push — master ( 7edc99...3ae628 )
by Jean-Christophe
06:53
created

RestControllerUtilitiesTrait   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 217
Duplicated Lines 0 %

Test Coverage

Coverage 32.42%

Importance

Changes 0
Metric Value
wmc 44
eloc 90
dl 0
loc 217
ccs 36
cts 111
cp 0.3242
rs 8.8798
c 0
b 0
f 0

21 Methods

Rating   Name   Duplication   Size   Complexity  
A getDatas() 0 2 1
A getResponseFormatter() 0 2 1
A connectDb() 0 4 2
A AddOperation() 0 2 1
A getRequestParam() 0 5 2
A operate_() 0 14 4
A _getRestServer() 0 5 2
A updateOperation() 0 2 1
A getRestServer() 0 2 1
A _getResponseFormatter() 0 5 2
A generatePagination() 0 13 3
A addViolation() 0 2 1
A getAssociatedMemberValues_() 0 8 2
A hasErrors() 0 2 2
A displayErrors() 0 15 4
A getInclude() 0 5 2
A _validateInstance() 0 13 4
A getPrimaryKeysFromDatas() 0 11 3
A addError() 0 2 1
A _setValuesToObject() 0 7 3
A getCondition() 0 6 2

How to fix   Complexity   

Complex Class

Complex classes like RestControllerUtilitiesTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use RestControllerUtilitiesTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ubiquity\controllers\rest;
4
5
use Ubiquity\orm\DAO;
6
use Ubiquity\utils\base\UString;
7
use Ubiquity\utils\http\URequest;
8
use Ubiquity\contents\validation\ValidatorsManager;
9
use Ubiquity\contents\validation\validators\ConstraintViolation;
10
use Ubiquity\orm\OrmUtils;
11
12
/**
13
 * Rest controller internal utilities.
14
 * Ubiquity\controllers\rest$RestControllerUtilitiesTrait
15
 * This class is part of Ubiquity
16
 *
17
 * @author jcheron <[email protected]>
18
 * @version 1.0.4
19
 * @property ResponseFormatter $responseFormatter
20
 * @property RestServer $server
21
 * @property string $model
22
 *
23
 */
24
trait RestControllerUtilitiesTrait {
25
	protected $errors;
26
27
	abstract public function _setResponseCode($value);
28
29
	protected function getDatas() {
30
		return URequest::getDatas ();
31
	}
32
33
	/**
34
	 *
35
	 * @param string $param
36
	 * @param string|boolean $default
37
	 * @return string|boolean
38
	 */
39 4
	protected function getRequestParam($param, $default) {
40 4
		if (isset ( $_GET [$param] )) {
41
			return $_GET [$param];
42
		}
43 4
		return $default;
44
	}
45
46
	protected function operate_($instance, $callback, $status, $exceptionMessage, $keyValues) {
47
		if (isset ( $instance )) {
48
			$result = $callback ( $instance );
49
			if ($result == true) {
50
				$formatter = $this->_getResponseFormatter ();
51
				echo $formatter->format ( [ "status" => $status,"data" => $formatter->cleanRestObject ( $instance ) ] );
52
			} elseif ($result === null) {
53
				$this->displayErrors ();
54
			} else {
55
				throw new \Exception ( $exceptionMessage );
56
			}
57
		} else {
58
			$this->_setResponseCode ( 404 );
59
			echo $this->_getResponseFormatter ()->format ( [ "message" => "No result found","keyValues" => $keyValues ] );
60
		}
61
	}
62
63
	protected function generatePagination(&$filter, $pageNumber, $pageSize) {
64
		$count = DAO::count ( $this->model, $filter );
65
		$pagesCount = ceil ( $count / $pageSize );
66
		$pages = [ 'self' => $pageNumber,'first' => 1,'last' => $pagesCount,'pageSize' => $pageSize ];
67
		if ($pageNumber - 1 > 0) {
68
			$pages ['prev'] = $pageNumber - 1;
69
		}
70
		if ($pageNumber + 1 <= $pagesCount) {
71
			$pages ['next'] = $pageNumber + 1;
72
		}
73
		$offset = ($pageNumber - 1) * $pageSize;
74
		$filter .= ' limit ' . $offset . ',' . $pageSize;
75
		return $pages;
76
	}
77
78
	protected function updateOperation($instance, $datas, $updateMany = false) {
79
		return DAO::update ( $instance, $updateMany );
80
	}
81
82
	protected function AddOperation($instance, $datas, $insertMany = false) {
83
		return DAO::insert ( $instance, $insertMany );
84
	}
85
86
	/**
87
	 *
88
	 * @return \Ubiquity\controllers\rest\ResponseFormatter
89
	 */
90 14
	protected function _getResponseFormatter() {
91 14
		if (! isset ( $this->responseFormatter )) {
92 14
			$this->responseFormatter = $this->getResponseFormatter ();
93
		}
94 14
		return $this->responseFormatter;
95
	}
96
97
	/**
98
	 * To override, returns the active formatter for the response
99
	 *
100
	 * @return \Ubiquity\controllers\rest\ResponseFormatter
101
	 */
102 8
	protected function getResponseFormatter(): ResponseFormatter {
103 8
		return new ResponseFormatter ();
104
	}
105
106 14
	protected function _getRestServer() {
107 14
		if (! isset ( $this->server )) {
108 14
			$this->server = $this->getRestServer ();
109
		}
110 14
		return $this->server;
111
	}
112
113
	/**
114
	 * To override, returns the active RestServer
115
	 *
116
	 * @return \Ubiquity\controllers\rest\RestServer
117
	 */
118 8
	protected function getRestServer(): RestServer {
119 8
		return new RestServer ( $this->config );
120
	}
121
122 7
	protected function connectDb($config) {
123 7
		$db = $config ["database"];
124 7
		if ($db ["dbName"] !== "") {
125 7
			DAO::connect ( $db ["type"], $db ["dbName"], $db ["serverName"] ?? '127.0.0.1', $db ["port"] ?? 3306, $db ["user"] ?? 'root', $db ["password"] ?? '', $db ["options"] ?? [ ], $db ["cache"] ?? false);
126
		}
127 7
	}
128
129
	/**
130
	 * Updates $instance with $values
131
	 * To eventually be redefined in derived classes
132
	 *
133
	 * @param object $instance the instance to update
134
	 * @param array|null $values
135
	 */
136
	protected function _setValuesToObject($instance, $values = null) {
137
		if (URequest::isJSON ()) {
138
			if(is_string($values)){
139
				$values = \json_decode ( $values, true );
140
			}
141
		}
142
		URequest::setValuesToObject ( $instance, $values );
143
	}
144
145
	/**
146
	 *
147
	 * @param string|boolean $include
148
	 * @return array|boolean
149
	 */
150 6
	protected function getInclude($include) {
151 6
		if (! UString::isBooleanStr ( $include )) {
152
			return explode ( ",", $include );
153
		}
154 6
		return UString::isBooleanTrue ( $include );
155
	}
156
157
	protected function addError($code, $title, $detail = null, $source = null, $status = null) {
158
		$this->errors [] = new RestError ( $code, $title, $detail, $source, $status );
159
	}
160
161
	protected function hasErrors() {
162
		return is_array ( $this->errors ) && sizeof ( $this->errors ) > 0;
163
	}
164
165
	protected function displayErrors() {
166
		if ($this->hasErrors ()) {
167
			$status = 200;
168
			$errors = [ ];
169
			foreach ( $this->errors as $error ) {
170
				$errors [] = $error->asArray ();
171
				if ($error->getStatus () > $status) {
172
					$status = $error->getStatus ();
173
				}
174
			}
175
			echo $this->_getResponseFormatter ()->format ( [ 'errors' => $errors ] );
176
			$this->_setResponseCode ( $status );
177
			return true;
178
		}
179
		return false;
180
	}
181
182
	/**
183
	 *
184
	 * @param string $ids The primary key values (comma separated if pk is multiple)
185
	 * @param callable $getDatas
186
	 * @param string $member The member to load
187
	 * @param boolean|string $include if true, loads associate members with associations, if string, example : client.*,commands
188
	 * @param boolean $useCache
189
	 * @param boolean $multiple
190
	 * @throws \Exception
191
	 */
192 3
	protected function getAssociatedMemberValues_($ids, $getDatas, $member, $include = false, $useCache = false, $multiple = true) {
193 3
		$include = $this->getInclude ( $include );
194 3
		$useCache = UString::isBooleanTrue ( $useCache );
195 3
		$datas = $getDatas ( [ $this->model,$ids ], $member, $include, $useCache );
196 3
		if ($multiple) {
197 2
			echo $this->_getResponseFormatter ()->get ( $datas );
198
		} else {
199 1
			echo $this->_getResponseFormatter ()->getOne ( $datas );
200
		}
201 3
	}
202
203
	public function _validateInstance($instance, $members) {
204
		if ($this->useValidation) {
205
			$isValid = true;
206
			$violations = ValidatorsManager::validate ( $instance );
207
			foreach ( $violations as $violation ) {
208
				if (array_search ( $violation->getMember (), $members ) !== false) {
209
					$this->addViolation ( $violation );
210
					$isValid = false;
211
				}
212
			}
213
			return $isValid;
214
		}
215
		return true;
216
	}
217
218
	protected function addViolation(ConstraintViolation $violation) {
219
		$this->addError ( 406, 'Validation error', $violation->getMessage (), $violation->getMember (), $violation->getValidatorType () );
220
	}
221
222
	protected function getPrimaryKeysFromDatas($datas, $model) {
223
		$pks = OrmUtils::getKeyFields ( $model );
224
		$result = [ ];
225
		foreach ( $pks as $pk ) {
226
			if (isset ( $datas [$pk] )) {
227
				$result [] = $datas [$pk];
228
			} else {
229
				$this->addError ( 404, 'Primary key required', 'The primary key ' . $pk . ' is required!', $pk );
230
			}
231
		}
232
		return $result;
233
	}
234
	
235 3
	protected function getCondition($condition){
236 3
		$condition=urldecode($condition);
237 3
		if(strpos($condition, 'like')!==false){
238 1
			$condition=str_replace('*', '%', $condition);
239
		}
240 3
		return $condition;
241
	}
242
}
243
244