Completed
Push — master ( 838c87...d3b7f0 )
by Aimeos
02:57
created

Standard::getItem()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 25
rs 8.8571
cc 3
eloc 16
nc 4
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015
6
 * @package Admin
7
 * @subpackage JsonAdm
8
 */
9
10
11
namespace Aimeos\Admin\JsonAdm;
12
13
14
/**
15
 * JSON API standard client
16
 *
17
 * @package Admin
18
 * @subpackage JsonAdm
19
 */
20
class Standard
21
	extends \Aimeos\Admin\JsonAdm\Base
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
22
	implements \Aimeos\Admin\JsonAdm\Common\Iface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	/**
25
	 * Deletes the resource or the resource list
26
	 *
27
	 * @param string $body Request body
28
	 * @param array &$header Variable which contains the HTTP headers and the new ones afterwards
29
	 * @param integer &$status Variable which contains the HTTP status afterwards
30
	 * @return string Content for response body
31
	 */
32
	public function delete( $body, array &$header, &$status )
33
	{
34
		$header = array( 'Content-Type' => 'application/vnd.api+json; supported-ext="bulk"' );
35
		$view = $this->getView();
36
37
		try
38
		{
39
			$view = $this->deleteItems( $view, $body );
40
			$status = 200;
41
		}
42
		catch( \Aimeos\Admin\JsonAdm\Exception $e )
43
		{
44
			$status = $e->getCode();
45
			$view->errors = array( array(
46
				'title' => $this->getContext()->getI18n()->dt( 'admin/jsonadm', $e->getMessage() ),
47
				'detail' => $e->getTraceAsString(),
48
			) );
49
		}
50
		catch( \Aimeos\MShop\Exception $e )
51
		{
52
			$status = 404;
53
			$view->errors = array( array(
54
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
55
				'detail' => $e->getTraceAsString(),
56
			) );
57
		}
58
		catch( \Exception $e )
59
		{
60
			$status = 500;
61
			$view->errors = array( array(
62
				'title' => $e->getMessage(),
63
				'detail' => $e->getTraceAsString(),
64
			) );
65
		}
66
67
		/** admin/jsonadm/standard/template-delete
68
		 * Relative path to the JSON API template for DELETE requests
69
		 *
70
		 * The template file contains the code and processing instructions
71
		 * to generate the result shown in the JSON API body. The
72
		 * configuration string is the path to the template file relative
73
		 * to the templates directory (usually in admin/jsonadm/templates).
74
		 *
75
		 * You can overwrite the template file configuration in extensions and
76
		 * provide alternative templates. These alternative templates should be
77
		 * named like the default one but with the string "standard" replaced by
78
		 * an unique name. You may use the name of your project for this. If
79
		 * you've implemented an alternative client class as well, "standard"
80
		 * should be replaced by the name of the new class.
81
		 *
82
		 * @param string Relative path to the template creating the body for the DELETE method of the JSON API
83
		 * @since 2015.12
84
		 * @category Developer
85
		 * @see admin/jsonadm/standard/template-get
86
		 * @see admin/jsonadm/standard/template-patch
87
		 * @see admin/jsonadm/standard/template-post
88
		 * @see admin/jsonadm/standard/template-put
89
		 * @see admin/jsonadm/standard/template-options
90
		 */
91
		$tplconf = 'admin/jsonadm/standard/template-delete';
92
		$default = 'delete-default.php';
93
94
		return $view->render( $view->config( $tplconf, $default ) );
95
	}
96
97
98
	/**
99
	 * Returns the requested resource or the resource list
100
	 *
101
	 * @param string $body Request body
102
	 * @param array &$header Variable which contains the HTTP headers and the new ones afterwards
103
	 * @param integer &$status Variable which contains the HTTP status afterwards
104
	 * @return string Content for response body
105
	 */
106
	public function get( $body, array &$header, &$status )
