Completed
Push — master ( cd5eb9...af944c )
by Aimeos
02:24
created

Standard::patch()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 37
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 37
rs 8.439
cc 6
eloc 21
nc 16
nop 3
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\Customer\Address;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API customer/address 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
	private $controller;
28
29
30
	/**
31
	 * Initializes the client
32
	 *
33
	 * @param \Aimeos\MShop\Context\Item\Iface $context MShop context object
34
	 * @param \Aimeos\MW\View\Iface $view View object
35
	 * @param array $templatePaths List of file system paths where the templates are stored
36
	 * @param string $path Name of the client, e.g "customer/address"
37
	 */
38
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\MW\View\Iface $view, array $templatePaths, $path )
39
	{
40
		parent::__construct( $context, $view, $templatePaths, $path );
41
42
		$this->controller = \Aimeos\Controller\Frontend\Customer\Factory::createController( $this->getContext() );
43
	}
44
45
46
	/**
47
	 * Deletes the resource or the resource list
48
	 *
49
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
50
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
51
	 * @param string|null $prefix Form parameter prefix when nesting parameters is required
52
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
53
	 */
54
	public function delete( ServerRequestInterface $request, ResponseInterface $response, $prefix = null )
55
	{
56
		$view = $this->getView();
57
		$view->prefix = $prefix;
58
59
		try
60
		{
61
			$relId = $view->param( 'relatedid' );
62
			$body = (string) $request->getBody();
63
64
			if( $relId === '' || $relId === null )
65
			{
66
				if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) ) {
67
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
68
				}
69
70
				if( !is_array( $payload->data ) ) {
71
					$payload->data = [$payload->data];
72
				}
73
74
				foreach( $payload->data as $entry )
75
				{
76
					if( !isset( $entry->id ) ) {
77
						throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'ID is missing' ), 400 );
78
					}
79
80
					$this->controller->deleteAddressItem( $entry->id );
81
				}
82
			}
83
			else
84
			{
85
				$this->controller->deleteAddressItem( $relId );
86
			}
87
88
			$status = 200;
89
		}
90
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
91
		{
92
			$status = 403;
93
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
94
		}
95
		catch( \Aimeos\MShop\Exception $e )
96
		{
97
			$status = 404;
98
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
99
		}
100
		catch( \Exception $e )
101
		{
102
			$status = 500;
103
			$view->errors = $this->getErrorDetails( $e );
104
		}
105
106
		return $this->render( $response, $view, $status );
107
	}
108
109
110
	/**
111
	 * Returns the resource or the resource list
112
	 *
113
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
114
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
115
	 * @param string|null $prefix Form parameter prefix when nesting parameters is required
116
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
117
	 */
118
	public function get( ServerRequestInterface $request, ResponseInterface $response, $prefix = null )
119
	{
120
		$view = $this->getView();
121
		$view->prefix = $prefix;
122
123
		try
124
		{
125
			$relId = $view->param( 'relatedid' );
126
			$cntl = \Aimeos\Controller\Frontend\Factory::createController( $this->getContext(), 'customer' );
127
128
			if( $relId == null ) {
129
				$view->items = $cntl->getItem( $view->param( 'id' ), ['customer/address'] )->getAddressItems();
130
			} else {
131
				$view->items = $cntl->getAddressItem( $relId );
132
			}
133
134
			$view->total = count( $view->items );
135
			$status = 200;
136
		}
137
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
138
		{
139
			$status = 403;
140
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
141
		}
142
		catch( \Aimeos\MShop\Exception $e )
143
		{
144
			$status = 404;
145
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
146
		}
147
		catch( \Exception $e )
148
		{
149
			$status = 500;
150
			$view->errors = $this->getErrorDetails( $e );
151
		}
152
153
		return $this->render( $response, $view, $status );
154
	}
155
156
157
	/**
158
	 * Updates the resource or the resource list partitially
159
	 *
160
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
161
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
162
	 * @param string|null $prefix Form parameter prefix when nesting parameters is required
163
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
164
	 */
165
	public function patch( ServerRequestInterface $request, ResponseInterface $response, $prefix = null )
166
	{
167
		$view = $this->getView();
168
		$view->prefix = $prefix;
169
170
		try
171
		{
172
			$body = (string) $request->getBody();
173
174
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data->attributes ) ) {
175
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
176
			}
177
178
			$cntl = \Aimeos\Controller\Frontend\Factory::createController( $this->getContext(), 'customer' );
