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

Standard   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 333
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 32
eloc 164
c 1
b 0
f 0
dl 0
loc 333
rs 9.84

6 Methods

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