Completed
Push — master ( b254ca...3fe05c )
by Aimeos
02:44
created

Base::setView()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017
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
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, $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( $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 )
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 )
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 )
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 )
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 )
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 )
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()
140
	{
141
		if( !isset( $this->view ) ) {
142
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'No view available' ) );
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\Admin\JQAdm\Iface Reference to this object for fluent calls
0 ignored issues
show
Documentation introduced by
Should the return type not be Base?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
154
	 */
155
	public function setView( \Aimeos\MW\View\Iface $view )
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 )
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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.php';
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()
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, $domain = null )
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()
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 )
281
	{
282
		$this->initCriteriaConditions( $criteria, $params );
283
		$this->initCriteriaSortations( $criteria, $params );
284
		$this->initCriteriaSlice( $criteria, $params );
285
286
		return $criteria;
287
	}
288
289
290
	/**
291
	 * Initializes the criteria object with conditions based on the given parameter
292
	 *
293
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
294
	 * @param array $params List of criteria data with condition, sorting and paging
295
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
296
	 */
297
	protected function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params )
298
	{
299
		if( !isset( $params['filter'] ) ) {
300
			return $criteria;
301
		}
302
303
		$existing = $criteria->getConditions();
304
		$criteria->setConditions( $criteria->toConditions( (array) $params['filter'] ) );
305
306
		$expr = array( $criteria->getConditions(), $existing );
307
		return $criteria->setConditions( $criteria->combine( '&&', $expr ) );
308
	}
309
310
311
	/**
312
	 * Initializes the criteria object with the slice based on the given parameter.
313
	 *
314
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
315
	 * @param array $params List of criteria data with condition, sorting and paging
316
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
317
	 */
318
	protected function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params )
319
	{
320
		$start = ( isset( $params['page']['offset'] ) ? (int) $params['page']['offset'] : 0 );
321
		$size = ( isset( $params['page']['limit'] ) ? (int) $params['page']['limit'] : 25 );
322
323
		return $criteria->setSlice( $start, $size );
324
	}
325
326
327
	/**
328
	 * Initializes the criteria object with sortations based on the given parameter
329
	 *
330
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
331
	 * @param array $params List of criteria data with condition, sorting and paging
332
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
0 ignored issues
show
Documentation introduced by
Should the return type not be \Aimeos\MW\Criteria\Iface|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
333
	 */
334
	protected function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params )
335
	{
336
		if( !isset( $params['sort'] ) ) {
337
			return;
338
		}
339
340
		$sortation = [];
341
342
		foreach( explode( ',', $params['sort'] ) as $sort )
343
		{
344
			if( $sort[0] === '-' ) {
345
				$sortation[] = $criteria->sort( '-', substr( $sort, 1 ) );
346
			} else {
347
				$sortation[] = $criteria->sort( '+', $sort );
348
			}
349
		}
350
351
		return $criteria->setSortations( $sortation );
352
	}
353
354
355
	/**
356
	 * Returns the available REST verbs and the available parameters
357
	 *
358
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
359
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
360
	 * @param string $allow Allowed HTTP methods
361
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
362
	 */
363
	public function getOptionsResponse( ServerRequestInterface $request, ResponseInterface $response, $allow )
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
364
	{
365
		$view = $this->getView();
366
367
		$tplconf = 'client/jsonapi/standard/template-options';
368
		$default = 'options-standard.php';
369
370
		$body = $view->render( $view->config( $tplconf, $default ) );
371
372
		return $response->withHeader( 'Allow', $allow )
373
			->withHeader( 'Cache-Control', 'max-age=300' )
374
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
375
			->withBody( $view->response()->createStreamFromString( $body ) )
376
			->withStatus( 200 );
377
	}
378
}
379