179
180
			$view->items = $cntl->editAddressItem( $view->param( 'relatedid' ), (array) $payload->data->attributes );
181
			$view->total = 1;
182
			$status = 200;
183
		}
184
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
185
		{
186
			$status = 403;
187
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
188
		}
189
		catch( \Aimeos\MShop\Exception $e )
190
		{
191
			$status = 404;
192
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
193
		}
194
		catch( \Exception $e )
195
		{
196
			$status = 500;
197
			$view->errors = $this->getErrorDetails( $e );
198
		}
199
200
		return $this->render( $response, $view, $status );
201
	}
202
203
204
	/**
205
	 * Creates or updates the resource or the resource list
206
	 *
207
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
208
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
209
	 * @param string|null $prefix Form parameter prefix when nesting parameters is required
210
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
211
	 */
212
	public function post( ServerRequestInterface $request, ResponseInterface $response, $prefix = null )
213
	{
214
		$view = $this->getView();
215
		$view->prefix = $prefix;
216
217
		try
218
		{
219
			$list = [];
220
			$body = (string) $request->getBody();
221
222
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) ) {
223
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
224
			}
225
226
			if( !is_array( $payload->data ) ) {
227
				$payload->data = [$payload->data];
228
			}
229
230
			foreach( $payload->data as $entry )
231
			{
232
				if( !isset( $entry->attributes ) ) {
233
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Attributes are missing' ) );
234
				}
235
236
				$list[] = $this->controller->addAddressItem( (array) $entry->attributes );
237
			}
238
239
240
			$view->total = count( $list );
241
			$view->items = $list;
242
			$status = 201;
243
		}
244
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
245
		{
246
			$status = 403;
247
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
248
		}
249
		catch( \Aimeos\MShop\Exception $e )
250
		{
251
			$status = 404;
252
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
253
		}
254
		catch( \Exception $e )
255
		{
256
			$status = 500;
257
			$view->errors = $this->getErrorDetails( $e );
258
		}
259
260
		return $this->render( $response, $view, $status );
261
	}
262
263
264
	/**
265
	 * Returns the available REST verbs and the available parameters
266
	 *
267
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
268
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
269
	 * @param string|null $prefix Form parameter prefix when nesting parameters is required
270
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
271
	 */
272
	public function options( ServerRequestInterface $request, ResponseInterface $response, $prefix = null )