107
	{
108
		$header = array( 'Content-Type' => 'application/vnd.api+json; supported-ext="bulk"' );
109
		$view = $this->getView();
110
111
		try
112
		{
113
			$view = $this->getItem( $view );
114
			$status = 200;
115
		}
116
		catch( \Aimeos\MShop\Exception $e )
117
		{
118
			$status = 404;
119
			$view->errors = array( array(
120
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
121
				'detail' => $e->getTraceAsString(),
122
			) );
123
		}
124
		catch( \Exception $e )
125
		{
126
			$status = 500;
127
			$view->errors = array( array(
128
				'title' => $e->getMessage(),
129
				'detail' => $e->getTraceAsString(),
130
			) );
131
		}
132
133
		/** admin/jsonadm/standard/template-get
134
		 * Relative path to the JSON API template for GET requests
135
		 *
136
		 * The template file contains the code and processing instructions
137
		 * to generate the result shown in the JSON API body. The
138
		 * configuration string is the path to the template file relative
139
		 * to the templates directory (usually in admin/jsonadm/templates).
140
		 *
141
		 * You can overwrite the template file configuration in extensions and
142
		 * provide alternative templates. These alternative templates should be
143
		 * named like the default one but with the string "standard" replaced by
144
		 * an unique name. You may use the name of your project for this. If
145
		 * you've implemented an alternative client class as well, "standard"
146
		 * should be replaced by the name of the new class.
147
		 *
148
		 * @param string Relative path to the template creating the body for the GET method of the JSON API
149
		 * @since 2015.12
150
		 * @category Developer
151
		 * @see admin/jsonadm/standard/template-delete
152
		 * @see admin/jsonadm/standard/template-patch
153
		 * @see admin/jsonadm/standard/template-post
154
		 * @see admin/jsonadm/standard/template-put
155
		 * @see admin/jsonadm/standard/template-options
156
		 */
157
		$tplconf = 'admin/jsonadm/standard/template-get';
158
		$default = 'get-default.php';
159
160
		return $view->render( $view->config( $tplconf, $default ) );
161
	}
162
163
164
	/**
165
	 * Updates the resource or the resource list partitially
166
	 *
167
	 * @param string $body Request body
168
	 * @param array &$header Variable which contains the HTTP headers and the new ones afterwards
169
	 * @param integer &$status Variable which contains the HTTP status afterwards
170
	 * @return string Content for response body
171
	 */
172
	public function patch( $body, array &$header, &$status )
173
	{
174
		$header = array( 'Content-Type' => 'application/vnd.api+json; supported-ext="bulk"' );
175
		$view = $this->getView();
176
177
		try
178
		{
179
			$view = $this->patchItems( $view, $body, $header );
180
			$status = 200;
181
		}
182
		catch( \Aimeos\Admin\JsonAdm\Exception $e )
183
		{
184
			$status = $e->getCode();
185
			$view->errors = array( array(
186
				'title' => $this->getContext()->getI18n()->dt( 'admin/jsonadm', $e->getMessage() ),
187
				'detail' => $e->getTraceAsString(),
188
			) );
189
		}
190
		catch( \Aimeos\MShop\Exception $e )
191
		{
192
			$status = 404;
193
			$view->errors = array( array(
194
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
195
				'detail' => $e->getTraceAsString(),
196
			) );
197
		}
198
		catch( \Exception $e )
199
		{
200
			$status = 500;
201
			$view->errors = array( array(
202
				'title' => $e->getMessage(),
203
				'detail' => $e->getTraceAsString(),
204
			) );
205
		}
206
207
		/** admin/jsonadm/standard/template-patch
208
		 * Relative path to the JSON API template for PATCH requests
209
		 *
210
		 * The template file contains the code and processing instructions
211
		 * to generate the result shown in the JSON API body. The
212
		 * configuration string is the path to the template file relative
213
		 * to the templates directory (usually in admin/jsonadm/templates).
214
		 *
215
		 * You can overwrite the template file configuration in extensions and
216
		 * provide alternative templates. These alternative templates should be
217
		 * named like the default one but with the string "standard" replaced by
218
		 * an unique name. You may use the name of your project for this. If
219
		 * you've implemented an alternative client class as well, "standard"
220
		 * should be replaced by the name of the new class.
221
		 *
222
		 * @param string Relative path to the template creating the body for the PATCH method of the JSON API
223
		 * @since 2015.12
224
		 * @category Developer
225
		 * @see admin/jsonadm/standard/template-get
226
		 * @see admin/jsonadm/standard/template-post
227
		 * @see admin/jsonadm/standard/template-delete
228
		 * @see admin/jsonadm/standard/template-put
229
		 * @see admin/jsonadm/standard/template-options
230
		 */
231
		$tplconf = 'admin/jsonadm/standard/template-patch';
232
		$default = 'patch-default.php';
233
234
		return $view->render( $view->config( $tplconf, $default ) );
235
	}
