Completed
Push — master ( 26c14b...5d21ce )
by Aimeos
02:35
created

Base::getResources()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2016
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 $view;
23
	private $context;
24
	private $templatePaths;
25
	private $path;
26
27
28
	/**
29
	 * Initializes the client
30
	 *
31
	 * @param \Aimeos\MShop\Context\Item\Iface $context MShop context object
32
	 * @param \Aimeos\MW\View\Iface $view View object
33
	 * @param array $templatePaths List of file system paths where the templates are stored
34
	 * @param string $path Name of the client separated by slashes, e.g "product/property"
35
	 */
36
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\MW\View\Iface $view, array $templatePaths, $path )
37
	{
38
		$this->view = $view;
39
		$this->context = $context;
40
		$this->templatePaths = $templatePaths;
41
		$this->path = $path;
42
	}
43
44
45
	/**
46
	 * Catch unknown methods
47
	 *
48
	 * @param string $name Name of the method
49
	 * @param array $param List of method parameter
50
	 * @throws \Aimeos\Admin\JsonAdm\Exception If method call failed
51
	 */
52
	public function __call( $name, array $param )
53
	{
54
		throw new \Aimeos\Admin\JsonAdm\Exception( sprintf( 'Unable to call method "%1$s"', $name ) );
55
	}
56
57
58
	/**
59
	 * Returns the items with parent/child relationships
60
	 *
61
	 * @param array $items List of items implementing \Aimeos\MShop\Common\Item\Iface
62
	 * @param array $include List of resource types that should be fetched
63
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
64
	 */
65
	protected function getChildItems( array $items, array $include )
66
	{
67
		return [];
68
	}
69
70
71
	/**
72
	 * Returns the context item object
73
	 *
74
	 * @return \Aimeos\MShop\Context\Item\Iface Context object
75
	 */
76
	protected function getContext()
77
	{
78
		return $this->context;
79
	}
80
81
82
	/**
83
	 * Returns the list of domains that are available as resources
84
	 *
85
	 * @param \Aimeos\MW\View\Iface $view View object with "resource" parameter
86
	 * @return array List of domain names
87
	 */
88
	protected function getDomains( \Aimeos\MW\View\Iface $view )
89
	{
90
		if( ( $domains = $view->param( 'resource' ) ) == '' )
91
		{
92
			/** admin/jsonadm/domains
93
			 * A list of domain names whose clients are available for the JSON API
94
			 *
95
			 * The HTTP OPTIONS method returns a list of resources known by the
96
			 * JSON API including their URLs. The list of available resources
97
			 * can be exteded dynamically be implementing a new Jsonadm client
98
			 * class handling request for this new domain.
99
			 *
100
			 * To add the new domain client to the list of resources returned
101
			 * by the HTTP OPTIONS method, you have to add its name in lower case
102
			 * to the existing configuration.
103
			 *
104
			 * @param array List of domain names
105
			 * @since 2016.01
106
			 * @category Developer
107
			 * @see admin/jsonadm/resources
108
			 */
109
			$default = array(
110
				'attribute', 'catalog', 'coupon', 'customer', 'locale', 'media', 'order',
111
				'plugin', 'price', 'product', 'service', 'supplier', 'stock', 'tag', 'text'
112
			);
113
			$domains = $this->getContext()->getConfig()->get( 'admin/jsonadm/domains', $default );
114
		}
115
116
		return (array) $domains;
117
	}
118
119
120
	/**
121
	 * Returns the IDs sent in the request body
122
	 *
123
	 * @param \stdClass $request Decoded request body
124
	 * @return array List of item IDs
125
	 */
126
	protected function getIds( $request )
127
	{
128
		$ids = [];
129
130
		if( isset( $request->data ) )
131
		{
132
			foreach( (array) $request->data as $entry )
133
			{
134
				if( isset( $entry->id ) ) {
135
					$ids[] = $entry->id;
136
				}
137
			}
138
		}
139
140
		return $ids;
141
	}
142
143
144
	/**
145
	 * Returns the list items for association relationships
146
	 *
147
	 * @param array $items List of items implementing \Aimeos\MShop\Common\Item\Iface
148
	 * @param array $include List of resource types that should be fetched
149
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
150
	 */
151
	protected function getListItems( array $items, array $include )
152
	{
153
		return [];
154
	}
155
156
157
	/**
158
	 * Returns the path to the client
159
	 *
160
	 * @return string Client path, e.g. "product/property"
161
	 */
