Passed
Push — master ( a04fe5...a14c92 )
by Aimeos
08:22 queued 05:52
created

Base::view()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017-2021
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
	implements \Aimeos\Client\JsonApi\Iface, \Aimeos\MW\Macro\Iface
25
{
26
	use \Aimeos\MW\Macro\Traits;
27
28
29
	private $view;
30
	private $context;
31
	private $path;
32
33
34
	/**
35
	 * Initializes the client
36
	 *
37
	 * @param \Aimeos\MShop\Context\Item\Iface $context MShop context object
38
	 * @param string $path Name of the client separated by slashes, e.g "catalog/lists"
39
	 */
40
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, string $path )
41
	{
42
		$this->context = $context;
43
		$this->path = $path;
44
	}
45
46
47
	/**
48
	 * Catch unknown methods
49
	 *
50
	 * @param string $name Name of the method
51
	 * @param array $param List of method parameter
52
	 * @throws \Aimeos\Client\JsonApi\Exception If method call failed
53
	 */
54
	public function __call( string $name, array $param )
55
	{
56
		throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Unable to call method "%1$s"', $name ) );
57
	}
58
59
60
	/**
61
	 * Deletes the resource or the resource list
62
	 *
63
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
64
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
65
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
66
	 */
67
	public function delete( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
68
	{
69
		return $this->defaultAction( $request, $response );
70
	}
71
72
73
	/**
74
	 * Retrieves the resource or the resource list
75
	 *
76
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
77
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
78
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
79
	 */
80
	public function get( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
81
	{
82
		return $this->defaultAction( $request, $response );
83
	}
84
85
86
	/**
87
	 * Updates the resource or the resource list partitially
88
	 *
89
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
90
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
91
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
92
	 */
93
	public function patch( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
94
	{
95
		return $this->defaultAction( $request, $response );
96
	}
97
98
99
	/**
100
	 * Creates or updates the resource or the resource list
101
	 *
102
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
103
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
104
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
105
	 */
106
	public function post( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
107
	{
108
		return $this->defaultAction( $request, $response );
109
	}
110
111
112
	/**
113
	 * Creates or updates the resource or the resource list
114
	 *
115
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
116
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
117
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
118
	 */
119
	public function put( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
120
	{
121
		return $this->defaultAction( $request, $response );
122
	}
123
124
125
	/**
126
	 * Creates or updates the resource or the resource list
127
	 *
128
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
129
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
130
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
131
	 */
132
	public function options( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
133
	{
134
		return $this->defaultAction( $request, $response );
135
	}
136
137
138
	/**
139
	 * Returns the view object that will generate the admin output.
140
	 *
141
	 * @return \Aimeos\MW\View\Iface The view object which generates the admin output
142
	 */
143
	public function view() : \Aimeos\MW\View\Iface
144
	{
145
		if( !isset( $this->view ) ) {
146
			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...
147
		}
148
149
		return $this->view;
150
	}
151
152
153
	/**
154
	 * Sets the view object that will generate the admin output.
155
	 *
156
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the admin output
157
	 * @return \Aimeos\Client\JsonApi\Iface Reference to this object for fluent calls
158
	 */
159
	public function setView( \Aimeos\MW\View\Iface $view ) : \Aimeos\Client\JsonApi\Iface
160
	{
161
		$this->view = $view;
162
		return $this;
163
	}
164
165
166
	/**
167
	 * Returns the default response for the resource
168
	 *
169
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
170
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
171
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
172
	 */
173
	protected function defaultAction( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
174
	{
175
		$status = 403;
176
		$view = $this->view();
177
178
		$view->errors = array( array(
179
			'title' => $this->getContext()->translate( 'client/jsonapi', 'Not allowed for this resource' ),
180
		) );
181
182
		/** client/jsonapi/template-error
183
		 * Relative path to the default JSON API template
184
		 *
185
		 * The template file contains the code and processing instructions
186
		 * to generate the result shown in the JSON API body. The
187
		 * configuration string is the path to the template file relative
188
		 * to the templates directory (usually in client/jsonapi/templates).
189
		 *
190
		 * You can overwrite the template file configuration in extensions and
191
		 * provide alternative templates. These alternative templates should be
192
		 * named like the default one but with the string "standard" replaced by
193
		 * an unique name. You may use the name of your project for this. If
194
		 * you've implemented an alternative client class as well, "standard"
195
		 * should be replaced by the name of the new class.
196
		 *
197
		 * @param string Relative path to the template creating the body for the JSON API response
198
		 * @since 2017.02
199
		 * @category Developer
200
		 * @see client/jsonapi/template-delete
201
		 * @see client/jsonapi/template-patch
202
		 * @see client/jsonapi/template-post
203
		 * @see client/jsonapi/template-get
204
		 * @see client/jsonapi/template-options
205
		 */
206
		$tplconf = 'client/jsonapi/template-error';
207
		$default = 'error-standard';
208
209
		$body = $view->render( $view->config( $tplconf, $default ) );
210
211
		return $response->withHeader( 'Content-Type', 'application/vnd.api+json' )
212
			->withBody( $view->response()->createStreamFromString( $body ) )
213
			->withStatus( $status );
214
	}
215
216
217
	/**
218
	 * Returns the context item object
219
	 *
220
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
221
	 */
222
	protected function getContext() : \Aimeos\MShop\Context\Item\Iface
223
	{
224
		return $this->context;
225
	}
226
227
228
	/**
229
	 * Returns the translated title and the details of the error
230
	 *
231
	 * @param \Exception $e Thrown exception
232
	 * @param string|null $domain Translation domain
233
	 * @return array Associative list with "title" and "detail" key (if debug config is enabled)
234
	 */
235
	protected function getErrorDetails( \Exception $e, string $domain = null ) : array
236
	{
237
		$details = [];
238
239
		if( $domain !== null ) {
240
			$details['title'] = $this->context->translate( $domain, $e->getMessage() );
241
		} else {
242
			$details['title'] = $e->getMessage();
243
		}
244
245
		/** client/jsonapi/debug
246
		 * Send debug information withing responses to clients if an error occurrs
247
		 *
248
		 * By default, the Aimeos client JSON REST API won't send any details
249
		 * besides the error message to the client if an error occurred. This
250
		 * prevents leaking sensitive information to attackers. For debugging
251
		 * your requests it's helpful to see the stack strace. If you set this
252
		 * configuration option to true, the stack trace will be returned too.
253
		 *
254
		 * @param boolean True to return the stack trace in JSON response, false for error message only
255
		 * @since 2017.07
256
		 * @category Developer
257
		 */
258
		if( $this->context->getConfig()->get( 'client/jsonapi/debug', false ) == true ) {
259
			$details['detail'] = $e->getTraceAsString();
260
		}
261
262
		return [$details]; // jsonapi.org requires a list of error objects
263
	}
264
265
266
	/**
267
	 * Returns the path to the client
268
	 *
269
	 * @return string Client path, e.g. "product/property"
270
	 */
271
	protected function getPath() : string
272
	{
273
		return $this->path;
274
	}
275
276
277
	/**
278
	 * Initializes the criteria object based on the given parameter
279
	 *
280
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
281
	 * @param array $params List of criteria data with condition, sorting and paging
282
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
283
	 */
284
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
285
	{
286
		return $criteria->order( $params['sort'] ?? [] )
287
			->add( $criteria->parse( $params['filter'] ?? [] ) )
288
			->slice( $params['page']['offset'] ?? 0, $params['page']['limit'] ?? 25 );
289
	}
290
291
292
	/**
293
	 * Returns the available REST verbs and the available parameters
294
	 *
295
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
296
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
297
	 * @param string $allow Allowed HTTP methods
298
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
299
	 */
300
	public function getOptionsResponse( ServerRequestInterface $request, ResponseInterface $response, string $allow ) : \Psr\Http\Message\ResponseInterface
301
	{
302
		$view = $this->view();
303
304
		$tplconf = 'client/jsonapi/template-options';
305
		$default = 'options-standard';
306
307
		$body = $view->render( $view->config( $tplconf, $default ) );
308
309
		return $response->withHeader( 'Allow', $allow )
310
			->withHeader( 'Cache-Control', 'max-age=300' )
311
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
312
			->withBody( $view->response()->createStreamFromString( $body ) )
313
			->withStatus( 200 );
314
	}
315
}
316