Completed
Push — master ( a13539...bd1b6d )
by Aimeos
04:27
created

Standard::delete()   A

Complexity

Conditions 5
Paths 25

Size

Total Lines 40
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 22
nc 25
nop 0
dl 0
loc 40
rs 9.2568
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2018-2020
6
 * @package Admin
7
 * @subpackage JQAdm
8
 */
9
10
11
namespace Aimeos\Admin\JQAdm\Subscription;
12
13
sprintf( 'subscription' ); // for translation
14
15
16
/**
17
 * Default implementation of subscription 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|null HTML output
30
	 */
31
	public function copy() : ?string
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, 'subscription' );
43
			$baseManager = \Aimeos\MShop::create( $context, 'order/base' );
44
45
			$view->item = $manager->getItem( $id );
46
			$view->itemBase = $baseManager->getItem( $view->item->getOrderBaseId(), ['order/base/address', 'order/base/product'] );
47
			$view->itemData = $this->toArray( $view->item, true );
48
			$view->itemSubparts = $this->getSubClientNames();
49
			$view->itemBody = '';
50
51
			foreach( $this->getSubClients() as $idx => $client )
52
			{
53
				$view->tabindex = ++$idx + 1;
54
				$view->itemBody .= $client->copy();
55
			}
56
		}
57
		catch( \Exception $e )
58
		{
59
			$this->report( $e, 'copy' );
60
		}
61
62
		return $this->render( $view );
63
	}
64
65
66
	/**
67
	 * Creates a new resource
68
	 *
69
	 * @return string|null HTML output
70
	 */
71
	public function create() : ?string
72
	{
73
		$view = $this->getView();
74
		$context = $this->getContext();
75
76
		try
77
		{
78
			$data = $view->param( 'item', [] );
79
80
			if( !isset( $view->item ) ) {
81
				$view->item = \Aimeos\MShop::create( $context, 'subscription' )->createItem();
82
			}
83
84
			$baseManager = \Aimeos\MShop::create( $context, 'order/base' );
85
			$baseId = ( $view->item->getOrderBaseId() ?: $view->param( 'item/subscription.ordbaseid' ) );
86
87
			if( $baseId ) {
88
				$view->itemBase = $baseManager->getItem( $baseId, ['order/base/address', 'order/base/product'] );
89
			} else {
90
				$view->itemBase = $baseManager->createItem();
91
			}
92
93
			$data['subscription.siteid'] = $view->item->getSiteId();
94
95
			$view->itemSubparts = $this->getSubClientNames();
96
			$view->itemData = $data;
97
			$view->itemBody = '';
98
99
			foreach( $this->getSubClients() as $idx => $client )
100
			{
101
				$view->tabindex = ++$idx + 1;
102
				$view->itemBody .= $client->create();
103
			}
104
		}
105
		catch( \Exception $e )
106
		{
107
			$this->report( $e, 'create' );
108
		}
109
110
		return $this->render( $view );
111
	}
112
113
114
	/**
115
	 * Deletes a resource
116
	 *
117
	 * @return string|null HTML output
118
	 */
119
	public function delete() : ?string
120
	{
121
		$view = $this->getView();
122
		$context = $this->getContext();
123
124
		$manager = \Aimeos\MShop::create( $context, 'subscription' );
125
		$manager->begin();
126
127
		try
128
		{
129
			if( ( $ids = $view->param( 'id' ) ) === null ) {
130
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
131
			}
132
133
			$search = $manager->createSearch()->setSlice( 0, count( (array) $ids ) );
134
			$search->setConditions( $search->compare( '==', 'subscription.id', $ids ) );
135
			$items = $manager->searchItems( $search );
136
137
			foreach( $items as $item )
138
			{
139
				$view->item = $item;
140
141
				foreach( $this->getSubClients() as $client ) {
142
					$client->delete();
143
				}
144
			}
145
146
			$manager->deleteItems( $items->toArray() );
147
			$manager->commit();
148
149
			$this->nextAction( $view, 'search', 'subscription', null, 'delete' );
150
			return null;
151
		}
152
		catch( \Exception $e )
153
		{
154
			$manager->rollback();
155
			$this->report( $e, 'delete' );
156
		}
157
158
		return $this->search();
159
	}