236
237
238
	/**
239
	 * Creates or updates the resource or the resource list
240
	 *
241
	 * @param string $body Request body
242
	 * @param array &$header Variable which contains the HTTP headers and the new ones afterwards
243
	 * @param integer &$status Variable which contains the HTTP status afterwards
244
	 * @return string Content for response body
245
	 */
246
	public function post( $body, array &$header, &$status )
247
	{
248
		$header = array( 'Content-Type' => 'application/vnd.api+json; supported-ext="bulk"' );
249
		$view = $this->getView();
250
251
		try
252
		{
253
			$view = $this->postItems( $view, $body, $header );
254
			$status = 201;
255
		}
256
		catch( \Aimeos\Admin\JsonAdm\Exception $e )
257
		{
258
			$status = $e->getCode();
259
			$view->errors = array( array(
260
				'title' => $this->getContext()->getI18n()->dt( 'admin/jsonadm', $e->getMessage() ),
261
				'detail' => $e->getTraceAsString(),
262
			) );
263
		}
264
		catch( \Aimeos\MShop\Exception $e )
265
		{
266
			$status = 404;
267
			$view->errors = array( array(
268
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
269
				'detail' => $e->getTraceAsString(),
270
			) );
271
		}
272
		catch( \Exception $e )
273
		{
274
			$status = 500;
275
			$view->errors = array( array(
276
				'title' => $e->getMessage(),
277
				'detail' => $e->getTraceAsString(),
278
			) );
279
		}
280
281
		/** admin/jsonadm/standard/template-post
282
		 * Relative path to the JSON API template for POST requests
283
		 *
284
		 * The template file contains the code and processing instructions
285
		 * to generate the result shown in the JSON API body. The
286
		 * configuration string is the path to the template file relative
287
		 * to the templates directory (usually in admin/jsonadm/templates).
288
		 *
289
		 * You can overwrite the template file configuration in extensions and
290
		 * provide alternative templates. These alternative templates should be
291
		 * named like the default one but with the string "standard" replaced by
292
		 * an unique name. You may use the name of your project for this. If
293
		 * you've implemented an alternative client class as well, "standard"
294
		 * should be replaced by the name of the new class.
295
		 *
296
		 * @param string Relative path to the template creating the body for the POST method of the JSON API
297
		 * @since 2015.12
298
		 * @category Developer
299
		 * @see admin/jsonadm/standard/template-get
300
		 * @see admin/jsonadm/standard/template-patch
301
		 * @see admin/jsonadm/standard/template-delete
302
		 * @see admin/jsonadm/standard/template-put
303
		 * @see admin/jsonadm/standard/template-options
304
		 */
305
		$tplconf = 'admin/jsonadm/standard/template-post';
306
		$default = 'post-default.php';
307
308
		return $view->render( $view->config( $tplconf, $default ) );
309
	}
310
311
312
	/**
313
	 * Creates or updates the resource or the resource list
314
	 *
315
	 * @param string $body Request body
316
	 * @param array &$header Variable which contains the HTTP headers and the new ones afterwards
317
	 * @param integer &$status Variable which contains the HTTP status afterwards
318
	 * @return string Content for response body
319
	 */
320
	public function put( $body, array &$header, &$status )
321
	{
322
		$status = 501;
323
		$header = array( 'Content-Type' => 'application/vnd.api+json; supported-ext="bulk"' );
324
		$view = $this->getView();
325
326
		$view->errors = array( array(
327
			'title' => $this->getContext()->getI18n()->dt( 'admin/jsonadm', 'Not implemented, use PATCH instead' ),
328
		) );
329
330
		/** admin/jsonadm/standard/template-put
331
		 * Relative path to the JSON API template for PUT requests
332
		 *
333
		 * The template file contains the code and processing instructions
334
		 * to generate the result shown in the JSON API body. The
335
		 * configuration string is the path to the template file relative
336
		 * to the templates directory (usually in admin/jsonadm/templates).
337
		 *
338
		 * You can overwrite the template file configuration in extensions and
339
		 * provide alternative templates. These alternative templates should be
340
		 * named like the default one but with the string "standard" replaced by
341
		 * an unique name. You may use the name of your project for this. If
342
		 * you've implemented an alternative client class as well, "standard"
343
		 * should be replaced by the name of the new class.
344
		 *
345
		 * @param string Relative path to the template creating the body for the PUT method of the JSON API
346
		 * @since 2015.12
347
		 * @category Developer
348
		 * @see admin/jsonadm/standard/template-delete
349
		 * @see admin/jsonadm/standard/template-patch
350
		 * @see admin/jsonadm/standard/template-post
351
		 * @see admin/jsonadm/standard/template-get
352
		 * @see admin/jsonadm/standard/template-options
353
		 */
354
		$tplconf = 'admin/jsonadm/standard/template-put';
355
		$default = 'put-default.php';
356
357
		return $view->render( $view->config( $tplconf, $default ) );
358
	}
