Passed
Push — master ( 26e563...322e4f )
by Aimeos
05:33
created

Base::toArray()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2022
7
 * @package MShop
8
 * @subpackage Order
9
 */
10
11
12
namespace Aimeos\MShop\Order\Item\Base\Service;
13
14
15
/**
16
 * Abstract class \Aimeos\MShop\Order\Item\Base\Service\Base.
17
 * @package MShop
18
 * @subpackage Order
19
 */
20
abstract class Base extends \Aimeos\MShop\Common\Item\Base implements Iface
21
{
22
	/**
23
	 * Delivery service.
24
	 */
25
	const TYPE_DELIVERY = 'delivery';
26
27
	/**
28
	 * Payment service.
29
	 */
30
	const TYPE_PAYMENT = 'payment';
31
32
33
	private $attributes;
34
	private $attributesMap;
35
	private $transactions;
36
	private $price;
37
38
39
	/**
40
	 * Initializes the order base service item
41
	 *
42
	 * @param \Aimeos\MShop\Price\Item\Iface $price
43
	 * @param array $values Values to be set on initialisation
44
	 * @param \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface[] $attributes List of order service attribute items
45
	 * @param \Aimeos\MShop\Order\Item\Base\Service\Transaction\Iface[] $attributes List of order service transaction items
46
	 */
47
	public function __construct( \Aimeos\MShop\Price\Item\Iface $price, array $values = [],
48
		array $attributes = [], array $transactions = [] )
49
	{
50
		parent::__construct( 'order.base.service.', $values );
51
52
		map( $attributes )->implements( \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface::class, true );
53
54
		$this->transactions = $transactions;
55
		$this->attributes = $attributes;
56
		$this->price = $price;
57
	}
58
59
60
	/**
61
	 * Clones internal objects of the order base product item.
62
	 */
63
	public function __clone()
64
	{
65
		foreach( $this->attributes as $key => $item ) {
66
			$this->attributes[$key] = clone $item;
67
		}
68
69
		foreach( $this->transactions as $key => $item ) {
70
			$this->transactions[$key] = clone $item;
71
		}
72
73
		$this->price = clone $this->price;
74
	}
75
76
77
	/**
78
	 * Adds new and replaces existing attribute items for the service.
79
	 *
80
	 * @param \Aimeos\Map|\Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface[] $attributes List of order service attribute items
81
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order base service item for chaining method calls
82
	 */
83
	public function addAttributeItems( iterable $attributes ) : \Aimeos\MShop\Order\Item\Base\Service\Iface
84
	{
85
		( $attributes = map( $attributes ) )->implements( \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface::class, true );
86
87
		foreach( $attributes as $attrItem ) {
88
			$this->setAttributeItem( $attrItem );
89
		}
90
91
		return $this;
92
	}
93
94
95
	/**
96
	 * Returns the item type
97
	 *
98
	 * @return string Item type, subtypes are separated by slashes
99
	 */
100
	public function getResourceType() : string
101
	{
102
		return 'order/base/service';
103
	}
104
105
106
	/**
107
	 * Returns the value or list of values of the attribute item for the ordered service with the given code.
108
	 *
109
	 * @param string $code Code of the service attribute item
110
	 * @param array|string $type Type or list of types of the service attribute items
111
	 * @return array|string|null Value or list of values of the attribute item for the ordered service and the given code
112
	 */
113
	public function getAttribute( string $code, $type = '' )
114
	{
115
		$list = [];
116
		$map = $this->getAttributeMap();
117
118
		foreach( (array) $type as $key )
119
		{
120
			if( isset( $map[$key][$code] ) )
121
			{
122
				foreach( $map[$key][$code] as $item ) {
123
					$list[] = $item->getValue();
124
				}
125
			}
126
		}
127
128
		return count( $list ) > 1 ? $list : ( reset( $list ) ?: null );
129
	}
130
131
132
	/**
133
	 * Returns the attribute item or list of attribute items for the ordered service with the given code.
134
	 *
135
	 * @param string $code Code of the service attribute item
136
	 * @param array|string $type Type of the service attribute item
137
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface|array|null
138
	 * 	Attribute item or list of items for the ordered service and the given code
139
	 */
140
	public function getAttributeItem( string $code, $type = '' )
141
	{
142
		$list = [];
143
		$map = $this->getAttributeMap();
144
145
		foreach( (array) $type as $key )
146
		{
147
			if( isset( $map[$key][$code] ) )
148
			{
149
				foreach( $map[$key][$code] as $item ) {
150
					$list[] = $item;
151
				}
152
			}
153
		}
154
155
		return count( $list ) > 1 ? $list : ( reset( $list ) ?: null );
156
	}
157
158
159
	/**
160
	 * Adds or replaces the attribute item in the list of service attributes.
161
	 *
162
	 * @param \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface $item Service attribute item
163
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order base service item for chaining method calls
164
	 */
165
	public function setAttributeItem( \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface $item ) : \Aimeos\MShop\Order\Item\Base\Service\Iface
166
	{
167
		$this->getAttributeMap();
168
169
		$type = $item->getType();
170
		$code = $item->getCode();
171
		$attrId = $item->getAttributeId();
172
173
		if( !isset( $this->attributesMap[$type][$code][$attrId] ) )
174
		{
175
			$this->attributesMap[$type][$code][$attrId] = $item;
176
			$this->attributes[] = $item;
177
		}
178
179
		$this->attributesMap[$type][$code][$attrId]->setValue( $item->getValue() );
180
		$this->setModified();
181
182
		return $this;
183
	}
184
185
186
	/**
187
	 * Returns the list of attribute items for the service.
188
	 *
189
	 * @param string|null $type Filters returned attributes by the given type or null for no filtering
190
	 * @return \Aimeos\Map List of attribute items implementing \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface
191
	 */
192
	public function getAttributeItems( string $type = null ) : \Aimeos\Map
193
	{
194
		if( $type === null ) {
195
			return map( $this->attributes );
196
		}
197
198
		$list = [];
199
200
		foreach( $this->attributes as $attrItem )
201
		{
202
			if( $attrItem->getType() === $type ) {
203
				$list[] = $attrItem;
204
			}
205
		}
206
207
		return map( $list );
208
	}
209
210
211
	/**
212
	 * Sets the new list of attribute items for the service.
213
	 *
214
	 * @param \Aimeos\Map|\Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface[] $attributes List of order service attribute items
215
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order base service item for chaining method calls
216
	 */
217
	public function setAttributeItems( iterable $attributes ) : \Aimeos\MShop\Order\Item\Base\Service\Iface
218
	{
219
		( $attributes = map( $attributes ) )->implements( \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface::class, true );
220
221
		$this->attributes = $attributes->all();
222
		$this->attributesMap = null;
223
		$this->setModified();
224
225
		return $this;
226
	}
227
228
229
	/**
230
	 * Returns the price item for the product.
231
	 *
232
	 * @return \Aimeos\MShop\Price\Item\Iface Price item with price, costs and rebate
233
	 */
234
	public function getPrice() : \Aimeos\MShop\Price\Item\Iface
235
	{
236
		return $this->price;
237
	}
238
239
240
	/**
241
	 * Sets the price item for the product.
242
	 *
243
	 * @param \Aimeos\MShop\Price\Item\Iface $price Price item containing price and additional costs
244
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order base product item for chaining method calls
245
	 */
246
	public function setPrice( \Aimeos\MShop\Price\Item\Iface $price ) : \Aimeos\MShop\Order\Item\Base\Service\Iface
247
	{
248
		if( $price !== $this->price )
249
		{
250
			$this->price = $price;
251
			$this->setModified();
252
		}
253
254
		return $this;
255
	}
256
257
258
	/**
259
	 * Adds a new transaction to the service.
260
	 *
261
	 * @param \Aimeos\MShop\Order\Item\Base\Service\Transaction\Iface $item Transaction item
262
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order base service item for chaining method calls
263
	 */
264
	public function addTransaction( \Aimeos\MShop\Order\Item\Base\Service\Transaction\Iface $item ) : \Aimeos\MShop\Order\Item\Base\Service\Iface
265
	{
266
		$this->transactions[] = $item;
267
		$this->setModified();
268
269
		return $this;
270
	}
271
272
273
	/**
274
	 * Returns the list of transactions items for the service.
275
	 *
276
	 * @param string|null $type Filters returned transactions by the given type or null for no filtering
277
	 * @return \Aimeos\Map List of transaction items implementing \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface
278
	 */
279
	public function getTransactions( string $type = null ) : \Aimeos\Map
280
	{
281
		return map( $this->transactions );
282
	}
283
284
285
	/**
286
	 * Sets the new list of transactions items for the service.
287
	 *
288
	 * @param iterable $list List of order service transaction items
289
	 * @return \Aimeos\MShop\Order\Item\Base\Service\Iface Order base service item for chaining method calls
290
	 */
291
	public function setTransactions( iterable $list ) : \Aimeos\MShop\Order\Item\Base\Service\Iface
292
	{
293
		$this->transactions = $list;
294
		$this->setModified();
295
296
		return $this;
297
	}
298
299
300
	/*
301
	 * Sets the item values from the given array and removes that entries from the list
302
	 *
303
	 * @param array &$list Associative list of item keys and their values
304
	 * @param bool True to set private properties too, false for public only
305
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface Order service item for chaining method calls
306
	 */
307
	public function fromArray( array &$list, bool $private = false ) : \Aimeos\MShop\Common\Item\Iface
308
	{
309
		$item = parent::fromArray( $list, $private );
310
		$price = $item->getPrice();
311
312
		foreach( $list as $key => $value )
313
		{
314
			switch( $key )
315
			{
316
				case 'order.base.service.price': $price = $price->setValue( $value ); break;
317
				case 'order.base.service.costs': $price = $price->setCosts( $value ); break;
318
				case 'order.base.service.rebate': $price = $price->setRebate( $value ); break;
319
				case 'order.base.service.taxrate': $price = $price->setTaxRate( $value ); break;
320
				case 'order.base.service.taxrates': $price = $price->setTaxRates( (array) $value ); break;
321
				default: continue 2;
322
			}
323
324
			unset( $list[$key] );
325
		}
326
327
		return $item->setPrice( $price );
328
	}
329
330
331
	/**
332
	 * Returns the item values as associative list.
333
	 *
334
	 * @param bool True to return private properties, false for public only
335
	 * @return array Associative list of item properties and their values
336
	 */
337
	public function toArray( bool $private = false ) : array
338
	{
339
		$list = parent::toArray( $private );
340
341
		$list['order.base.service.price'] = $this->price->getValue();
342
		$list['order.base.service.costs'] = $this->price->getCosts();
343
		$list['order.base.service.rebate'] = $this->price->getRebate();
344
		$list['order.base.service.taxrate'] = $this->price->getTaxRate();
345
		$list['order.base.service.taxrates'] = $this->price->getTaxRates();
346
347
		return $list;
348
	}
349
350
351
	/**
352
	 * Checks if the given address type is valid
353
	 *
354
	 * @param string $value Address type defined in \Aimeos\MShop\Order\Item\Base\Address\Base
355
	 * @throws \Aimeos\MShop\Order\Exception If type is invalid
356
	 */
357
	protected function checkType( string $value )
358
	{
359
		switch( $value )
360
		{
361
			case \Aimeos\MShop\Order\Item\Base\Address\Base::TYPE_DELIVERY:
362
			case \Aimeos\MShop\Order\Item\Base\Address\Base::TYPE_PAYMENT:
363
				return;
364
			default:
365
				throw new \Aimeos\MShop\Order\Exception( sprintf( 'Service of type "%1$s" not available', $value ) );
366
		}
367
	}
368
369
370
	/**
371
	 * Returns the attribute map for the service.
372
	 *
373
	 * @return array Associative list of type and code as key and an \Aimeos\MShop\Order\Item\Base\Service\Attribute\Iface as value
374
	 */
375
	protected function getAttributeMap() : array
376
	{
377
		if( !isset( $this->attributesMap ) )
378
		{
379
			$this->attributesMap = [];
380
381
			foreach( $this->attributes as $item ) {
382
				$this->attributesMap[$item->getType()][$item->getCode()][$item->getAttributeId()] = $item;
383
			}
384
		}
385
386
		return $this->attributesMap;
387
	}
388
}
389