160
161
162
	/**
163
	 * Exports a resource
164
	 *
165
	 * @return string Admin output to display
166
	 */
167
	public function export() : ?string
168
	{
169
		$view = $this->getView();
170
		$context = $this->getContext();
171
172
		try
173
		{
174
			$params = $this->storeSearchParams( $view->param(), 'subscription' );
175
			$msg = ['sitecode' => $context->getLocale()->getSiteItem()->getCode()];
176
177
			if( isset( $params['filter'] ) ) {
178
				$msg['filter'] = $this->getCriteriaConditions( $params['filter'] );
179
			}
180
181
			if( isset( $params['sort'] ) ) {
182
				$msg['sort'] = $this->getCriteriaSortations( $params['sort'] );
183
			}
184
185
			$mq = $context->getMessageQueueManager()->get( 'mq-admin' )->getQueue( 'subscription-export' );
186
			$mq->add( json_encode( $msg ) );
187
188
			$msg = $context->getI18n()->dt( 'admin', 'Your export will be available in a few minutes for download' );
189
			$view->info = $view->get( 'info', [] ) + ['subscription-item' => $msg];
190
		}
191
		catch( \Exception $e )
192
		{
193
			$this->report( $e, 'export' );
194
		}
195
196
		return $this->search();
197
	}
198
199
200
	/**
201
	 * Returns a single resource
202
	 *
203
	 * @return string|null HTML output
204
	 */
205
	public function get() : ?string
206
	{
207
		$view = $this->getView();
208
		$context = $this->getContext();
209
210
		try
211
		{
212
			if( ( $id = $view->param( 'id' ) ) === null ) {
213
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
214
			}
215
216
			$manager = \Aimeos\MShop::create( $context, 'subscription' );
217
			$baseManager = \Aimeos\MShop::create( $context, 'order/base' );
218
219
			$view->item = $manager->getItem( $id );
220
			$view->itemBase = $baseManager->getItem( $view->item->getOrderBaseId(), ['order/base/address', 'order/base/product'] );
221
			$view->itemSubparts = $this->getSubClientNames();
222
			$view->itemData = $this->toArray( $view->item );
223
			$view->itemBody = '';
224
225
			foreach( $this->getSubClients() as $idx => $client )
226
			{
227
				$view->tabindex = ++$idx + 1;
228
				$view->itemBody .= $client->get();
229
			}
230
		}
231
		catch( \Exception $e )
232
		{
233
			$this->report( $e, 'get' );
234
		}
235
236
		return $this->render( $view );
237
	}
238
239
240
	/**
241
	 * Saves the data
242
	 *
243
	 * @return string|null HTML output
244
	 */
245
	public function save() : ?string
246
	{
247
		$view = $this->getView();
248
		$context = $this->getContext();
249
250
		$manager = \Aimeos\MShop::create( $context, 'subscription' );
251
		$manager->begin();
252
253
		try
254
		{
255
			$item = $this->fromArray( $view->param( 'item', [] ) );
256
			$view->item = $item->getId() ? $item : $manager->saveItem( $item );
0 ignored issues
show
Bug introduced by
The method saveItem() does not exist on Aimeos\MShop\Common\Manager\Iface. Did you maybe mean saveItems()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

256
			$view->item = $item->getId() ? $item : $manager->/** @scrutinizer ignore-call */ saveItem( $item );

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
257
			$view->itemBody = '';
258
259
			foreach( $this->getSubClients() as $client ) {
260
				$view->itemBody .= $client->save();
261
			}
262
263
			$manager->saveItem( clone $view->item );
264
			$manager->commit();
265
266
			$this->nextAction( $view, $view->param( 'next' ), 'subscription', $view->item->getId(), 'save' );
267
			return null;
268
		}
269
		catch( \Exception $e )
270
		{
271
			$manager->rollback();
272
			$this->report( $e, 'save' );
273
		}
274
275
		return $this->create();
276
	}