273
	{
274
		$view = $this->getView();
275
		$view->prefix = $prefix;
276
277
		$view->attributes = [
278
			'customer.address.salutation' => [
279
				'label' => 'Customer salutation, i.e. "comany" ,"mr", "mrs", "miss" or ""',
280
				'type' => 'string', 'default' => '', 'required' => false,
281
			],
282
			'customer.address.company' => [
283
				'label' => 'Company name',
284
				'type' => 'string', 'default' => '', 'required' => false,
285
			],
286
			'customer.address.vatid' => [
287
				'label' => 'VAT ID of the company',
288
				'type' => 'string', 'default' => '', 'required' => false,
289
			],
290
			'customer.address.title' => [
291
				'label' => 'Title of the customer',
292
				'type' => 'string', 'default' => '', 'required' => false,
293
			],
294
			'customer.address.firstname' => [
295
				'label' => 'First name of the customer',
296
				'type' => 'string', 'default' => '', 'required' => false,
297
			],
298
			'customer.address.lastname' => [
299
				'label' => 'Last name of the customer or full name',
300
				'type' => 'string', 'default' => '', 'required' => true,
301
			],
302
			'customer.address.address1' => [
303
				'label' => 'First address part like street',
304
				'type' => 'string', 'default' => '', 'required' => true,
305
			],
306
			'customer.address.address2' => [
307
				'label' => 'Second address part like house number',
308
				'type' => 'string', 'default' => '', 'required' => false,
309
			],
310
			'customer.address.address3' => [
311
				'label' => 'Third address part like flat number',
312
				'type' => 'string', 'default' => '', 'required' => false,
313
			],
314
			'customer.address.postal' => [
315
				'label' => 'Zip code of the city',
316
				'type' => 'string', 'default' => '', 'required' => false,
317
			],
318
			'customer.address.city' => [
319
				'label' => 'Name of the town/city',
320
				'type' => 'string', 'default' => '', 'required' => true,
321
			],
322
			'customer.address.state' => [
323
				'label' => 'Two letter code of the country state',
324
				'type' => 'string', 'default' => '', 'required' => false,
325
			],
326
			'customer.address.countryid' => [
327
				'label' => 'Two letter ISO country code',
328
				'type' => 'string', 'default' => '', 'required' => true,
329
			],
330
			'customer.address.languageid' => [
331
				'label' => 'Two or five letter ISO language code, e.g. "de" or "de_CH"',
332
				'type' => 'string', 'default' => '', 'required' => false,
333
			],
334
			'customer.address.telephone' => [
335
				'label' => 'Telephone number consisting of option leading "+" and digits without spaces',
336
				'type' => 'string', 'default' => '', 'required' => false,
337
			],
338
			'customer.address.telefax' => [
339
				'label' => 'Faximile number consisting of option leading "+" and digits without spaces',
340
				'type' => 'string', 'default' => '', 'required' => false,
341
			],
342
			'customer.address.email' => [
343
				'label' => 'E-mail address',
344
				'type' => 'string', 'default' => '', 'required' => false,
345
			],
346
			'customer.address.website' => [
347
				'label' => 'Web site including "http://" or "https://"',
348
				'type' => 'string', 'default' => '', 'required' => false,
349
			],
350
			'customer.address.longitude' => [
351
				'label' => 'Longitude of the customer location as float value',
352
				'type' => 'float', 'default' => '', 'required' => false,
353
			],
354
			'customer.address.latitude' => [
355
				'label' => 'Latitude of the customer location as float value',
356
				'type' => 'float', 'default' => '', 'required' => false,
357
			],
358
			'customer.address.label' => [
359
				'label' => 'Label to identify the customer, usually the full name',
360
				'type' => 'string', 'default' => '', 'required' => true,
361
			],
362
			'customer.address.code' => [
363
				'label' => 'Unique customer identifier, usually e-mail address',
364
				'type' => 'string', 'default' => '', 'required' => true,
365
			],
366
			'customer.address.birthday' => [
367
				'label' => 'ISO date in YYYY-MM-DD format of the birthday',
368
				'type' => 'string', 'default' => '', 'required' => false,
369
			],
370
			'customer.address.status' => [
371
				'label' => 'Customer account status, i.e. "0" for disabled, "1" for enabled',
372
				'type' => 'integer', 'default' => '1', 'required' => false,
373
			],
374
		];
375
376
		$tplconf = 'client/jsonapi/standard/template-options';
377
		$default = 'options-standard.php';
378
379
		$body = $view->render( $view->config( $tplconf, $default ) );
380
381
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
382
			->withHeader( 'Cache-Control', 'max-age=300' )
383
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
384
			->withBody( $view->response()->createStreamFromString( $body ) )
385
			->withStatus( 200 );
386
	}
387
388
389
	/**
390
	 * Returns the response object with the rendered header and body
391
	 *
392
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
393
	 * @param \Aimeos\MW\View\Iface $view View instance
394
	 * @param integer $status HTTP status code
395
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
396
	 */
397
	protected function render( ResponseInterface $response, \Aimeos\MW\View\Iface $view, $status )
398
	{
399
		/** client/jsonapi/customer/address/standard/template
400
		 * Relative path to the customer address JSON API template
401
		 *
402
		 * The template file contains the code and processing instructions
403
		 * to generate the result shown in the JSON API body. The
404
		 * configuration string is the path to the template file relative
405
		 * to the templates directory (usually in client/jsonapi/templates).
406
		 *
407
		 * You can overwrite the template file configuration in extensions and
408
		 * provide alternative templates. These alternative templates should be
409
		 * named like the default one but with the string "standard" replaced by
410
		 * an unique name. You may use the name of your project for this. If
411
		 * you've implemented an alternative client class as well, "standard"
412
		 * should be replaced by the name of the new class.
413
		 *
414
		 * @param string Relative path to the template creating the body for the JSON API
415
		 * @since 2017.07
416
		 * @category Developer
417
		 */
418
		$tplconf = 'client/jsonapi/customer/address/standard/template';
419
		$default = 'customer/address/standard.php';
420
421
		$body = $view->render( $view->config( $tplconf, $default ) );
422
423
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
424
			->withHeader( 'Cache-Control', 'no-cache, private' )
425
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
426
			->withBody( $view->response()->createStreamFromString( $body ) )
427
			->withStatus( $status );
428
	}
429
}
430