Passed
Push — master ( d7f029...202469 )
by Jean-Christophe
15:08
created

RestBaseController::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3.004

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 15
ccs 12
cts 13
cp 0.9231
rs 9.8666
cc 3
nc 4
nop 0
crap 3.004
1
<?php
2
namespace Ubiquity\controllers\rest;
3
4
use Ubiquity\cache\CacheManager;
5
use Ubiquity\controllers\Controller;
6
use Ubiquity\controllers\Startup;
7
use Ubiquity\orm\DAO;
8
use Ubiquity\utils\base\UString;
9
use Ubiquity\controllers\Router;
10
use Ubiquity\orm\OrmUtils;
11
use Ubiquity\events\EventsManager;
12
use Ubiquity\events\RestEvents;
13
14
/**
15
 * Abstract base class for Rest controllers.
16
 * Ubiquity\controllers\rest$RestController
17
 * This class is part of Ubiquity
18
 *
19
 * @author jcheron <[email protected]>
20
 * @version 1.0.8
21
 *
22
 */
23
abstract class RestBaseController extends Controller {
24
	use RestControllerUtilitiesTrait;
25
26
	protected $config;
27
28
	protected $model;
29
30
	protected $contentType;
31
32
	protected $restCache;
33
34
	protected $useValidation = true;
35
36
	/**
37
	 *
38
	 * @var ResponseFormatter
39
	 */
40
	protected $responseFormatter;
41
42
	/**
43
	 *
44
	 * @var RestServer
45
	 */
46
	protected $server;
47
48 13
	public function __construct() {
49 13
		if (! \headers_sent()) {
50 13
			@\set_exception_handler(array(
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition for set_exception_handler(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

50
			/** @scrutinizer ignore-unhandled */ @\set_exception_handler(array(

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
51 13
				$this,
52 13
				'_errorHandler'
53
			));
54 13
			$this->config = Startup::getConfig();
55 13
			$this->server = $this->_getRestServer();
56 13
			$this->server->cors();
57 13
			$this->responseFormatter = $this->_getResponseFormatter();
58 13
			$this->server->_setContentType($this->contentType);
59 13
			$this->restCache = CacheManager::getRestCacheController(\get_class($this));
60
		}
61 13
		if (! $this->isValid(Startup::getAction()))
62
			$this->onInvalidControl();
63 13
	}
64
65 1
	public function index() {
66 1
		$routesPath = Router::getRoutesPathByController(get_class($this));
67 1
		echo $this->_getResponseFormatter()->format([
68 1
			'links' => $routesPath
69
		]);
70 1
	}
71
72 3
	public function isValid($action) {
73 3
		if (isset($this->restCache['authorizations'])) {
74 2
			if (\array_search($action, $this->restCache['authorizations']) !== false) {
75 1
				return $this->server->isValid();
76
			}
77
		}
78 3
		return true;
79
	}
80
81
	/**
82
	 * Returns true if $action require an authentification with token
83
	 *
84
	 * @param string $action
85
	 * @return boolean
86
	 */
87
	protected function requireAuth($action) {
88
		if (isset($this->restCache["authorizations"])) {
89
			return array_search($action, $this->restCache["authorizations"]) !== false;
90
		}
91
		return false;
92
	}
93
94
	public function onInvalidControl() {
95
		throw new \Exception('HTTP/1.1 401 Unauthorized, you need an access token for this request', 401);
96
	}
97
98
	/**
99
	 * Realize the connection to the server
100
	 * To override in derived classes to define your own authentication
101
	 */
102 1
	public function connect() {
103 1
		$resp = $this->server->connect();
104 1
		echo $this->_format($resp);
105 1
	}
106
107
	public function initialize() {}
108
109 13
	public function finalize() {
110 13
		parent::finalize();
111 13
		$this->server->finalizeTokens();
112 13
	}
113
114
	public function _errorHandler($e) {
115
		$this->_setResponseCode(200);
116
		echo $this->_getResponseFormatter()->formatException($e);
117
	}
118
119 1
	public function _setResponseCode($value) {
120 1
		\http_response_code($value);
121 1
	}
122
123
	/**
124
	 * Returns a list of objects from the server.
125
	 *
126
	 * @param string $condition
127
	 *        	the sql Where part
128
	 * @param boolean|string $include
129
	 *        	if true, loads associate members with associations, if string, example : client.*,commands
130
	 * @param boolean $useCache
131
	 */
132 1
	public function _get($condition = '1=1', $include = false, $useCache = false) {
133
		try {
134 1
			$condition = $this->getCondition($condition);
135 1
			$include = $this->getInclude($include);
136 1
			$useCache = UString::isBooleanTrue($useCache);
137 1
			$datas = DAO::getAll($this->model, $condition, $include, null, $useCache);
138 1
			echo $this->_getResponseFormatter()->get($datas);
139
		} catch (\Exception $e) {
140
			$this->_setResponseCode(500);
141
			echo $this->_getResponseFormatter()->formatException($e);
142
		}
143 1
	}
144
145
	/**
146
	 * Get the first object corresponding to the $keyValues.
147
	 *
148
	 * @param string $keyValues
149
	 *        	primary key(s) value(s) or condition
150
	 * @param boolean|string $include
151
	 *        	if true, loads associate members with associations, if string, example : client.*,commands
152
	 * @param boolean $useCache
153
	 *        	if true then response is cached
154
	 */
155 3
	public function _getOne($keyValues, $include = false, $useCache = false) {
156 3
		$keyValues = $this->getCondition($keyValues);
157 3
		$include = $this->getInclude($include);
158 3
		$useCache = UString::isBooleanTrue($useCache);
159 3
		$data = DAO::getById($this->model, $keyValues, $include, $useCache);
160 3
		if (isset($data)) {
161 3
			$_SESSION["_restInstance"] = $data;
162 3
			echo $this->_getResponseFormatter()->getOne($data);
163
		} else {
164 1
			$this->_setResponseCode(404);
165 1
			echo $this->_getResponseFormatter()->format(RestError::notFound($keyValues, "RestController/getOne")->asArray());
166
		}
167 3
	}
168
169 1
	public function _format($arrayMessage) {
170 1
		return $this->_getResponseFormatter()->format($arrayMessage);
171
	}
172
173
	/**
174
	 *
175
	 * @param string $ids
176
	 * @param string $member
177
	 * @param string|boolean $include
178
	 *        	if true, loads associate members with associations, if string, example : client.*,commands
179
	 * @param boolean $useCache
180
	 */
181 1
	public function _getManyToOne($ids, $member, $include = false, $useCache = false) {
182
		$this->getAssociatedMemberValues_($ids, function ($instance, $member, $include, $useCache) {
183 1
			return DAO::getManyToOne($instance, $member, $include, $useCache);
184 1
		}, $member, $include, $useCache, false);
185 1
	}
186
187
	/**
188
	 *
189
	 * @param string $ids
190
	 * @param string $member
191
	 * @param string|boolean $include
192
	 *        	if true, loads associate members with associations, if string, example : client.*,commands
193
	 * @param boolean $useCache
194
	 * @throws \Exception
195
	 */
196 1
	public function _getOneToMany($ids, $member, $include = false, $useCache = false) {
197
		$this->getAssociatedMemberValues_($ids, function ($instance, $member, $include, $useCache) {
198 1
			return DAO::getOneToMany($instance, $member, $include, $useCache);
199 1
		}, $member, $include, $useCache, true);
200 1
	}
201
202
	/**
203
	 *
204
	 * @param string $ids
205
	 * @param string $member
206
	 * @param string|boolean $include
207
	 *        	if true, loads associate members with associations, if string, example : client.*,commands
208
	 * @param boolean $useCache
209
	 * @throws \Exception
210
	 */
211 1
	public function _getManyToMany($ids, $member, $include = false, $useCache = false) {
212
		$this->getAssociatedMemberValues_($ids, function ($instance, $member, $include, $useCache) {
213 1
			return DAO::getManyToMany($instance, $member, $include, null, $useCache);
214 1
		}, $member, $include, $useCache, true);
215 1
	}
216
217
	/**
218
	 * Update an instance of $model selected by the primary key $keyValues
219
	 * Require members values in $_POST array
220
	 *
221
	 * @param array $keyValues
222
	 */
223
	public function _update(...$keyValues) {
224
		$instance = DAO::getById($this->model, $keyValues, false);
225
		$this->operate_($instance, function ($instance) {
226
			$datas = $this->getDatas();
227
			EventsManager::trigger(RestEvents::BEFORE_UPDATE, $instance, $datas, $this);
228
			$this->_setValuesToObject($instance, $datas);
229
			if ($this->_validateInstance($instance, \array_keys($datas))) {
230
				return $this->updateOperation($instance, $datas, true);
231
			}
232
			return null;
233
		}, 'updated', 'Unable to update the instance', $keyValues);
234
	}
235
236
	/**
237
	 * Insert a new instance of $model
238
	 * Require members values in $_POST array
239
	 */
240
	public function _add() {
241
		$model = $this->model;
242
		$instance = new $model();
243
		$this->operate_($instance, function ($instance) use ($model) {
244
			$datas = $this->getDatas();
245
			EventsManager::trigger(RestEvents::BEFORE_INSERT, $instance, $datas, $this);
246
			$this->_setValuesToObject($instance, $datas);
247
			$fields = \array_keys(OrmUtils::getSerializableFields($model));
248
			if ($this->_validateInstance($instance, $fields, [
249
				'id' => false
250
			])) {
251
				return $this->AddOperation($instance, $datas, true);
252
			}
253
			return null;
254
		}, 'inserted', 'Unable to insert the instance', []);
255
	}
256
257
	/**
258
	 * Delete the instance of $model selected by the primary key $keyValues
259
	 *
260
	 * @param array $keyValues
261
	 */
262
	public function _delete(...$keyValues) {
263
		$instance = DAO::getById($this->model, $keyValues, false);
264
		$this->operate_($instance, function ($instance) {
265
			return DAO::remove($instance);
266
		}, 'deleted', 'Unable to delete the instance', $keyValues);
267
	}
268
269 1
	public static function _getApiVersion() {
270 1
		return '?';
271
	}
272
273
	/**
274
	 * Returns the template for creating this type of controller
275
	 *
276
	 * @return string
277
	 */
278 1
	public static function _getTemplateFile() {
279 1
		return 'restController.tpl';
280
	}
281
}
282