Completed
Push — master ( 026233...c7df97 )
by Aimeos
02:33
created

Base::setView()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2017
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, $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( $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()
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\JQAdm\Iface Reference to this object for fluent calls
74
	 */
75
	public function setAimeos( \Aimeos\Bootstrap $aimeos )
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()
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\JQAdm\Iface Reference to this object for fluent calls
102
	 */
103
	public function setView( \Aimeos\MW\View\Iface $view )
104
	{
105
		$this->view = $view;
106
		return $this;
107
	}
108
109
110
	/**
111
	 * Returns the items with parent/child relationships
112
	 *
113
	 * @param array $items List of items implementing \Aimeos\MShop\Common\Item\Iface
114
	 * @param array $include List of resource types that should be fetched
115
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
116
	 */
117
	protected function getChildItems( array $items, array $include )
118
	{
119
		return [];
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()
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 )
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
			$default = array(
162
				'attribute', 'catalog', 'coupon', 'customer', 'locale', 'media', 'order',
163
				'plugin', 'price', 'product', 'service', 'supplier', 'stock', 'tag', 'text'
164
			);
165
			$domains = $this->getContext()->getConfig()->get( 'admin/jsonadm/domains', $default );
166
		}
167
168
		return (array) $domains;
169
	}
170
171
172
	/**
173
	 * Returns the IDs sent in the request body
174
	 *
175
	 * @param \stdClass $request Decoded request body
176
	 * @return array List of item IDs
177
	 */
178
	protected function getIds( $request )
179
	{
180
		$ids = [];
181
182
		if( isset( $request->data ) )
183
		{
184
			foreach( (array) $request->data as $entry )
185
			{
186
				if( isset( $entry->id ) ) {
187
					$ids[] = $entry->id;
188
				}
189
			}
190
		}
191
192
		return $ids;
193
	}
194
195
196
	/**
197
	 * Returns the list items for association relationships
198
	 *
199
	 * @param array $items List of items implementing \Aimeos\MShop\Common\Item\Iface
200
	 * @param array $include List of resource types that should be fetched
201
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
202
	 */
203
	protected function getListItems( array $items, array $include )
204
	{
205
		return [];
206
	}
207
208
209
	/**
210
	 * Returns the path to the client
211
	 *
212
	 * @return string Client path, e.g. "product/property"
213
	 */
214
	protected function getPath()
215
	{
216
		return $this->path;
217
	}
218
219
220
	/**
221
	 * Returns the items associated via a lists table
222
	 *
223
	 * @param array $listItems List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
224
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
225
	 */
226
	protected function getRefItems( array $listItems )
227
	{
228
		$list = $map = [];
229
		$context = $this->getContext();
230
231
		foreach( $listItems as $listItem ) {
232
			$map[$listItem->getDomain()][] = $listItem->getRefId();
233
		}
234
235
		foreach( $map as $domain => $ids )
236
		{
237
			$manager = \Aimeos\MShop\Factory::createManager( $context, $domain );
238
239
			$search = $manager->createSearch();
240
			$search->setConditions( $search->compare( '==', $domain . '.id', $ids ) );
241
242
			$list = array_merge( $list, $manager->searchItems( $search ) );
243
		}
244
245
		return $list;
246
	}
247
248
249
	/**
250
	 * Returns the list of additional resources
251
	 *
252
	 * @param \Aimeos\MW\View\Iface $view View object with "resource" parameter
253
	 * @return array List of domain names
254
	 */
255
	protected function getResources( \Aimeos\MW\View\Iface $view )
256
	{
257
		/** admin/jsonadm/resources
258
		 * A list of additional resources name whose clients are available for the JSON API
259
		 *
260
		 * The HTTP OPTIONS method returns a list of resources known by the
261
		 * JSON API including their URLs. The list of available resources
262
		 * can be exteded dynamically be implementing a new Jsonadm client
263
		 * class handling request for this new domain.
264
		 *
265
		 * The resource config lists the resources that are not automatically
266
		 * derived from the admin/jsonadm/domains configuration.
267
		 *
268
		 * @param array List of domain names
269
		 * @since 2017.07
270
		 * @category Developer
271
		 * @see admin/jsonadm/domains
272
		 */
273
		return (array) $view->config( 'admin/jsonadm/resources', ['coupon/config', 'plugin/config', 'service/config'] );
274
	}
275
276
277
	/**
278
	 * Initializes the criteria object based on the given parameter
279
	 *
280
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
281
	 * @param array $params List of criteria data with condition, sorting and paging
282
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
283
	 */
284
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params )
285
	{
286
		$this->initCriteriaConditions( $criteria, $params );
287
		$this->initCriteriaSortations( $criteria, $params );
288
		$this->initCriteriaSlice( $criteria, $params );
289
290
		return $criteria;
291
	}
292
293
294
	/**
295
	 * Initializes the criteria object with conditions based on the given parameter
296
	 *
297
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
298
	 * @param array $params List of criteria data with condition, sorting and paging
299
	 */
300
	protected function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params )