162
	protected function getPath()
163
	{
164
		return $this->path;
165
	}
166
167
168
	/**
169
	 * Returns the items associated via a lists table
170
	 *
171
	 * @param array $listItems List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
172
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
173
	 */
174
	protected function getRefItems( array $listItems )
175
	{
176
		$list = $map = [];
177
		$context = $this->getContext();
178
179
		foreach( $listItems as $listItem ) {
180
			$map[$listItem->getDomain()][] = $listItem->getRefId();
181
		}
182
183
		foreach( $map as $domain => $ids )
184
		{
185
			$manager = \Aimeos\MShop\Factory::createManager( $context, $domain );
186
187
			$search = $manager->createSearch();
188
			$search->setConditions( $search->compare( '==', $domain . '.id', $ids ) );
189
190
			$list = array_merge( $list, $manager->searchItems( $search ) );
191
		}
192
193
		return $list;
194
	}
195
196
197
	/**
198
	 * Returns the list of additional resources
199
	 *
200
	 * @param \Aimeos\MW\View\Iface $view View object with "resource" parameter
201
	 * @return array List of domain names
202
	 */
203
	protected function getResources( \Aimeos\MW\View\Iface $view )
204
	{
205
		/** admin/jsonadm/resources
206
		 * A list of additional resources name whose clients are available for the JSON API
207
		 *
208
		 * The HTTP OPTIONS method returns a list of resources known by the
209
		 * JSON API including their URLs. The list of available resources
210
		 * can be exteded dynamically be implementing a new Jsonadm client
211
		 * class handling request for this new domain.
212
		 *
213
		 * The resource config lists the resources that are not automatically
214
		 * derived from the admin/jsonadm/domains configuration.
215
		 *
216
		 * @param array List of domain names
217
		 * @since 2017.07
218
		 * @category Developer
219
		 * @see admin/jsonadm/domains
220
		 */
221
		return (array) $view->config( 'admin/jsonadm/resources', ['coupon/config'] );
222
	}
223
224
225
	/**
226
	 * Returns the paths to the template files
227
	 *
228
	 * @return array List of file system paths
229
	 */
230
	protected function getTemplatePaths()
231
	{
232
		return $this->templatePaths;
233
	}
234
235
236
	/**
237
	 * Returns the view object
238
	 *
239
	 * @return \Aimeos\MW\View\Iface View object
240
	 */
241
	protected function getView()
242
	{
243
		return $this->view;
244
	}
245
246
247
	/**
248
	 * Initializes the criteria object based on the given parameter
249
	 *
250
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
251
	 * @param array $params List of criteria data with condition, sorting and paging
252
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
253
	 */
254
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params )
255
	{
256
		$this->initCriteriaConditions( $criteria, $params );
257
		$this->initCriteriaSortations( $criteria, $params );
258
		$this->initCriteriaSlice( $criteria, $params );
259
260
		return $criteria;
261
	}
262
263
264
	/**
265
	 * Initializes the criteria object with conditions based on the given parameter
266
	 *
267
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
268
	 * @param array $params List of criteria data with condition, sorting and paging
269
	 */
270
	protected function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params )
271
	{
272
		if( !isset( $params['filter'] ) ) {
273
			return;
274
		}
275
276
		$existing = $criteria->getConditions();
277
		$criteria->setConditions( $criteria->toConditions( (array) $params['filter'] ) );
278
279
		$expr = array( $criteria->getConditions(), $existing );
280
		$criteria->setConditions( $criteria->combine( '&&', $expr ) );
281
	}
282
283
284
	/**
285
	 * Initializes the criteria object with the slice based on the given parameter.
286
	 *
287
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
288
	 * @param array $params List of criteria data with condition, sorting and paging
289
	 */
290
	protected function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params )
291
	{
292
		$start = ( isset( $params['page']['offset'] ) ? (int) $params['page']['offset'] : 0 );
293
		$size = ( isset( $params['page']['limit'] ) ? (int) $params['page']['limit'] : 25 );
294
295
		$criteria->setSlice( $start, $size );
296
	}
297
298
299
	/**
300
	 * Initializes the criteria object with sortations based on the given parameter
301
	 *
302
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
303
	 * @param array $params List of criteria data with condition, sorting and paging
304
	 */
305
	protected function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params )
