Test Failed
Branch master (5614f0)
by Jean-Christophe
07:11
created

JsonApiRestController::_checkResource()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.1481

Importance

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