Completed
Push — master ( a3fccc...85d71b )
by Aimeos
03:57
created

Standard::create()   A

Complexity

Conditions 5
Paths 26

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 18
nc 26
nop 0
dl 0
loc 33
rs 9.3554
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
	 * Adds the required data used in the template
28
	 *
29
	 * @param \Aimeos\MW\View\Iface $view View object
30
	 * @return \Aimeos\MW\View\Iface View object with assigned parameters
31
	 */
32
	public function addData( \Aimeos\MW\View\Iface $view ) : \Aimeos\MW\View\Iface
33
	{
34
		$view->itemSubparts = $this->getSubClientNames();
35
		return $view;
36
	}
37
38
39
	/**
40
	 * Copies a resource
41
	 *
42
	 * @return string|null HTML output
43
	 */
44
	public function copy() : ?string
45
	{
46
		$view = $this->getObject()->addData( $this->getView() );
47
		$context = $this->getContext();
48
49
		try
50
		{
51
			if( ( $id = $view->param( 'id' ) ) === null ) {
52
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
53
			}
54
55
			$manager = \Aimeos\MShop::create( $context, 'subscription' );
56
			$baseManager = \Aimeos\MShop::create( $context, 'order/base' );
57
58
			$view->item = $manager->getItem( $id );
59
			$view->itemBase = $baseManager->getItem( $view->item->getOrderBaseId(), ['order/base/address', 'order/base/product'] );
60
			$view->itemData = $this->toArray( $view->item, true );
61
			$view->itemBody = parent::copy();
62
		}
63
		catch( \Exception $e )
64
		{
65
			$this->report( $e, 'copy' );
66
		}
67
68
		return $this->render( $view );
69
	}
70
71
72
	/**
73
	 * Creates a new resource
74
	 *
75
	 * @return string|null HTML output
76
	 */
77
	public function create() : ?string
78
	{
79
		$view = $this->getObject()->addData( $this->getView() );
80
		$context = $this->getContext();
81
82
		try
83
		{
84
			$data = $view->param( 'item', [] );
85
86
			if( !isset( $view->item ) ) {
87
				$view->item = \Aimeos\MShop::create( $context, 'subscription' )->createItem();
88
			}
89
90
			$baseManager = \Aimeos\MShop::create( $context, 'order/base' );
91
			$baseId = ( $view->item->getOrderBaseId() ?: $view->param( 'item/subscription.ordbaseid' ) );
92
93
			if( $baseId ) {
94
				$view->itemBase = $baseManager->getItem( $baseId, ['order/base/address', 'order/base/product'] );
95
			} else {
96
				$view->itemBase = $baseManager->createItem();
97
			}
98
99
			$data['subscription.siteid'] = $view->item->getSiteId();
100
101
			$view->itemData = array_replace_recursive( $this->toArray( $view->item ), $data );
102
			$view->itemBody = parent::create();
103
		}
104
		catch( \Exception $e )
105
		{
106
			$this->report( $e, 'create' );
107
		}
108
109
		return $this->render( $view );
110
	}
111
112
113
	/**
114
	 * Deletes a resource
115
	 *
116
	 * @return string|null HTML output
117
	 */
118
	public function delete() : ?string
119
	{
120
		$view = $this->getView();
121
122
		$manager = \Aimeos\MShop::create( $this->getContext(), 'subscription' );
123
		$manager->begin();
124
125
		try
126
		{
127
			if( ( $ids = $view->param( 'id' ) ) === null ) {
128
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
129
			}
130
131
			$search = $manager->createSearch()->setSlice( 0, count( (array) $ids ) );
132
			$search->setConditions( $search->compare( '==', 'subscription.id', $ids ) );
133
			$items = $manager->searchItems( $search );
134
135
			foreach( $items as $item )
136
			{
137
				$view->item = $item;
138
				parent::delete();
139
			}
140
141
			$manager->deleteItems( $items->toArray() );
142
			$manager->commit();
143
144
			return $this->redirect( 'subscription', 'search', null, 'delete' );
145
		}
146
		catch( \Exception $e )
147
		{
148
			$manager->rollback();
149
			$this->report( $e, 'delete' );
150
		}
151
152
		return $this->search();
153
	}
