Passed
Push — master ( a6b03a...955296 )
by Aimeos
02:30
created

Standard::patch()   C

Complexity

Conditions 14
Paths 157

Size

Total Lines 57
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 57
rs 5.7916
c 0
b 0
f 0
cc 14
nc 157
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Basket\Product;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API basket/product client
19
 *
20
 * @package Client
21
 * @subpackage JsonApi
22
 */
23
class Standard
24
	extends \Aimeos\Client\JsonApi\Basket\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 string $path Name of the client, e.g "basket/product"
35
	 */
36
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, $path )
37
	{
38
		parent::__construct( $context, $path );
39
40
		$this->controller = \Aimeos\Controller\Frontend\Basket\Factory::create( $this->getContext() );
41
	}
42
43
44
	/**
45
	 * Deletes the resource or the resource list
46
	 *
47
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
48
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
49
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
50
	 */
51
	public function delete( ServerRequestInterface $request, ResponseInterface $response )
52
	{
53
		$view = $this->getView();
54
55
		try
56
		{
57
			$this->clearCache();
58
			$this->controller->setType( $view->param( 'id', 'default' ) );
59
60
			$relId = $view->param( 'relatedid' );
61
			$body = (string) $request->getBody();
62
63
			if( $relId === '' || $relId === null )
64
			{
65
				if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) ) {
66
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
67
				}
68
69
				if( !is_array( $payload->data ) ) {
70
					$payload->data = [$payload->data];
71
				}
72
73
				foreach( $payload->data as $entry )
74
				{
75
					if( !isset( $entry->id ) ) {
76
						throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Position (ID) is missing' ) );
77
					}
78
79
					$this->controller->deleteProduct( $entry->id );
80
				}
81
			}
82
			else
83
			{
84
				$this->controller->deleteProduct( $relId );
85
			}
86
87
88
			$view->item = $this->controller->get();
89
			$status = 200;
90
		}
91
		catch( \Aimeos\MShop\Plugin\Provider\Exception $e )
92
		{
93
			$status = 409;
94
			$errors = $this->translatePluginErrorCodes( $e->getErrorCodes() );
95
			$view->errors = $this->getErrorDetails( $e, 'mshop' ) + $errors;
96
		}
97
		catch( \Aimeos\MShop\Exception $e )
98
		{
99
			$status = 404;
100
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
101
		}
102
		catch( \Exception $e )
103
		{
104
			$status = 500;
105
			$view->errors = $this->getErrorDetails( $e );
106
		}
107
108
		return $this->render( $response, $view, $status );
109
	}
110
111
112
	/**
113
	 * Updates the resource or the resource list partitially
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 patch( ServerRequestInterface $request, ResponseInterface $response )
120
	{
121
		$view = $this->getView();
122
123
		try
124
		{
125
			$this->clearCache();
126
			$this->controller->setType( $view->param( 'id', 'default' ) );
127
128
			$body = (string) $request->getBody();
129
			$relId = $view->param( 'relatedid' );
130
131
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) || !isset( $payload->data->attributes ) ) {
132
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
133
			}
134
135
			if( !is_array( $payload->data ) ) {
0 ignored issues
show
introduced by
The condition is_array($payload->data) is always false.
Loading history...
136
				$payload->data = [$payload->data];
137
			}
138
139
			foreach( $payload->data as $entry )
140
			{
141
				if( $relId !== '' && $relId !== null ) {
142
					$entry->id = $relId;
143
				}
144
145
				if( !isset( $entry->id ) ) {
146
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Position (ID) is missing' ) );
147
				}
148
149
				$qty = ( isset( $entry->attributes->quantity ) ? $entry->attributes->quantity : 1 );
150
				$cfgAttrCodes = ( isset( $entry->attributes->codes ) ? (array) $entry->attributes->codes : [] );
151
152
				$this->controller->editProduct( $entry->id, $qty, $cfgAttrCodes );
153
			}
154
155
			$view->item = $this->controller->get();
156
			$status = 200;
157
		}
158
		catch( \Aimeos\MShop\Plugin\Provider\Exception $e )
159
		{
160
			$status = 409;
161
			$errors = $this->translatePluginErrorCodes( $e->getErrorCodes() );
162
			$view->errors = $this->getErrorDetails( $e, 'mshop' ) + $errors;
163
		}
164
		catch( \Aimeos\MShop\Exception $e )
165
		{
166
			$status = 404;
167
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
168
		}
169
		catch( \Exception $e )
170
		{
171
			$status = 500;
172
			$view->errors = $this->getErrorDetails( $e );
173
		}
174
175
		return $this->render( $response, $view, $status );
176
	}
177
178
179
	/**
180
	 * Creates or updates the resource or the resource list
181
	 *
182
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
183
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
184
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
185
	 */
186
	public function post( ServerRequestInterface $request, ResponseInterface $response )
187
	{
188
		$view = $this->getView();
189
190
		try
191
		{
192
			$this->clearCache();
193
			$this->controller->setType( $view->param( 'id', 'default' ) );
194
195
			$body = (string) $request->getBody();
196
197
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) ) {
198
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
199
			}
