Passed
Push — master ( d36a99...d31551 )
by Jean-Christophe
06:01
created

RestControllerUtilitiesTrait::getDatas()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
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.3
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
	protected function operate_($instance, $callback, $status, $exceptionMessage, $keyValues) {
34
		if (isset ( $instance )) {
35
			$result = $callback ( $instance );
36
			if ($result === true) {
37
				$formatter = $this->_getResponseFormatter ();
38
				echo $formatter->format ( [ "status" => $status,"data" => $formatter->cleanRestObject ( $instance ) ] );
39
			} elseif ($result === null) {
40
				$this->displayErrors ();
41
			} else {
42
				throw new \Exception ( $exceptionMessage );
43
			}
44
		} else {
45
			$this->_setResponseCode ( 404 );
46
			echo $this->_getResponseFormatter ()->format ( [ "message" => "No result found","keyValues" => $keyValues ] );
47
		}
48
	}
49
50
	protected function generatePagination(&$filter, $pageNumber, $pageSize) {
51
		$count = DAO::count ( $this->model, $filter );
52
		$pagesCount = ceil ( $count / $pageSize );
53
		$pages = [ 'self' => $pageNumber,'first' => 1,'last' => $pagesCount,'pageSize' => $pageSize ];
54
		if ($pageNumber - 1 > 0) {
55
			$pages ['prev'] = $pageNumber - 1;
56
		}
57
		if ($pageNumber + 1 <= $pagesCount) {
58
			$pages ['next'] = $pageNumber + 1;
59
		}
60
		$offset = ($pageNumber - 1) * $pageSize;
61
		$filter .= ' limit ' . $offset . ',' . $pageSize;
62
		return $pages;
63
	}
64
	
65
	protected function updateOperation($instance,$datas,$updateMany=false){
66
		return DAO::update($instance,$updateMany);
67
	}
68
	
69
	protected function AddOperation($instance,$datas,$insertMany=false){
70
		return DAO::insert($instance,$insertMany);
71
	}
72
73
	/**
74
	 *
75
	 * @return \Ubiquity\controllers\rest\ResponseFormatter
76
	 */
77 10
	protected function _getResponseFormatter() {
78 10
		if (! isset ( $this->responseFormatter )) {
79 10
			$this->responseFormatter = $this->getResponseFormatter ();
80
		}
81 10
		return $this->responseFormatter;
82
	}
83
84
	/**
85
	 * To override, returns the active formatter for the response
86
	 *
87
	 * @return \Ubiquity\controllers\rest\ResponseFormatter
88
	 */
89 4
	protected function getResponseFormatter(): ResponseFormatter {
90 4
		return new ResponseFormatter ();
91
	}
92
93 10
	protected function _getRestServer() {
94 10
		if (! isset ( $this->server )) {
95 10
			$this->server = $this->getRestServer ();
96
		}
97 10
		return $this->server;
98
	}
99
100
	/**
101
	 * To override, returns the active RestServer
102
	 *
103
	 * @return \Ubiquity\controllers\rest\RestServer
104
	 */
105 4
	protected function getRestServer(): RestServer {
106 4
		return new RestServer ( $this->config );
107
	}
108
109 7
	protected function connectDb($config) {
110 7
		$db = $config ["database"];
111 7
		if ($db ["dbName"] !== "") {
112 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 );
113
		}
114 7
	}
115
116
	/**
117
	 * Updates $instance with $values
118
	 * To eventually be redefined in derived classes
119
	 *
120
	 * @param object $instance the instance to update
121
	 * @param array|null $values
122
	 */
123
	protected function _setValuesToObject($instance, $values = null) {
124
		if (URequest::isJSON ()) {
125
			$values = \json_decode ( $values, true );
126
		}
127
		URequest::setValuesToObject ( $instance, $values );
128
	}
129
130
	/**
131
	 *
132
	 * @param string|boolean $include
133
	 * @return array|boolean
134
	 */
135 6
	protected function getInclude($include) {
136 6
		if (! UString::isBooleanStr ( $include )) {
137
			return explode ( ",", $include );
138
		}
139 6
		return UString::isBooleanTrue ( $include );
140
	}
141
142
	protected function addError($code, $title, $detail = null, $source = null, $status = null) {
143
		$this->errors [] = new RestError ( $code, $title, $detail, $source, $status );
144
	}
145
146
	protected function hasErrors() {
147
		return is_array ( $this->errors ) && sizeof ( $this->errors ) > 0;
148
	}
149
150
	protected function displayErrors() {
151
		if ($this->hasErrors ()) {
152
			$status = 200;
153
			$errors = [ ];
154
			foreach ( $this->errors as $error ) {
155
				$errors [] = $error->asArray ();
156
				if ($error->getStatus () > $status) {
157
					$status = $error->getStatus ();
158
				}
159
			}
160
			echo $this->_getResponseFormatter ()->format ( [ 'errors' => $errors ] );
161
			$this->_setResponseCode ( $status );
162
			return true;
163
		}
164
		return false;
165
	}
166
167
	/**
168
	 *
169
	 * @param string $ids The primary key values (comma separated if pk is multiple)
170
	 * @param callable $getDatas
171
	 * @param string $member The member to load
172
	 * @param boolean|string $include if true, loads associate members with associations, if string, example : client.*,commands
173
	 * @param boolean $useCache
174
	 * @param boolean $multiple
175
	 * @throws \Exception
176
	 */
177 3
	protected function getAssociatedMemberValues_($ids, $getDatas, $member, $include = false, $useCache = false, $multiple = true) {
178 3
		$include = $this->getInclude ( $include );
179 3
		$useCache = UString::isBooleanTrue ( $useCache );
180 3
		$datas = $getDatas ( [ $this->model,$ids ], $member, $include, $useCache );
181 3
		if ($multiple) {
182 2
			echo $this->_getResponseFormatter ()->get ( $datas );
183
		} else {
184 1
			echo $this->_getResponseFormatter ()->getOne ( $datas );
185
		}
186 3
	}
187
188
	public function validateInstance($instance, $members) {
189
		if ($this->useValidation) {
190
			$isValid = true;
191
			$violations = ValidatorsManager::validate ( $instance );
192
			foreach ( $violations as $violation ) {
193
				if (array_search ( $violation->getMember (), $members ) !== false) {
194
					$this->addViolation ( $violation );
195
					$isValid = false;
196
				}
197
			}
198
			return $isValid;
199
		}
200
		return true;
201
	}
202
203
	protected function addViolation(ConstraintViolation $violation) {
204
		$this->addError ( 406, 'Validation error', $violation->getMessage (), $violation->getMember (), $violation->getValidatorType () );
205
	}
206
207
	protected function getPrimaryKeysFromDatas($datas, $model) {
208
		$pks = OrmUtils::getKeyFields ( $model );
209
		$result = [ ];
210
		foreach ( $pks as $pk ) {
211
			if (isset ( $datas [$pk] )) {
212
				$result [] = $datas [$pk];
213
			} else {
214
				$this->addError ( 404, 'Primary key required', 'The primary key ' . $pk . ' is required!', $pk );
215
			}
216
		}
217
		return $result;
218
	}
219
}
220
221