Completed
Push — master ( 30aab1...d7b409 )
by Aimeos
10:43 queued 06:09
created

Base::require()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2020
6
 * @package Admin
7
 * @subpackage JQAdm
8
 */
9
10
11
namespace Aimeos\Admin\JQAdm;
12
13
sprintf( 'type' ); // for translation
14
15
16
/**
17
 * Common abstract class for all admin client classes.
18
 *
19
 * @package Admin
20
 * @subpackage JQAdm
21
 */
22
abstract class Base
23
	implements \Aimeos\Admin\JQAdm\Iface
24
{
25
	private $view;
26
	private $aimeos;
27
	private $context;
28
	private $subclients;
29
	private $object;
30
31
32
	/**
33
	 * Initializes the class instance.
34
	 *
35
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
36
	 */
37
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context )
38
	{
39
		$this->context = $context;
40
	}
41
42
43
	/**
44
	 * Catch unknown methods
45
	 *
46
	 * @param string $name Name of the method
47
	 * @param array $param List of method parameter
48
	 * @throws \Aimeos\Admin\JQAdm\Exception If method call failed
49
	 */
50
	public function __call( string $name, array $param )
51
	{
52
		throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Unable to call method "%1$s"', $name ) );
53
	}
54
55
56
	/**
57
	 * Adds the required data used in the attribute template
58
	 *
59
	 * @param \Aimeos\MW\View\Iface $view View object
60
	 * @return \Aimeos\MW\View\Iface View object with assigned parameters
61
	 */
62
	public function addData( \Aimeos\MW\View\Iface $view ) : \Aimeos\MW\View\Iface
63
	{
64
		return $view;
65
	}
66
67
68
	/**
69
	 * Returns the Aimeos bootstrap object
70
	 *
71
	 * @return \Aimeos\Bootstrap The Aimeos bootstrap object
72
	 */
73
	public function getAimeos() : \Aimeos\Bootstrap
74
	{
75
		if( !isset( $this->aimeos ) ) {
76
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Aimeos object not available' ) );
77
		}
78
79
		return $this->aimeos;
80
	}
81
82
83
	/**
84
	 * Sets the Aimeos bootstrap object
85
	 *
86
	 * @param \Aimeos\Bootstrap $aimeos The Aimeos bootstrap object
87
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
88
	 */
89
	public function setAimeos( \Aimeos\Bootstrap $aimeos ) : \Aimeos\Admin\JQAdm\Iface
90
	{
91
		$this->aimeos = $aimeos;
92
		return $this;
93
	}
94
95
96
	/**
97
	 * Makes the outer decorator object available to inner objects
98
	 *
99
	 * @param \Aimeos\Admin\JQAdm\Iface $object Outmost object
100
	 * @return \Aimeos\Admin\JQAdm\Iface Same object for fluent interface
101
	 */
102
	public function setObject( \Aimeos\Admin\JQAdm\Iface $object ) : \Aimeos\Admin\JQAdm\Iface
103
	{
104
		$this->object = $object;
105
		return $this;
106
	}
107
108
109
	/**
110
	 * Returns the view object that will generate the admin output.
111
	 *
112
	 * @return \Aimeos\MW\View\Iface The view object which generates the admin output
113
	 */
114
	public function getView() : \Aimeos\MW\View\Iface
115
	{
116
		if( !isset( $this->view ) ) {
117
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'No view available' ) );
118
		}
119
120
		return $this->view;
121
	}
122
123
124
	/**
125
	 * Sets the view object that will generate the admin output.
126
	 *
127
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the admin output
128
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
129
	 */
130
	public function setView( \Aimeos\MW\View\Iface $view ) : \Aimeos\Admin\JQAdm\Iface
131
	{
132
		$this->view = $view;
133
		return $this;
134
	}
135
136
137
	/**
138
	 * Copies a resource
139
	 *
140
	 * @return string|null Output to display
141
	 */