277
278
279
	/**
280
	 * Returns a list of resource according to the conditions
281
	 *
282
	 * @return string|null HTML output
283
	 */
284
	public function search() : ?string
285
	{
286
		$view = $this->getView();
287
		$context = $this->getContext();
288
289
		try
290
		{
291
			$total = 0;
292
			$params = $this->storeSearchParams( $view->param(), 'subscription' );
293
			$manager = \Aimeos\MShop::create( $context, 'subscription' );
294
295
			$search = $manager->createSearch();
296
			$search->setSortations( [$search->sort( '-', 'subscription.ctime' )] );
297
			$search = $this->initCriteria( $search, $params );
298
299
			$view->items = $manager->searchItems( $search, [], $total );
300
			$view->baseItems = $this->getOrderBaseItems( $view->items );
301
			$view->filterAttributes = $manager->getSearchAttributes( true );
302
			$view->filterOperators = $search->getOperators();
303
			$view->total = $total;
304
			$view->itemBody = '';
305
306
			foreach( $this->getSubClients() as $client ) {
307
				$view->itemBody .= $client->search();
308
			}
309
		}
310
		catch( \Exception $e )
311
		{
312
			$this->report( $e, 'search' );
313
		}
314
315
		/** admin/jqadm/subscription/template-list
316
		 * Relative path to the HTML body template for the subscription list.
317
		 *
318
		 * The template file contains the HTML code and processing instructions
319
		 * to generate the result shown in the body of the frontend. The
320
		 * configuration string is the path to the template file relative
321
		 * to the templates directory (usually in admin/jqadm/templates).
322
		 *
323
		 * You can overwrite the template file configuration in extensions and
324
		 * provide alternative templates. These alternative templates should be
325
		 * named like the default one but with the string "default" replaced by
326
		 * an unique name. You may use the name of your project for this. If
327
		 * you've implemented an alternative client class as well, "default"
328
		 * should be replaced by the name of the new class.
329
		 *
330
		 * @param string Relative path to the template creating the HTML code
331
		 * @since 2016.04
332
		 * @category Developer
333
		 */
334
		$tplconf = 'admin/jqadm/subscription/template-list';
335
		$default = 'subscription/list-standard';
336
337
		return $view->render( $view->config( $tplconf, $default ) );
338
	}
339
340
341
	/**
342
	 * Returns the sub-client given by its name.
343
	 *
344
	 * @param string $type Name of the client type
345
	 * @param string|null $name Name of the sub-client (Default if null)
346
	 * @return \Aimeos\Admin\JQAdm\Iface Sub-client object
347
	 */
348
	public function getSubClient( string $type, string $name = null ) : \Aimeos\Admin\JQAdm\Iface
