Passed
Branch master (d032f7)
by Aimeos
05:30
created

Standard::copy()   A

Complexity

Conditions 5
Paths 23

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 23
nc 23
nop 0
dl 0
loc 39
rs 9.2408
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017-2018
6
 * @package Admin
7
 * @subpackage JQAdm
8
 */
9
10
11
namespace Aimeos\Admin\JQAdm\Attribute;
12
13
sprintf( 'attribute' ); // for translation
14
15
16
/**
17
 * Default implementation of attribute JQAdm client.
18
 *
19
 * @package Admin
20
 * @subpackage JQAdm
21
 */
22
class Standard
23
	extends \Aimeos\Admin\JQAdm\Common\Admin\Factory\Base
24
	implements \Aimeos\Admin\JQAdm\Common\Admin\Factory\Iface
25
{
26
	/**
27
	 * Copies a resource
28
	 *
29
	 * @return string HTML output
30
	 */
31
	public function copy()
32
	{
33
		$view = $this->getView();
34
		$context = $this->getContext();
35
36
		try
37
		{
38
			if( ( $id = $view->param( 'id' ) ) === null ) {
39
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
40
			}
41
42
			$manager = \Aimeos\MShop::create( $context, 'attribute' );
43
			$view->item = $manager->getItem( $id, $this->getDomains() );
44
45
			$view->itemData = $this->toArray( $view->item, true );
46
			$view->itemSubparts = $this->getSubClientNames();
47
			$view->itemTypes = $this->getTypeItems();
48
			$view->itemBody = '';
49
50
			foreach( $this->getSubClients() as $idx => $client )
51
			{
52
				$view->tabindex = ++$idx + 1;
53
				$view->itemBody .= $client->copy();
54
			}
55
		}
56
		catch( \Aimeos\MShop\Exception $e )
57
		{
58
			$error = array( 'attribute-item' => $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
59
			$view->errors = $view->get( 'errors', [] ) + $error;
60
			$this->logException( $e );
61
		}
62
		catch( \Exception $e )
63
		{
64
			$error = array( 'attribute-item' => $e->getMessage() . ', ' . $e->getFile() . ':' . $e->getLine() );
65
			$view->errors = $view->get( 'errors', [] ) + $error;
66
			$this->logException( $e );
67
		}
68
69
		return $this->render( $view );
70
	}
71
72
73
	/**
74
	 * Creates a new resource
75
	 *
76
	 * @return string HTML output
77
	 */
78
	public function create()
79
	{
80
		$view = $this->getView();
81
		$context = $this->getContext();
82
83
		try
84
		{
85
			$data = $view->param( 'item', [] );
86
87
			if( !isset( $view->item ) ) {
88
				$view->item = \Aimeos\MShop::create( $context, 'attribute' )->createItem();
89
			}
90
91
			$data['attribute.siteid'] = $view->item->getSiteId();
92
93
			$view->itemSubparts = $this->getSubClientNames();
94
			$view->itemTypes = $this->getTypeItems();
95
			$view->itemData = $data;
96
			$view->itemBody = '';
97
98
			foreach( $this->getSubClients() as $idx => $client )
99
			{
100
				$view->tabindex = ++$idx + 1;
101
				$view->itemBody .= $client->create();
102
			}
103
		}
104
		catch( \Aimeos\MShop\Exception $e )
105
		{
106
			$error = array( 'attribute-item' => $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
107
			$view->errors = $view->get( 'errors', [] ) + $error;
108
			$this->logException( $e );
109
		}
110
		catch( \Exception $e )
111
		{
112
			$error = array( 'attribute-item' => $e->getMessage() . ', ' . $e->getFile() . ':' . $e->getLine() );
113
			$view->errors = $view->get( 'errors', [] ) + $error;
114
			$this->logException( $e );
115
		}
116
117
		return $this->render( $view );
118
	}
119
120
121
	/**
122
	 * Deletes a resource
123
	 *
124
	 * @return string|null HTML output
125
	 */
126
	public function delete()
127
	{
128
		$view = $this->getView();
129
		$context = $this->getContext();
130
131
		$manager = \Aimeos\MShop::create( $context, 'attribute' );
132
		$manager->begin();
133
134
		try
135
		{
136
			if( ( $id = $view->param( 'id' ) ) === null ) {
137
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
138
			}
139
140
			$view->item = $manager->getItem( $id, $this->getDomains() );
141
142
			foreach( $this->getSubClients() as $client ) {
143
				$client->delete();
144
			}
145
146
			$manager->saveItem( $view->item );
147
			$manager->deleteItem( $id );
148
			$manager->commit();
149
150
			$this->nextAction( $view, 'search', 'attribute', null, 'delete' );
151
			return;
152
		}
153
		catch( \Aimeos\MShop\Exception $e )
154
		{
155
			$error = array( 'attribute-item' => $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
156
			$view->errors = $view->get( 'errors', [] ) + $error;
157
			$this->logException( $e );
158
		}
159
		catch( \Exception $e )
160
		{
161
			$error = array( 'attribute-item' => $e->getMessage() . ', ' . $e->getFile() . ':' . $e->getLine() );
162
			$view->errors = $view->get( 'errors', [] ) + $error;
163
			$this->logException( $e );
164
		}
165
166
		$manager->rollback();
167
168
		return $this->search();
169
	}
170
171
172
	/**
173
	 * Returns a single resource
174
	 *
175
	 * @return string HTML output
176
	 */
177
	public function get()
178
	{
179
		$view = $this->getView();
180
		$context = $this->getContext();
181
182
		try
183
		{
184
			if( ( $id = $view->param( 'id' ) ) === null ) {
185
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
186
			}
187
188
			$manager = \Aimeos\MShop::create( $context, 'attribute' );
189
190
			$view->item = $manager->getItem( $id, $this->getDomains() );
191
			$view->itemSubparts = $this->getSubClientNames();
192
			$view->itemData = $this->toArray( $view->item );
193
			$view->itemTypes = $this->getTypeItems();
194
			$view->itemBody = '';
195
196
			foreach( $this->getSubClients() as $idx => $client )
197
			{
198
				$view->tabindex = ++$idx + 1;
199
				$view->itemBody .= $client->get();
200
			}
201
		}
202
		catch( \Aimeos\MShop\Exception $e )
203
		{
204
			$error = array( 'attribute-item' => $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
205
			$view->errors = $view->get( 'errors', [] ) + $error;
206
			$this->logException( $e );
207
		}
208
		catch( \Exception $e )
209
		{
210
			$error = array( 'attribute-item' => $e->getMessage() . ', ' . $e->getFile() . ':' . $e->getLine() );
211
			$view->errors = $view->get( 'errors', [] ) + $error;
212
			$this->logException( $e );
213
		}
214
215
		return $this->render( $view );
216
	}
217
218
219
	/**
220
	 * Saves the data
221
	 *
222
	 * @return string HTML output
223
	 */
224
	public function save()
225
	{
226
		$view = $this->getView();
227
		$context = $this->getContext();
228
229
		$manager = \Aimeos\MShop::create( $context, 'attribute' );
230
		$manager->begin();
231
232
		try
233
		{
234
			$item = $this->fromArray( $view->param( 'item', [] ) );
235
			$view->item = $item->getId() ? $item : $manager->saveItem( $item );
236
			$view->itemBody = '';
237
238
			foreach( $this->getSubClients() as $client ) {
239
				$view->itemBody .= $client->save();
240
			}
241
242
			$manager->saveItem( clone $view->item );
243
			$manager->commit();
244
245
			$this->nextAction( $view, $view->param( 'next' ), 'attribute', $view->item->getId(), 'save' );
246
			return;
247
		}
248
		catch( \Aimeos\Admin\JQAdm\Exception $e )
249
		{
250
			// fall through to create
251
		}
252
		catch( \Aimeos\MShop\Exception $e )
253
		{
254
			$error = array( 'attribute-item' => $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
255
			$view->errors = $view->get( 'errors', [] ) + $error;
256
			$this->logException( $e );
257
		}
258
		catch( \Exception $e )
259
		{
260
			$error = array( 'attribute-item' => $e->getMessage() . ', ' . $e->getFile() . ':' . $e->getLine() );
261
			$view->errors = $view->get( 'errors', [] ) + $error;
262
			$this->logException( $e );
263
		}
264
265
		$manager->rollback();
266
267
		return $this->create();
268
	}
269
270
271
	/**
272
	 * Returns a list of resource according to the conditions
273
	 *
274
	 * @return string HTML output
275
	 */
276
	public function search()
277
	{
278
		$view = $this->getView();
279
		$context = $this->getContext();
280
281
		try
282
		{
283
			$total = 0;
284
			$params = $this->storeSearchParams( $view->param(), 'attribute' );
285
			$manager = \Aimeos\MShop::create( $context, 'attribute' );
286
			$search = $this->initCriteria( $manager->createSearch(), $params );
287
288
			$view->items = $manager->searchItems( $search, $this->getDomains(), $total );
289
			$view->filterAttributes = $manager->getSearchAttributes( true );
290
			$view->filterOperators = $search->getOperators();
291
			$view->itemTypes = $this->getTypeItems();
292
			$view->total = $total;
293
			$view->itemBody = '';
294
295
			foreach( $this->getSubClients() as $client ) {
296
				$view->itemBody .= $client->search();
297
			}
298
		}
299
		catch( \Aimeos\MShop\Exception $e )
300
		{
301
			$error = array( 'attribute-item' => $context->getI18n()->dt( 'mshop', $e->getMessage() ) );
302
			$view->errors = $view->get( 'errors', [] ) + $error;
303
			$this->logException( $e );
304
		}
305
		catch( \Exception $e )
306
		{
307
			$error = array( 'attribute-item' => $e->getMessage() . ', ' . $e->getFile() . ':' . $e->getLine() );
308
			$view->errors = $view->get( 'errors', [] ) + $error;
309
			$this->logException( $e );
310
		}
311
312
		/** admin/jqadm/attribute/template-list
313
		 * Relative path to the HTML body template for the attribute list.
314
		 *
315
		 * The template file contains the HTML code and processing instructions
316
		 * to generate the result shown in the body of the frontend. The
317
		 * configuration string is the path to the template file relative
318
		 * to the templates directory (usually in admin/jqadm/templates).
319
		 *
320
		 * You can overwrite the template file configuration in extensions and
321
		 * provide alternative templates. These alternative templates should be
322
		 * named like the default one but with the string "default" replaced by
323
		 * an unique name. You may use the name of your project for this. If
324
		 * you've implemented an alternative client class as well, "default"
325
		 * should be replaced by the name of the new class.
326
		 *
327
		 * @param string Relative path to the template creating the HTML code
328
		 * @since 2017.07
329
		 * @category Developer
330
		 */
331
		$tplconf = 'admin/jqadm/attribute/template-list';
332
		$default = 'attribute/list-standard';
333
334
		return $view->render( $view->config( $tplconf, $default ) );
335
	}
336
337
338
	/**
339
	 * Returns the sub-client given by its name.
340
	 *
341
	 * @param string $type Name of the client type
342
	 * @param string|null $name Name of the sub-client (Default if null)
343
	 * @return \Aimeos\Admin\JQAdm\Iface Sub-client object
344
	 */
345
	public function getSubClient( $type, $name = null )
346
	{
347
		/** admin/jqadm/attribute/decorators/excludes
348
		 * Excludes decorators added by the "common" option from the attribute JQAdm client
349
		 *
350
		 * Decorators extend the functionality of a class by adding new aspects
351
		 * (e.g. log what is currently done), executing the methods of the underlying
352
		 * class only in certain conditions (e.g. only for logged in users) or
353
		 * modify what is returned to the caller.
354
		 *
355
		 * This option allows you to remove a decorator added via
356
		 * "client/jqadm/common/decorators/default" before they are wrapped
357
		 * around the JQAdm client.
358
		 *
359
		 *  admin/jqadm/attribute/decorators/excludes = array( 'decorator1' )
360
		 *
361
		 * This would remove the decorator named "decorator1" from the list of
362
		 * common decorators ("\Aimeos\Admin\JQAdm\Common\Decorator\*") added via
363
		 * "client/jqadm/common/decorators/default" to the JQAdm client.
364
		 *
365
		 * @param array List of decorator names
366
		 * @since 2017.07
367
		 * @category Developer
368
		 * @see admin/jqadm/common/decorators/default
369
		 * @see admin/jqadm/attribute/decorators/global
370
		 * @see admin/jqadm/attribute/decorators/local
371
		 */
372
373
		/** admin/jqadm/attribute/decorators/global
374
		 * Adds a list of globally available decorators only to the attribute JQAdm client
375
		 *
376
		 * Decorators extend the functionality of a class by adding new aspects
377
		 * (e.g. log what is currently done), executing the methods of the underlying
378
		 * class only in certain conditions (e.g. only for logged in users) or
379
		 * modify what is returned to the caller.
380
		 *
381
		 * This option allows you to wrap global decorators
382
		 * ("\Aimeos\Admin\JQAdm\Common\Decorator\*") around the JQAdm client.
383
		 *
384
		 *  admin/jqadm/attribute/decorators/global = array( 'decorator1' )
385
		 *
386
		 * This would add the decorator named "decorator1" defined by
387
		 * "\Aimeos\Admin\JQAdm\Common\Decorator\Decorator1" only to the JQAdm client.
388
		 *
389
		 * @param array List of decorator names
390
		 * @since 2017.07
391
		 * @category Developer
392
		 * @see admin/jqadm/common/decorators/default
393
		 * @see admin/jqadm/attribute/decorators/excludes
394
		 * @see admin/jqadm/attribute/decorators/local
395
		 */
396
397
		/** admin/jqadm/attribute/decorators/local
398
		 * Adds a list of local decorators only to the attribute JQAdm client
399
		 *
400
		 * Decorators extend the functionality of a class by adding new aspects
401
		 * (e.g. log what is currently done), executing the methods of the underlying
402
		 * class only in certain conditions (e.g. only for logged in users) or
403
		 * modify what is returned to the caller.
404
		 *
405
		 * This option allows you to wrap local decorators
406
		 * ("\Aimeos\Admin\JQAdm\Attribute\Decorator\*") around the JQAdm client.
407
		 *
408
		 *  admin/jqadm/attribute/decorators/local = array( 'decorator2' )
409
		 *
410
		 * This would add the decorator named "decorator2" defined by
411
		 * "\Aimeos\Admin\JQAdm\Attribute\Decorator\Decorator2" only to the JQAdm client.
412
		 *
413
		 * @param array List of decorator names
414
		 * @since 2017.07
415
		 * @category Developer
416
		 * @see admin/jqadm/common/decorators/default
417
		 * @see admin/jqadm/attribute/decorators/excludes
418
		 * @see admin/jqadm/attribute/decorators/global
419
		 */
420
		return $this->createSubClient( 'attribute/' . $type, $name );
421
	}
422
423
424
	/**
425
	 * Returns the domain names whose items should be fetched too
426
	 *
427
	 * @return string[] List of domain names
428
	 */
429
	protected function getDomains()
430
	{
431
		/** admin/jqadm/attribute/domains
432
		 * List of domain items that should be fetched along with the attribute
433
		 *
434
		 * If you need to display additional content, you can configure your own
435
		 * list of domains (attribute, media, price, attribute, text, etc. are
436
		 * domains) whose items are fetched from the storage.
437
		 *
438
		 * @param array List of domain names
439
		 * @since 2017.07
440
		 * @category Developer
441
		 */
442
		$domains = array( 'attribute/property', 'media', 'price', 'text' );
443
444
		return $this->getContext()->getConfig()->get( 'admin/jqadm/attribute/domains', $domains );
445
	}
446
447
448
	/**
449
	 * Returns the list of sub-client names configured for the client.
450
	 *
451
	 * @return array List of JQAdm client names
452
	 */
453
	protected function getSubClientNames()
454
	{
455
		/** admin/jqadm/attribute/standard/subparts
456
		 * List of JQAdm sub-clients rendered within the attribute section
457
		 *
458
		 * The output of the frontend is composed of the code generated by the JQAdm
459
		 * clients. Each JQAdm client can consist of serveral (or none) sub-clients
460
		 * that are responsible for rendering certain sub-parts of the output. The
461
		 * sub-clients can contain JQAdm clients themselves and therefore a
462
		 * hierarchical tree of JQAdm clients is composed. Each JQAdm client creates
463
		 * the output that is placed inside the container of its parent.
464
		 *
465
		 * At first, always the JQAdm code generated by the parent is printed, then
466
		 * the JQAdm code of its sub-clients. The order of the JQAdm sub-clients
467
		 * determines the order of the output of these sub-clients inside the parent
468
		 * container. If the configured list of clients is
469
		 *
470
		 *  array( "subclient1", "subclient2" )
471
		 *
472
		 * you can easily change the order of the output by reordering the subparts:
473
		 *
474
		 *  admin/jqadm/<clients>/subparts = array( "subclient1", "subclient2" )
475
		 *
476
		 * You can also remove one or more parts if they shouldn't be rendered:
477
		 *
478
		 *  admin/jqadm/<clients>/subparts = array( "subclient1" )
479
		 *
480
		 * As the clients only generates structural JQAdm, the layout defined via CSS
481
		 * should support adding, removing or reordering content by a fluid like
482
		 * design.
483
		 *
484
		 * @param array List of sub-client names
485
		 * @since 2017.07
486
		 * @category Developer
487
		 */
488
		return $this->getContext()->getConfig()->get( 'admin/jqadm/attribute/standard/subparts', [] );
489
	}
490
491
492
	/**
493
	 * Returns the available attribute type items
494
	 *
495
	 * @return array List of item implementing \Aimeos\MShop\Common\Type\Iface
496
	 */
497
	protected function getTypeItems()
498
	{
499
		$typeManager = \Aimeos\MShop::create( $this->getContext(), 'attribute/type' );
500
501
		$search = $typeManager->createSearch( true )->setSlice( 0, 10000 );
502
		$search->setSortations( [$search->sort( '+', 'attribute.type.position' )] );
503
504
		return $this->map( $typeManager->searchItems( $search ) );
505
	}
506
507
508
	/**
509
	 * Creates new and updates existing items using the data array
510
	 *
511
	 * @param string[] Data array
0 ignored issues
show
Bug introduced by
The type Aimeos\Admin\JQAdm\Attribute\Data was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
512
	 * @return \Aimeos\MShop\Attribute\Item\Iface New attribute item object
513
	 */
514
	protected function fromArray( array $data )
515
	{
516
		$manager = \Aimeos\MShop::create( $this->getContext(), 'attribute' );
517
518
		if( isset( $data['attribute.id'] ) && $data['attribute.id'] != '' ) {
519
			$item = $manager->getItem( $data['attribute.id'], $this->getDomains() );
520
		} else {
521
			$item = $manager->createItem();
522
		}
523
524
		$item->fromArray( $data );
525
526
		return $item;
527
	}
528
529
530
	/**
531
	 * Constructs the data array for the view from the given item
532
	 *
533
	 * @param \Aimeos\MShop\Attribute\Item\Iface $item Attribute item object
534
	 * @return string[] Multi-dimensional associative list of item data
535
	 */
536
	protected function toArray( \Aimeos\MShop\Attribute\Item\Iface $item, $copy = false )
537
	{
538
		$data = $item->toArray( true );
539
540
		if( $copy === true )
541
		{
542
			$data['attribute.siteid'] = $this->getContext()->getLocale()->getSiteId();
543
			$data['attribute.code'] = $data['attribute.code'] . '_copy';
544
			$data['attribute.id'] = '';
545
		}
546
547
		return $data;
548
	}
549
550
551
	/**
552
	 * Returns the rendered template including the view data
553
	 *
554
	 * @param \Aimeos\MW\View\Iface $view View object with data assigned
555
	 * @return string HTML output
556
	 */
557
	protected function render( \Aimeos\MW\View\Iface $view )
558
	{
559
		/** admin/jqadm/attribute/template-item
560
		 * Relative path to the HTML body template for the attribute item.
561
		 *
562
		 * The template file contains the HTML code and processing instructions
563
		 * to generate the result shown in the body of the frontend. The
564
		 * configuration string is the path to the template file relative
565
		 * to the templates directory (usually in admin/jqadm/templates).
566
		 *
567
		 * You can overwrite the template file configuration in extensions and
568
		 * provide alternative templates. These alternative templates should be
569
		 * named like the default one but with the string "default" replaced by
570
		 * an unique name. You may use the name of your project for this. If
571
		 * you've implemented an alternative client class as well, "default"
572
		 * should be replaced by the name of the new class.
573
		 *
574
		 * @param string Relative path to the template creating the HTML code
575
		 * @since 2017.07
576
		 * @category Developer
577
		 */
578
		$tplconf = 'admin/jqadm/attribute/template-item';
579
		$default = 'attribute/item-standard';
580
581
		return $view->render( $view->config( $tplconf, $default ) );
582
	}
583
}
584