142
	public function copy() : ?string
143
	{
144
		$body = null;
145
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
146
147
		foreach( $this->getSubClients() as $client ) {
148
			$body .= $client->copy();
149
		}
150
151
		return $body;
152
	}
153
154
155
	/**
156
	 * Creates a new resource
157
	 *
158
	 * @return string|null Output to display
159
	 */
160
	public function create() : ?string
161
	{
162
		$body = null;
163
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
164
165
		foreach( $this->getSubClients() as $client ) {
166
			$body .= $client->create();
167
		}
168
169
		return $body;
170
	}
171
172
173
	/**
174
	 * Deletes a resource
175
	 *
176
	 * @return string|null Output to display
177
	 */
178
	public function delete() : ?string
179
	{
180
		$body = null;
181
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
182
183
		foreach( $this->getSubClients() as $client ) {
184
			$body .= $client->delete();
185
		}
186
187
		return $body;
188
	}
189
190
191
	/**
192
	 * Exports a resource
193
	 *
194
	 * @return string|null Output to display
195
	 */
196
	public function export() : ?string
197
	{
198
		$body = null;
199
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
200
201
		foreach( $this->getSubClients() as $client ) {
202
			$body .= $client->export();
203
		}
204
205
		return $body;
206
	}
207
208
209
	/**
210
	 * Returns a resource
211
	 *
212
	 * @return string|null Output to display
213
	 */
214
	public function get() : ?string
215
	{
216
		$body = null;
217
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
218
219
		foreach( $this->getSubClients() as $client ) {
220
			$body .= $client->get();
221
		}
222
223
		return $body;
224
	}
225
226
227
	/**
228
	 * Imports a resource
229
	 *
230
	 * @return string|null Output to display
231
	 * @deprecated 2021.01
232
	 */
233
	public function import() : ?string
234
	{
235
		$body = null;
236
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
237
238
		foreach( $this->getSubClients() as $client ) {
239
			$body .= $client->import();
240
		}
241
242
		return null;
243
	}
244
245
246
	/**
247
	 * Saves the data
248
	 *
249
	 * @return string|null Output to display
250
	 */
251
	public function save() : ?string
252
	{
253
		$body = null;
254
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
255
256
		foreach( $this->getSubClients() as $client ) {
257
			$body .= $client->save();
258
		}
259
260
		return $body;
261
	}
262
263
264
	/**
265
	 * Returns a list of resource according to the conditions
266
	 *
267
	 * @return string|null Output to display
268
	 */
269
	public function search() : ?string
270
	{
271
		$body = null;
272
		$view = $this->getView();
0 ignored issues
show
Unused Code introduced by
The assignment to $view is dead and can be removed.
Loading history...
273
274
		foreach( $this->getSubClients() as $client ) {
275
			$body .= $client->search();
276
		}
277
278
		return $body;
279
	}
280
281
282
	/**
283
	 * Adds the decorators to the client object
284
	 *
285
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
286
	 * @param array $decorators List of decorator name that should be wrapped around the client
287
	 * @param string $classprefix Decorator class prefix, e.g. "\Aimeos\Admin\JQAdm\Catalog\Decorator\"
288
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
289
	 */
290
	protected function addDecorators( \Aimeos\Admin\JQAdm\Iface $client, array $decorators, string $classprefix ) : \Aimeos\Admin\JQAdm\Iface
291
	{
292
		foreach( $decorators as $name )
293
		{
294
			if( ctype_alnum( $name ) === false )
295
			{
296
				$classname = is_string( $name ) ? $classprefix . $name : '<not a string>';
297
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid class name "%1$s"', $classname ) );
298
			}
299
300
			$classname = $classprefix . $name;
301
302
			if( class_exists( $classname ) === false ) {
303
				throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not found', $classname ) );
304
			}
305
306
			$client = new $classname( $client, $this->context );
307
308
			\Aimeos\MW\Common\Base::checkClass( '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\Iface', $client );
309
		}
310
311
		return $client;
312
	}