200
201
			if( !is_array( $payload->data ) ) {
202
				$payload->data = [$payload->data];
203
			}
204
205
			foreach( $payload->data as $entry )
206
			{
207
				if( !isset( $entry->attributes ) || !isset( $entry->attributes->{'product.id'} ) ) {
208
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Product ID is missing' ) );
209
				}
210
211
				$qty = ( isset( $entry->attributes->quantity ) ? $entry->attributes->quantity : 1 );
212
				$stocktype = ( isset( $entry->attributes->stocktype ) ? $entry->attributes->stocktype : 'default' );
213
				$variantAttrIds = ( isset( $entry->attributes->variant ) ? (array) $entry->attributes->variant : [] );
214
				$hiddenAttrIds = ( isset( $entry->attributes->hidden ) ? (array) $entry->attributes->hidden : [] );
215
				$configAttrIds = ( isset( $entry->attributes->config ) ? get_object_vars( $entry->attributes->config ) : [] );
216
				$customAttrIds = ( isset( $entry->attributes->custom ) ? get_object_vars( $entry->attributes->custom ) : [] );
217
218
				$this->controller->addProduct( $entry->attributes->{'product.id'}, $qty, $stocktype,
219
					$variantAttrIds, $configAttrIds, $hiddenAttrIds, $customAttrIds );
220
			}
221
222
223
			$view->item = $this->controller->get();
224
			$status = 201;
225
		}
226
		catch( \Aimeos\MShop\Plugin\Provider\Exception $e )
227
		{
228
			$status = 409;
229
			$errors = $this->translatePluginErrorCodes( $e->getErrorCodes() );
230
			$view->errors = $this->getErrorDetails( $e, 'mshop' ) + $errors;
231
		}
232
		catch( \Aimeos\MShop\Exception $e )
233
		{
234
			$status = 404;
235
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
236
		}
237
		catch( \Exception $e )
238
		{
239
			$status = 500;
240
			$view->errors = $this->getErrorDetails( $e );
241
		}
242
243
		return $this->render( $response, $view, $status );
244
	}
245
246
247
	/**
248
	 * Returns the available REST verbs and the available parameters
249
	 *
250
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
251
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
252
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
253
	 */
254
	public function options( ServerRequestInterface $request, ResponseInterface $response )
255
	{
256
		$view = $this->getView();
257
258
		$view->attributes = [
259
			'product.id' => [
260
				'label' => 'Product ID from article, bundle or selection product (POST only)',
261
				'type' => 'string', 'default' => '', 'required' => true,
262
			],
263
			'quantity' => [
264
				'label' => 'Number of product items (POST only)',
265
				'type' => 'string', 'default' => '1', 'required' => false,
266
			],
267
			'stocktype' => [
268
				'label' => 'Code of the warehouse/location type (POST only)',
269
				'type' => 'string', 'default' => 'default', 'required' => false,
270
			],
271
			'variant' => [
272
				'label' => 'List of attribute IDs of the selected variant attributes (POST only)',
273
				'type' => 'array', 'default' => '[]', 'required' => false,
274
			],
275
			'config' => [
276
				'label' => 'List of attribute IDs of the selected config attributes (POST only)',
277
				'type' => 'array', 'default' => '[]', 'required' => false,
278
			],
279
			'hidden' => [
280
				'label' => 'List of attribute IDs of the hidden product attributes that will be added but should be invisible (POST only)',
281
				'type' => 'array', 'default' => '[]', 'required' => false,
282
			],
283
			'custom' => [
284
				'label' => 'List of values entered by the user for the custom attributes with the attribute IDs as keys (POST only)',
285
				'type' => 'array[<attrid>]', 'default' => '[]', 'required' => false,
286
			],
287
			'codes' => [
288
				'label' => 'List of product options (added via "config") that should be removed (PATCH only)',
289
				'type' => 'array', '' => '[]', 'required' => false,
290
			],
291
		];
292
293
		$tplconf = 'client/jsonapi/standard/template-options';
294
		$default = 'options-standard';
295
296
		$body = $view->render( $view->config( $tplconf, $default ) );
297
298
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
299
			->withHeader( 'Cache-Control', 'max-age=300' )
300
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
301
			->withBody( $view->response()->createStreamFromString( $body ) )
302
			->withStatus( 200 );
303
	}
304
305
306
	/**
307
	 * Returns the response object with the rendered header and body
308
	 *
309
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
310
	 * @param \Aimeos\MW\View\Iface $view View instance
311
	 * @param integer $status HTTP status code
312
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
313
	 */
314
	protected function render( ResponseInterface $response, \Aimeos\MW\View\Iface $view, $status )
315
	{
316
		$tplconf = 'client/jsonapi/basket/standard/template';
317
		$default = 'basket/standard';
318
319
		$body = $view->render( $view->config( $tplconf, $default ) );
320
321
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
322
			->withHeader( 'Cache-Control', 'no-cache, private' )
323
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
324
			->withBody( $view->response()->createStreamFromString( $body ) )
325
			->withStatus( $status );
326
	}
327
}
328