Passed
Push — master ( 8f16ed...3311dc )
by Aimeos
10:04
created

src/MShop/Order/Item/Base/Product/Base.php (2 issues)

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2011
6
 * @copyright Aimeos (aimeos.org), 2015-2018
7
 * @package MShop
8
 * @subpackage Order
9
 */
10
11
12
namespace Aimeos\MShop\Order\Item\Base\Product;
13
14
15
/**
16
 * Basket item abstract class defining available flags.
17
 *
18
 * @package MShop
19
 * @subpackage Order
20
 */
21
abstract class Base extends \Aimeos\MShop\Common\Item\Base
22
{
23
	/**
24
	 * No flag used.
25
	 * No order product flag set.
26
	 */
27
	const FLAG_NONE = 0;
28
29
	/**
30
	 * Product is immutable.
31
	 * Ordered product can't be modifed or deleted by the customer because it
32
	 * was e.g. added by a coupon provider.
33
	 */
34
	const FLAG_IMMUTABLE = 1;
35
36
37
	private $attributes;
38
	private $attributesMap;
39
	private $products;
40
	private $price;
41
42
43
	/**
44
	 * Initializes the order product instance.
45
	 *
46
	 * @param \Aimeos\MShop\Price\Item\Iface $price Price item
47
	 * @param array $values Associative list of order product values
48
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface[] $attributes List of order attribute items
49
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Iface[] $products List of ordered subproduct items
50
	 */
51
	public function __construct( \Aimeos\MShop\Price\Item\Iface $price, array $values = [], array $attributes = [], array $products = [] )
52
	{
53
		parent::__construct( 'order.base.product.', $values );
54
55
		\Aimeos\MW\Common\Base::checkClassList( \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface::class, $attributes );
56
		$this->attributes = $attributes;
57
58
		\Aimeos\MW\Common\Base::checkClassList( \Aimeos\MShop\Order\Item\Base\Product\Iface::class, $products );
59
		$this->products = $products;
60
61
		$this->price = $price;
62
	}
63
64
65
	/**
66
	 * Clones internal objects of the order base product item.
67
	 */
68
	public function __clone()
69
	{
70
		$this->price = clone $this->price;
71
	}
72
73
74
	/**
75
	 * Returns the value or list of values of the attribute item for the ordered product with the given code.
76
	 *
77
	 * @param string $code Code of the product attribute item
78
	 * @param string $type Type of the product attribute item
79
	 * @return array|string|null Value or list of values of the attribute item for the ordered product and the given code
80
	 */
81
	public function getAttribute( $code, $type = '' )
82
	{
83
		$map = $this->getAttributeMap();
84
85
		if( !isset( $map[$type][$code] ) ) {
86
			return null;
87
		}
88
89
		if( count( $map[$type][$code] ) === 1 ) {
90
			return reset( $map[$type][$code] )->getValue();
91
		}
92
93
		$list = [];
94
		foreach( $map[$type][$code] as $item ) {
95
			$list[] = $item->getValue();
96
		}
97
98
		return $list;
99
	}
100
101
102
	/**
103
	 * Returns the attribute item or list of attribute items for the ordered product with the given code.
104
	 *
105
	 * @param string $code Code of the product attribute item
106
	 * @param string $type Type of the product attribute item
107
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface|array|null
108
	 * 	Attribute item or list of items for the ordered product and the given code
109
	 */
110
	public function getAttributeItem( $code, $type = '' )
111
	{
112
		$map = $this->getAttributeMap();
113
114
		if( !isset( $map[$type][$code] ) ) {
115
			return null;
116
		}
117
118
		if( count( $map[$type][$code] ) === 1 ) {
119
			return reset( $map[$type][$code] );
120
		}
121
122
		return $map[$type][$code];
123
	}
124
125
126
	/**
127
	 * Returns the list of attribute items for the ordered product.
128
	 *
129
	 * @param string|null $type Filters returned attributes by the given type or null for no filtering
130
	 * @return array List of attribute items implementing \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface
131
	 */
132
	public function getAttributeItems( $type = null )
133
	{
134
		if( $type === null ) {
135
			return $this->attributes;
136
		}
137
138
		$list = [];
139
140
		foreach( $this->attributes as $attrItem )
141
		{
142
			if( $attrItem->getType() === $type ) {
143
				$list[] = $attrItem;
144
			}
145
		}
146
147
		return $list;
148
	}
149
150
151
	/**
152
	 * Adds or replaces the attribute item in the list of service attributes.
153
	 *
154
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface $item Service attribute item
155
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface Order base product item for chaining method calls
156
	 */
157
	public function setAttributeItem( \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface $item )
158
	{
159
		$this->getAttributeMap();
160
161
		$type = $item->getType();
162
		$code = $item->getCode();
163
		$attrId = $item->getAttributeId();
164
165
		if( !isset( $this->attributesMap[$type][$code][$attrId] ) )
166
		{
167
			$this->attributesMap[$type][$code][$attrId] = $item;
168
			$this->attributes[] = $item;
169
		}
170
171
		$this->attributesMap[$type][$code][$attrId]->setValue( $item->getValue() );
172
		$this->setModified();
173
174
		return $this;
175
	}
176
177
178
	/**
179
	 * Sets the new list of attribute items for the product.
180
	 *
181
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface[] $attributes List of order product attribute items
182
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface Order base product item for chaining method calls
183
	 */
184
	public function setAttributeItems( array $attributes )
185
	{
186
		\Aimeos\MW\Common\Base::checkClassList( \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface::class, $attributes );
187
188
		$this->attributes = $attributes;
189
		$this->attributesMap = null;
190
		$this->setModified();
191
192
		return $this;
193
	}
194
195
196
	/**
197
	 * Returns the price item for the product.
198
	 *
199
	 * @return \Aimeos\MShop\Price\Item\Iface Price item with price, costs and rebate
200
	 */
201
	public function getPrice()
202
	{
203
		return $this->price;
204
	}
205
206
207
	/**
208
	 * Sets the price item for the product.
209
	 *
210
	 * @param \Aimeos\MShop\Price\Item\Iface $price Price item containing price and additional costs
211
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface Order base product item for chaining method calls
212
	 */
213
	public function setPrice( \Aimeos\MShop\Price\Item\Iface $price )
214
	{
215
		if( $price !== $this->price )
216
		{
217
			$this->price = $price;
218
			$this->setModified();
219
		}
220
221
		return $this;
222
	}
223
224
225
	/**
226
	 * Returns all of sub-product items
227
	 *
228
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface[] List of product items
229
	 */
230
	public function getProducts()
231
	{
232
		return $this->products;
233
	}
234
235
236
	/**
237
	 * Sets all sub-product items
238
	 *
239
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Iface[] $products List of product items
240
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface Order base product item for chaining method calls
241
	 */
242
	public function setProducts( array $products )
243
	{
244
		\Aimeos\MW\Common\Base::checkClassList( \Aimeos\MShop\Order\Item\Base\Product\Iface::class, $products );
245
246
		$this->products = $products;
247
		$this->setModified();
248
249
		return $this;
250
	}
251
252
253
	/**
254
	 * Returns the item type
255
	 *
256
	 * @return string Item type, subtypes are separated by slashes
257
	 */
258
	public function getResourceType()
259
	{
260
		return 'order/base/product';
261
	}
262
263
264
	/*
265
	 * Sets the item values from the given array and removes that entries from the list
266
	 *
267
	 * @param array &$list Associative list of item keys and their values
268
	 * @param boolean True to set private properties too, false for public only
269
	 * @return \Aimeos\MShop\Order\Item\Base\Product\Iface Order product item for chaining method calls
270
	 */
271
	public function fromArray( array &$list, $private = false )
272
	{
273
		$item = parent::fromArray( $list, $private );
274
		$price = $item->getPrice();
275
276
		foreach( $list as $key => $value )
277
		{
278
			switch( $key )
279
			{
280
				case 'order.base.product.price': $price = $price->setValue( $value ); break;
281
				case 'order.base.product.costs': $price = $price->setCosts( $value ); break;
282
				case 'order.base.product.rebate': $price = $price->setRebate( $value ); break;
283
				case 'order.base.product.taxrate': $price = $price->setTaxRate( $value ); break;
284
				default: continue 2;
285
			}
286
287
			unset( $list[$key] );
288
		}
289
290
		return $item->setPrice( $price );
291
	}
292
293
294
	/**
295
	 * Returns the item values as associative list.
296
	 *
297
	 * @param boolean True to return private properties, false for public only
298
	 * @return array Associative list of item properties and their values
299
	 */
300
	public function toArray( $private = false )
301
	{
302
		$list = parent::toArray( $private );
303
304
		$list['order.base.product.price'] = $this->price->getValue();
305
		$list['order.base.product.costs'] = $this->price->getCosts();
306
		$list['order.base.product.rebate'] = $this->price->getRebate();
307
		$list['order.base.product.taxrate'] = $this->price->getTaxRate();
308
309
		return $list;
310
	}
311
312
313
	/**
314
	 * Checks if the given flag constant is valid.
315
	 *
316
	 * @param integer $value Flag constant value
317
	 */
318
	protected function checkFlags( $value )
319
	{
320
		$value = (int) $value;
321
322
		if( $value < \Aimeos\MShop\Order\Item\Base\Product\Base::FLAG_NONE ||
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
323
			$value > \Aimeos\MShop\Order\Item\Base\Product\Base::FLAG_IMMUTABLE
0 ignored issues
show
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
324
		) {
325
			throw new \Aimeos\MShop\Order\Exception( sprintf( 'Flags "%1$s" not within allowed range', $value ) );
326
		}
327
328
		return $value;
329
	}
330
331
332
	/**
333
	 * Returns the attribute map for the ordered products.
334
	 *
335
	 * @return array Associative list of type and code as key and an \Aimeos\MShop\Order\Item\Base\Product\Attribute\Iface as value
336
	 */
337
	protected function getAttributeMap()
338
	{
339
		if( !isset( $this->attributesMap ) )
340
		{
341
			$this->attributesMap = [];
342
343
			foreach( $this->attributes as $item ) {
344
				$this->attributesMap[$item->getType()][$item->getCode()][$item->getAttributeId()] = $item;
345
			}
346
		}
347
348
		return $this->attributesMap;
349
	}
350
}
351