Passed
Push — master ( cba8a4...d54449 )
by Aimeos
04:49
created

Base::initCriteriaSlice()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 6
rs 10
cc 3
nc 4
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017-2020
6
 * @package Client
7
 * @subpackage JsonApi
8
 */
9
10
11
namespace Aimeos\Client\JsonApi;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API common client
19
 *
20
 * @package Client
21
 * @subpackage JsonApi
22
 */
23
abstract class Base implements \Aimeos\Client\JsonApi\Iface
24
{
25
	private $view;
26
	private $context;
27
	private $path;
28
29
30
	/**
31
	 * Initializes the client
32
	 *
33
	 * @param \Aimeos\MShop\Context\Item\Iface $context MShop context object
34
	 * @param string $path Name of the client separated by slashes, e.g "catalog/lists"
35
	 */
36
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, string $path )
37
	{
38
		$this->context = $context;
39
		$this->path = $path;
40
	}
41
42
43
	/**
44
	 * Catch unknown methods
45
	 *
46
	 * @param string $name Name of the method
47
	 * @param array $param List of method parameter
48
	 * @throws \Aimeos\Client\JsonApi\Exception If method call failed
49
	 */
50
	public function __call( string $name, array $param )
51
	{
52
		throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Unable to call method "%1$s"', $name ) );
53
	}
54
55
56
	/**
57
	 * Deletes the resource or the resource list
58
	 *
59
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
60
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
61
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
62
	 */
