Passed
Push — master ( 2f6281...521642 )
by Aimeos
05:58
created

Standard::checkParts()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 2
nc 2
nop 1
dl 0
loc 4
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;
13
14
15
/**
16
 * Default implementation of the shopping basket.
17
 *
18
 * @package MShop
19
 * @subpackage Order
20
 */
21
class Standard extends \Aimeos\MShop\Order\Item\Base\Base
22
{
23
	// protected is a workaround for serialize problem
24
	protected $price;
25
	protected $locale;
26
	protected $customer;
27
	protected $recalc = false;
28
	protected $available = true;
29
30
31
	/**
32
	 * Initializes the shopping cart.
33
	 *
34
	 * @param \Aimeos\MShop\Price\Item\Iface $price Default price of the basket (usually 0.00)
35
	 * @param \Aimeos\MShop\Locale\Item\Iface $locale Locale item containing the site, language and currency
36
	 * @param array $values Associative list of key/value pairs containing, e.g. the order or user ID
37
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Iface[] $products List of ordered product items
38
	 * @param \Aimeos\MShop\Order\Item\Base\Address\Iface[] $addresses List of order address items
39
	 * @param \Aimeos\MShop\Order\Item\Base\Service\Iface[] $services List of order service items
40
	 * @param \Aimeos\MShop\Order\Item\Base\Product\Iface[] $coupons Associative list of coupon codes as keys and order product items as values
41
	 * @param \Aimeos\MShop\Customer\Item\Iface|null $custItem Customer item object
42
	 */
43
	public function __construct( \Aimeos\MShop\Price\Item\Iface $price, \Aimeos\MShop\Locale\Item\Iface $locale,
44
		array $values = [], array $products = [], array $addresses = [], array $services = [], array $coupons = [],
45
		?\Aimeos\MShop\Customer\Item\Iface $custItem = null )
46
	{
47
		parent::__construct( $price, $locale, $values, $products, $addresses, $services, $coupons );
48
49
		$this->price = $price;
50
		$this->locale = $locale;
51
		$this->customer = $custItem;
52
	}
53
54
55
	/**
56
	 * Clones internal objects of the order base item.
57
	 */
58
	public function __clone()
59
	{
60
		parent::__clone();
61
62
		$this->price = clone $this->price;
63
		$this->locale = clone $this->locale;
64
	}
65
66
67
	/**
68
	 * Tests if all necessary items are available to create the order.
69
	 *
70
	 * @param array $what Type of data
71
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for method chaining
72
	 * @throws \Aimeos\MShop\Order\Exception if there are no products in the basket
73
	 */
74
	public function check( array $what = ['order/base/address', 'order/base/coupon', 'order/base/product', 'order/base/service'] ) : \Aimeos\MShop\Order\Item\Base\Iface
75
	{
76
		$this->notify( 'check.before', $what );
77
78
		if( in_array( 'order/base/product', $what ) && ( count( $this->getProducts() ) < 1 ) ) {
79
			throw new \Aimeos\MShop\Order\Exception( sprintf( 'Basket empty' ) );
80
		}
81
82
		$this->notify( 'check.after', $what );
83
84
		return $this;
85
	}
86
87
88
	/**
89
	 * Returns the associated customer item
90
	 *
91
	 * @return \Aimeos\MShop\Customer\Item\Iface|null Customer item
92
	 */
93
	public function getCustomerItem() : ?\Aimeos\MShop\Customer\Item\Iface
94
	{
95
		return $this->customer;
96
	}
97
98
99
	/**
100
	 * Returns the ID of the order if already available.
101
	 *
102
	 * @return string|null ID of the order item
103
	 */
104
	public function getId() : ?string
105
	{
106
		return $this->get( 'order.base.id' );
107
	}
108
109
110
	/**
111
	 * Sets the id of the order base object.
112
	 *
113
	 * @param string|null $id Unique ID of the order base object
114
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
115
	 */
116
	public function setId( ?string $id ) : \Aimeos\MShop\Common\Item\Iface
117
	{
118
		$id = \Aimeos\MShop\Common\Item\Base::checkId( $this->getId(), $id );
119
		$this->set( 'order.base.id', $id );
120
121
		if( $id !== null ) {
122
			$this->modified = false;
123
		}
124
125
		return $this;
126
	}
127
128
129
	/**
130
	 * Returns the ID of the site the item is stored.
131
	 *
132
	 * @return string Site ID (or null if not available)
133
	 */
134
	public function getSiteId() : string
135
	{
136
		return $this->get( 'order.base.siteid', '' );
137
	}
138
139
140
	/**
141
	 * Returns the code of the site the item is stored.
142
	 *
143
	 * @return string Site code (or empty string if not available)
144
	 */
145
	public function getSiteCode() : string
146
	{
147
		return $this->get( 'order.base.sitecode', '' );
148
	}
149
150
151
	/**
152
	 * Returns the comment field of the order item.
153
	 *
154
	 * @return string Comment for the order
155
	 */
156
	public function getComment() : string
157
	{
158
		return $this->get( 'order.base.comment', '' );
159
	}
160
161
162
	/**
163
	 * Sets the comment field of the order item
164
	 *
165
	 * @param string $comment Comment for the order
166
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
167
	 */
168
	public function setComment( ?string $comment ) : \Aimeos\MShop\Order\Item\Base\Iface
169
	{
170
		return $this->set( 'order.base.comment', (string) $comment );
171
	}
172
173
174
	/**
175
	 * Returns modify date/time of the order item base product.
176
	 *
177
	 * @return string|null Returns modify date/time of the order base item
178
	 */
179
	public function getTimeModified() : ?string
180
	{
181
		return $this->get( 'order.base.mtime' );
182
	}
183
184
185
	/**
186
	 * Returns the create date of the item.
187
	 *
188
	 * @return string|null ISO date in YYYY-MM-DD hh:mm:ss format
189
	 */
190
	public function getTimeCreated() : ?string
191
	{
192
		return $this->get( 'order.base.ctime' );
193
	}
194
195
196
	/**
197
	 * Returns the editor code of editor who created/modified the item at last.
198
	 *
199
	 * @return string Editorcode of editor who created/modified the item at last
200
	 */
201
	public function editor() : string
202
	{
203
		return $this->get( 'order.base.editor', '' );
204
	}
205
206
207
	/**
208
	 * Returns the customer ID of the customer who has ordered.
209
	 *
210
	 * @return string Unique ID of the customer
211
	 */
212
	public function getCustomerId() : string
213
	{
214
		return $this->get( 'order.base.customerid', '' );
215
	}
216
217
218
	/**
219
	 * Sets the customer ID of the customer who has ordered.
220
	 *
221
	 * @param string $customerid Unique ID of the customer
222
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
223
	 */
224
	public function setCustomerId( ?string $customerid ) : \Aimeos\MShop\Order\Item\Base\Iface
225
	{
226
		if( (string) $customerid !== $this->getCustomerId() )
227
		{
228
			$this->notify( 'setCustomerId.before', (string) $customerid );
229
			$this->set( 'order.base.customerid', (string) $customerid );
230
			$this->notify( 'setCustomerId.after', (string) $customerid );
231
		}
232
233
		return $this;
234
	}
235
236
237
	/**
238
	 * Returns the customer reference field of the order item
239
	 *
240
	 * @return string Customer reference for the order
241
	 */
242
	public function getCustomerReference() : string
243
	{
244
		return $this->get( 'order.base.customerref', '' );
245
	}
246
247
248
	/**
249
	 * Sets the customer reference field of the order item
250
	 *
251
	 * @param string $value Customer reference for the order
252
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
253
	 */
254
	public function setCustomerReference( ?string $value ) : \Aimeos\MShop\Order\Item\Base\Iface
255
	{
256
		return $this->set( 'order.base.customerref', (string) $value );
257
	}
258
259
260
	/**
261
	 * Returns the locales for the basic order item.
262
	 *
263
	 * @return \Aimeos\MShop\Locale\Item\Iface Object containing information
264
	 *  about site, language, country and currency
265
	 */
266
	public function locale() : \Aimeos\MShop\Locale\Item\Iface
267
	{
268
		return $this->locale;
269
	}
270
271
272
	/**
273
	 * Sets the locales for the basic order item.
274
	 *
275
	 * @param \Aimeos\MShop\Locale\Item\Iface $locale Object containing information
276
	 *  about site, language, country and currency
277
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
278
	 */
279
	public function setLocale( \Aimeos\MShop\Locale\Item\Iface $locale ) : \Aimeos\MShop\Order\Item\Base\Iface
280
	{
281
		$this->notify( 'setLocale.before', $locale );
282
283
		$this->locale = clone $locale;
284
		$this->modified = true;
285
286
		$this->notify( 'setLocale.after', $locale );
287
288
		return $this;
289
	}
290
291
292
	/**
293
	 * Returns a price item with amounts calculated for the products, costs, etc.
294
	 *
295
	 * @return \Aimeos\MShop\Price\Item\Iface Price item with price, costs and rebate the customer has to pay
296
	 */
297
	public function getPrice() : \Aimeos\MShop\Price\Item\Iface
298
	{
299
		if( $this->recalc )
300
		{
301
			$price = $this->price->clear();
302
303
			foreach( $this->getServices() as $list )
304
			{
305
				foreach( $list as $service ) {
306
					$price = $price->addItem( $service->getPrice() );
307
				}
308
			}
309
310
			foreach( $this->getProducts() as $product ) {
311
				$price = $price->addItem( $product->getPrice(), $product->getQuantity() );
312
			}
313
314
			$this->price = $price;
315
			$this->recalc = false;
316
		}
317
318
		return $this->price;
319
	}
320
321
322
	/**
323
	 * Tests if the item is available based on status, time, language and currency
324
	 *
325
	 * @return bool True if available, false if not
326
	 */
327
	public function isAvailable() : bool
328
	{
329
		return $this->available;
330
	}
331
332
333
	/**
334
	 * Sets the general availability of the item
335
	 *
336
	 * @param bool $value True if available, false if not
337
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for method chaining
338
	 */
339
	public function setAvailable( bool $value ) : \Aimeos\MShop\Common\Item\Iface
340
	{
341
		$this->available = $value;
342
		return $this;
343
	}
344
345
346
	/**
347
	 * Sets the modified flag of the object.
348
	 *
349
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for method chaining
350
	 */
351
	public function setModified() : \Aimeos\MShop\Order\Item\Base\Iface
352
	{
353
		$this->recalc = true;
354
		return parent::setModified();
355
	}
356
357
358
	/*
359
	 * Sets the item values from the given array and removes that entries from the list
360
	 *
361
	 * @param array &$list Associative list of item keys and their values
362
	 * @param bool True to set private properties too, false for public only
363
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
364
	 */
365
	public function fromArray( array &$list, bool $private = false ) : \Aimeos\MShop\Common\Item\Iface
366
	{
367
		$item = $this;
368
		$locale = $item->locale();
369
370
		unset( $list['order.base.siteid'] );
371
		unset( $list['order.base.ctime'] );
372
		unset( $list['order.base.mtime'] );
373
		unset( $list['order.base.editor'] );
374
375
		foreach( $list as $key => $value )
376
		{
377
			switch( $key )
378
			{
379
				case 'order.base.id': $item = $item->setId( $value ); break;
380
				case 'order.base.customerid': $item = $item->setCustomerId( $value ); break;
381
				case 'order.base.languageid': $locale = $locale->setLanguageId( $value ); break;
382
				case 'order.base.customerref': $item = $item->setCustomerReference( $value ); break;
383
				case 'order.base.comment': $item = $item->setComment( $value ); break;
384
				default: continue 2;
385
			}
386
387
			unset( $list[$key] );
388
		}
389
390
		return $item->setLocale( $locale );
391
	}
392
393
394
	/**
395
	 * Returns the item values as array.
396
	 *
397
	 * @param bool True to return private properties, false for public only
398
	 * @return array Associative list of item properties and their values
399
	 */
400
	public function toArray( bool $private = false ) : array
401
	{
402
		$price = $this->getPrice();
403
		$locale = $this->locale();
404
405
		$list = array(
406
			'order.base.id' => $this->getId(),
407
			'order.base.sitecode' => $this->getSiteCode(),
408
			'order.base.customerid' => $this->getCustomerId(),
409
			'order.base.languageid' => $locale->getLanguageId(),
410
			'order.base.currencyid' => $price->getCurrencyId(),
411
			'order.base.price' => $price->getValue(),
412
			'order.base.costs' => $price->getCosts(),
413
			'order.base.rebate' => $price->getRebate(),
414
			'order.base.taxvalue' => $price->getTaxValue(),
415
			'order.base.taxflag' => $price->getTaxFlag(),
416
			'order.base.customerref' => $this->getCustomerReference(),
417
			'order.base.comment' => $this->getComment(),
418
		);
419
420
		if( $private === true )
421
		{
422
			$list['order.base.siteid'] = $this->getSiteId();
423
			$list['order.base.mtime'] = $this->getTimeModified();
424
			$list['order.base.ctime'] = $this->getTimeCreated();
425
			$list['order.base.editor'] = $this->editor();
426
		}
427
428
		return $list;
429
	}
430
431
432
	/**
433
	 * Notifies listeners before the basket becomes an order.
434
	 *
435
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Order base item for chaining method calls
436
	 */
437
	public function finish() : \Aimeos\MShop\Order\Item\Base\Iface
438
	{
439
		$this->notify( 'setOrder.before' );
440
		return $this;
441
	}
442
443
444
	/**
445
	 * Checks if the price uses the same currency as the price in the basket.
446
	 *
447
	 * @param \Aimeos\MShop\Price\Item\Iface $item Price item
448
	 */
449
	protected function checkPrice( \Aimeos\MShop\Price\Item\Iface $item )
450
	{
451
		$price = clone $this->price;
452
		$price->addItem( $item );
453
	}
454
}
455