313
314
315
	/**
316
	 * Adds the decorators to the client object
317
	 *
318
	 * @param \Aimeos\Admin\JQAdm\Iface $client Admin object
319
	 * @param string $path Admin string in lower case, e.g. "catalog/detail/basic"
320
	 * @return \Aimeos\Admin\JQAdm\Iface Admin object
321
	 */
322
	protected function addClientDecorators( \Aimeos\Admin\JQAdm\Iface $client, string $path ) : \Aimeos\Admin\JQAdm\Iface
323
	{
324
		if( !is_string( $path ) || $path === '' ) {
0 ignored issues
show
introduced by
The condition is_string($path) is always true.
Loading history...
325
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid domain "%1$s"', $path ) );
326
		}
327
328
		$localClass = str_replace( '/', '\\', ucwords( $path, '/' ) );
329
		$config = $this->context->getConfig();
330
331
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\Common\\Decorator\\';
332
		$decorators = $config->get( 'admin/jqadm/' . $path . '/decorators/global', [] );
333
		$client = $this->addDecorators( $client, $decorators, $classprefix );
334
335
		$classprefix = '\\Aimeos\\Admin\\JQAdm\\' . $localClass . '\\Decorator\\';
336
		$decorators = $config->get( 'admin/jqadm/' . $path . '/decorators/local', [] );
337
		$client = $this->addDecorators( $client, $decorators, $classprefix );
338
339
		return $client;
340
	}
341
342
343
	/**
344
	 * Returns the sub-client given by its name.
345
	 *
346
	 * @param string $path Name of the sub-part in lower case (can contain a path like catalog/filter/tree)
347
	 * @param string|null $name Name of the implementation, will be from configuration (or Default) if null
348
	 * @return \Aimeos\Admin\JQAdm\Iface Sub-part object
349
	 */
350
	protected function createSubClient( string $path, string $name = null ) : \Aimeos\Admin\JQAdm\Iface
351
	{
352
		$path = strtolower( $path );
353
354
		if( $name === null ) {
355
			$name = $this->context->getConfig()->get( 'admin/jqadm/' . $path . '/name', 'Standard' );
356
		}
357
358
		if( empty( $name ) || ctype_alnum( $name ) === false ) {
359
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Invalid characters in client name "%1$s"', $name ) );
360
		}
361
362
		$subnames = str_replace( '/', '\\', ucwords( $path, '/' ) );
363
364
		$classname = '\\Aimeos\\Admin\\JQAdm\\' . $subnames . '\\' . $name;
365
366
		if( class_exists( $classname ) === false ) {
367
			throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Class "%1$s" not available', $classname ) );
368
		}
369
370
		$object = new $classname( $this->context );
371
		$object = \Aimeos\MW\Common\Base::checkClass( '\\Aimeos\\Admin\\JQAdm\\Iface', $object );
372
		$object = $this->addClientDecorators( $object, $path );
373
374
		return $object->setObject( $object )->setAimeos( $this->aimeos )->setView( $this->view );
0 ignored issues
show
Bug introduced by
The method setObject() does not exist on Aimeos\Admin\JQAdm\Iface. It seems like you code against a sub-type of said class. However, the method does not exist in Aimeos\Admin\JQAdm\Common\Admin\Factory\Iface or Aimeos\Admin\JQAdm\Common\Decorator\Iface. Are you sure you never get one of those? ( Ignorable by Annotation )

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

374
		return $object->/** @scrutinizer ignore-call */ setObject( $object )->setAimeos( $this->aimeos )->setView( $this->view );
Loading history...
375
	}
