Completed
Push — master ( 1f65a3...0feaa6 )
by Jean-Christophe
01:28
created

RestController::finalize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 3
nc 1
nop 0
1
<?php
2
3
namespace micro\controllers\rest;
4
5
use micro\controllers\Controller;
6
use micro\orm\DAO;
7
use micro\controllers\Startup;
8
use micro\utils\StrUtils;
9
use micro\cache\CacheManager;
10
use micro\utils\RequestUtils;
11
12
/**
13
 * @author jc
14
 * Abstract base class for Rest controllers
15
 *
16
 */
17
abstract class RestController extends Controller {
18
	protected $config;
19
	protected $model;
20
	protected $contentType;
21
	protected $restCache;
22
	/**
23
	 * @var ResponseFormatter
24
	 */
25
	protected $responseFormatter;
26
27
	/**
28
	 * @var RestServer
29
	 */
30
	protected $server;
31
32
	public function __construct(){
33
		@\set_exception_handler(array ($this,'_errorHandler' ));
1 ignored issue
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
34
		if(!\headers_sent()){
35
			$this->config=Startup::getConfig();
36
			$this->server=new RestServer($this->config);
37
			$this->server->cors();
38
			$this->responseFormatter=new ResponseFormatter();
39
			$this->contentType="application/json";
40
			$this->server->_setContentType($this->contentType);
41
			$this->restCache=CacheManager::getRestCacheController(\get_class($this));
42
		}
43
		parent::__construct();
44
	}
45
46
	public function isValid(){
47
		if(isset($this->restCache["authorizations"])){
48
			if(\array_search(Startup::getAction(), $this->restCache["authorizations"])!==false){
49
				return $this->server->isValid();
50
			}
51
		}
52
		return true;
53
	}
54
55
	public function connect(){
56
		$this->server->connect($this);
57
	}
58
59
	public function initialize(){
60
		$thisClass=\get_class($this);
61
		if(!isset($this->model))
62
			$this->model=CacheManager::getRestResource($thisClass);
63
		if(!isset($this->model)){
64
			$modelsNS=$this->config["mvcNS"]["models"];
65
			$this->model=$modelsNS."\\".$this->responseFormatter->getModel($thisClass);
66
		}
67
		$this->connectDb($this->config);
68
	}
69
70
	public function finalize(){
71
		parent::finalize();
72
		$this->server->finalizeTokens();
73
	}
74
75
76
77
	public function _errorHandler($e){
78
		$this->_setResponseCode(500);
79
		echo $this->responseFormatter->formatException($e);
80
	}
81
82
	public function _setResponseCode($value){
83
		\http_response_code($value);
84
	}
85
86
	protected function connectDb($config){
87
		$db=$config["database"];
88
		if($db["dbName"]!==""){
89
			DAO::connect($db["type"],$db["dbName"],@$db["serverName"],@$db["port"],@$db["user"],@$db["password"],@$db["cache"]);
90
		}
91
	}
92
93
	/**
94
	 * Updates $instance with $values
95
	 * To eventually be redefined in derived classes
96
	 * @param object $instance the instance to update
97
	 * @param array $values
98
	 */
99
	protected function _setValuesToObject($instance,$values){
100
		RequestUtils::setValuesToObject($instance,$values);
101
	}
102
103
	public function index() {
104
			$datas=DAO::getAll($this->model);
105
			$datas=\array_map(function($o){return $o->_rest;}, $datas);
106
			echo $this->responseFormatter->get($datas);
107
	}
108
109
	/**
110
	 * @param string $condition
111
	 * @param boolean $loadManyToOne
112
	 * @param boolean $loadOneToMany
113
	 * @param boolean $useCache
114
	 */
115
	public function get($condition="1=1",$loadManyToOne=false,$loadOneToMany=false,$useCache=false){
116
		try{
117
			$condition=\urldecode($condition);
118
			$loadManyToOne=StrUtils::isBooleanTrue($loadManyToOne);
119
			$loadOneToMany=StrUtils::isBooleanTrue($loadOneToMany);
120
			$useCache=StrUtils::isBooleanTrue($useCache);
121
			$datas=DAO::getAll($this->model,$condition,$loadManyToOne,$loadOneToMany,$useCache);
122
			$datas=\array_map(function($o){return $o->_rest;}, $datas);
123
			echo $this->responseFormatter->get($datas);
124
		}catch (\Exception $e){
125
			$this->_setResponseCode(500);
126
			echo $this->responseFormatter->formatException($e);
127
		}
128
	}
129
130
	/**
131
	 * @param string $keyValues
132
	 * @param boolean $loadManyToOne
133
	 * @param boolean $loadOneToMany
134
	 * @param boolean $useCache
135
	 */
136
	public function getOne($keyValues,$loadManyToOne=false,$loadOneToMany=false,$useCache=false){
137
		$keyValues=\urldecode($keyValues);
138
		$loadManyToOne=StrUtils::isBooleanTrue($loadManyToOne);
139
		$loadOneToMany=StrUtils::isBooleanTrue($loadOneToMany);
140
		$useCache=StrUtils::isBooleanTrue($useCache);
141
		$data=DAO::getOne($this->model, $keyValues,$loadManyToOne,$loadOneToMany,$useCache);
142
		if(isset($data)){
143
			$_SESSION["_restInstance"]=$data;
144
			echo $this->responseFormatter->getOne($data->_rest);
145
		}
146
		else{
147
			$this->_setResponseCode(404);
148
			echo $this->responseFormatter->format(["message"=>"No result found","keyValues"=>$keyValues]);
149
		}
150
	}
151
152
	public function _format($arrayMessage){
153
		return $this->responseFormatter->format($arrayMessage);
154
	}
155
156
	/**
157
	 * @param string $member
158
	 * @param boolean $useCache
159
	 * @throws \Exception
160
	 */
161 View Code Duplication
	public function getOneToMany($member,$useCache=false){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
		if(isset($_SESSION["_restInstance"])){
163
			$useCache=StrUtils::isBooleanTrue($useCache);
164
			$datas=DAO::getOneToMany($_SESSION["_restInstance"], $member,null,$useCache);
165
			$datas=\array_map(function($o){return $o->_rest;}, $datas);
166
			echo $this->responseFormatter->get($datas);
167
		}else{
168
			throw new \Exception("You have to call getOne before calling getOneToMany.");
169
		}
170
	}
171
172
	/**
173
	 * @param string $member
174
	 * @param boolean $useCache
175
	 * @throws \Exception
176
	 */
177 View Code Duplication
	public function getManyToMany($member,$useCache=false){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
178
		if(isset($_SESSION["_restInstance"])){
179
			$useCache=StrUtils::isBooleanTrue($useCache);
180
			$datas=DAO::getManyToMany($_SESSION["_restInstance"], $member,null,$useCache);
181
			$datas=\array_map(function($o){return $o->_rest;}, $datas);
182
			echo $this->responseFormatter->get($datas);
183
		}else{
184
			throw new \Exception("You have to call getOne before calling getManyToMany.");
185
		}
186
	}
187
188
	/**
189
	 * Update an instance of $model selected by the primary key $keyValues
190
	 * @param $keyValues
191
	 * @authorization
192
	 */
193
	public function update(...$keyValues){
194
		$instance=DAO::getOne($this->model, $keyValues);
195
		if(isset($instance)){
196
			$this->_setValuesToObject($instance,RequestUtils::getInput());
0 ignored issues
show
Bug introduced by
It seems like \micro\utils\RequestUtils::getInput() targeting micro\utils\RequestUtils::getInput() can also be of type null; however, micro\controllers\rest\R...r::_setValuesToObject() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
197
			$result=DAO::update($instance);
198
			if($result){
199
				echo $this->responseFormatter->format(["status"=>"updated","data"=>$instance->_rest]);
200
			}else{
201
				throw new \Exception("Unable to update the instance");
202
			}
203
		}else{
204
			$this->_setResponseCode(404);
205
			echo $this->responseFormatter->format(["message"=>"No result found","keyValues"=>$keyValues]);
206
		}
207
	}
208
}
209