Passed
Push — master ( 1b0a2e...121449 )
by Aimeos
02:28
created

Base::saveRelationships()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 13
nc 7
nop 3
dl 0
loc 26
rs 8.8333
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-2018
6
 * @package Admin
7
 * @subpackage JsonAdm
8
 */
9
10
11
namespace Aimeos\Admin\JsonAdm;
12
13
14
/**
15
 * JSON API common client
16
 *
17
 * @package Admin
18
 * @subpackage JsonAdm
19
 */
20
abstract class Base
21
{
22
	private $context;
23
	private $aimeos;
24
	private $view;
25
	private $path;
26
27
28
	/**
29
	 * Initializes the client
30
	 *
31
	 * @param \Aimeos\MShop\Context\Item\Iface $context MShop context object
32
	 * @param string $path Name of the client separated by slashes, e.g "product/property"
33
	 */
34
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, string $path )
35
	{
36
		$this->context = $context;
37
		$this->path = $path;
38
	}
39
40
41
	/**
42
	 * Catch unknown methods
43
	 *
44
	 * @param string $name Name of the method
45
	 * @param array $param List of method parameter
46
	 * @throws \Aimeos\Admin\JsonAdm\Exception If method call failed
47
	 */
48
	public function __call( string $name, array $param )
49
	{
50
		throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Unable to call method "%1$s"', $name ) );
51
	}
52
53
54
	/**
55
	 * Returns the Aimeos bootstrap object
56
	 *
57
	 * @return \Aimeos\Bootstrap The Aimeos bootstrap object
58
	 */
59
	public function getAimeos() : \Aimeos\Bootstrap
60
	{
61
		if( !isset( $this->aimeos ) ) {
62
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Aimeos object not available' ) );
63
		}
64
65
		return $this->aimeos;
66
	}
67
68
69
	/**
70
	 * Sets the Aimeos bootstrap object
71
	 *
72
	 * @param \Aimeos\Bootstrap $aimeos The Aimeos bootstrap object
73
	 * @return \Aimeos\Admin\JsonAdm\Iface Reference to this object for fluent calls
74
	 */
75
	public function setAimeos( \Aimeos\Bootstrap $aimeos ) : \Aimeos\Admin\JsonAdm\Iface
76
	{
77
		$this->aimeos = $aimeos;
78
		return $this;
79
	}
80
81
82
	/**
83
	 * Returns the view object that will generate the admin output.
84
	 *
85
	 * @return \Aimeos\MW\View\Iface The view object which generates the admin output
86
	 */
87
	public function getView() : \Aimeos\MW\View\Iface
88
	{
89
		if( !isset( $this->view ) ) {
90
			throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'No view available' ) );
91
		}
92
93
		return $this->view;
94
	}
95
96
97
	/**
98
	 * Sets the view object that will generate the admin output.
99
	 *
100
	 * @param \Aimeos\MW\View\Iface $view The view object which generates the admin output
101
	 * @return \Aimeos\Admin\JsonAdm\Iface Reference to this object for fluent calls
102
	 */
103
	public function setView( \Aimeos\MW\View\Iface $view ) : \Aimeos\Admin\JsonAdm\Iface
104
	{
105
		$this->view = $view;
106
		return $this;
107
	}
108
109
110
	/**
111
	 * Returns the items with parent/child relationships
112
	 *
113
	 * @param \Aimeos\Map $items List of items implementing \Aimeos\MShop\Common\Item\Iface
114
	 * @param array $include List of resource types that should be fetched
115
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Common\Item\Iface
116
	 */
117
	protected function getChildItems( \Aimeos\Map $items, array $include ) : \Aimeos\Map
118
	{
119
		return map();
120
	}
121
122
123
	/**
124
	 * Returns the context item object
125
	 *
126
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
127
	 */
128
	protected function getContext() : \Aimeos\MShop\Context\Item\Iface
129
	{
130
		return $this->context;
131
	}
132
133
134
	/**
135
	 * Returns the list of domains that are available as resources
136
	 *
137
	 * @param \Aimeos\MW\View\Iface $view View object with "resource" parameter
138
	 * @return array List of domain names
139
	 */
140
	protected function getDomains( \Aimeos\MW\View\Iface $view ) : array
141
	{
142
		if( ( $domains = $view->param( 'resource' ) ) == '' )
143
		{
144
			/** admin/jsonadm/domains
145
			 * A list of domain names whose clients are available for the JSON API
146
			 *
147
			 * The HTTP OPTIONS method returns a list of resources known by the
148
			 * JSON API including their URLs. The list of available resources
149
			 * can be exteded dynamically be implementing a new Jsonadm client
150
			 * class handling request for this new domain.
151
			 *
152
			 * To add the new domain client to the list of resources returned
153
			 * by the HTTP OPTIONS method, you have to add its name in lower case
154
			 * to the existing configuration.
155
			 *
156
			 * @param array List of domain names
157
			 * @since 2016.01
158
			 * @category Developer
159
			 * @see admin/jsonadm/resources
160
			 */
161
			$domains = $this->getContext()->getConfig()->get( 'admin/jsonadm/domains', [] );
162
		}
163
164
		return (array) $domains;
165
	}
