Passed
Push — master ( bb5a4f...9ad936 )
by Aimeos
13:22 queued 10:01
created

Base::setAimeos()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

386
		return $object->/** @scrutinizer ignore-call */ setObject( $object )->setAimeos( $this->aimeos )->setView( $this->view );
Loading history...
387
	}
388
389
390
	/**
391
	 * Returns the value for the given key in the array
392
	 *
393
	 * @param array $values Multi-dimensional associative list of key/value pairs
394
	 * @param string $key Parameter key like "name" or "list/test" for associative arrays
395
	 * @param mixed $default Returned value if no one for key is available
396
	 * @return mixed Value from the array or default value if not present in array
397
	 */
398
	protected function getValue( array $values, $key, $default = null )
399
	{
400
		foreach( explode( '/', trim( $key, '/' ) ) as $part )
401
		{
402
			if( array_key_exists( $part, $values ) ) {
403
				$values = $values[$part];
404
			} else {
405
				return $default;
406
			}
407
		}
408
409
		return $values;
410
	}
411
412
413
	/**
414
	 * Returns the known client parameters and their values
415
	 *
416
	 * @param array $names List of parameter names
417
	 * @return array Associative list of parameters names as key and their values
418
	 */
419
	protected function getClientParams( $names = ['id', 'resource', 'site', 'locale'] ) : array
420
	{
421
		$list = [];
422
423
		foreach( $names as $name )
424
		{
425
			if( ( $val = $this->view->param( $name ) ) !== null && !is_array( $val ) ) {
426
				$list[$name] = $val;
427
			}
428
		}
429
430
		return $list;
431
	}
432
433
434
	/**
435
	 * Returns the context object.
436
	 *
437
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
438
	 */
439
	protected function getContext() : \Aimeos\MShop\Context\Item\Iface
440
	{
441
		return $this->context;
442
	}
443
444
445
	/**
446
	 * Returns the list of sub-client names configured for the client.
447
	 *
448
	 * @return array List of admin client names
449
	 */
450
	abstract protected function getSubClientNames() : array;
451
452
453
	/**
454
	 * Returns the available class names without namespace that are stored in the given path
455
	 *
456
	 * @param string $relpath Path relative to the include paths
457
	 * @param string[] $excludes List of file names to execlude
458
	 * @return string[] List of available class names
459
	 */
460
	protected function getClassNames( string $relpath, array $excludes = ['Base.php', 'Iface.php', 'Example.php', 'None.php'] ) : array
461
	{
462
		$list = [];
463
464
		foreach( $this->getAimeos()->getIncludePaths() as $path )
465
		{
466
			$path .= DIRECTORY_SEPARATOR . $relpath;
467
468
			if( is_dir( $path ) )
469
			{
470
				foreach( new \DirectoryIterator( $path ) as $entry )
471
				{
472
					if( $entry->isFile() && !in_array( $entry->getFileName(), $excludes ) ) {
473
						$list[] = pathinfo( $entry->getFileName(), PATHINFO_FILENAME );
474
					}
475
				}
476
			}
477
		}
478
479
		sort( $list );
480
		return $list;
481
	}
482
483
484
	/**
485
	 * Returns the array of criteria conditions based on the given parameters
486
	 *
487
	 * @param array $params List of criteria data with condition, sorting and paging
488
	 * @return array Multi-dimensional associative list of criteria conditions
489
	 */
490
	protected function getCriteriaConditions( array $params ) : array
491
	{
492
		$expr = [];
493
494
		if( isset( $params['key'] ) )
495
		{
496
			foreach( (array) $params['key'] as $idx => $key )
497
			{
498
				if( $key != '' && isset( $params['op'][$idx] ) && $params['op'][$idx] != ''
499
					&& isset( $params['val'][$idx] ) && $params['val'][$idx] != ''
500
				) {
501
					$expr[] = [$params['op'][$idx] => [$key => $params['val'][$idx]]];
502
				}
503
			}
504
505
			if( !empty( $expr ) ) {
506
				$expr = ['&&' => $expr];
507
			}
508
		}
509
510
		return $expr;
511
	}
512
513
514
	/**
515
	 * Returns the outer decoratorator of the object
516
	 *
517
	 * @return \Aimeos\Admin\JQAdm\Iface Outmost object
518
	 */
519
	protected function getObject() : Iface
520
	{
521
		if( isset( $this->object ) ) {
522
			return $this->object;
523
		}
524
525
		return $this;
526
	}
527
528
529
	/**
530
	 * Returns the configured sub-clients or the ones named in the default parameter if none are configured.
531
	 *
532
	 * @return array List of sub-clients implementing \Aimeos\Admin\JQAdm\Iface ordered in the same way as the names
533
	 */
534
	protected function getSubClients() : array
535
	{
536
		if( !isset( $this->subclients ) )
537
		{
538
			$this->subclients = [];
539
540
			foreach( $this->getSubClientNames() as $name ) {
541
				$this->subclients[] = $this->getSubClient( $name );
542
			}
543
		}
544
545
		return $this->subclients;
546
	}
