Passed
Push — master ( 5331be...a6b5c0 )
by Jean-Christophe
06:09
created

JsonApiRestController::getRestServer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 2
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
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
use Ubiquity\controllers\rest\RestServer;
12
13
/**
14
 * Rest JsonAPI implementation.
15
 * Ubiquity\controllers\rest\api\jsonapi$JsonApiRestController
16
 * This class is part of Ubiquity
17
 *
18
 * @author jcheron <[email protected]>
19
 * @version 1.1.1
20
 * @since Ubiquity 2.0.11
21
 *
22
 */
23
abstract class JsonApiRestController extends RestBaseController {
24
	const API_VERSION = 'JsonAPI 1.0';
25
26 5
	protected function _setResource($resource) {
27 5
		$modelsNS = $this->config ["mvcNS"] ["models"];
28 5
		$this->model = $modelsNS . "\\" . ucfirst ( $resource );
29 5
	}
30
31 5
	protected function _checkResource($resource, $callback) {
32 5
		$this->_setResource ( $resource );
33 5
		if (class_exists ( $this->model )) {
34 5
			$callback ();
35
		} else {
36
			$error = new RestError ( 404, "Not existing class", $this->model . " class does not exists!", Startup::getController () . "/" . Startup::getAction () );
37
			echo $this->_format ( $error->asArray () );
38
		}
39 5
	}
40
41
	/**
42
	 *
43
	 * @param string $param
44
	 * @param string|boolean $default
45
	 * @return string|boolean
46
	 */
47 4
	protected function getRequestParam($param, $default) {
48 4
		if (isset ( $_GET [$param] )) {
49
			return $_GET [$param];
50
		}
51 4
		return $default;
52
	}
53
54
	protected function getDatas() {
55
		$datas = URequest::getInput ();
56
		if (sizeof ( $datas ) > 0) {
57
			$datas = current ( array_keys ( $datas ) );
58
			$datas = json_decode ( $datas, true );
59
			$attributes = $datas ["data"] ["attributes"] ?? [ ];
60
			if (isset ( $datas ["data"] ["id"] )) {
61
				$key = OrmUtils::getFirstKey ( $this->model );
62
				$attributes [$key] = $datas ["data"] ["id"];
63
			}
64
			return $attributes;
65
		}
66
		$this->addError ( 204, 'No content', 'The POST request has no content!' );
67
	}
68
69
	/**
70
	 *
71
	 * @return RestServer
72
	 */
73 8
	protected function getRestServer(): RestServer {
74 8
		return new JsonApiRestServer ( $this->config );
75
	}
76
77
	/**
78
	 *
79
	 * @route("{resource}/","methods"=>["options"])
80
	 */
81
	public function options($resource) {
82
	}
83
84
	/**
85
	 *
86
	 * {@inheritdoc}
87
	 * @see \Ubiquity\controllers\rest\RestBaseController::index()
88
	 * @route("links/","methods"=>["get"],"priority"=>3000)
89
	 */
90 1
	public function index() {
91 1
		parent::index ();
92 1
	}
93
94
	/**
95
	 * Returns all the instances from the model $resource.
96
	 * Query parameters:
97
	 * - **include**: 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).
98
	 * - **filter**: The filter to apply to the query (where part of an SQL query) (default: 1=1).
99
	 * - **page[number]**: The page to display (in this case, the page size is set to 1).
100
	 * - **page[size]**: The page size (count of instance per page) (default: 1).
101
	 *
102
	 * @route("{resource}/","methods"=>["get"],"priority"=>0)
103
	 */
104 1
	public function getAll_($resource) {
105
		$this->_checkResource ( $resource, function () {
106 1
			$filter = $this->getRequestParam ( 'filter', '1=1' );
107 1
			$pages = null;
108 1
			if (isset ( $_GET ['page'] )) {
109
				$pageNumber = $_GET ['page'] ['number'];
110
				$pageSize = $_GET ['page'] ['size'] ?? 1;
111
				$pages = $this->generatePagination ( $filter, $pageNumber, $pageSize );
112
			}
113 1
			$datas = DAO::getAll ( $this->model, $filter, $this->getInclude ( $this->getRequestParam ( 'include', true ) ) );
114 1
			echo $this->_getResponseFormatter ()->get ( $datas, $pages );
115 1
		} );
116 1
	}
117
118
	/**
119
	 * Returns an instance of $resource, by primary key $id.
120
	 * Query parameters:
121
	 * - **include**: 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).
122
	 * - **filter**: The filter to apply to the query (where part of an SQL query) (default: 1=1).
123
	 *
124
	 * @param string $resource The resource (model) to use
125
	 * @param string $id The primary key value(s), if the primary key is composite, use a comma to separate the values (e.g. 1,115,AB)
126
	 *
127
	 * @route("{resource}/{id}/","methods"=>["get"],"priority"=>1000)
128
	 */
129 2
	public function getOne_($resource, $id) {
130
		$this->_checkResource ( $resource, function () use ($id) {
131 2
			$this->_getOne ( $id, true, false );
132 2
		} );
133 2
	}
134
135
	/**
136
	 * Returns an associated member value(s).
137
	 * Query parameters:
138
	 * - **include**: 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).
139
	 *
140
	 * @param string $resource The resource (model) to use
141
	 * @param string $id The primary key value(s), if the primary key is composite, use a comma to separate the values (e.g. 1,115,AB)
142
	 * @param string $member The member to load
143
	 *
144
	 * @route("{resource}/{id}/relationships/{member}/","methods"=>["get"],"priority"=>2000)
145
	 */
146 3
	public function getRelationShip_($resource, $id, $member) {
147
		$this->_checkResource ( $resource, function () use ($id, $member) {
148 3
			$relations = OrmUtils::getAnnotFieldsInRelations ( $this->model );
149 3
			if (isset ( $relations [$member] )) {
150 3
				$include = $this->getRequestParam ( 'include', true );
151 3
				switch ($relations [$member] ['type']) {
152 3
					case 'manyToOne' :
153 1
						$this->_getManyToOne ( $id, $member, $include );
154 1
						break;
155 2
					case 'oneToMany' :
156 1
						$this->_getOneToMany ( $id, $member, $include );
157 1
						break;
158 1
					case 'manyToMany' :
159 1
						$this->_getManyToMany ( $id, $member, $include );
160 1
						break;
161
				}
162
			}
163 3
		} );
164 3
	}
165
166
	/**
167
	 * Inserts a new instance of $resource.
168
	 * Data attributes are send in data[attributes] request header
169
	 *
170
	 * @param string $resource The resource (model) to use
171
	 * @route("{resource}/","methods"=>["post"],"priority"=>0)
172
	 */
173
	public function add_($resource) {
174
		$this->_checkResource ( $resource, function () {
175
			parent::_add ();
176
		} );
177
	}
178
179
	/**
180
	 * Updates an existing instance of $resource.
181
	 * Data attributes are send in data[attributes] request header
182
	 *
183
	 * @param string $resource The resource (model) to use
184
	 *
185
	 * @route("{resource}/","methods"=>["patch"],"priority"=>0)
186
	 */
187
	public function update_($resource) {
188
		$this->_checkResource ( $resource, function () {
189
			$pks = $this->getPrimaryKeysFromDatas ( $this->getDatas (), $this->model );
190
			if (! $this->hasErrors ()) {
191
				parent::_update ( ...$pks );
192
			} else {
193
				echo $this->displayErrors ();
194
			}
195
		} );
196
	}
197
198
	/**
199
	 * Deletes an existing instance of $resource.
200
	 *
201
	 * @param string $resource The resource (model) to use
202
	 * @param string $ids 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