376
377
378
	/**
379
	 * Returns the value for the given key in the array
380
	 *
381
	 * @param array $values Multi-dimensional associative list of key/value pairs
382
	 * @param string $key Parameter key like "name" or "list/test" for associative arrays
383
	 * @param mixed $default Returned value if no one for key is available
384
	 * @return mixed Value from the array or default value if not present in array
385
	 */
386
	protected function getValue( array $values, $key, $default = null )
387
	{
388
		foreach( explode( '/', trim( $key, '/' ) ) as $part )
389
		{
390
			if( array_key_exists( $part, $values ) ) {
391
				$values = $values[$part];
392
			} else {
393
				return $default;
394
			}
395
		}
396
397
		return $values;
398
	}
399
400
401
	/**
402
	 * Returns the known client parameters and their values
403
	 *
404
	 * @param array $names List of parameter names
405
	 * @return array Associative list of parameters names as key and their values
406
	 */
407
	protected function getClientParams( $names = ['id', 'resource', 'site', 'lang'] ) : array
408
	{
409
		$list = [];
410
411
		foreach( $names as $name )
412
		{
413
			if( ( $val = $this->view->param( $name ) ) !== null ) {
414
				$list[$name] = $val;
415
			}
416
		}
417
418
		return $list;
419
	}
420
421
422
	/**
423
	 * Returns the context object.
424
	 *
425
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
426
	 */
427
	protected function getContext() : \Aimeos\MShop\Context\Item\Iface
428
	{
429
		return $this->context;
430
	}
431
432
433
	/**
434
	 * Returns the list of sub-client names configured for the client.
435
	 *
436
	 * @return array List of admin client names
437
	 */
438
	abstract protected function getSubClientNames() : array;
439
440
441
	/**
442
	 * Returns the available class names without namespace that are stored in the given path
443
	 *
444
	 * @param string $relpath Path relative to the include paths
445
	 * @param string[] $excludes List of file names to execlude
446
	 * @return string[] List of available class names
447
	 */
448
	protected function getClassNames( string $relpath, array $excludes = ['Base.php', 'Iface.php', 'Example.php', 'None.php'] ) : array
449
	{
450
		$list = [];
451
452
		foreach( $this->getAimeos()->getIncludePaths() as $path )
453
		{
454
			$path .= DIRECTORY_SEPARATOR . $relpath;
455
456
			if( is_dir( $path ) )
457
			{
458
				foreach( new \DirectoryIterator( $path ) as $entry )
459
				{
460
					if( $entry->isFile() && !in_array( $entry->getFileName(), $excludes ) ) {
461
						$list[] = pathinfo( $entry->getFileName(), PATHINFO_FILENAME );
462
					}
463
				}
464
			}
465
		}
466
467
		sort( $list );
468
		return $list;
469
	}
470
471
472
	/**
473
	 * Returns the array of criteria conditions based on the given parameters
474
	 *
475
	 * @param array $params List of criteria data with condition, sorting and paging
476
	 * @return array Multi-dimensional associative list of criteria conditions
477
	 */
478
	protected function getCriteriaConditions( array $params ) : array
479
	{
480
		$expr = [];
481
482
		if( isset( $params['key'] ) )
483
		{
484
			foreach( (array) $params['key'] as $idx => $key )
485
			{
486
				if( $key != '' && isset( $params['op'][$idx] ) && $params['op'][$idx] != ''
487
					&& isset( $params['val'][$idx] ) && $params['val'][$idx] != ''
488
				) {
489
					$expr[] = [$params['op'][$idx] => [$key => $params['val'][$idx]]];
490
				}
491
			}
492
493
			if( !empty( $expr ) ) {
494
				$expr = ['&&' => $expr];
495
			}
496
		}
497
498
		return $expr;
499
	}
500
501
502
	/**
503
	 * Returns the array of criteria sortations based on the given parameters
504
	 *
505
	 * @param array $params List of criteria data with condition, sorting and paging
506
	 * @return array Associative list of criteria sortations
507
	 */
508
	protected function getCriteriaSortations( array $params ) : array