547
548
549
	/**
550
	 * Initializes the criteria object based on the given parameter
551
	 *
552
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
553
	 * @param array $params List of criteria data with condition, sorting and paging
554
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
555
	 */
556
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
557
	{
558
		if( isset( $params['sort'] ) && !empty( $params['sort'] ) ) {
559
			$criteria->order( $params['sort'] );
560
		}
561
562
		return $criteria->slice( $params['page']['offset'] ?? 0, $params['page']['limit'] ?? 25 )
563
			->add( $criteria->parse( $this->getCriteriaConditions( $params['filter'] ?? [] ) ) );
564
	}
565
566
567
	/**
568
	 * Flattens the nested configuration array
569
	 *
570
	 * @param array $config Multi-dimensional list of key/value pairs
571
	 * @param string $path Path of keys separated by slashes (/) to add new values for
572
	 * @return array List of arrays with "key" and "val" keys
573
	 */
574
	protected function flatten( array $config, string $path = '' ) : array
575
	{
576
		$list = [];
577
578
		foreach( $config as $key => $val )
579
		{
580
			if( is_array( $val ) ) {
581
				$list = array_merge( $list, $this->flatten( $val, $path . '/' . $key ) );
582
			} else {
583
				$list[] = ['key' => trim( $path . '/' . $key, '/' ), 'val' => $val];
584
			}
585
		}
586
587
		return $list;
588
	}
589
590
591
	/**
592
	 * Writes the exception details to the log
593
	 *
594
	 * @param \Exception $e Exception object
595
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
596
	 */
597
	protected function log( \Exception $e ) : Iface
598
	{
599
		$msg = $e->getMessage() . PHP_EOL;
600
601
		if( $e instanceof \Aimeos\Admin\JQAdm\Exception ) {
602
			$msg .= print_r( $e->getDetails(), true ) . PHP_EOL;
0 ignored issues
show
Bug introduced by
Are you sure print_r($e->getDetails(), true) of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

602
			$msg .= /** @scrutinizer ignore-type */ print_r( $e->getDetails(), true ) . PHP_EOL;
Loading history...
603
		}
604
605
		$this->context->getLogger()->log( $msg . $e->getTraceAsString(), \Aimeos\MW\Logger\Base::ERR, 'admin/jqadm' );
606
607
		return $this;
608
	}
609
610
611
	/**
612
	 * Returns a map of code/item pairs
613
	 *
614
	 * @param \Aimeos\MShop\Common\Item\Type\Iface[] $items Associative list of type items
615
	 * @return \Aimeos\MShop\Common\Item\Type\Iface[] Associative list of codes as keys and items as values
616
	 * @deprecated 2021.01
617
	 */
618
	protected function map( \Aimeos\Map $items ) : array
619
	{
620
		$list = [];
621
622
		foreach( $items as $item ) {
623
			$list[$item->getCode()] = $item;
624
		}
625
626
		return $list;
627
	}
628
629
630
	/**
631
	 * Adds a redirect to the response for the next action
632
	 *
633
	 * @param string $resource Resource name
634
	 * @param string|null $action Next action
635
	 * @param string|null $id ID of the next resource item
636
	 * @param string|null $act Current action name
637
	 * @return string|null Returns value for the actions
638
	 */
639
	protected function redirect( string $resource, ?string $action, string $id = null,
640
		string $method = null ) : ?string
641
	{
642
		$params = $this->getClientParams();
643
		$context = $this->getContext();
644
		$view = $this->view();
645
646
		$params['resource'] = $resource;
647
		unset( $params['id'] );
648
649
		switch( $action )
650
		{
651
			case 'search':
652
				$target = $view->config( 'admin/jqadm/url/search/target' );
653
				$cntl = $view->config( 'admin/jqadm/url/search/controller', 'Jqadm' );
654
				$action = $view->config( 'admin/jqadm/url/search/action', 'search' );
655
				$conf = $view->config( 'admin/jqadm/url/search/config', [] );
656
				$url = $view->url( $target, $cntl, $action, $params, [], $conf );
657
				break;
658
			case 'create':
659
				$params['parentid'] = $id;
660
				$target = $view->config( 'admin/jqadm/url/create/target' );
661
				$cntl = $view->config( 'admin/jqadm/url/create/controller', 'Jqadm' );
662
				$action = $view->config( 'admin/jqadm/url/create/action', 'create' );
663
				$conf = $view->config( 'admin/jqadm/url/create/config', [] );
664
				$url = $view->url( $target, $cntl, $action, $params, [], $conf );
665
				break;
666
			case 'copy':
667
				$target = $view->config( 'admin/jqadm/url/copy/target' );
668
				$cntl = $view->config( 'admin/jqadm/url/copy/controller', 'Jqadm' );
669
				$action = $view->config( 'admin/jqadm/url/copy/action', 'copy' );
670
				$conf = $view->config( 'admin/jqadm/url/copy/config', [] );
671
				$url = $view->url( $target, $cntl, $action, ['id' => $id] + $params, [], $conf );
672
				break;
673
			default:
674
				$target = $view->config( 'admin/jqadm/url/get/target' );
675
				$cntl = $view->config( 'admin/jqadm/url/get/controller', 'Jqadm' );
676
				$action = $view->config( 'admin/jqadm/url/get/action', 'get' );
677
				$conf = $view->config( 'admin/jqadm/url/get/config', [] );
678
				$url = $view->url( $target, $cntl, $action, ['id' => $id] + $params, [], $conf );
679
		}
680
681
		switch( $method )
682
		{
683
			case 'save':
684
				$context->getSession()->set( 'info', [$context->translate( 'admin', 'Item saved successfully' )] ); break;
685
			case 'delete':
686
				$context->getSession()->set( 'info', [$context->translate( 'admin', 'Item deleted successfully' )] ); break;
687
		}
688
689
		$view->response()->withStatus( 302 );
690
		$view->response()->withHeader( 'Location', $url );
691
		$view->response()->withHeader( 'Cache-Control', 'no-store' );
692
693
		return null;
694
	}
