|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
|
|
3
|
|
|
namespace LukePOLO\LaraCart; |
|
4
|
|
|
|
|
5
|
|
|
use Illuminate\Auth\AuthManager; |
|
6
|
|
|
use Illuminate\Contracts\Events\Dispatcher; |
|
7
|
|
|
use Illuminate\Database\Eloquent\Model; |
|
8
|
|
|
use Illuminate\Session\SessionManager; |
|
9
|
|
|
use LukePOLO\LaraCart\Contracts\CouponContract; |
|
10
|
|
|
use LukePOLO\LaraCart\Contracts\LaraCartContract; |
|
11
|
|
|
use LukePOLO\LaraCart\Exceptions\ModelNotFound; |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Class LaraCart |
|
15
|
|
|
* |
|
16
|
|
|
* @package LukePOLO\LaraCart |
|
17
|
|
|
*/ |
|
18
|
|
|
class LaraCart implements LaraCartContract |
|
19
|
|
|
{ |
|
20
|
|
|
const SERVICE = 'laracart'; |
|
21
|
|
|
const HASH = 'generateCartHash'; |
|
22
|
|
|
const RANHASH = 'generateRandomCartItemHash'; |
|
23
|
|
|
|
|
24
|
|
|
protected $events; |
|
25
|
|
|
protected $session; |
|
26
|
|
|
protected $authManager; |
|
27
|
|
|
|
|
28
|
|
|
public $cart; |
|
29
|
|
|
public $prefix; |
|
30
|
|
|
public $itemModel; |
|
31
|
|
|
public $itemModelRelations; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* LaraCart constructor. |
|
35
|
|
|
* |
|
36
|
|
|
* @param SessionManager $session |
|
37
|
|
|
* @param Dispatcher $events |
|
38
|
|
|
* @param AuthManager $authManager |
|
39
|
|
|
*/ |
|
40
|
|
|
public function __construct(SessionManager $session, Dispatcher $events, AuthManager $authManager) |
|
41
|
|
|
{ |
|
42
|
|
|
$this->session = $session; |
|
43
|
|
|
$this->events = $events; |
|
44
|
|
|
$this->authManager = $authManager; |
|
45
|
|
|
$this->prefix = config('laracart.cache_prefix', 'laracart'); |
|
46
|
|
|
$this->itemModel = config('laracart.item_model', null); |
|
47
|
|
|
$this->itemModelRelations = config('laracart.item_model_relations', []); |
|
48
|
|
|
|
|
49
|
|
|
$this->setInstance($this->session->get($this->prefix . '.instance', 'default')); |
|
50
|
|
|
} |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Gets all current instances inside the session |
|
54
|
|
|
* |
|
55
|
|
|
* @return mixed |
|
56
|
|
|
*/ |
|
57
|
|
|
public function getInstances() |
|
58
|
|
|
{ |
|
59
|
|
|
return $this->session->get($this->prefix . '.instances', []); |
|
60
|
|
|
} |
|
61
|
|
|
|
|
62
|
|
|
/** |
|
63
|
|
|
* Sets and Gets the instance of the cart in the session we should be using |
|
64
|
|
|
* |
|
65
|
|
|
* @param string $instance |
|
66
|
|
|
* |
|
67
|
|
|
* @return LaraCart |
|
68
|
|
|
*/ |
|
69
|
|
|
public function setInstance($instance = 'default') |
|
70
|
|
|
{ |
|
71
|
|
|
$this->get($instance); |
|
72
|
|
|
|
|
73
|
|
|
$this->session->set($this->prefix . '.instance', $instance); |
|
74
|
|
|
|
|
75
|
|
|
if (!in_array($instance, $this->getInstances())) { |
|
76
|
|
|
$this->session->push($this->prefix . '.instances', $instance); |
|
77
|
|
|
} |
|
78
|
|
|
$this->events->fire('laracart.new'); |
|
79
|
|
|
|
|
80
|
|
|
return $this; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
/** |
|
84
|
|
|
* Gets the instance in the session |
|
85
|
|
|
* |
|
86
|
|
|
* @param string $instance |
|
87
|
|
|
* |
|
88
|
|
|
* @return $this cart instance |
|
89
|
|
|
*/ |
|
90
|
|
|
public function get($instance = 'default') |
|
91
|
|
|
{ |
|
92
|
|
|
if (config('laracart.cross_devices', false) && $this->authManager->check()) { |
|
93
|
|
|
if (!empty($cartSessionID = $this->authManager->user()->cart_session_id)) { |
|
94
|
|
|
$this->session->setId($cartSessionID); |
|
95
|
|
|
$this->session->start(); |
|
96
|
|
|
} |
|
97
|
|
|
} |
|
98
|
|
|
|
|
99
|
|
|
if (empty($this->cart = $this->session->get($this->prefix . '.' . $instance))) { |
|
100
|
|
|
$this->cart = new Cart($instance); |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
return $this; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
/** |
|
107
|
|
|
* Gets an an attribute from the cart |
|
108
|
|
|
* |
|
109
|
|
|
* @param $attribute |
|
110
|
|
|
* @param $defaultValue |
|
111
|
|
|
* |
|
112
|
|
|
* @return mixed |
|
113
|
|
|
*/ |
|
114
|
|
|
public function getAttribute($attribute, $defaultValue = null) |
|
115
|
|
|
{ |
|
116
|
|
|
return array_get($this->cart->attributes, $attribute, $defaultValue); |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
/** |
|
120
|
|
|
* Gets all the carts attributes |
|
121
|
|
|
* |
|
122
|
|
|
* @return mixed |
|
123
|
|
|
*/ |
|
124
|
|
|
public function getAttributes() |
|
125
|
|
|
{ |
|
126
|
|
|
return $this->cart->attributes; |
|
127
|
|
|
} |
|
128
|
|
|
|
|
129
|
|
|
/** |
|
130
|
|
|
* Adds an Attribute to the cart |
|
131
|
|
|
* |
|
132
|
|
|
* @param $attribute |
|
133
|
|
|
* @param $value |
|
134
|
|
|
*/ |
|
135
|
|
|
public function setAttribute($attribute, $value) |
|
136
|
|
|
{ |
|
137
|
|
|
array_set($this->cart->attributes, $attribute, $value); |
|
138
|
|
|
|
|
139
|
|
|
$this->update(); |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* Updates cart session |
|
144
|
|
|
*/ |
|
145
|
|
|
public function update() |
|
146
|
|
|
{ |
|
147
|
|
|
$this->session->set($this->prefix . '.' . $this->cart->instance, $this->cart); |
|
148
|
|
|
|
|
149
|
|
|
if (config('laracart.cross_devices', false) && $this->authManager->check()) { |
|
150
|
|
|
$this->authManager->user()->cart_session_id = $this->session->getId(); |
|
151
|
|
|
$this->authManager->user()->save(); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
$this->session->save(); |
|
155
|
|
|
|
|
156
|
|
|
$this->events->fire('laracart.update', $this->cart); |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
/** |
|
160
|
|
|
* Removes an attribute from the cart |
|
161
|
|
|
* |
|
162
|
|
|
* @param $attribute |
|
163
|
|
|
*/ |
|
164
|
|
|
public function removeAttribute($attribute) |
|
165
|
|
|
{ |
|
166
|
|
|
array_forget($this->cart->attributes, $attribute); |
|
167
|
|
|
|
|
168
|
|
|
$this->update(); |
|
169
|
|
|
} |
|
170
|
|
|
|
|
171
|
|
|
/** |
|
172
|
|
|
* Creates a CartItem and then adds it to cart |
|
173
|
|
|
* |
|
174
|
|
|
* @param string|int $itemID |
|
175
|
|
|
* @param null $name |
|
176
|
|
|
* @param int $qty |
|
177
|
|
|
* @param string $price |
|
178
|
|
|
* @param array $options |
|
179
|
|
|
* @param bool|true $taxable |
|
180
|
|
|
* |
|
181
|
|
|
* @return CartItem |
|
182
|
|
|
*/ |
|
183
|
|
|
public function addLine($itemID, $name = null, $qty = 1, $price = '0.00', $options = [], $taxable = true) |
|
184
|
|
|
{ |
|
185
|
|
|
return $this->add($itemID, $name, $qty, $price, $options, $taxable, true); |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
/** |
|
189
|
|
|
* Creates a CartItem and then adds it to cart |
|
190
|
|
|
* |
|
191
|
|
|
* @param $itemID |
|
192
|
|
|
* @param null $name |
|
193
|
|
|
* @param int $qty |
|
194
|
|
|
* @param string $price |
|
195
|
|
|
* @param array $options |
|
196
|
|
|
* @param bool|false $taxable |
|
197
|
|
|
* @param bool|false $lineItem |
|
198
|
|
|
* |
|
199
|
|
|
* @return CartItem |
|
200
|
|
|
* |
|
201
|
|
|
* @throws ModelNotFound |
|
202
|
|
|
*/ |
|
203
|
|
|
public function add( |
|
204
|
|
|
$itemID, |
|
205
|
|
|
$name = null, |
|
206
|
|
|
$qty = 1, |
|
207
|
|
|
$price = '0.00', |
|
208
|
|
|
$options = [], |
|
209
|
|
|
$taxable = true, |
|
210
|
|
|
$lineItem = false |
|
211
|
|
|
) { |
|
212
|
|
|
|
|
213
|
|
|
if (!empty(config('laracart.item_model'))) { |
|
|
|
|
|
|
214
|
|
|
|
|
215
|
|
|
$itemModel = $itemID; |
|
216
|
|
|
|
|
217
|
|
|
if (!$this->isItemModel($itemModel)) { |
|
218
|
|
|
$itemModel = (new $this->itemModel)->with($this->itemModelRelations)->find($itemID); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
if (empty($itemModel)) { |
|
222
|
|
|
throw new ModelNotFound('Could not find the item ' . $itemID); |
|
223
|
|
|
} |
|
224
|
|
|
|
|
225
|
|
|
$bindings = config('laracart.item_model_bindings'); |
|
226
|
|
|
|
|
227
|
|
|
$itemID = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_ID]]; |
|
228
|
|
|
$name = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_NAME]]; |
|
229
|
|
|
|
|
230
|
|
|
if (empty($qty = $name) || !is_int($name)) { |
|
231
|
|
|
$qty = 1; |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
$price = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_PRICE]]; |
|
235
|
|
|
$options = $this->getItemModelOptions($itemModel, $bindings[\LukePOLO\LaraCart\CartItem::ITEM_OPTIONS]); |
|
236
|
|
|
$taxable = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_TAXABLE]] ? true : false; |
|
237
|
|
|
} |
|
238
|
|
|
|
|
239
|
|
|
$item = $this->addItem(new CartItem( |
|
240
|
|
|
$itemID, |
|
241
|
|
|
$name, |
|
242
|
|
|
$qty, |
|
243
|
|
|
$price, |
|
244
|
|
|
$options, |
|
245
|
|
|
$taxable, |
|
246
|
|
|
$lineItem |
|
247
|
|
|
)); |
|
248
|
|
|
|
|
249
|
|
|
$this->update(); |
|
250
|
|
|
|
|
251
|
|
|
return $this->getItem($item->getHash()); |
|
252
|
|
|
} |
|
253
|
|
|
|
|
254
|
|
|
/** |
|
255
|
|
|
* Adds the cartItem into the cart session |
|
256
|
|
|
* |
|
257
|
|
|
* @param CartItem $cartItem |
|
258
|
|
|
* |
|
259
|
|
|
* @return CartItem |
|
260
|
|
|
*/ |
|
261
|
|
|
public function addItem(CartItem $cartItem) |
|
262
|
|
|
{ |
|
263
|
|
|
$itemHash = $cartItem->generateHash(); |
|
264
|
|
|
|
|
265
|
|
|
if ($this->getItem($itemHash)) { |
|
266
|
|
|
$this->getItem($itemHash)->qty += $cartItem->qty; |
|
267
|
|
|
} else { |
|
268
|
|
|
$this->cart->items[] = $cartItem; |
|
269
|
|
|
} |
|
270
|
|
|
|
|
271
|
|
|
$this->events->fire('laracart.addItem', $cartItem); |
|
272
|
|
|
|
|
273
|
|
|
return $cartItem; |
|
274
|
|
|
} |
|
275
|
|
|
|
|
276
|
|
|
/** |
|
277
|
|
|
* Increment the quantity of a cartItem based on the itemHash |
|
278
|
|
|
* |
|
279
|
|
|
* @param $itemHash |
|
280
|
|
|
* |
|
281
|
|
|
* @return CartItem | null |
|
282
|
|
|
*/ |
|
283
|
|
|
public function increment($itemHash) |
|
284
|
|
|
{ |
|
285
|
|
|
$item = $this->getItem($itemHash); |
|
286
|
|
|
$item->qty++; |
|
287
|
|
|
$this->update(); |
|
288
|
|
|
|
|
289
|
|
|
return $item; |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
/** |
|
293
|
|
|
* Decrement the quantity of a cartItem based on the itemHash |
|
294
|
|
|
* |
|
295
|
|
|
* @param $itemHash |
|
296
|
|
|
* |
|
297
|
|
|
* @return CartItem | null |
|
298
|
|
|
*/ |
|
299
|
|
|
public function decrement($itemHash) |
|
300
|
|
|
{ |
|
301
|
|
|
$item = $this->getItem($itemHash); |
|
302
|
|
|
if ($item->qty > 1) { |
|
303
|
|
|
$item->qty--; |
|
304
|
|
|
$this->update(); |
|
305
|
|
|
|
|
306
|
|
|
return $item; |
|
307
|
|
|
} |
|
308
|
|
|
$this->removeItem($itemHash); |
|
309
|
|
|
$this->update(); |
|
310
|
|
|
|
|
311
|
|
|
return null; |
|
312
|
|
|
} |
|
313
|
|
|
|
|
314
|
|
|
/** |
|
315
|
|
|
* Find items in the cart matching a data set |
|
316
|
|
|
* |
|
317
|
|
|
* |
|
318
|
|
|
* param $data |
|
319
|
|
|
* @return array |
|
320
|
|
|
*/ |
|
321
|
|
|
public function find($data) |
|
322
|
|
|
{ |
|
323
|
|
|
$matches = []; |
|
324
|
|
|
|
|
325
|
|
|
foreach ($this->getItems() as $item) { |
|
326
|
|
|
if ($item->find($data)) { |
|
327
|
|
|
$matches[] = $item; |
|
328
|
|
|
} |
|
329
|
|
|
} |
|
330
|
|
|
|
|
331
|
|
|
return $matches; |
|
332
|
|
|
} |
|
333
|
|
|
|
|
334
|
|
|
/** |
|
335
|
|
|
* Finds a cartItem based on the itemHash |
|
336
|
|
|
* |
|
337
|
|
|
* @param $itemHash |
|
338
|
|
|
* |
|
339
|
|
|
* @return CartItem | null |
|
340
|
|
|
*/ |
|
341
|
|
|
public function getItem($itemHash) |
|
342
|
|
|
{ |
|
343
|
|
|
return array_get($this->getItems(), $itemHash); |
|
344
|
|
|
} |
|
345
|
|
|
|
|
346
|
|
|
/** |
|
347
|
|
|
* Gets all the items within the cart |
|
348
|
|
|
* |
|
349
|
|
|
* @return array |
|
350
|
|
|
*/ |
|
351
|
|
|
public function getItems($collectable = false) |
|
352
|
|
|
{ |
|
353
|
|
|
$items = []; |
|
354
|
|
|
if (isset($this->cart->items) === true) { |
|
355
|
|
|
foreach ($this->cart->items as $item) { |
|
356
|
|
|
$items[$item->getHash()] = $item; |
|
357
|
|
|
} |
|
358
|
|
|
} |
|
359
|
|
|
return $collectable? collect($items):$items; |
|
360
|
|
|
} |
|
361
|
|
|
|
|
362
|
|
|
return $items; |
|
|
|
|
|
|
363
|
|
|
} |
|
|
|
|
|
|
364
|
|
|
|
|
365
|
|
|
/** |
|
366
|
|
|
* Updates an items attributes |
|
367
|
|
|
* |
|
368
|
|
|
* @param $itemHash |
|
369
|
|
|
* @param $key |
|
370
|
|
|
* @param $value |
|
371
|
|
|
* |
|
372
|
|
|
* @return CartItem |
|
373
|
|
|
* |
|
374
|
|
|
* @throws Exceptions\InvalidPrice |
|
375
|
|
|
* @throws Exceptions\InvalidQuantity |
|
376
|
|
|
*/ |
|
377
|
|
|
public function updateItem($itemHash, $key, $value) |
|
|
|
|
|
|
378
|
|
|
{ |
|
379
|
|
|
if (empty($item = $this->getItem($itemHash)) === false) { |
|
|
|
|
|
|
380
|
|
|
$item->$key = $value; |
|
381
|
|
|
} |
|
382
|
|
|
|
|
383
|
|
|
$item->generateHash(); |
|
384
|
|
|
|
|
385
|
|
|
$this->update(); |
|
386
|
|
|
|
|
387
|
|
|
return $item; |
|
388
|
|
|
} |
|
389
|
|
|
|
|
390
|
|
|
/** |
|
391
|
|
|
* Removes a CartItem based on the itemHash |
|
392
|
|
|
* |
|
393
|
|
|
* @param $itemHash |
|
394
|
|
|
*/ |
|
395
|
|
|
public function removeItem($itemHash) |
|
396
|
|
|
{ |
|
397
|
|
|
foreach ($this->cart->items as $itemKey => $item) { |
|
398
|
|
|
if ($item->getHash() == $itemHash) { |
|
399
|
|
|
unset($this->cart->items[$itemKey]); |
|
400
|
|
|
break; |
|
401
|
|
|
} |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
$this->events->fire('laracart.removeItem', $item); |
|
405
|
|
|
|
|
406
|
|
|
$this->update(); |
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
/** |
|
410
|
|
|
* Empties the carts items |
|
411
|
|
|
*/ |
|
412
|
|
|
public function emptyCart() |
|
413
|
|
|
{ |
|
414
|
|
|
unset($this->cart->items); |
|
415
|
|
|
|
|
416
|
|
|
$this->update(); |
|
417
|
|
|
|
|
418
|
|
|
$this->events->fire('laracart.empty', $this->cart->instance); |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
/** |
|
422
|
|
|
* Completely destroys cart and anything associated with it |
|
423
|
|
|
*/ |
|
424
|
|
|
public function destroyCart() |
|
425
|
|
|
{ |
|
426
|
|
|
$instance = $this->cart->instance; |
|
427
|
|
|
|
|
428
|
|
|
$this->session->forget($this->prefix . '.' . $instance); |
|
429
|
|
|
|
|
430
|
|
|
$this->setInstance('default'); |
|
431
|
|
|
|
|
432
|
|
|
$this->events->fire('laracart.destroy', $instance); |
|
433
|
|
|
|
|
434
|
|
|
$this->update(); |
|
435
|
|
|
} |
|
436
|
|
|
|
|
437
|
|
|
/** |
|
438
|
|
|
* Gets the coupons for the current cart |
|
439
|
|
|
* |
|
440
|
|
|
* @return array |
|
441
|
|
|
*/ |
|
442
|
|
|
public function getCoupons() |
|
443
|
|
|
{ |
|
444
|
|
|
return $this->cart->coupons; |
|
445
|
|
|
} |
|
446
|
|
|
|
|
447
|
|
|
/** |
|
448
|
|
|
* Finds a specific coupon in the cart |
|
449
|
|
|
* |
|
450
|
|
|
* @param $code |
|
451
|
|
|
* @return mixed |
|
452
|
|
|
*/ |
|
453
|
|
|
public function findCoupon($code) |
|
454
|
|
|
{ |
|
455
|
|
|
return array_get($this->cart->coupons, $code); |
|
456
|
|
|
} |
|
457
|
|
|
|
|
458
|
|
|
/** |
|
459
|
|
|
* Applies a coupon to the cart |
|
460
|
|
|
* |
|
461
|
|
|
* @param CouponContract $coupon |
|
462
|
|
|
*/ |
|
463
|
|
|
public function addCoupon(CouponContract $coupon) |
|
464
|
|
|
{ |
|
465
|
|
|
if (!$this->cart->multipleCoupons) { |
|
466
|
|
|
$this->cart->coupons = []; |
|
467
|
|
|
} |
|
468
|
|
|
|
|
469
|
|
|
$this->cart->coupons[$coupon->code] = $coupon; |
|
470
|
|
|
|
|
471
|
|
|
$this->update(); |
|
472
|
|
|
} |
|
473
|
|
|
|
|
474
|
|
|
/** |
|
475
|
|
|
* Removes a coupon in the cart |
|
476
|
|
|
* |
|
477
|
|
|
* @param $code |
|
478
|
|
|
*/ |
|
479
|
|
|
public function removeCoupon($code) |
|
480
|
|
|
{ |
|
481
|
|
|
foreach ($this->getItems() as $item) { |
|
482
|
|
|
if (isset($item->code) && $item->code == $code) { |
|
483
|
|
|
$item->code = null; |
|
484
|
|
|
$item->discount = null; |
|
485
|
|
|
$item->couponInfo = []; |
|
486
|
|
|
} |
|
487
|
|
|
} |
|
488
|
|
|
|
|
489
|
|
|
array_forget($this->cart->coupons, $code); |
|
490
|
|
|
|
|
491
|
|
|
$this->update(); |
|
492
|
|
|
} |
|
493
|
|
|
|
|
494
|
|
|
/** |
|
495
|
|
|
* Gets a specific fee from the fees array |
|
496
|
|
|
* |
|
497
|
|
|
* @param $name |
|
498
|
|
|
* |
|
499
|
|
|
* @return mixed |
|
500
|
|
|
*/ |
|
501
|
|
|
public function getFee($name) |
|
502
|
|
|
{ |
|
503
|
|
|
return array_get($this->cart->fees, $name, new CartFee(null, false)); |
|
504
|
|
|
} |
|
505
|
|
|
|
|
506
|
|
|
/** |
|
507
|
|
|
* Allows to charge for additional fees that may or may not be taxable |
|
508
|
|
|
* ex - service fee , delivery fee, tips |
|
509
|
|
|
* |
|
510
|
|
|
* @param $name |
|
511
|
|
|
* @param $amount |
|
512
|
|
|
* @param bool|false $taxable |
|
513
|
|
|
* @param array $options |
|
514
|
|
|
*/ |
|
515
|
|
|
public function addFee($name, $amount, $taxable = false, array $options = []) |
|
516
|
|
|
{ |
|
517
|
|
|
array_set($this->cart->fees, $name, new CartFee($amount, $taxable, $options)); |
|
518
|
|
|
|
|
519
|
|
|
$this->update(); |
|
520
|
|
|
} |
|
521
|
|
|
|
|
522
|
|
|
/** |
|
523
|
|
|
* Removes a fee from the fee array |
|
524
|
|
|
* |
|
525
|
|
|
* @param $name |
|
526
|
|
|
*/ |
|
527
|
|
|
public function removeFee($name) |
|
528
|
|
|
{ |
|
529
|
|
|
array_forget($this->cart->fees, $name); |
|
530
|
|
|
|
|
531
|
|
|
$this->update(); |
|
532
|
|
|
} |
|
533
|
|
|
|
|
534
|
|
|
/** |
|
535
|
|
|
* Removes all the fees set in the cart |
|
536
|
|
|
* |
|
537
|
|
|
*/ |
|
538
|
|
|
public function removeFees() |
|
539
|
|
|
{ |
|
540
|
|
|
$this->cart->fees = []; |
|
541
|
|
|
|
|
542
|
|
|
$this->update(); |
|
543
|
|
|
} |
|
544
|
|
|
|
|
545
|
|
|
/** |
|
546
|
|
|
* Gets the total tax for the cart |
|
547
|
|
|
* |
|
548
|
|
|
* @param bool|true $format |
|
549
|
|
|
* |
|
550
|
|
|
* @return string |
|
551
|
|
|
*/ |
|
552
|
|
|
public function taxTotal($format = true) |
|
553
|
|
|
{ |
|
554
|
|
|
$totalTax = 0; |
|
555
|
|
|
$discounted = 0; |
|
556
|
|
|
$totalDiscount = $this->totalDiscount(false); |
|
557
|
|
|
|
|
558
|
|
|
if ($this->count() != 0) { |
|
559
|
|
|
foreach ($this->getItems() as $item) { |
|
560
|
|
|
if ($discounted >= $totalDiscount) { |
|
561
|
|
|
$totalTax += $item->tax(); |
|
562
|
|
|
} else { |
|
563
|
|
|
$itemPrice = $item->subTotal(false); |
|
564
|
|
|
|
|
565
|
|
|
if (($discounted + $itemPrice) > $totalDiscount) { |
|
566
|
|
|
$totalTax += $item->tax($totalDiscount - $discounted); |
|
567
|
|
|
} |
|
568
|
|
|
|
|
569
|
|
|
$discounted += $itemPrice; |
|
570
|
|
|
} |
|
571
|
|
|
} |
|
572
|
|
|
} |
|
573
|
|
|
|
|
574
|
|
|
foreach ($this->getFees() as $fee) { |
|
575
|
|
|
if ($fee->taxable) { |
|
576
|
|
|
$totalTax += $fee->amount * $fee->tax; |
|
577
|
|
|
} |
|
578
|
|
|
} |
|
579
|
|
|
|
|
580
|
|
|
return $this->formatMoney($totalTax, null, null, $format); |
|
581
|
|
|
} |
|
582
|
|
|
|
|
583
|
|
|
/** |
|
584
|
|
|
* Gets the total of the cart with or without tax |
|
585
|
|
|
* |
|
586
|
|
|
* @param boolean $format |
|
587
|
|
|
* @param boolean $withDiscount |
|
588
|
|
|
* |
|
589
|
|
|
* @return string |
|
590
|
|
|
*/ |
|
591
|
|
|
public function total($format = true, $withDiscount = true, $withTax = true) |
|
592
|
|
|
{ |
|
593
|
|
|
$total = $this->subTotal(false) + $this->feeTotals(false); |
|
594
|
|
|
|
|
595
|
|
|
if ($withDiscount) { |
|
596
|
|
|
$total -= $this->totalDiscount(false); |
|
597
|
|
|
} |
|
598
|
|
|
|
|
599
|
|
|
if ($withTax) { |
|
600
|
|
|
$total += $this->taxTotal(false); |
|
601
|
|
|
} |
|
602
|
|
|
|
|
603
|
|
|
return $this->formatMoney($total, null, null, $format); |
|
604
|
|
|
} |
|
605
|
|
|
|
|
606
|
|
|
/** |
|
607
|
|
|
* Gets the subtotal of the cart with or without tax |
|
608
|
|
|
* |
|
609
|
|
|
* @param boolean $format |
|
610
|
|
|
* @param boolean $withDiscount |
|
611
|
|
|
* |
|
612
|
|
|
* @return string |
|
613
|
|
|
*/ |
|
614
|
|
|
public function subTotal($format = true, $withDiscount = true) |
|
615
|
|
|
{ |
|
616
|
|
|
$total = 0; |
|
617
|
|
|
|
|
618
|
|
|
if ($this->count() != 0) { |
|
619
|
|
|
foreach ($this->getItems() as $item) { |
|
620
|
|
|
$total += $item->subTotal(false, $withDiscount); |
|
621
|
|
|
} |
|
622
|
|
|
} |
|
623
|
|
|
|
|
624
|
|
|
return $this->formatMoney($total, null, null, $format); |
|
625
|
|
|
} |
|
626
|
|
|
|
|
627
|
|
|
/** |
|
628
|
|
|
* Get the count based on qty, or number of unique items |
|
629
|
|
|
* |
|
630
|
|
|
* @param bool $withItemQty |
|
631
|
|
|
* |
|
632
|
|
|
* @return int |
|
633
|
|
|
*/ |
|
634
|
|
|
public function count($withItemQty = true) |
|
635
|
|
|
{ |
|
636
|
|
|
$count = 0; |
|
637
|
|
|
|
|
638
|
|
|
foreach ($this->getItems() as $item) { |
|
639
|
|
|
if ($withItemQty) { |
|
640
|
|
|
$count += $item->qty; |
|
641
|
|
|
} else { |
|
642
|
|
|
$count++; |
|
643
|
|
|
} |
|
644
|
|
|
} |
|
645
|
|
|
|
|
646
|
|
|
return $count; |
|
647
|
|
|
} |
|
648
|
|
|
|
|
649
|
|
|
/** |
|
650
|
|
|
* |
|
651
|
|
|
* Formats the number into a money format based on the locale and international formats |
|
652
|
|
|
* |
|
653
|
|
|
* @param $number |
|
654
|
|
|
* @param $locale |
|
655
|
|
|
* @param $internationalFormat |
|
656
|
|
|
* @param $format |
|
657
|
|
|
* |
|
658
|
|
|
* @return string |
|
659
|
|
|
*/ |
|
660
|
|
|
public static function formatMoney($number, $locale = null, $internationalFormat = null, $format = true) |
|
661
|
|
|
{ |
|
662
|
|
|
$number = number_format($number, 2, '.', ''); |
|
663
|
|
|
|
|
664
|
|
|
if ($format) { |
|
665
|
|
|
setlocale(LC_MONETARY, null); |
|
666
|
|
|
setlocale(LC_MONETARY, empty($locale) ? config('laracart.locale', 'en_US.UTF-8') : $locale); |
|
667
|
|
|
|
|
668
|
|
|
if (empty($internationalFormat) === true) { |
|
669
|
|
|
$internationalFormat = config('laracart.international_format', false); |
|
670
|
|
|
} |
|
671
|
|
|
|
|
672
|
|
|
$number = money_format($internationalFormat ? '%i' : '%n', $number); |
|
673
|
|
|
} |
|
674
|
|
|
|
|
675
|
|
|
return $number; |
|
676
|
|
|
} |
|
677
|
|
|
|
|
678
|
|
|
/** |
|
679
|
|
|
* Gets all the fee totals |
|
680
|
|
|
* |
|
681
|
|
|
* @param boolean $format |
|
682
|
|
|
* |
|
683
|
|
|
* @return string |
|
684
|
|
|
*/ |
|
685
|
|
|
public function feeTotals($format = true, $withTax = false) |
|
686
|
|
|
{ |
|
687
|
|
|
$feeTotal = 0; |
|
688
|
|
|
|
|
689
|
|
|
foreach ($this->getFees() as $fee) { |
|
690
|
|
|
$feeTotal += $fee->amount; |
|
691
|
|
|
|
|
692
|
|
|
if ($withTax && $fee->taxable && $fee->tax > 0) { |
|
693
|
|
|
$feeTotal += $fee->amount * $fee->tax; |
|
694
|
|
|
} |
|
695
|
|
|
} |
|
696
|
|
|
|
|
697
|
|
|
return $this->formatMoney($feeTotal, null, null, $format); |
|
698
|
|
|
} |
|
699
|
|
|
|
|
700
|
|
|
/** |
|
701
|
|
|
* Gets all the fees on the cart object |
|
702
|
|
|
* |
|
703
|
|
|
* @return mixed |
|
704
|
|
|
*/ |
|
705
|
|
|
public function getFees() |
|
706
|
|
|
{ |
|
707
|
|
|
return $this->cart->fees; |
|
708
|
|
|
} |
|
709
|
|
|
|
|
710
|
|
|
/** |
|
711
|
|
|
* Gets the total amount discounted |
|
712
|
|
|
* |
|
713
|
|
|
* @param boolean $format |
|
714
|
|
|
* |
|
715
|
|
|
* @return string |
|
716
|
|
|
*/ |
|
717
|
|
|
public function totalDiscount($format = true) |
|
718
|
|
|
{ |
|
719
|
|
|
$total = 0; |
|
720
|
|
|
|
|
721
|
|
|
foreach ($this->cart->coupons as $coupon) { |
|
722
|
|
|
if ($coupon->appliedToCart) { |
|
723
|
|
|
$total += $coupon->discount(); |
|
724
|
|
|
} |
|
725
|
|
|
} |
|
726
|
|
|
|
|
727
|
|
|
return $this->formatMoney($total, null, null, $format); |
|
728
|
|
|
} |
|
729
|
|
|
|
|
730
|
|
|
/** |
|
731
|
|
|
* Checks to see if its an item model |
|
732
|
|
|
* |
|
733
|
|
|
* @param $itemModel |
|
734
|
|
|
* |
|
735
|
|
|
* @return bool |
|
736
|
|
|
*/ |
|
737
|
|
|
private function isItemModel($itemModel) |
|
738
|
|
|
{ |
|
739
|
|
|
if (is_object($itemModel) && get_class($itemModel) == config('laracart.item_model')) { |
|
740
|
|
|
return true; |
|
741
|
|
|
} |
|
742
|
|
|
} |
|
743
|
|
|
|
|
744
|
|
|
/** |
|
745
|
|
|
* Gets the item models options based the config |
|
746
|
|
|
* |
|
747
|
|
|
* @param Model $itemModel |
|
748
|
|
|
* @param array $options |
|
749
|
|
|
* |
|
750
|
|
|
* @return array |
|
751
|
|
|
*/ |
|
752
|
|
|
private function getItemModelOptions(Model $itemModel, $options = []) |
|
753
|
|
|
{ |
|
754
|
|
|
$itemOptions = []; |
|
755
|
|
|
foreach ($options as $option) { |
|
756
|
|
|
$itemOptions[$option] = $this->getFromModel($itemModel, $option); |
|
757
|
|
|
} |
|
758
|
|
|
|
|
759
|
|
|
return array_filter($itemOptions, function ($value) { |
|
760
|
|
|
if ($value !== false && empty($value)) { |
|
761
|
|
|
return false; |
|
762
|
|
|
} |
|
763
|
|
|
|
|
764
|
|
|
return true; |
|
765
|
|
|
}); |
|
766
|
|
|
} |
|
767
|
|
|
|
|
768
|
|
|
/** |
|
769
|
|
|
* Gets a option from the model |
|
770
|
|
|
* |
|
771
|
|
|
* @param Model $itemModel |
|
772
|
|
|
* @param $attr |
|
773
|
|
|
* @param null $defaultValue |
|
774
|
|
|
* |
|
775
|
|
|
* @return Model|null |
|
776
|
|
|
*/ |
|
777
|
|
|
private function getFromModel(Model $itemModel, $attr, $defaultValue = null) |
|
778
|
|
|
{ |
|
779
|
|
|
$variable = $itemModel; |
|
780
|
|
|
|
|
781
|
|
|
if (!empty($attr)) { |
|
782
|
|
|
foreach (explode('.', $attr) as $attr) { |
|
783
|
|
|
$variable = array_get($variable, $attr); |
|
784
|
|
|
} |
|
785
|
|
|
} |
|
786
|
|
|
|
|
787
|
|
|
if (empty($variable)) { |
|
788
|
|
|
$variable = $defaultValue; |
|
789
|
|
|
} |
|
790
|
|
|
return $variable; |
|
791
|
|
|
} |
|
792
|
|
|
|
|
793
|
|
|
} |
|
|
|
|
|
|
794
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.