Passed
Push — master ( 0de2f4...fcf15e )
by Aimeos
02:41
created

Standard::patch()   B

Complexity

Conditions 7
Paths 34

Size

Total Lines 34
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 34
rs 8.8333
c 0
b 0
f 0
cc 7
nc 34
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017-2018
6
 * @package Client
7
 * @subpackage JsonApi
8
 */
9
10
11
namespace Aimeos\Client\JsonApi\Customer;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API standard client
19
 *
20
 * @package Client
21
 * @subpackage JsonApi
22
 */
23
class Standard
24
	extends \Aimeos\Client\JsonApi\Base
25
	implements \Aimeos\Client\JsonApi\Iface
26
{
27
	/**
28
	 * Deletes the resource or the resource list
29
	 *
30
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
31
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
32
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
33
	 */
34
	public function delete( ServerRequestInterface $request, ResponseInterface $response )
35
	{
36
		$view = $this->getView();
37
38
		try
39
		{
40
			\Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' )->use( [] )->delete();
1 ignored issue
show
Bug introduced by
The method use() does not exist on Aimeos\Controller\Frontend\Iface. It seems like you code against a sub-type of said class. However, the method does not exist in Aimeos\Controller\Frontend\Common\Iface or Aimeos\Controller\Frontend\Common\Decorator\Iface or Aimeos\Controller\Fronte...ommon\Decorator\Example. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

40
			\Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' )->/** @scrutinizer ignore-call */ use( [] )->delete();
Loading history...
41
			$status = 200;
42
		}
43
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
44
		{
45
			$status = 403;
46
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
47
		}
48
		catch( \Aimeos\MShop\Exception $e )
49
		{
50
			$status = 404;
51
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
52
		}
53
		catch( \Exception $e )
54
		{
55
			$status = 500;
56
			$view->errors = $this->getErrorDetails( $e );
57
		}
58
59
		return $this->render( $response, $view, $status );
60
	}
61
62
63
	/**
64
	 * Returns the resource or the resource list
65
	 *
66
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
67
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
68
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
69
	 */
70
	public function get( ServerRequestInterface $request, ResponseInterface $response )
71
	{
72
		$view = $this->getView();
73
74
		try
75
		{
76
			$ref = $view->param( 'include', [] );
0 ignored issues
show
Unused Code introduced by
The assignment to $ref is dead and can be removed.
Loading history...
77
			$ref = ( $inc = $view->param( 'include' ) ) ? explode( ',', $inc ) : [];
78
79
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' );
80
			$view->item = $cntl->use( $ref )->get();
81
			$status = 200;
82
		}
83
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
84
		{
85
			$status = 403;
86
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
87
		}
88
		catch( \Aimeos\MShop\Exception $e )
89
		{
90
			$status = 404;
91
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
92
		}
93
		catch( \Exception $e )
94
		{
95
			$status = 500;
96
			$view->errors = $this->getErrorDetails( $e );
97
		}
98
99
		return $this->render( $response, $view, $status );
100
	}
101
102
103
	/**
104
	 * Updates the resource or the resource list partitially
105
	 *
106
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
107
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
108
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
109
	 */
110
	public function patch( ServerRequestInterface $request, ResponseInterface $response )
111
	{
112
		$view = $this->getView();
113
114
		try
115
		{
116
			$body = (string) $request->getBody();
117
			$ref = ( $inc = $view->param( 'include' ) ) ? explode( ',', $inc ) : [];
118
119
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data->attributes ) ) {
120
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
121
			}
122
123
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' )->use( $ref );
124
			$view->item = $cntl->add( (array) $payload->data->attributes )->store()->get();
125
			$status = 200;
126
		}
127
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
128
		{
129
			$status = 403;
130
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
131
		}
132
		catch( \Aimeos\MShop\Exception $e )
133
		{
134
			$status = 404;
135
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
136
		}
137
		catch( \Exception $e )