301
	{
302
		if( !isset( $params['filter'] ) ) {
303
			return;
304
		}
305
306
		$existing = $criteria->getConditions();
307
		$criteria->setConditions( $criteria->toConditions( (array) $params['filter'] ) );
308
309
		$expr = array( $criteria->getConditions(), $existing );
310
		$criteria->setConditions( $criteria->combine( '&&', $expr ) );
311
	}
312
313
314
	/**
315
	 * Initializes the criteria object with the slice based on the given parameter.
316
	 *
317
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
318
	 * @param array $params List of criteria data with condition, sorting and paging
319
	 */
320
	protected function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params )
321
	{
322
		$start = ( isset( $params['page']['offset'] ) ? (int) $params['page']['offset'] : 0 );
323
		$size = ( isset( $params['page']['limit'] ) ? (int) $params['page']['limit'] : 25 );
324
325
		$criteria->setSlice( $start, $size );
326
	}
327
328
329
	/**
330
	 * Initializes the criteria object with sortations based on the given parameter
331
	 *
332
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
333
	 * @param array $params List of criteria data with condition, sorting and paging
334
	 */
335
	protected function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params )
336
	{
337
		if( !isset( $params['sort'] ) ) {
338
			return;
339
		}
340
341
		$sortation = [];
342
343
		foreach( explode( ',', $params['sort'] ) as $sort )
344
		{
345
			if( $sort[0] === '-' ) {
346
				$sortation[] = $criteria->sort( '-', substr( $sort, 1 ) );
347
			} else {
348
				$sortation[] = $criteria->sort( '+', $sort );
349
			}
350
		}
351
352
		$criteria->setSortations( $sortation );
353
	}
354
355
356
	/**
357
	 * Creates of updates several items at once
358
	 *
359
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
360
	 * @param \stdClass $request Object with request body data
361
	 * @return array List of items
362
	 */
363
	protected function saveData( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $request )
364
	{
365
		$data = [];
366
367
		if( isset( $request->data ) )
368
		{
369
			foreach( (array) $request->data as $entry ) {
370
				$data[] = $this->saveEntry( $manager, $entry );
371
			}
372
		}
373
374
		return $data;
375
	}
376
377
378
	/**
379
	 * Saves and returns the new or updated item
380
	 *
381
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
382
	 * @param \stdClass $entry Object including "id" and "attributes" elements
383
	 * @return \Aimeos\MShop\Common\Item\Iface New or updated item
384
	 */
385
	protected function saveEntry( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $entry )
386
	{
387
		if( isset( $entry->id ) ) {
388
			$item = $manager->getItem( $entry->id );
389
		} else {
390
			$item = $manager->createItem();
391
		}
392
393
		$item = $this->addItemData( $manager, $item, $entry, $item->getResourceType() );
394
		$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...
395
396
		if( isset( $entry->relationships ) ) {
397
			$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...
398
		}
399
400
		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...
401
	}
402
403
404
	/**
405
	 * Saves the item references associated via the list
406
	 *
407
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
408
	 * @param \Aimeos\MShop\Common\Item\Iface $item Domain item with an unique ID set
409
	 * @param \stdClass $relationships Object including the <domain>/data/attributes structure
410
	 */
411
	protected function saveRelationships( \Aimeos\MShop\Common\Manager\Iface $manager,
412
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $relationships )
413
	{
414
		$id = $item->getId();
415
		$listManager = $manager->getSubManager( 'lists' );
416
417
		foreach( (array) $relationships as $domain => $list )
418
		{
419
			if( isset( $list->data ) )
420
			{
421
				foreach( (array) $list->data as $data )
422
				{
423
					$listItem = $this->addItemData( $listManager, $listManager->createItem(), $data, $domain );
424
425
					if( isset( $data->id ) ) {
426
						$listItem->setRefId( $data->id );
427
					}
428
429
					$listItem->setParentId( $id );
430
					$listItem->setDomain( $domain );
431
432
					$listManager->saveItem( $listItem, false );
433
				}
434
			}
435
		}
436
	}
437
438
439
	/**
440
	 * Adds the data from the given object to the item
441
	 *
442
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager object
443
	 * @param \Aimeos\MShop\Common\Item\Iface $item Item object to add the data to
444
	 * @param \stdClass $data Object with "attributes" property
445
	 * @param string $domain Domain of the type item
446
	 * @return \Aimeos\MShop\Common\Item\Iface Item including the data
447
	 */
448
	protected function addItemData(\Aimeos\MShop\Common\Manager\Iface $manager,
449
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $data, $domain )
450
	{
451
		if( isset( $data->attributes ) )
452
		{
453
			$attr = (array) $data->attributes;
454
			$key = str_replace( '/', '.', $item->getResourceType() );
455
456
			if( isset( $attr[$key.'.type'] ) )
457
			{
458
				$typeItem = $manager->getSubManager( 'type' )->findItem( $attr[$key.'.type'], [], $domain );
459
				$attr[$key.'.typeid'] = $typeItem->getId();
460
			}
461
462
			$item->fromArray( $attr );
463
		}
464
465
		return $item;
466
	}
467
}
468