349
	{
350
		/** admin/jqadm/subscription/decorators/excludes
351
		 * Excludes decorators added by the "common" option from the subscription JQAdm client
352
		 *
353
		 * Decorators extend the functionality of a class by adding new aspects
354
		 * (e.g. log what is currently done), executing the methods of the underlying
355
		 * class only in certain conditions (e.g. only for logged in users) or
356
		 * modify what is returned to the caller.
357
		 *
358
		 * This option allows you to remove a decorator added via
359
		 * "client/jqadm/common/decorators/default" before they are wrapped
360
		 * around the JQAdm client.
361
		 *
362
		 *  admin/jqadm/subscription/decorators/excludes = array( 'decorator1' )
363
		 *
364
		 * This would remove the decorator named "decorator1" from the list of
365
		 * common decorators ("\Aimeos\Admin\JQAdm\Common\Decorator\*") added via
366
		 * "client/jqadm/common/decorators/default" to the JQAdm client.
367
		 *
368
		 * @param array List of decorator names
369
		 * @since 2018.04
370
		 * @category Developer
371
		 * @see admin/jqadm/common/decorators/default
372
		 * @see admin/jqadm/subscription/decorators/global
373
		 * @see admin/jqadm/subscription/decorators/local
374
		 */
375
376
		/** admin/jqadm/subscription/decorators/global
377
		 * Adds a list of globally available decorators only to the subscription JQAdm client
378
		 *
379
		 * Decorators extend the functionality of a class by adding new aspects
380
		 * (e.g. log what is currently done), executing the methods of the underlying
381
		 * class only in certain conditions (e.g. only for logged in users) or
382
		 * modify what is returned to the caller.
383
		 *
384
		 * This option allows you to wrap global decorators
385
		 * ("\Aimeos\Admin\JQAdm\Common\Decorator\*") around the JQAdm client.
386
		 *
387
		 *  admin/jqadm/subscription/decorators/global = array( 'decorator1' )
388
		 *
389
		 * This would add the decorator named "decorator1" defined by
390
		 * "\Aimeos\Admin\JQAdm\Common\Decorator\Decorator1" only to the JQAdm client.
391
		 *
392
		 * @param array List of decorator names
393
		 * @since 2018.04
394
		 * @category Developer
395
		 * @see admin/jqadm/common/decorators/default
396
		 * @see admin/jqadm/subscription/decorators/excludes
397
		 * @see admin/jqadm/subscription/decorators/local
398
		 */
399
400
		/** admin/jqadm/subscription/decorators/local
401
		 * Adds a list of local decorators only to the subscription JQAdm client
402
		 *
403
		 * Decorators extend the functionality of a class by adding new aspects
404
		 * (e.g. log what is currently done), executing the methods of the underlying
405
		 * class only in certain conditions (e.g. only for logged in users) or
406
		 * modify what is returned to the caller.
407
		 *
408
		 * This option allows you to wrap local decorators
409
		 * ("\Aimeos\Admin\JQAdm\Subscription\Decorator\*") around the JQAdm client.
410
		 *
411
		 *  admin/jqadm/subscription/decorators/local = array( 'decorator2' )
412
		 *
413
		 * This would add the decorator named "decorator2" defined by
414
		 * "\Aimeos\Admin\JQAdm\Subscription\Decorator\Decorator2" only to the JQAdm client.
415
		 *
416
		 * @param array List of decorator names
417
		 * @since 2018.04
418
		 * @category Developer
419
		 * @see admin/jqadm/common/decorators/default
420
		 * @see admin/jqadm/subscription/decorators/excludes
421
		 * @see admin/jqadm/subscription/decorators/global
422
		 */
423
		return $this->createSubClient( 'subscription/' . $type, $name );
424
	}
425
426
427
	/**
428
	 * Returns the base order items (baskets) for the given subscription items
429
	 *
430
	 * @param \Aimeos\Map $items List of subscription items implementing \Aimeos\MShop\Subscription\Item\Iface
431
	 * @return \Aimeos\Map List of order base items implementing \Aimeos\MShop\Order\Item\Base\Iface
432
	 */
433
	protected function getOrderBaseItems( \Aimeos\Map $items ) : \Aimeos\Map
434
	{
435
		$baseIds = $items->getOrderBaseId()->toArray();
436
		$manager = \Aimeos\MShop::create( $this->getContext(), 'order/base' );
437
438
		$search = $manager->createSearch()->setSlice( 0, count( $baseIds ) );
439
		$search->setConditions( $search->compare( '==', 'order.base.id', $baseIds ) );
440
441
		return $manager->searchItems( $search, ['order/base/address', 'order/base/product'] );
442
	}
443
444
445
	/**
446
	 * Returns the list of sub-client names configured for the client.
447
	 *
448
	 * @return array List of JQAdm client names
449
	 */
450
	protected function getSubClientNames() : array