138
		{
139
			$status = 500;
140
			$view->errors = $this->getErrorDetails( $e );
141
		}
142
143
		return $this->render( $response, $view, $status );
144
	}
145
146
147
	/**
148
	 * Creates or updates the resource or the resource list
149
	 *
150
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
151
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
152
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
153
	 */
154
	public function post( ServerRequestInterface $request, ResponseInterface $response )
155
	{
156
		$view = $this->getView();
157
158
		try
159
		{
160
			$body = (string) $request->getBody();
161
162
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data->attributes ) ) {
163
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
164
			}
165
166
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' )->use( [] );
167
			$view->item = $cntl->add( (array) $payload->data->attributes )->store()->get();
168
			$view->nodata = true; // only expose customer ID to attackers
169
			$status = 201;
170
		}
171
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
172
		{
173
			$status = 403;
174
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
175
		}
176
		catch( \Aimeos\MShop\Exception $e )
177
		{
178
			$status = 404;
179
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
180
		}
181
		catch( \Exception $e )
182
		{
183
			$status = 500;
184
			$view->errors = $this->getErrorDetails( $e );
185
		}
186
187
		return $this->render( $response, $view, $status );
188
	}
189
190
191
	/**
192
	 * Returns the available REST verbs and the available parameters
193
	 *
194
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
195
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
196
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
197
	 */
198
	public function options( ServerRequestInterface $request, ResponseInterface $response )
199
	{
200
		$view = $this->getView();
201
202
		$view->attributes = [
203
			'customer.salutation' => [
204
				'label' => 'Customer salutation, i.e. "comany" ,"mr", "mrs", "miss" or ""',
205
				'type' => 'string', 'default' => '', 'required' => false,
206
			],
207
			'customer.company' => [
208
				'label' => 'Company name',
209
				'type' => 'string', 'default' => '', 'required' => false,
210
			],
211
			'customer.vatid' => [
212
				'label' => 'VAT ID of the company',
213
				'type' => 'string', 'default' => '', 'required' => false,
214
			],
215
			'customer.title' => [
216
				'label' => 'Title of the customer',
217
				'type' => 'string', 'default' => '', 'required' => false,
218
			],
219
			'customer.firstname' => [
220
				'label' => 'First name of the customer',
221
				'type' => 'string', 'default' => '', 'required' => false,
222
			],
223
			'customer.lastname' => [
224
				'label' => 'Last name of the customer or full name',
225
				'type' => 'string', 'default' => '', 'required' => true,
226
			],
227
			'customer.address1' => [
228
				'label' => 'First address part like street',
229
				'type' => 'string', 'default' => '', 'required' => true,
230
			],
231
			'customer.address2' => [
232
				'label' => 'Second address part like house number',
233
				'type' => 'string', 'default' => '', 'required' => false,
234
			],
235
			'customer.address3' => [
236
				'label' => 'Third address part like flat number',
237
				'type' => 'string', 'default' => '', 'required' => false,
238
			],
239
			'customer.postal' => [
240
				'label' => 'Zip code of the city',
241
				'type' => 'string', 'default' => '', 'required' => false,
242
			],
243
			'customer.city' => [
244
				'label' => 'Name of the town/city',
245
				'type' => 'string', 'default' => '', 'required' => true,
246
			],
247
			'customer.state' => [
248
				'label' => 'Two letter code of the country state',
249
				'type' => 'string', 'default' => '', 'required' => false,
250
			],
251
			'customer.countryid' => [
252
				'label' => 'Two letter ISO country code',
253
				'type' => 'string', 'default' => '', 'required' => true,
254
			],
255
			'customer.languageid' => [
256
				'label' => 'Two or five letter ISO language code, e.g. "de" or "de_CH"',
257
				'type' => 'string', 'default' => '', 'required' => false,
258
			],
259
			'customer.telephone' => [
260
				'label' => 'Telephone number consisting of option leading "+" and digits without spaces',
261
				'type' => 'string', 'default' => '', 'required' => false,
262
			],
263
			'customer.telefax' => [
264
				'label' => 'Faximile number consisting of option leading "+" and digits without spaces',
265
				'type' => 'string', 'default' => '', 'required' => false,
266
			],
267
			'customer.email' => [
268
				'label' => 'E-mail address',
269
				'type' => 'string', 'default' => '', 'required' => false,
270
			],
271
			'customer.website' => [
272
				'label' => 'Web site including "http://" or "https://"',
273
				'type' => 'string', 'default' => '', 'required' => false,
274
			],
275
			'customer.longitude' => [
276
				'label' => 'Longitude of the customer location as float value',
277
				'type' => 'float', 'default' => '', 'required' => false,
278
			],
279
			'customer.latitude' => [
280
				'label' => 'Latitude of the customer location as float value',
281
				'type' => 'float', 'default' => '', 'required' => false,
282
			],
283
			'customer.label' => [
284
				'label' => 'Label to identify the customer, will be firstname, lastname and company if empty',
285
				'type' => 'string', 'default' => '', 'required' => true,
286
			],
287
			'customer.code' => [
288
				'label' => 'Unique customer identifier, will be the e-mail address if empty',
289
				'type' => 'string', 'default' => '', 'required' => false,
290
			],
291
			'customer.password' => [
292
				'label' => 'Password of the customer, generated if emtpy',
293
				'type' => 'string', 'default' => '', 'required' => false,
294
			],
295
			'customer.birthday' => [
296
				'label' => 'ISO date in YYYY-MM-DD format of the birthday',
297
				'type' => 'string', 'default' => '', 'required' => false,
298
			],
299
			'customer.status' => [
300
				'label' => 'Customer account status, i.e. "0" for disabled, "1" for enabled and is enabled by default',
301
				'type' => 'integer', 'default' => '1', 'required' => false,
302
			],
303
		];
304
305
		$tplconf = 'client/jsonapi/standard/template-options';
306
		$default = 'options-standard';
307
308
		$body = $view->render( $view->config( $tplconf, $default ) );
309
310
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
311
			->withHeader( 'Cache-Control', 'max-age=300' )
312
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
313
			->withBody( $view->response()->createStreamFromString( $body ) )
314
			->withStatus( 200 );
315
	}
