Completed
Push — master ( 88af42...a70447 )
by Aimeos
03:41
created

Base::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
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
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 array();
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
			 */
108
			$default = array(
109
				'attribute', 'catalog', 'coupon', 'customer', 'locale', 'media',
110
				'order', 'plugin', 'price', 'product', 'service', 'supplier', 'tag', 'text'
111
			);
112
			$domains = $this->getContext()->getConfig()->get( 'admin/jsonadm/domains', $default );
113
		}
114
115
		return (array) $domains;
116
	}
117
118
119
	/**
120
	 * Returns the IDs sent in the request body
121
	 *
122
	 * @param \stdClass $request Decoded request body
123
	 * @return array List of item IDs
124
	 */
125
	protected function getIds( $request )
126
	{
127
		$ids = array();
128
129
		if( isset( $request->data ) )
130
		{
131
			foreach( (array) $request->data as $entry )
132
			{
133
				if( isset( $entry->id ) ) {
134
					$ids[] = $entry->id;
135
				}
136
			}
137
		}
138
139
		return $ids;
140
	}
141
142
143
	/**
144
	 * Returns the list items for association relationships
145
	 *
146
	 * @param array $items List of items implementing \Aimeos\MShop\Common\Item\Iface
147
	 * @param array $include List of resource types that should be fetched
148
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
149
	 */
150
	protected function getListItems( array $items, array $include )
151
	{
152
		return array();
153
	}
154
155
156
	/**
157
	 * Returns the path to the client
158
	 *
159
	 * @return string Client path, e.g. "product/property"
160
	 */
161
	protected function getPath()
162
	{
163
		return $this->path;
164
	}
165
166
167
	/**
168
	 * Returns the items associated via a lists table
169
	 *
170
	 * @param array $listItems List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
171
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
172
	 */
173
	protected function getRefItems( array $listItems )
174
	{
175
		$list = $map = array();
176
		$context = $this->getContext();
177
178
		foreach( $listItems as $listItem ) {
179
			$map[$listItem->getDomain()][] = $listItem->getRefId();
180
		}
181
182
		foreach( $map as $domain => $ids )
183
		{
184
			$manager = \Aimeos\MShop\Factory::createManager( $context, $domain );
185
186
			$search = $manager->createSearch();
187
			$search->setConditions( $search->compare( '==', $domain . '.id', $ids ) );
188
189
			$list = array_merge( $list, $manager->searchItems( $search ) );
190
		}
191
192
		return $list;
193
	}
194
195
196
	/**
197
	 * Returns the paths to the template files
198
	 *
199
	 * @return array List of file system paths
200
	 */
201
	protected function getTemplatePaths()
202
	{
203
		return $this->templatePaths;
204
	}
205
206
207
	/**
208
	 * Returns the view object
209
	 *
210
	 * @return \Aimeos\MW\View\Iface View object
211
	 */
212
	protected function getView()
213
	{
214
		return $this->view;
215
	}
216
217
218
	/**
219
	 * Initializes the criteria object based on the given parameter
220
	 *
221
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
222
	 * @param array $params List of criteria data with condition, sorting and paging
223
	 * @return \Aimeos\MW\Criteria\Iface Initialized criteria object
224
	 */
225
	protected function initCriteria( \Aimeos\MW\Criteria\Iface $criteria, array $params )
226
	{
227
		$this->initCriteriaConditions( $criteria, $params );
228
		$this->initCriteriaSortations( $criteria, $params );
229
		$this->initCriteriaSlice( $criteria, $params );
230
231
		return $criteria;
232
	}
233
234
235
	/**
236
	 * Initializes the criteria object with conditions based on the given parameter
237
	 *
238
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
239
	 * @param array $params List of criteria data with condition, sorting and paging
240
	 */
241
	protected function initCriteriaConditions( \Aimeos\MW\Criteria\Iface $criteria, array $params )
242
	{
243
		if( !isset( $params['filter'] ) ) {
244
			return;
245
		}
246
247
		$existing = $criteria->getConditions();
248
		$criteria->setConditions( $criteria->toConditions( (array) $params['filter'] ) );
249
250
		$expr = array( $criteria->getConditions(), $existing );
251
		$criteria->setConditions( $criteria->combine( '&&', $expr ) );
252
	}
253
254
255
	/**
256
	 * Initializes the criteria object with the slice based on the given parameter.
257
	 *
258
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
259
	 * @param array $params List of criteria data with condition, sorting and paging
260
	 */
261
	protected function initCriteriaSlice( \Aimeos\MW\Criteria\Iface $criteria, array $params )
262
	{
263
		$start = ( isset( $params['page']['offset'] ) ? (int) $params['page']['offset'] : 0 );
264
		$size = ( isset( $params['page']['limit'] ) ? (int) $params['page']['limit'] : 25 );
265
266
		$criteria->setSlice( $start, $size );
267
	}