359
360
361
	/**
362
	 * Returns the available REST verbs and the available resources
363
	 *
364
	 * @param string $body Request body
365
	 * @param array &$header Variable which contains the HTTP headers and the new ones afterwards
366
	 * @param integer &$status Variable which contains the HTTP status afterwards
367
	 * @return string Content for response body
368
	 */
369
	public function options( $body, array &$header, &$status )
370
	{
371
		$context = $this->getContext();
372
		$view = $this->getView();
373
374
		try
375
		{
376
			$resources = $attributes = array();
377
378
			foreach( $this->getDomains( $view ) as $domain )
379
			{
380
				$manager = \Aimeos\MShop\Factory::createManager( $context, $domain );
381
				$resources = array_merge( $resources, $manager->getResourceType( true ) );
382
				$attributes = array_merge( $attributes, $manager->getSearchAttributes( true ) );
383
			}
384
385
			$view->resources = $resources;
386
			$view->attributes = $attributes;
387
388
			$header = array(
389
				'Content-Type' => 'application/vnd.api+json; supported-ext="bulk"',
390
				'Allow' => 'DELETE,GET,PATCH,POST,OPTIONS'
391
			);
392
			$status = 200;
393
		}
394
		catch( \Aimeos\MShop\Exception $e )
395
		{
396
			$status = 404;
397
			$view->errors = array( array(
398
				'title' => $context->getI18n()->dt( 'mshop', $e->getMessage() ),
399
				'detail' => $e->getTraceAsString(),
400
			) );
401
		}
402
		catch( \Exception $e )
403
		{
404
			$status = 500;
405
			$view->errors = array( array(
406
				'title' => $e->getMessage(),
407
				'detail' => $e->getTraceAsString(),
408
			) );
409
		}
410
411
		/** admin/jsonadm/standard/template-options
412
		 * Relative path to the JSON API template for OPTIONS requests
413
		 *
414
		 * The template file contains the code and processing instructions
415
		 * to generate the result shown in the JSON API body. The
416
		 * configuration string is the path to the template file relative
417
		 * to the templates directory (usually in admin/jsonadm/templates).
418
		 *
419
		 * You can overwrite the template file configuration in extensions and
420
		 * provide alternative templates. These alternative templates should be
421
		 * named like the default one but with the string "standard" replaced by
422
		 * an unique name. You may use the name of your project for this. If
423
		 * you've implemented an alternative client class as well, "standard"
424
		 * should be replaced by the name of the new class.
425
		 *
426
		 * @param string Relative path to the template creating the body for the OPTIONS method of the JSON API
427
		 * @since 2015.12
428
		 * @category Developer
429
		 * @see admin/jsonadm/standard/template-delete
430
		 * @see admin/jsonadm/standard/template-patch
431
		 * @see admin/jsonadm/standard/template-post
432
		 * @see admin/jsonadm/standard/template-get
433
		 * @see admin/jsonadm/standard/template-put
434
		 */
435
		$tplconf = 'admin/jsonadm/standard/template-options';
436
		$default = 'options-default.php';
437
438
		return $view->render( $view->config( $tplconf, $default ) );
439
	}
440
441
442
	/**
443
	 * Deletes one or more items
444
	 *
445
	 * @param \Aimeos\MW\View\Iface $view View instance with "param" view helper
446
	 * @param string $body Request body
447
	 * @return \Aimeos\MW\View\Iface $view View object that will contain the "total" property afterwards
448
	 * @throws \Aimeos\Admin\JsonAdm\Exception If the request body is invalid
449
	 */
450
	protected function deleteItems( \Aimeos\MW\View\Iface $view, $body )
451
	{
452
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $this->getPath() );
453
454
		if( ( $id = $view->param( 'id' ) ) == null )
455
		{
456
			if( ( $request = json_decode( $body ) ) === null || !isset( $request->data ) || !is_array( $request->data ) ) {
457
				throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Invalid JSON in body' ), 400 );
458
			}
459
460
			$ids = $this->getIds( $request );
461
			$manager->deleteItems( $ids );
462
			$view->total = count( $ids );
463
		}