316
317
318
	/**
319
	 * Returns the response object with the rendered header and body
320
	 *
321
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
322
	 * @param \Aimeos\MW\View\Iface $view View instance
323
	 * @param integer $status HTTP status code
324
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
325
	 */
326
	protected function render( ResponseInterface $response, \Aimeos\MW\View\Iface $view, $status )
327
	{
328
		/** client/jsonapi/customer/standard/template
329
		 * Relative path to the customer JSON API template
330
		 *
331
		 * The template file contains the code and processing instructions
332
		 * to generate the result shown in the JSON API body. The
333
		 * configuration string is the path to the template file relative
334
		 * to the templates directory (usually in client/jsonapi/templates).
335
		 *
336
		 * You can overwrite the template file configuration in extensions and
337
		 * provide alternative templates. These alternative templates should be
338
		 * named like the default one but with the string "standard" replaced by
339
		 * an unique name. You may use the name of your project for this. If
340
		 * you've implemented an alternative client class as well, "standard"
341
		 * should be replaced by the name of the new class.
342
		 *
343
		 * @param string Relative path to the template creating the body for the JSON API
344
		 * @since 2017.04
345
		 * @category Developer
346
		 */
347
		$tplconf = 'client/jsonapi/customer/standard/template';
348
		$default = 'customer/standard';
349
350
		$body = $view->render( $view->config( $tplconf, $default ) );
351
352
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
353
			->withHeader( 'Cache-Control', 'no-cache, private' )
354
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
355
			->withBody( $view->response()->createStreamFromString( $body ) )
356
			->withStatus( $status );
357
	}
358
}
359