166
167
168
	/**
169
	 * Returns the list items for association relationships
170
	 *
171
	 * @param \Aimeos\Map $items List of items implementing \Aimeos\MShop\Common\Item\Iface
172
	 * @param array $include List of resource types that should be fetched
173
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
174
	 */
175
	protected function getListItems( \Aimeos\Map $items, array $include ) : \Aimeos\Map
176
	{
177
		return map();
178
	}
179
180
181
	/**
182
	 * Returns the path to the client
183
	 *
184
	 * @return string Client path, e.g. "product/property"
185
	 */
186
	protected function getPath() : string
187
	{
188
		return $this->path;
189
	}
190
191
192
	/**
193
	 * Returns the items associated via a lists table
194
	 *
195
	 * @param \Aimeos\Map $listItems List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
196
	 * @return \Aimeos\Map List of items implementing \Aimeos\MShop\Common\Item\Iface
197
	 */
198
	protected function getRefItems( \Aimeos\Map $listItems ) : \Aimeos\Map
199
	{
200
		$map = [];
201
		$list = map();
202
		$context = $this->getContext();
203
204
		foreach( $listItems as $listItem ) {
205
			$map[$listItem->getDomain()][] = $listItem->getRefId();
206
		}
207
208
		foreach( $map as $domain => $ids )
209
		{
210
			$manager = \Aimeos\MShop::create( $context, $domain );
211
212
			$search = $manager->createSearch();
213
			$search->setConditions( $search->compare( '==', str_replace( '/', '.', $domain ) . '.id', $ids ) );
214
215
			$list = $list->merge( $manager->searchItems( $search ) );
216
		}
217
218
		return $list;
219
	}
220
221
222
	/**
223
	 * Returns the list of allowed resources
224
	 *
225
	 * @param \Aimeos\MW\View\Iface $view View object with "access" helper
226
	 * @param array List of all available resources
0 ignored issues
show
Bug introduced by
The type Aimeos\Admin\JsonAdm\List was not found. Maybe you did not declare it correctly or list all dependencies?

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

filter:
    dependency_paths: ["lib/*"]

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

Loading history...
227
	 * @return array List of allowed resources
228
	 */
229
	protected function getAllowedResources( \Aimeos\MW\View\Iface $view, array $resources ) : array
230
	{
231
		$config = $this->getContext()->getConfig();
232
		$allowed = [];
233
234
		foreach( $resources as $resource )
235
		{
236
			if( $view->access( $config->get( 'admin/jsonadm/resource/' . $resource . '/groups', [] ) ) === true ) {
237
				$allowed[] = $resource;
238
			}
239
		}
240
241
		return $allowed;
242
	}
243
244
245
	/**
246
	 * Returns the list of additional resources
247
	 *
248
	 * @param \Aimeos\MW\View\Iface $view View object with "resource" parameter
249
	 * @return array List of domain names
250
	 */
251
	protected function getResources( \Aimeos\MW\View\Iface $view ) : array
252
	{
253
		/** admin/jsonadm/resources
254
		 * A list of additional resources name whose clients are available for the JSON API
255
		 *
256
		 * The HTTP OPTIONS method returns a list of resources known by the
257
		 * JSON API including their URLs. The list of available resources
258
		 * can be exteded dynamically be implementing a new Jsonadm client
259
		 * class handling request for this new domain.
260
		 *
261
		 * The resource config lists the resources that are not automatically
262
		 * derived from the admin/jsonadm/domains configuration.
263
		 *
264
		 * @param array List of domain names
265
		 * @since 2017.07
266
		 * @category Developer
267
		 * @see admin/jsonadm/domains
268
		 */
269
		return (array) $view->config( 'admin/jsonadm/resources', [] );
270
	}
271
272
273
	/**
274
	 * Initializes the criteria object based on the given parameter
275
	 *
276
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
277
	 * @param array $params List of criteria data with condition, sorting and paging
278
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
279
	 */
280
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
281
	{
282
		$this->initCriteriaConditions( $criteria, $params );
283
		$this->initCriteriaSortations( $criteria, $params );
284
		$this->initCriteriaSlice( $criteria, $params );
285
286
		return $criteria;
287
	}