63
	public function delete( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
64
	{
65
		return $this->defaultAction( $request, $response );
66
	}
67
68
69
	/**
70
	 * Retrieves the resource or the resource list
71
	 *
72
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
73
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
74
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
75
	 */
76
	public function get( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
77
	{
78
		return $this->defaultAction( $request, $response );
79
	}
80
81
82
	/**
83
	 * Updates the resource or the resource list partitially
84
	 *
85
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
86
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
87
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
88
	 */
89
	public function patch( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
90
	{
91
		return $this->defaultAction( $request, $response );
92
	}
93
94
95
	/**
96
	 * Creates or updates the resource or the resource list
97
	 *
98
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
99
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
100
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
101
	 */
102
	public function post( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
103
	{
104
		return $this->defaultAction( $request, $response );
105
	}
106
107
108
	/**
109
	 * Creates or updates the resource or the resource list
110
	 *
111
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
112
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
113
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
114
	 */
115
	public function put( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
116
	{
117
		return $this->defaultAction( $request, $response );
118
	}
119
120
121
	/**
122
	 * Creates or updates the resource or the resource list
123
	 *
124
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
125
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
126
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
127
	 */
128
	public function options( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
129
	{
130
		return $this->defaultAction( $request, $response );
131
	}
132
133
134
	/**
135
	 * Returns the view object that will generate the admin output.
136
	 *
137
	 * @return \Aimeos\MW\View\Iface The view object which generates the admin output
138
	 */
139
	public function getView() : \Aimeos\MW\View\Iface
140
	{
141
		if( !isset( $this->view ) ) {
142
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'No view available' ) );
0 ignored issues
show
Bug introduced by
The type Aimeos\Admin\JsonAdm\Exception was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
143
		}
144
145
		return $this->view;
146
	}
147
148
149
	/**
150
	 * Sets the view object that will generate the admin output.
151
	 *
152
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the admin output
153
	 * @return \Aimeos\Client\JsonApi\Iface Reference to this object for fluent calls
154
	 */
155
	public function setView( \Aimeos\MW\View\Iface $view ) : \Aimeos\Client\JsonApi\Iface
156
	{
157
		$this->view = $view;
158
		return $this;
159
	}
160
161
162
	/**
163
	 * Returns the default response for the resource
164
	 *
165
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
166
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
167
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
168
	 */
169
	protected function defaultAction( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
170
	{
171
		$status = 403;
172
		$view = $this->getView();
173
174
		$view->errors = array( array(
175
			'title' => $this->getContext()->getI18n()->dt( 'client/jsonapi', 'Not allowed for this resource' ),
176
		) );
177
178
		/** client/jsonapi/standard/template-error
179
		 * Relative path to the default JSON API template
180
		 *
181
		 * The template file contains the code and processing instructions
182
		 * to generate the result shown in the JSON API body. The
183
		 * configuration string is the path to the template file relative
184
		 * to the templates directory (usually in client/jsonapi/templates).
185
		 *
186
		 * You can overwrite the template file configuration in extensions and
187
		 * provide alternative templates. These alternative templates should be
188
		 * named like the default one but with the string "standard" replaced by
189
		 * an unique name. You may use the name of your project for this. If
190
		 * you've implemented an alternative client class as well, "standard"
191
		 * should be replaced by the name of the new class.
192
		 *
193
		 * @param string Relative path to the template creating the body for the JSON API response
194
		 * @since 2017.02
195
		 * @category Developer
196
		 * @see client/jsonapi/standard/template-delete
197
		 * @see client/jsonapi/standard/template-patch
198
		 * @see client/jsonapi/standard/template-post
199
		 * @see client/jsonapi/standard/template-get
200
		 * @see client/jsonapi/standard/template-options
201
		 */
202
		$tplconf = 'client/jsonapi/standard/template-error';
203
		$default = 'error-standard';
204
205
		$body = $view->render( $view->config( $tplconf, $default ) );
206
207
		return $response->withHeader( 'Content-Type', 'application/vnd.api+json' )
208
			->withBody( $view->response()->createStreamFromString( $body ) )
209
			->withStatus( $status );
210
	}
211
212
213
	/**
214
	 * Returns the context item object
215
	 *
216
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
217
	 */
218
	protected function getContext() : \Aimeos\MShop\Context\Item\Iface
219
	{
220
		return $this->context;
221
	}
222
223
224
	/**
225
	 * Returns the translated title and the details of the error
226
	 *
227
	 * @param \Exception $e Thrown exception
228
	 * @param string|null $domain Translation domain
229
	 * @return array Associative list with "title" and "detail" key (if debug config is enabled)
230
	 */
231
	protected function getErrorDetails( \Exception $e, string $domain = null ) : array
232
	{
233
		$details = [];
234
235
		if( $domain !== null ) {
236
			$details['title'] = $this->context->getI18n()->dt( $domain, $e->getMessage() );
237
		} else {
238
			$details['title'] = $e->getMessage();
239
		}
240
241
		/** client/jsonapi/debug
242
		 * Send debug information withing responses to clients if an error occurrs
243
		 *
244
		 * By default, the Aimeos client JSON REST API won't send any details
245
		 * besides the error message to the client if an error occurred. This
246
		 * prevents leaking sensitive information to attackers. For debugging
247
		 * your requests it's helpful to see the stack strace. If you set this
248
		 * configuration option to true, the stack trace will be returned too.
249
		 *
250
		 * @param boolean True to return the stack trace in JSON response, false for error message only
251
		 * @since 2017.07
252
		 * @category Developer
253
		 */
254
		if( $this->context->getConfig()->get( 'client/jsonapi/debug', false ) == true ) {
255
			$details['detail'] = $e->getTraceAsString();
256
		}
257
258
		return [$details]; // jsonapi.org requires a list of error objects
259
	}
260
261
262
	/**
263
	 * Returns the path to the client
264
	 *
265
	 * @return string Client path, e.g. "product/property"
266
	 */
267
	protected function getPath() : string
268
	{
269
		return $this->path;
270
	}
271
272
273
	/**
274
	 * Initializes the criteria object based on the given parameter
275
	 *
276
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
277
	 * @param array $params List of criteria data with condition, sorting and paging
278
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
279
	 */
280
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
281
	{
282
		return $criteria->order( $params['sort'] ?? [] )
283
			->add( $criteria->parse( $params['filter'] ?? [] ) )
284
			->slice( $params['page']['offset'] ?? 0, $params['page']['limit'] ?? 25 );
285
	}
286
287
288
	/**
289
	 * Returns the available REST verbs and the available parameters
290
	 *
291
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
292
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
293
	 * @param string $allow Allowed HTTP methods
294
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
295
	 */
296
	public function getOptionsResponse( ServerRequestInterface $request, ResponseInterface $response, string $allow ) : \Psr\Http\Message\ResponseInterface
297
	{
298
		$view = $this->getView();
299
300
		$tplconf = 'client/jsonapi/standard/template-options';
301
		$default = 'options-standard';
302
303
		$body = $view->render( $view->config( $tplconf, $default ) );
304
305
		return $response->withHeader( 'Allow', $allow )
306
			->withHeader( 'Cache-Control', 'max-age=300' )
307
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
308
			->withBody( $view->response()->createStreamFromString( $body ) )
309
			->withStatus( 200 );
310
	}
311
}
312