154
155
156
	/**
157
	 * Exports a resource
158
	 *
159
	 * @return string Admin output to display
160
	 */
161
	public function export() : ?string
162
	{
163
		$view = $this->getView();
164
		$context = $this->getContext();
165
166
		try
167
		{
168
			$params = $this->storeSearchParams( $view->param(), 'subscription' );
169
			$msg = ['sitecode' => $context->getLocale()->getSiteItem()->getCode()];
170
171
			if( isset( $params['filter'] ) ) {
172
				$msg['filter'] = $this->getCriteriaConditions( (array) $params['filter'] );
173
			}
174
175
			if( isset( $params['sort'] ) ) {
176
				$msg['sort'] = $this->getCriteriaSortations( (array) $params['sort'] );
177
			}
178
179
			$mq = $context->getMessageQueueManager()->get( 'mq-admin' )->getQueue( 'subscription-export' );
180
			$mq->add( json_encode( $msg ) );
181
182
			$msg = $context->getI18n()->dt( 'admin', 'Your export will be available in a few minutes for download' );
183
			$view->info = $view->get( 'info', [] ) + ['subscription-item' => $msg];
184
		}
185
		catch( \Exception $e )
186
		{
187
			$this->report( $e, 'export' );
188
		}
189
190
		return $this->search();
191
	}
192
193
194
	/**
195
	 * Returns a single resource
196
	 *
197
	 * @return string|null HTML output
198
	 */
199
	public function get() : ?string
200
	{
201
		$view = $this->getObject()->addData( $this->getView() );
202
		$context = $this->getContext();
203
204
		try
205
		{
206
			if( ( $id = $view->param( 'id' ) ) === null ) {
207
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', 'id' ) );
208
			}
209
210
			$manager = \Aimeos\MShop::create( $context, 'subscription' );
211
			$baseManager = \Aimeos\MShop::create( $context, 'order/base' );
212
213
			$view->item = $manager->getItem( $id );
214
			$view->itemBase = $baseManager->getItem( $view->item->getOrderBaseId(), ['order/base/address', 'order/base/product'] );
215
			$view->itemData = $this->toArray( $view->item );
216
			$view->itemBody = parent::get();
217
		}
218
		catch( \Exception $e )
219
		{
220
			$this->report( $e, 'get' );
221
		}
222
223
		return $this->render( $view );
224
	}
225
226
227
	/**
228
	 * Saves the data
229
	 *
230
	 * @return string|null HTML output
231
	 */
232
	public function save() : ?string
233
	{
234
		$view = $this->getView();
235
236
		$manager = \Aimeos\MShop::create( $this->getContext(), 'subscription' );
237
		$manager->begin();
238
239
		try
240
		{
241
			$item = $this->fromArray( $view->param( 'item', [] ) );
242
			$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

242
			$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...
243
			$view->itemBody = parent::save();
244
245
			$manager->saveItem( clone $view->item );
246
			$manager->commit();
247
248
			return $this->redirect( 'subscription', $view->param( 'next' ), $view->item->getId(), 'save' );
249
		}
250
		catch( \Exception $e )
251
		{
252
			$manager->rollback();
253
			$this->report( $e, 'save' );
254
		}
255
256
		return $this->create();
257
	}
258
259
260
	/**
261
	 * Returns a list of resource according to the conditions
262
	 *
263
	 * @return string|null HTML output
264
	 */
265
	public function search() : ?string
266
	{
267
		$view = $this->getView();
268
269
		try
270
		{
271
			$total = 0;
272
			$params = $this->storeSearchParams( $view->param(), 'subscription' );
273
			$manager = \Aimeos\MShop::create( $this->getContext(), 'subscription' );
274
275
			$search = $manager->createSearch( false, true );
0 ignored issues
show
Unused Code introduced by
The call to Aimeos\MShop\Common\Manager\Iface::createSearch() has too many arguments starting with true. ( Ignorable by Annotation )

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

275
			/** @scrutinizer ignore-call */ 
276
   $search = $manager->createSearch( false, true );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

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