464
		else
465
		{
466
			$manager->deleteItem( $id );
467
			$view->total = 1;
468
		}
469
470
		return $view;
471
	}
472
473
474
	/**
475
	 * Retrieves the item or items and adds the data to the view
476
	 *
477
	 * @param \Aimeos\MW\View\Iface $view View instance
478
	 * @return \Aimeos\MW\View\Iface View instance with additional data assigned
479
	 */
480
	protected function getItem( \Aimeos\MW\View\Iface $view )
481
	{
482
		$total = 1;
483
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $this->getPath() );
484
		$include = ( ( $include = $view->param( 'include' ) ) !== null ? explode( ',', $include ) : array() );
485
486
		if( ( $id = $view->param( 'id' ) ) == null )
487
		{
488
			$search = $this->initCriteria( $manager->createSearch(), $view->param() );
489
			$view->data = $manager->searchItems( $search, array(), $total );
490
			$view->childItems = $this->getChildItems( $view->data, $include );
491
			$view->listItems = $this->getListItems( $view->data, $include );
492
		}
493
		else
494
		{
495
			$view->data = $manager->getItem( $id, array() );
496
			$view->childItems = $this->getChildItems( array( $id => $view->data ), $include );
497
			$view->listItems = $this->getListItems( array( $id => $view->data ), $include );
498
		}
499
500
		$view->refItems = $this->getRefItems( $view->listItems );
501
		$view->total = $total;
502
503
		return $view;
504
	}
505
506
507
	/**
508
	 * Saves new attributes for one or more items
509
	 *
510
	 * @param \Aimeos\MW\View\Iface $view View that will contain the "data" and "total" properties afterwards
511
	 * @param string $body Request body
512
	 * @param array &$header Associative list of HTTP headers as value/result parameter
513
	 * @throws \Aimeos\Admin\JsonAdm\Exception If "id" parameter isn't available or the body is invalid
514
	 * @return \Aimeos\MW\View\Iface Updated view instance
515
	 */
516
	protected function patchItems( \Aimeos\MW\View\Iface $view, $body, array &$header )
517
	{
518
		if( ( $request = json_decode( $body ) ) === null || !isset( $request->data ) ) {
519
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Invalid JSON in body' ), 400 );
520
		}
521
522
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $this->getPath() );
523
524
		if( is_array( $request->data ) )
525
		{
526
			$data = $this->saveData( $manager, $request );
527
528
			$view->data = $data;
529
			$view->total = count( $data );
530
			$header['Content-Type'] = 'application/vnd.api+json; ext="bulk"; supported-ext="bulk"';
531
		}
532
		elseif( ( $id = $view->param( 'id' ) ) != null )
533
		{
534
			$request->data->id = $id;
535
			$data = $this->saveEntry( $manager, $request->data );
536
537
			$view->data = $data;
538
			$view->total = 1;
539
		}
540
		else
541
		{
542
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'No ID given' ), 400 );
543
		}
544
545
		return $view;
546
	}
547
548
549
	/**
550
	 * Creates one or more new items
551
	 *
552
	 * @param \Aimeos\MW\View\Iface $view View that will contain the "data" and "total" properties afterwards
553
	 * @param string $body Request body
554
	 * @param array &$header Associative list of HTTP headers as value/result parameter
555
	 * @return \Aimeos\MW\View\Iface Updated view instance
556
	 */
557
	protected function postItems( \Aimeos\MW\View\Iface $view, $body, array &$header )
558
	{
559
		if( ( $request = json_decode( $body ) ) === null || !isset( $request->data ) ) {
560
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Invalid JSON in body' ), 400 );
561
		}
562
563
		if( isset( $request->data->id ) || $view->param( 'id' ) != null ) {
564
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Client generated IDs are not supported' ), 403 );
565
		}
566
567
568
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), $this->getPath() );
569
570
		if( is_array( $request->data ) )
571
		{
572
			$data = $this->saveData( $manager, $request );
573
574
			$view->data = $data;
575
			$view->total = count( $data );
576
			$header['Content-Type'] = 'application/vnd.api+json; ext="bulk"; supported-ext="bulk"';
577
		}
578
		else
579
		{
580
			$request->data->id = null;
581
			$data = $this->saveEntry( $manager, $request->data );
582
583
			$view->data = $data;
584
			$view->total = 1;
585
		}
586
587
		return $view;
588
	}
589
}
590