306
	{
307
		if( !isset( $params['sort'] ) ) {
308
			return;
309
		}
310
311
		$sortation = [];
312
313
		foreach( explode( ',', $params['sort'] ) as $sort )
314
		{
315
			if( $sort[0] === '-' ) {
316
				$sortation[] = $criteria->sort( '-', substr( $sort, 1 ) );
317
			} else {
318
				$sortation[] = $criteria->sort( '+', $sort );
319
			}
320
		}
321
322
		$criteria->setSortations( $sortation );
323
	}
324
325
326
	/**
327
	 * Creates of updates several items at once
328
	 *
329
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
330
	 * @param \stdClass $request Object with request body data
331
	 * @return array List of items
332
	 */
333
	protected function saveData( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $request )
334
	{
335
		$data = [];
336
337
		if( isset( $request->data ) )
338
		{
339
			foreach( (array) $request->data as $entry ) {
340
				$data[] = $this->saveEntry( $manager, $entry );
341
			}
342
		}
343
344
		return $data;
345
	}
346
347
348
	/**
349
	 * Saves and returns the new or updated item
350
	 *
351
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
352
	 * @param \stdClass $entry Object including "id" and "attributes" elements
353
	 * @return \Aimeos\MShop\Common\Item\Iface New or updated item
354
	 */
355
	protected function saveEntry( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $entry )
356
	{
357
		if( isset( $entry->id ) ) {
358
			$item = $manager->getItem( $entry->id );
359
		} else {
360
			$item = $manager->createItem();
361
		}
362
363
		$item = $this->addItemData( $manager, $item, $entry, $item->getResourceType() );
364
		$item = $manager->saveItem( $item );
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $item is correct as $manager->saveItem($item) (which targets Aimeos\MShop\Common\Manager\Iface::saveItem()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
365
366
		if( isset( $entry->relationships ) ) {
367
			$this->saveRelationships( $manager, $item, $entry->relationships );
0 ignored issues
show
Documentation introduced by
$item is of type null, but the function expects a object<Aimeos\MShop\Common\Item\Iface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
368
		}
369
370
		return $manager->getItem( $item->getId() );
0 ignored issues
show
Bug introduced by
The method getId cannot be called on $item (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
371
	}
372
373
374
	/**
375
	 * Saves the item references associated via the list
376
	 *
377
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
378
	 * @param \Aimeos\MShop\Common\Item\Iface $item Domain item with an unique ID set
379
	 * @param \stdClass $relationships Object including the <domain>/data/attributes structure
380
	 */
381
	protected function saveRelationships( \Aimeos\MShop\Common\Manager\Iface $manager,
382
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $relationships )
383
	{
384
		$id = $item->getId();
385
		$listManager = $manager->getSubManager( 'lists' );
386
387
		foreach( (array) $relationships as $domain => $list )
388
		{
389
			if( isset( $list->data ) )
390
			{
391
				foreach( (array) $list->data as $data )
392
				{
393
					$listItem = $this->addItemData( $listManager, $listManager->createItem(), $data, $domain );
394
395
					if( isset( $data->id ) ) {
396
						$listItem->setRefId( $data->id );
397
					}
398
399
					$listItem->setParentId( $id );
400
					$listItem->setDomain( $domain );
401
402
					$listManager->saveItem( $listItem, false );
403
				}
404
			}
405
		}
406
	}
407
408
409
	/**
410
	 * Adds the data from the given object to the item
411
	 *
412
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager object
413
	 * @param \Aimeos\MShop\Common\Item\Iface $item Item object to add the data to
414
	 * @param \stdClass $data Object with "attributes" property
415
	 * @param string $domain Domain of the type item
416
	 * @return \Aimeos\MShop\Common\Item\Iface Item including the data
417
	 */
418
	protected function addItemData(\Aimeos\MShop\Common\Manager\Iface $manager,
419
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $data, $domain )
420
	{
421
		if( isset( $data->attributes ) )
422
		{
423
			$attr = (array) $data->attributes;
424
			$key = str_replace( '/', '.', $item->getResourceType() );
425
426
			if( isset( $attr[$key.'.type'] ) )
427
			{
428
				$typeItem = $manager->getSubManager( 'type' )->findItem( $attr[$key.'.type'], [], $domain );
429
				$attr[$key.'.typeid'] = $typeItem->getId();
430
			}
431
432
			$item->fromArray( $attr );
433
		}
434
435
		return $item;
436
	}
437
}
438