Completed
Push — master ( 270945...1cb1eb )
by Aimeos
03:29
created

Standard   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 339
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 49
eloc 152
c 1
b 0
f 0
dl 0
loc 339
rs 8.48

6 Methods

Rating   Name   Duplication   Size   Complexity  
A options() 0 45 1
A render() 0 31 1
D delete() 0 62 15
C post() 0 49 12
B patch() 0 48 10
B get() 0 42 10

How to fix   Complexity   

Complex Class

Complex classes like Standard often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Standard, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017-2020
6
 * @package Client
7
 * @subpackage JsonApi
8
 */
9
10
11
namespace Aimeos\Client\JsonApi\Customer\Relationships;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API customer/relationships 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 ) : \Psr\Http\Message\ResponseInterface
35
	{
36
		$view = $this->getView();
37
38
		try
39
		{
40
			$body = (string) $request->getBody();
41
			$relId = $view->param( 'relatedid' );
42
			$ref = ( $inc = $view->param( 'include' ) ) ? explode( ',', $inc ) : [];
43
44
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' );
45
			$items = $cntl->uses( $ref )->get()->getListItems( $ref );
46
47
			if( $relId == null )
48
			{
49
				if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) ) {
50
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
51
				}
52
53
				if( !is_array( $payload->data ) ) {
54
					$payload->data = [$payload->data];
55
				}
56
57
				foreach( $payload->data as $entry )
58
				{
59
					if( !isset( $entry->id ) ) {
60
						throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'ID is missing' ), 400 );
61
					}
62
63
					if( isset( $items[$entry->id] ) ) {
64
						$cntl->deleteListItem( $items[$entry->id]->getDomain(), $items[$entry->id] );
65
					}
66
				}
67
68
				$cntl->store();
69
			}
70
			else
71
			{
72
				if( isset( $items[$relId] ) ) {
73
					$cntl->deleteListItem( $items[$relId]->getDomain(), $items[$relId] )->store();
74
				}
75
			}
76
77
			$status = 200;
78
		}
79
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
80
		{
81
			$status = 403;
82
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
83
		}
84
		catch( \Aimeos\MShop\Exception $e )
85
		{
86
			$status = 404;
87
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
88
		}
89
		catch( \Exception $e )
90
		{
91
			$status = $e->getCode() >= 100 && $e->getCode() < 600 ? $e->getCode() : 500;
92
			$view->errors = $this->getErrorDetails( $e );
93
		}
94
95
		return $this->render( $response, $view, $status );
96
	}
97
98
99
	/**
100
	 * Returns 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 get( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
107
	{
108
		$view = $this->getView();
109
110
		try
111
		{
112
			$relId = $view->param( 'relatedid' );
113
			$ref = ( $inc = $view->param( 'include' ) ) ? explode( ',', $inc ) : [];
114
115
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' );
116
			$items = $cntl->uses( $ref )->get()->getListItems( $ref );
117
118
			if( $relId === null )
119
			{
120
				$view->items = $items;
121
				$view->total = count( $items );
122
			}
123
			else
124
			{
125
				$view->items = isset( $items[$relId] ) ? $items[$relId] : null;
126
				$view->total = empty( $view->items ) ? 0 : 1;
127
			}
128
129
			$status = 200;
130
		}
131
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
132
		{
133
			$status = 403;
134
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
135
		}
136
		catch( \Aimeos\MShop\Exception $e )
137
		{
138
			$status = 404;
139
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
140
		}
141
		catch( \Exception $e )
142
		{
143
			$status = $e->getCode() >= 100 && $e->getCode() < 600 ? $e->getCode() : 500;
144
			$view->errors = $this->getErrorDetails( $e );
145
		}
146
147
		return $this->render( $response, $view, $status );
148
	}
149
150
151
	/**
152
	 * Updates the resource or the resource list partitially
153
	 *
154
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
155
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
156
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
157
	 */
158
	public function patch( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
159
	{
160
		$view = $this->getView();
161
162
		try
163
		{
164
			$body = (string) $request->getBody();
165
166
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data->attributes ) ) {
167
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
168
			}
169
170
			$status = 404;
171
			$view->total = 0;
172
			$relId = $view->param( 'relatedid' );
173
			$ref = ( $inc = $view->param( 'include' ) ) ? explode( ',', $inc ) : [];
174
175
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' );
176
			$items = $cntl->uses( $ref )->get()->getListItems( $ref );
177
178
			if( isset( $items[$relId] ) )
179
			{
180
				$attributes = (array) $payload->data->attributes;
181
				$listItem = $items[$relId]->fromArray( $attributes );
182
				$cntl->addListItem( $listItem->getDomain(), $listItem )->store();
183
184
				$view->items = $listItem;
185
				$view->total = 1;
186
				$status = 200;
187
			}
188
		}
189
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
190
		{
191
			$status = 403;
192
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
193
		}
194
		catch( \Aimeos\MShop\Exception $e )
195
		{
196
			$status = 404;
197
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
198
		}
199
		catch( \Exception $e )
200
		{
201
			$status = $e->getCode() >= 100 && $e->getCode() < 600 ? $e->getCode() : 500;
202
			$view->errors = $this->getErrorDetails( $e );
203
		}
204
205
		return $this->render( $response, $view, $status );
206
	}
207
208
209
	/**
210
	 * Creates or updates the resource or the resource list
211
	 *
212
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
213
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
214
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
215
	 */
