Passed
Push — master ( 55710c...55bc39 )
by Jean-Christophe
06:21
created

JsonApiRestController::getAll_()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2.1481

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 11
ccs 6
cts 9
cp 0.6667
rs 9.9666
c 0
b 0
f 0
cc 2
nc 1
nop 1
crap 2.1481
1
<?php
2
3
namespace Ubiquity\controllers\rest\api\jsonapi;
4
5
use Ubiquity\orm\DAO;
6
use Ubiquity\controllers\rest\RestError;
7
use Ubiquity\controllers\Startup;
8
use Ubiquity\controllers\rest\RestBaseController;
9
use Ubiquity\utils\http\URequest;
10
use Ubiquity\orm\OrmUtils;
11
12
/**
13
 * Rest JsonAPI implementation.
14
 * Ubiquity\controllers\rest\api\jsonapi$JsonApiRestController
15
 * This class is part of Ubiquity
16
 *
17
 * @author jcheron <[email protected]>
18
 * @version 1.1.0
19
 * @since Ubiquity 2.0.11
20
 *
21
 */
22
abstract class JsonApiRestController extends RestBaseController {
23
	const API_VERSION = 'JsonAPI 1.0';
24
25 3
	protected function _setResource($resource) {
26 3
		$modelsNS = $this->config ["mvcNS"] ["models"];
27 3
		$this->model = $modelsNS . "\\" . ucfirst ( $resource );
28 3
	}
29
30 3
	protected function _checkResource($resource, $callback) {
31 3
		$this->_setResource ( $resource );
32 3
		if (class_exists ( $this->model )) {
33 3
			$callback ();
34
		} else {
35
			$error = new RestError ( 404, "Not existing class", $this->model . " class does not exists!", Startup::getController () . "/" . Startup::getAction () );
36
			echo $this->_format ( $error->asArray () );
37
		}
38 3
	}
39
40
	/**
41
	 *
42
	 * @param string $param
43
	 * @param string|boolean $default
44
	 * @return string|boolean
45
	 */
46 3
	protected function getRequestParam($param, $default) {
47 3
		if (isset ( $_GET [$param] )) {
48
			return $_GET [$param];
49
		}
50 3
		return $default;
51
	}
52
53
	protected function getDatas() {
54
		$datas = URequest::getInput ();
55
		if (sizeof ( $datas ) > 0) {
56
			$datas = current ( array_keys ( $datas ) );
57
			$datas = json_decode ( $datas, true );
58
			$attributes = $datas ["data"] ["attributes"] ?? [ ];
59
			if (isset ( $datas ["id"] )) {
60
				$key = OrmUtils::getFirstKey ( $this->model );
61
				$attributes [$key] = $datas ["id"];
62
			}
63
			return $attributes;
64
		}
65
		$this->addError ( 204, 'No content', 'The POST request has no content!' );
66
	}
67
68
	/**
69
	 *
70
	 * @route("{resource}/","methods"=>["options"])
71
	 */
72
	public function options($resource) {
73
	}
74
75
	/**
76
	 *
77
	 * {@inheritdoc}
78
	 * @see \Ubiquity\controllers\rest\RestBaseController::index()
79
	 * @route("links/","methods"=>["get"],"priority"=>3000)
80
	 */
81 1
	public function index() {
82 1
		parent::index ();
83 1
	}
84
85
	/**
86
	 * Returns all the instances from the model $resource.
87
	 * Query parameters:
88
	 * - **included**: A string of associated members to load, comma separated (e.g. users,groups,organization...), or a boolean: true for all members, false for none (default: true).
89
	 * - **filter**: The filter to apply to the query (where part of an SQL query) (default: 1=1).
90
	 * - **page[number]**: The page to display (in this case, the page size is set to 1).
91
	 * - **page[size]**: The page size (count of instance per page) (default: 1).
92
	 *
93
	 * @route("{resource}/","methods"=>["get"],"priority"=>0)
94
	 */
95 1
	public function getAll_($resource) {
96
		$this->_checkResource ( $resource, function () {
97 1
			$filter = $this->getRequestParam ( 'filter', '1=1' );
98 1
			$pages = null;
99 1
			if (isset ( $_GET ['page'] )) {
100
				$pageNumber = $_GET ['page'] ['number'];
101
				$pageSize = $_GET ['page'] ['size'] ?? 1;
102
				$pages = $this->generatePagination ( $filter, $pageNumber, $pageSize );
103
			}
104 1
			$datas = DAO::getAll ( $this->model, $filter, $this->getIncluded ( $this->getRequestParam ( 'included', true ) ) );
105 1
			echo $this->_getResponseFormatter ()->get ( $datas, $pages );
106 1
		} );
107 1
	}
108
109
	/**
110
	 * Returns an instance of $resource, by primary key $id.
111
	 * Query parameters:
112
	 * - **included**: A string of associated members to load, comma separated (e.g. users,groups,organization...), or a boolean: true for all members, false for none (default: true).
113
	 * - **filter**: The filter to apply to the query (where part of an SQL query) (default: 1=1).
114
	 *
115
	 * @param string $resource
116
	 *        	The resource (model) to use
117
	 * @param string $id
118
	 *        	The primary key value(s), if the primary key is composite, use a comma to separate the values (e.g. 1,115,AB)
119
	 *
120
	 * @route("{resource}/{id}/","methods"=>["get"],"priority"=>1000)
121
	 */
122 1
	public function getOne_($resource, $id) {
123
		$this->_checkResource ( $resource, function () use ($id) {
124 1
			$this->_getOne ( $id, true, false );
125 1
		} );
126 1
	}
127
128
	/**
129
	 * Returns an associated member value(s).
130
	 * Query parameters:
131
	 * - **included**: A string of associated members to load, comma separated (e.g. users,groups,organization...), or a boolean: true for all members, false for none (default: true).
132
	 *
133
	 * @param string $resource
134
	 *        	The resource (model) to use
135
	 * @param string $id
136
	 *        	The primary key value(s), if the primary key is composite, use a comma to separate the values (e.g. 1,115,AB)
137
	 * @param string $member
138
	 *        	The member to load
139
	 *
140
	 * @route("{resource}/{id}/relationships/{member}/","methods"=>["get"],"priority"=>2000)
141
	 */
142 2
	public function getRelationShip_($resource, $id, $member) {
143
		$this->_checkResource ( $resource, function () use ($id, $member) {
144 2
			$relations = OrmUtils::getAnnotFieldsInRelations ( $this->model );
145 2
			if (isset ( $relations [$member] )) {
146 2
				$included = $this->getRequestParam ( 'included', true );
147 2
				switch ($relations [$member] ['type']) {
148 2
					case 'manyToOne' :
149 1
						$this->_getManyToOne ( $id, $member, $this->getIncluded ( $included ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getIncluded($included) can also be of type string[]; however, parameter $included of Ubiquity\controllers\res...roller::_getManyToOne() does only seem to accept boolean|string, maybe add an additional type check? ( Ignorable by Annotation )

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

149
						$this->_getManyToOne ( $id, $member, /** @scrutinizer ignore-type */ $this->getIncluded ( $included ) );
Loading history...
150 1
						break;
151 1
					case 'oneToMany' :
152
						$this->_getOneToMany ( $id, $member, $this->getIncluded ( $included ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getIncluded($included) can also be of type string[]; however, parameter $included of Ubiquity\controllers\res...roller::_getOneToMany() does only seem to accept boolean|string, maybe add an additional type check? ( Ignorable by Annotation )

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

152
						$this->_getOneToMany ( $id, $member, /** @scrutinizer ignore-type */ $this->getIncluded ( $included ) );
Loading history...
153
						break;
154 1
					case 'manyToMany' :
155 1
						$this->_getManyToMany ( $id, $member, $this->getIncluded ( $included ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getIncluded($included) can also be of type string[]; however, parameter $included of Ubiquity\controllers\res...oller::_getManyToMany() does only seem to accept boolean|string, maybe add an additional type check? ( Ignorable by Annotation )

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

155
						$this->_getManyToMany ( $id, $member, /** @scrutinizer ignore-type */ $this->getIncluded ( $included ) );
Loading history...
156 1
						break;
157
				}
158
			}
159 2
		} );
160 2
	}
161
162
	/**
163
	 * Inserts a new instance of $resource.
164
	 * Data attributes are send in data[attributes] request header
165
	 *
166
	 * @param string $resource
167
	 *        	The resource (model) to use
168
	 * @route("{resource}/","methods"=>["post"],"priority"=>0)
169
	 */
170
	public function add_($resource) {
171
		$this->_checkResource ( $resource, function () {
172
			parent::_add ();
173
		} );
174
	}
175
176
	/**
177
	 * Updates an existing instance of $resource.
178
	 * Data attributes are send in data[attributes] request header
179
	 *
180
	 * @param string $resource
181
	 *        	The resource (model) to use
182
	 *
183
	 * @route("{resource}/","methods"=>["patch"],"priority"=>0)
184
	 */
185
	public function update_($resource) {
186
		$this->_checkResource ( $resource, function () {
187
			$pks = $this->getPrimaryKeysFromDatas ( $this->getDatas (), $this->model );
188
			if (! $this->hasErrors ()) {
189
				parent::_update ( $pks );
190
			} else {
191
				echo $this->displayErrors ();
192
			}
193
		} );
194
	}
195
196
	/**
197
	 * Deletes an existing instance of $resource.
198
	 *
199
	 * @param string $resource
200
	 *        	The resource (model) to use
201
	 * @param string $ids
202
	 *        	The primary key value(s), if the primary key is composite, use a comma to separate the values (e.g. 1,115,AB)
203
	 *
204
	 * @route("{resource}/{id}/","methods"=>["delete"],"priority"=>0)
205
	 */
206
	public function delete_($resource, ...$id) {
207
		$this->_checkResource ( $resource, function () use ($id) {
208
			$this->_delete ( $id );
209
		} );
210
	}
211
212
	/**
213
	 * Returns the api version
214
	 *
215
	 * @return string
216
	 */
217 1
	public static function _getApiVersion() {
218 1
		return self::API_VERSION;
219
	}
220
}
221
222