288
289
290
	/**
291
	 * Initializes the criteria object with conditions based on the given parameter
292
	 *
293
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
294
	 * @param array $params List of criteria data with condition, sorting and paging
295
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
296
	 */
297
	protected function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
298
	{
299
		if( !isset( $params['filter'] ) ) {
300
			return $criteria;
301
		}
302
303
		if( ( $cond = $criteria->toConditions( (array) $params['filter'] ) ) !== null ) {
304
			return $criteria->setConditions( $criteria->combine( '&&', [$cond, $criteria->getConditions()] ) );
305
		}
306
307
		return $criteria;
308
	}
309
310
311
	/**
312
	 * Initializes the criteria object with the slice based on the given parameter.
313
	 *
314
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
315
	 * @param array $params List of criteria data with condition, sorting and paging
316
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
317
	 */
318
	protected function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
319
	{
320
		$start = ( isset( $params['page']['offset'] ) ? (int) $params['page']['offset'] : 0 );
321
		$size = ( isset( $params['page']['limit'] ) ? (int) $params['page']['limit'] : 25 );
322
323
		return $criteria->setSlice( $start, $size );
324
	}
325
326
327
	/**
328
	 * Initializes the criteria object with sortations based on the given parameter
329
	 *
330
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
331
	 * @param array $params List of criteria data with condition, sorting and paging
332
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
333
	 */
334
	protected function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params ) : \Aimeos\MW\Criteria\Iface
335
	{
336
		if( !isset( $params['sort'] ) ) {
337
			return $criteria;
338
		}
339
340
		$sortation = [];
341
342
		foreach( explode( ',', $params['sort'] ) as $sort )
343
		{
344
			if( $sort[0] === '-' ) {
345
				$sortation[] = $criteria->sort( '-', substr( $sort, 1 ) );
346
			} else {
347
				$sortation[] = $criteria->sort( '+', $sort );
348
			}
349
		}
350
351
		return $criteria->setSortations( $sortation );
352
	}
353
354
355
	/**
356
	 * Creates of updates several items at once
357
	 *
358
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
359
	 * @param \stdClass $request Object with request body data
360
	 * @return \Aimeos\Map List of items
361
	 */
362
	protected function saveData( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $request ) : \Aimeos\Map
363
	{
364
		$data = [];
365
366
		if( isset( $request->data ) )
367
		{
368
			foreach( (array) $request->data as $entry ) {
369
				$data[] = $this->saveEntry( $manager, $entry );
370
			}
371
		}
372
373
		return map( $data );
374
	}
375
376
377
	/**
378
	 * Saves and returns the new or updated item
379
	 *
380
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
381
	 * @param \stdClass $entry Object including "id" and "attributes" elements
382
	 * @return \Aimeos\MShop\Common\Item\Iface New or updated item
383
	 */
384
	protected function saveEntry( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $entry ) : \Aimeos\MShop\Common\Item\Iface
385
	{
386
		if( isset( $entry->id ) ) {
387
			$item = $manager->getItem( $entry->id );
388
		} else {
389
			$item = $manager->createItem();
390
		}
391
392
		if( isset( $entry->attributes ) && ( $attr = (array) $entry->attributes ) ) {
393
			$item = $item->fromArray( $attr, true );
394
		}
395
396
		$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

396
		/** @scrutinizer ignore-call */ 
397
  $item = $manager->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...
397
398
		if( isset( $entry->relationships ) ) {
399
			$this->saveRelationships( $manager, $item, $entry->relationships );
400
		}
401
402
		return $manager->getItem( $item->getId() );
403
	}
404
405
406
	/**
407
	 * Saves the item references associated via the list
408
	 *
409
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
410
	 * @param \Aimeos\MShop\Common\Item\Iface $item Domain item with an unique ID set
411
	 * @param \stdClass $relationships Object including the <domain>/data/attributes structure
412
	 */
413
	protected function saveRelationships( \Aimeos\MShop\Common\Manager\Iface $manager,
414
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $relationships )
415
	{
416
		$id = $item->getId();
417
		$listManager = $manager->getSubManager( 'lists' );
418
419
		foreach( (array) $relationships as $domain => $list )
420
		{
421
			if( isset( $list->data ) )
422
			{
423
				foreach( (array) $list->data as $data )
424
				{
425
					$listItem = $listManager->createItem()->setType( 'default' );
426
427
					if( isset( $data->attributes ) && ( $attr = (array) $data->attributes ) ) {
428
						$item = $item->fromArray( $attr, true );
429
					}
430
431
					if( isset( $data->id ) ) {
432
						$listItem->setRefId( $data->id );
433
					}
434
435
					$listItem->setParentId( $id );
436
					$listItem->setDomain( $domain );
437
438
					$listManager->saveItem( $listItem, false );
439
				}
440
			}
441
		}
442
	}
443
}
444