509
	{
510
		$sortation = [];
511
512
		foreach( $params as $sort )
513
		{
514
			if( $sort[0] === '-' ) {
515
				$sortation[substr( $sort, 1 )] = '-';
516
			} else {
517
				$sortation[$sort] = '+';
518
			}
519
		}
520
521
		return $sortation;
522
	}
523
524
525
	/**
526
	 * Returns the outer decoratorator of the object
527
	 *
528
	 * @return \Aimeos\Admin\JQAdm\Iface Outmost object
529
	 */
530
	protected function getObject() : Iface
531
	{
532
		if( isset( $this->object ) ) {
533
			return $this->object;
534
		}
535
536
		return $this;
537
	}
538
539
540
	/**
541
	 * Returns the configured sub-clients or the ones named in the default parameter if none are configured.
542
	 *
543
	 * @return array List of sub-clients implementing \Aimeos\Admin\JQAdm\Iface ordered in the same way as the names
544
	 */
545
	protected function getSubClients() : array
546
	{
547
		if( !isset( $this->subclients ) )
548
		{
549
			$this->subclients = [];
550
551
			foreach( $this->getSubClientNames() as $name ) {
552
				$this->subclients[] = $this->getSubClient( $name );
553
			}
554
		}
555
556
		return $this->subclients;
557
	}
558
559
560
	/**
561
	 * Initializes the criteria object based on the given parameter
562
	 *
563
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
564
	 * @param array $params List of criteria data with condition, sorting and paging
565
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
566
	 */
567
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
568
	{
569
		if( isset( $params['filter'] ) ) {
570
			$criteria = $this->initCriteriaConditions( $criteria, (array) $params['filter'] )
571
				->setSlice( 0, $criteria->getSliceSize() );
572
		}
573
574
		if( isset( $params['sort'] ) ) {
575
			$criteria = $this->initCriteriaSortations( $criteria, (array) $params['sort'] );
576
		}
577
578
		$page = [];
579
		if( isset( $params['page'] ) ) {
580
			$page = (array) $params['page'];
581
		}
582
583
		return $this->initCriteriaSlice( $criteria, $page );
584
	}
585
586
587
	/**
588
	 * Writes the exception details to the log
589
	 *
590
	 * @param \Exception $e Exception object
591
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
592
	 */
593
	protected function log( \Exception $e ) : Iface
594
	{
595
		$logger = $this->context->getLogger();
596
		$logger->log( $e->getMessage(), \Aimeos\MW\Logger\Base::ERR, 'admin/jqadm' );
597
		$logger->log( $e->getTraceAsString(), \Aimeos\MW\Logger\Base::ERR, 'admin/jqadm' );
598
599
		return $this;
600
	}
601
602
603
	/**
604
	 * Returns a map of code/item pairs
605
	 *
606
	 * @param \Aimeos\MShop\Common\Item\Type\Iface[] $items Associative list of type items
607
	 * @return \Aimeos\MShop\Common\Item\Type\Iface[] Associative list of codes as keys and items as values
608
	 * @deprecated 2021.01
609
	 */
610
	protected function map( \Aimeos\Map $items ) : array
611
	{
612
		$list = [];
613
614
		foreach( $items as $item ) {
615
			$list[$item->getCode()] = $item;
616
		}
617
618
		return $list;
619
	}
620
621
622
	/**
623
	 * Adds a redirect to the response for the next action
624
	 *
625
	 * @param string $resource Resource name
626
	 * @param string|null $action Next action
627
	 * @param string|null $id ID of the next resource item
628
	 * @param string|null $act Current action name
629
	 * @return string|null Returns value for the actions
630
	 */
631
	protected function redirect( string $resource, ?string $action, string $id = null,
632
		string $method = null ) : ?string