451
	{
452
		/** admin/jqadm/subscription/standard/subparts
453
		 * List of JQAdm sub-clients rendered within the subscription section
454
		 *
455
		 * The output of the frontend is composed of the code generated by the JQAdm
456
		 * clients. Each JQAdm client can consist of serveral (or none) sub-clients
457
		 * that are responsible for rendering certain sub-parts of the output. The
458
		 * sub-clients can contain JQAdm clients themselves and therefore a
459
		 * hierarchical tree of JQAdm clients is composed. Each JQAdm client creates
460
		 * the output that is placed inside the container of its parent.
461
		 *
462
		 * At first, always the JQAdm code generated by the parent is printed, then
463
		 * the JQAdm code of its sub-clients. The subscription of the JQAdm sub-clients
464
		 * determines the subscription of the output of these sub-clients inside the parent
465
		 * container. If the configured list of clients is
466
		 *
467
		 *  array( "subclient1", "subclient2" )
468
		 *
469
		 * you can easily change the subscription of the output by resubscriptioning the subparts:
470
		 *
471
		 *  admin/jqadm/<clients>/subparts = array( "subclient1", "subclient2" )
472
		 *
473
		 * You can also remove one or more parts if they shouldn't be rendered:
474
		 *
475
		 *  admin/jqadm/<clients>/subparts = array( "subclient1" )
476
		 *
477
		 * As the clients only generates structural JQAdm, the layout defined via CSS
478
		 * should support adding, removing or resubscriptioning content by a fluid like
479
		 * design.
480
		 *
481
		 * @param array List of sub-client names
482
		 * @since 2018.04
483
		 * @category Developer
484
		 */
485
		return $this->getContext()->getConfig()->get( 'admin/jqadm/subscription/standard/subparts', [] );
486
	}
487
488
489
	/**
490
	 * Creates new and updates existing items using the data array
491
	 *
492
	 * @param array $data Data array
493
	 * @return \Aimeos\MShop\Subscription\Item\Iface New subscription item object
494
	 */
495
	protected function fromArray( array $data ) : \Aimeos\MShop\Subscription\Item\Iface
496
	{
497
		$manager = \Aimeos\MShop::create( $this->getContext(), 'subscription' );
498
499
		if( isset( $data['subscription.id'] ) && $data['subscription.id'] != '' ) {
500
			$item = $manager->getItem( $data['subscription.id'] );
501
		} else {
502
			$item = $manager->createItem();
503
		}
504
505
		$item->fromArray( $data, true );
506
507
		return $item;
508
	}
509
510
511
	/**
512
	 * Constructs the data array for the view from the given item
513
	 *
514
	 * @param \Aimeos\MShop\Subscription\Item\Iface $item Subscription item object
515
	 * @return string[] Multi-dimensional associative list of item data
516
	 */
517
	protected function toArray( \Aimeos\MShop\Subscription\Item\Iface $item, bool $copy = false ) : array
518
	{
519
		$siteId = $this->getContext()->getLocale()->getSiteId();
520
		$data = $item->toArray( true );
521
522
		if( $copy === true )
523
		{
524
			$data['subscription.siteid'] = $siteId;
525
			$data['subscription.id'] = '';
526
		}
527
528
		return $data;
529
	}
530
531
532
	/**
533
	 * Returns the rendered template including the view data
534
	 *
535
	 * @param \Aimeos\MW\View\Iface $view View object with data assigned
536
	 * @return string|null HTML output
537
	 */
538
	protected function render( \Aimeos\MW\View\Iface $view ) : string
539
	{
540
		/** admin/jqadm/subscription/template-item
541
		 * Relative path to the HTML body template for the subscription item.
542
		 *
543
		 * The template file contains the HTML code and processing instructions
544
		 * to generate the result shown in the body of the frontend. The
545
		 * configuration string is the path to the template file relative
546
		 * to the templates directory (usually in admin/jqadm/templates).
547
		 *
548
		 * You can overwrite the template file configuration in extensions and
549
		 * provide alternative templates. These alternative templates should be
550
		 * named like the default one but with the string "default" replaced by
551
		 * an unique name. You may use the name of your project for this. If
552
		 * you've implemented an alternative client class as well, "default"
553
		 * should be replaced by the name of the new class.
554
		 *
555
		 * @param string Relative path to the template creating the HTML code
556
		 * @since 2016.04
557
		 * @category Developer
558
		 */
559
		$tplconf = 'admin/jqadm/subscription/template-item';
560
		$default = 'subscription/item-standard';
561
562
		return $view->render( $view->config( $tplconf, $default ) );
563
	}
564
}
565