695
696
697
	/**
698
	 * Writes the exception details to the log
699
	 *
700
	 * @param \Exception $e Exception object
701
	 * @param string $method Method it's called from
702
	 * @return \Aimeos\Admin\JQAdm\Iface Reference to this object for fluent calls
703
	 */
704
	protected function report( \Exception $e, string $method ) : Iface
705
	{
706
		$view = $this->view;
707
		$i18n = $this->context->getI18n();
708
709
		if( $e instanceof \Aimeos\Admin\JQAdm\Exception )
710
		{
711
			$view->errors = array_merge( $view->get( 'errors', [] ), [$e->getMessage()] );
712
			return $this->log( $e );
713
		}
714
		elseif( $e instanceof \Aimeos\MShop\Exception )
715
		{
716
			$view->errors = array_merge( $view->get( 'errors', [] ), [$i18n->dt( 'mshop', $e->getMessage() )] );
717
			return $this->log( $e );
718
		}
719
720
		switch( $method )
721
		{
722
			case 'save': $msg = $i18n->dt( 'admin', 'Error saving data' ); break;
723
			case 'delete': $msg = $i18n->dt( 'admin', 'Error deleting data' ); break;
724
			default: $msg = $i18n->dt( 'admin', 'Error retrieving data' ); break;
725
		}
726
727
		$view->errors = array_merge( $view->get( 'errors', [] ), [$msg] );
728
729
		return $this->log( $e );
730
	}
731
732
733
	/**
734
	 * Checks and returns the request parameter for the given name
735
	 *
736
	 * @param string $name Name of the request parameter, can be a path like 'page/limit'
737
	 * @return mixed Parameter value
738
	 * @throws \Aimeos\Admin\JQAdm\Exception If the parameter is missing
739
	 */
740
	protected function require( string $name )
741
	{
742
		if( ( $value = $this->view()->param( $name ) ) !== null ) {
743
			return $value;
744
		}
745
746
		$msg = $this->context->translate( 'admin', 'Required parameter "%1$s" is missing' );
747
		throw new \Aimeos\Admin\JQAdm\Exception( sprintf( $msg, $name ) );
748
	}
749
750
751
	/**
752
	 * Stores and returns the parameters used for searching items
753
	 *
754
	 * @param array $params GET/POST parameter set
755
	 * @param string $name Name of the panel/subpanel
756
	 * @return array Associative list of parameters for searching items
757
	 */
758
	protected function storeFilter( array $params, string $name ) : array
759
	{
760
		$key = 'aimeos/admin/jqadm/' . $name;
761
		$session = $this->getContext()->getSession();
762
763
		foreach( ['fields', 'filter', 'page', 'sort'] as $part )
764
		{
765
			if( isset( $params[$part] ) ) {
766
				$session->set( $key . '/' . $part, $params[$part] );
767
			}
768
		}
769
770
		return [
771
			'fields' => $session->get( $key . '/fields' ),
772
			'filter' => $session->get( $key . '/filter' ),
773
			'page' => $session->get( $key . '/page' ),
774
			'sort' => $session->get( $key . '/sort' ),
775
		];
776
	}
777
778
779
	/**
780
	 * Throws an exception with given details
781
	 *
782
	 * @param array $errors List of key/message pairs of errors
783
	 * @throws \Aimeos\Admin\JQAdm\Exception Exception with error details
784
	 */
785
	protected function notify( array $errors ) : Iface
786
	{
787
		$list = [];
788
		$i18n = $this->context->getI18n();
789
790
		foreach( $errors as $key => $error )
791
		{
792
			if( $error ) {
793
				$list[] = $key . ': ' . $i18n->dt( 'mshop', $error );
794
			}
795
		}
796
797
		if( !empty( $list ) ) {
798
			throw new \Aimeos\Admin\JQAdm\Exception( join( "\n", $list ) );
799
		}
800
801
		return $this;
802
	}
803
}
804