633
	{
634
		$params = $this->getClientParams();
635
		$context = $this->getContext();
636
		$view = $this->getView();
637
638
		$params['resource'] = $resource;
639
		unset( $params['id'] );
640
641
		switch( $action )
642
		{
643
			case 'search':
644
				$target = $view->config( 'admin/jqadm/url/search/target' );
645
				$cntl = $view->config( 'admin/jqadm/url/search/controller', 'Jqadm' );
646
				$action = $view->config( 'admin/jqadm/url/search/action', 'search' );
647
				$conf = $view->config( 'admin/jqadm/url/search/config', [] );
648
				$url = $view->url( $target, $cntl, $action, $params, [], $conf );
649
				break;
650
			case 'create':
651
				$params['parentid'] = $id;
652
				$target = $view->config( 'admin/jqadm/url/create/target' );
653
				$cntl = $view->config( 'admin/jqadm/url/create/controller', 'Jqadm' );
654
				$action = $view->config( 'admin/jqadm/url/create/action', 'create' );
655
				$conf = $view->config( 'admin/jqadm/url/create/config', [] );
656
				$url = $view->url( $target, $cntl, $action, $params, [], $conf );
657
				break;
658
			case 'copy':
659
				$target = $view->config( 'admin/jqadm/url/copy/target' );
660
				$cntl = $view->config( 'admin/jqadm/url/copy/controller', 'Jqadm' );
661
				$action = $view->config( 'admin/jqadm/url/copy/action', 'copy' );
662
				$conf = $view->config( 'admin/jqadm/url/copy/config', [] );
663
				$url = $view->url( $target, $cntl, $action, ['id' => $id] + $params, [], $conf );
664
				break;
665
			default:
666
				$target = $view->config( 'admin/jqadm/url/get/target' );
667
				$cntl = $view->config( 'admin/jqadm/url/get/controller', 'Jqadm' );
668
				$action = $view->config( 'admin/jqadm/url/get/action', 'get' );
669
				$conf = $view->config( 'admin/jqadm/url/get/config', [] );
670
				$url = $view->url( $target, $cntl, $action, ['id' => $id] + $params, [], $conf );
671
		}
672
673
		switch( $method )
674
		{
675
			case 'save':
676
				$context->getSession()->set( 'info', [$context->getI18n()->dt( 'admin', 'Item saved successfully' )] ); break;
677
			case 'delete':
678
				$context->getSession()->set( 'info', [$context->getI18n()->dt( 'admin', 'Item deleted successfully' )] ); break;
679
		}
680
681
		$view->response()->withStatus( 302 );
682
		$view->response()->withHeader( 'Location', $url );
683
		$view->response()->withHeader( 'Cache-Control', 'no-store' );
684
685
		return null;
686
	}
687
688
689
	/**
690
	 * Writes the exception details to the log
691
	 *
692
	 * @param \Exception $e Exception object
693
	 * @param string $method Method it's called from
694
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
695
	 */
696
	protected function report( \Exception $e, string $method ) : Iface
697
	{
698
		$view = $this->view;
699
		$i18n = $this->context->getI18n();
700
701
		if( $e instanceof \Aimeos\Admin\JQAdm\Exception )
702
		{
703
			$view->errors = array_merge( $view->get( 'errors', [] ), [$e->getMessage()] );
704
			return $this;
705
		}
706
		elseif( $e instanceof \Aimeos\MShop\Exception )
707
		{
708
			$view->errors = array_merge( $view->get( 'errors', [] ), [$i18n->dt( 'mshop', $e->getMessage() )] );
709
			return $this;
710
		}
711
712
		switch( $method )
713
		{
714
			case 'save': $msg = $i18n->dt( 'admin', 'Error saving data' ); break;
715
			case 'delete': $msg = $i18n->dt( 'admin', 'Error deleting data' ); break;
716
			default: $msg = $i18n->dt( 'admin', 'Error retrieving data' ); break;
717
		}
718
719
		$view->errors = array_merge( $view->get( 'errors', [] ), [$msg] );
720
721
		return $this->log( $e );
722
	}