216
	public function post( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
217
	{
218
		$view = $this->getView();
219
220
		try
221
		{
222
			$body = (string) $request->getBody();
223
			$ref = ( $inc = $view->param( 'include' ) ) ? explode( ',', $inc ) : [];
224
			$cntl = \Aimeos\Controller\Frontend::create( $this->getContext(), 'customer' )->uses( $ref );
225
226
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data ) ) {
227
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
228
			}
229
230
			if( !is_array( $payload->data ) ) {
231
				$payload->data = [$payload->data];
232
			}
233
234
			foreach( $payload->data as $entry )
235
			{
236
				if( !isset( $entry->attributes ) ) {
237
					throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Attributes are missing' ) );
238
				}
239
240
				$listItem = $cntl->createListItem( (array) $entry->attributes );
241
				$cntl->addListItem( $listItem->getDomain(), $listItem );
242
			}
243
244
			$view->items = $cntl->store()->get()->getListItems( $ref );
245
			$view->total = count( $view->items );
246
			$status = 201;
247
		}
248
		catch( \Aimeos\Controller\Frontend\Customer\Exception $e )
249
		{
250
			$status = 403;
251
			$view->errors = $this->getErrorDetails( $e, 'controller/frontend' );
252
		}
253
		catch( \Aimeos\MShop\Exception $e )
254
		{
255
			$status = 404;
256
			$view->errors = $this->getErrorDetails( $e, 'mshop' );
257
		}
258
		catch( \Exception $e )
259
		{
260
			$status = $e->getCode() >= 100 && $e->getCode() < 600 ? $e->getCode() : 500;
261
			$view->errors = $this->getErrorDetails( $e );
262
		}
263
264
		return $this->render( $response, $view, $status );
265
	}
266
267
268
	/**
269
	 * Returns the available REST verbs and the available parameters
270
	 *
271
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
272
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
273
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
274
	 */
275
	public function options( ServerRequestInterface $request, ResponseInterface $response ) : \Psr\Http\Message\ResponseInterface
276
	{
277
		$view = $this->getView();
278
279
		$view->attributes = [
280
			'customer.lists.refid' => [
281
				'label' => 'ID of the related domain item',
282
				'type' => 'string', 'default' => '', 'required' => true,
283
			],
284
			'customer.lists.domain' => [
285
				'label' => 'Domain of the related item, e.g. "product"',
286
				'type' => 'string', 'default' => '', 'required' => true,
287
			],
288
			'customer.lists.type' => [
289
				'label' => 'Customer relationship type, e.g. "favorite"',
290
				'type' => 'string', 'default' => '', 'required' => false,
291
			],
292
			'customer.lists.config' => [
293
				'label' => 'Associative list of key/value configuration pairs',
294
				'type' => 'string', 'default' => '[]', 'required' => false,
295
			],
296
			'customer.lists.datestart' => [
297
				'label' => 'Start date when the relationship is valied',
298
				'type' => 'string', 'default' => '', 'required' => false,
299
			],
300
			'customer.lists.dateend' => [
301
				'label' => 'End date until the relationship is valid',
302
				'type' => 'string', 'default' => '', 'required' => false,
303
			],
304
			'customer.lists.status' => [
305
				'label' => 'Status of the relationship (0=disable, 1=enabled)',
306
				'type' => 'string', 'default' => '1', 'required' => false,
307
			],
308
		];
309
310
		$tplconf = 'client/jsonapi/standard/template-options';
311
		$default = 'options-standard';
312
313
		$body = $view->render( $view->config( $tplconf, $default ) );
314
315
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
316
			->withHeader( 'Cache-Control', 'max-age=300' )
317
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
318
			->withBody( $view->response()->createStreamFromString( $body ) )
319
			->withStatus( 200 );
320
	}
321
322
323
	/**
324
	 * Returns the response object with the rendered header and body
325
	 *
326
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
327
	 * @param \Aimeos\MW\View\Iface $view View instance
328
	 * @param int $status HTTP status code
329
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
330
	 */
331
	protected function render( ResponseInterface $response, \Aimeos\MW\View\Iface $view, int $status ) : \Psr\Http\Message\ResponseInterface
332
	{
333
		/** client/jsonapi/customer/relationships/standard/template
334
		 * Relative path to the customer relationships JSON API template
335
		 *
336
		 * The template file contains the code and processing instructions
337
		 * to generate the result shown in the JSON API body. The
338
		 * configuration string is the path to the template file relative
339
		 * to the templates directory (usually in client/jsonapi/templates).
340
		 *
341
		 * You can overwrite the template file configuration in extensions and
342
		 * provide alternative templates. These alternative templates should be
343
		 * named like the default one but with the string "standard" replaced by
344
		 * an unique name. You may use the name of your project for this. If
345
		 * you've implemented an alternative client class as well, "standard"
346
		 * should be replaced by the name of the new class.
347
		 *
348
		 * @param string Relative path to the template creating the body for the JSON API
349
		 * @since 2017.07
350
		 * @category Developer
351
		 */
352
		$tplconf = 'client/jsonapi/customer/relationships/standard/template';
353
		$default = 'customer/relationships/standard';
354
355
		$body = $view->render( $view->config( $tplconf, $default ) );
356
357
		return $response->withHeader( 'Allow', 'DELETE,GET,OPTIONS,PATCH,POST' )
358
			->withHeader( 'Cache-Control', 'no-cache, private' )
359
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
360
			->withBody( $view->response()->createStreamFromString( $body ) )
361
			->withStatus( $status );
362
	}
363
}
364