268
269
270
	/**
271
	 * Initializes the criteria object with sortations based on the given parameter
272
	 *
273
	 * @param \Aimeos\MW\Criteria\Iface $criteria Criteria object
274
	 * @param array $params List of criteria data with condition, sorting and paging
275
	 */
276
	protected function initCriteriaSortations( \Aimeos\MW\Criteria\Iface $criteria, array $params )
277
	{
278
		if( !isset( $params['sort'] ) ) {
279
			return;
280
		}
281
282
		$sortation = array();
283
284
		foreach( explode( ',', $params['sort'] ) as $sort )
285
		{
286
			if( $sort[0] === '-' ) {
287
				$sortation[] = $criteria->sort( '-', substr( $sort, 1 ) );
288
			} else {
289
				$sortation[] = $criteria->sort( '+', $sort );
290
			}
291
		}
292
293
		$criteria->setSortations( $sortation );
294
	}
295
296
297
	/**
298
	 * Creates of updates several items at once
299
	 *
300
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
301
	 * @param \stdClass $request Object with request body data
302
	 * @return array List of items
303
	 */
304
	protected function saveData( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $request )
305
	{
306
		$data = array();
307
308
		if( isset( $request->data ) )
309
		{
310
			foreach( (array) $request->data as $entry ) {
311
				$data[] = $this->saveEntry( $manager, $entry );
312
			}
313
		}
314
315
		return $data;
316
	}
317
318
319
	/**
320
	 * Saves and returns the new or updated item
321
	 *
322
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
323
	 * @param \stdClass $entry Object including "id" and "attributes" elements
324
	 * @return \Aimeos\MShop\Common\Item\Iface New or updated item
325
	 */
326
	protected function saveEntry( \Aimeos\MShop\Common\Manager\Iface $manager, \stdClass $entry )
327
	{
328
		if( isset( $entry->id ) ) {
329
			$item = $manager->getItem( $entry->id );
330
		} else {
331
			$item = $manager->createItem();
332
		}
333
334
		$item = $this->addItemData( $manager, $item, $entry, $item->getResourceType() );
335
		$manager->saveItem( $item );
336
337
		if( isset( $entry->relationships ) ) {
338
			$this->saveRelationships( $manager, $item, $entry->relationships );
339
		}
340
341
		return $manager->getItem( $item->getId() );
342
	}
343
344
345
	/**
346
	 * Saves the item references associated via the list
347
	 *
348
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager responsible for the items
349
	 * @param \Aimeos\MShop\Common\Item\Iface $item Domain item with an unique ID set
350
	 * @param \stdClass $relationships Object including the <domain>/data/attributes structure
351
	 */
352
	protected function saveRelationships( \Aimeos\MShop\Common\Manager\Iface $manager,
353
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $relationships )
354
	{
355
		$id = $item->getId();
356
		$listManager = $manager->getSubManager( 'lists' );
357
358
		foreach( (array) $relationships as $domain => $list )
359
		{
360
			if( isset( $list->data ) )
361
			{
362
				foreach( (array) $list->data as $data )
363
				{
364
					$listItem = $this->addItemData( $listManager, $listManager->createItem(), $data, $domain );
365
366
					if( isset( $data->id ) ) {
367
						$listItem->setRefId( $data->id );
368
					}
369
370
					$listItem->setParentId( $id );
371
					$listItem->setDomain( $domain );
372
373
					$listManager->saveItem( $listItem, false );
374
				}
375
			}
376
		}
377
	}
378
379
380
	/**
381
	 * Adds the data from the given object to the item
382
	 *
383
	 * @param \Aimeos\MShop\Common\Manager\Iface $manager Manager object
384
	 * @param \Aimeos\MShop\Common\Item\Iface $item Item object to add the data to
385
	 * @param \stdClass $data Object with "attributes" property
386
	 * @param string $domain Domain of the type item
387
	 * @return \Aimeos\MShop\Common\Item\Iface Item including the data
388
	 */
389
	protected function addItemData(\Aimeos\MShop\Common\Manager\Iface $manager,
390
		\Aimeos\MShop\Common\Item\Iface $item, \stdClass $data, $domain )
391
	{
392
		if( isset( $data->attributes ) )
393
		{
394
			$attr = (array) $data->attributes;
395
			$key = str_replace( '/', '.', $item->getResourceType() );
396
397
			if( isset( $attr[$key.'.type'] ) )
398
			{
399
				$typeItem = $manager->getSubManager( 'type' )->findItem( $attr[$key.'.type'], array(), $domain );
400
				$attr[$key.'.typeid'] = $typeItem->getId();
401
			}
402
403
			$item->fromArray( $attr );
404
		}
405
406
		return $item;
407
	}
408
}
409