723
724
725
	/**
726
	 * Checks and returns the request parameter for the given name
727
	 *
728
	 * @param string $name Name of the request parameter, can be a path like 'page/limit'
729
	 * @return mixed Parameter value
730
	 * @throws \Aimeos\Admin\JQAdm\Exception If the parameter is missing
731
	 */
732
	protected function require( string $name )
733
	{
734
		if( ( $value = $this->getView()->param( $name ) ) !== null ) {
735
			return $value;
736
		}
737
738
		throw new \Aimeos\Admin\JQAdm\Exception( sprintf( 'Required parameter "%1$s" is missing', $name ) );
739
	}
740
741
742
	/**
743
	 * Stores and returns the parameters used for searching items
744
	 *
745
	 * @param array $params GET/POST parameter set
746
	 * @param string $name Name of the panel/subpanel
747
	 * @return array Associative list of parameters for searching items
748
	 */
749
	protected function storeFilter( array $params, string $name ) : array
750
	{
751
		return $this->storeSearchParams( $params, $name );
752
	}
753
754
755
	/**
756
	 * Stores and returns the parameters used for searching items
757
	 *
758
	 * @param array $params GET/POST parameter set
759
	 * @param string $name Name of the panel/subpanel
760
	 * @return array Associative list of parameters for searching items
761
	 * @deprecated 2021.01 Use storeFilter() instead
762
	 */
763
	protected function storeSearchParams( array $params, string $name ) : array
764
	{
765
		$key = 'aimeos/admin/jqadm/' . $name;
766
		$session = $this->getContext()->getSession();
767
768
		if( isset( $params['filter'] ) ) {
769
			$session->set( $key . '/filter', $params['filter'] );
770
		}
771
772
		if( isset( $params['sort'] ) ) {
773
			$session->set( $key . '/sort', $params['sort'] );
774
		}
775
776
		if( isset( $params['page'] ) ) {
777
			$session->set( $key . '/page', $params['page'] );
778
		}
779
780
		if( isset( $params['fields'] ) ) {
781
			$session->set( $key . '/fields', $params['fields'] );
782
		}
783
784
		return [
785
			'fields' => $session->get( $key . '/fields' ),
786
			'filter' => $session->get( $key . '/filter' ),
787
			'page' => $session->get( $key . '/page' ),
788
			'sort' => $session->get( $key . '/sort' ),
789
		];
790
	}
791
792
793
	/**
794
	 * Initializes the criteria object with conditions based on the given parameter
795
	 *
796
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
797
	 * @param array $params List of criteria data with condition, sorting and paging
798
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
799
	 */
800
	private function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
801
	{
802
		if( ( $cond = $criteria->toConditions( $this->getCriteriaConditions( $params ) ) ) !== null ) {
803
			return $criteria->setConditions( $criteria->combine( '&&', [$cond, $criteria->getConditions()] ) );
804
		}
805
806
		return $criteria;
807
	}
808
809
810
	/**
811
	 * Initializes the criteria object with the slice based on the given parameter.
812
	 *
813
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
814
	 * @param array $params List of criteria data with condition, sorting and paging
815
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
816
	 */
817
	private function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
818
	{
819
		$start = ( isset( $params['offset'] ) ? $params['offset'] : 0 );
820
		$size = ( isset( $params['limit'] ) ? $params['limit'] : 25 );
821
822
		return $criteria->setSlice( $start, $size );
823
	}
824
825
826
	/**
827
	 * Initializes the criteria object with sortations based on the given parameter
828
	 *
829
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
830
	 * @param array $params List of criteria data with condition, sorting and paging
831
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
832
	 */
833
	private function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
834
	{
835
		return $criteria->setSortations( $criteria->toSortations( $this->getCriteriaSortations( $params ) ) );
836
	}
837
}
838