Completed
Pull Request — master (#104)
by Luke
02:31
created

LaraCart   D

Complexity

Total Complexity 88

Size/Duplication

Total Lines 722
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 33
Bugs 5 Features 3
Metric Value
wmc 88
c 33
b 5
f 3
lcom 1
cbo 4
dl 0
loc 722
rs 4.4444

38 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A getInstances() 0 4 1
A setInstance() 0 13 2
B get() 0 15 5
A getAttribute() 0 4 1
A getAttributes() 0 4 1
A setAttribute() 0 6 1
A update() 0 11 3
A removeAttribute() 0 6 1
A addLine() 0 4 1
B add() 0 40 4
A addItem() 0 14 2
A increment() 0 8 1
A decrement() 0 14 2
A find() 0 12 3
A getItem() 0 4 1
A getItems() 0 11 3
A updateItem() 0 12 2
A removeItem() 0 13 3
A emptyCart() 0 8 1
A destroyCart() 0 12 1
A getCoupons() 0 4 1
A findCoupon() 0 4 1
A addCoupon() 0 10 2
A removeCoupon() 0 14 4
A getFee() 0 4 1
A addFee() 0 6 1
A removeFee() 0 6 1
C taxTotal() 0 30 7
A total() 0 14 3
A subTotal() 0 12 3
A count() 0 14 3
B formatMoney() 0 17 5
B feeTotals() 0 14 5
A getFees() 0 4 1
A totalDiscount() 0 12 3
A isItemModel() 0 6 3
A getItemModelOptions() 0 15 4

How to fix   Complexity   

Complex Class

Complex classes like LaraCart often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use LaraCart, and based on these observations, apply Extract Interface, too.

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
12
/**
13
 * Class LaraCart
14
 *
15
 * @package LukePOLO\LaraCart
16
 */
17
class LaraCart implements LaraCartContract
18
{
19
    const QTY = 'qty';
20
    const HASH = 'generateCartHash';
21
    const PRICE = 'price';
22
    const SERVICE = 'laracart';
23
    const RANHASH = 'generateRandomCartItemHash';
24
25
    protected $events;
26
    protected $session;
27
    protected $authManager;
28
    protected $prefix;
29
30
    public $cart;
31
32
    /**
33
     * LaraCart constructor.
34
     *
35
     * @param SessionManager $session
36
     * @param Dispatcher $events
37
     * @param AuthManager $authManager
38
     */
39
    public function __construct(SessionManager $session, Dispatcher $events, AuthManager $authManager)
40
    {
41
        $this->session = $session;
42
        $this->events = $events;
43
        $this->authManager = $authManager;
44
        $this->prefix = config('laracart.cache_prefix', 'laracart');
45
46
        $this->setInstance($this->session->get($this->prefix . '.instance', 'default'));
47
    }
48
49
    /**
50
     * Gets all current instances inside the session
51
     *
52
     * @return mixed
53
     */
54
    public function getInstances()
55
    {
56
        return $this->session->get($this->prefix . '.instances', []);
57
    }
58
59
    /**
60
     * Sets and Gets the instance of the cart in the session we should be using
61
     *
62
     * @param string $instance
63
     *
64
     * @return LaraCart
65
     */
66
    public function setInstance($instance = 'default')
67
    {
68
        $this->get($instance);
69
70
        $this->session->set($this->prefix . '.instance', $instance);
71
72
        if (!in_array($instance, $this->getInstances())) {
73
            $this->session->push($this->prefix . '.instances', $instance);
74
        }
75
        $this->events->fire('laracart.new');
76
77
        return $this;
78
    }
79
80
    /**
81
     * Gets the instance in the session
82
     *
83
     * @param string $instance
84
     *
85
     * @return $this cart instance
86
     */
87
    public function get($instance = 'default')
88
    {
89
        if (config('laracart.cross_devices', false) && $this->authManager->check()) {
90
            if (!empty($cartSessionID = $this->authManager->user()->cart_session_id)) {
91
                $this->session->setId($cartSessionID);
92
                $this->session->start();
93
            }
94
        }
95
96
        if (empty($this->cart = $this->session->get($this->prefix . '.' . $instance))) {
97
            $this->cart = new Cart($instance);
98
        }
99
100
        return $this;
101
    }
102
103
    /**
104
     * Gets an an attribute from the cart
105
     *
106
     * @param $attribute
107
     * @param $defaultValue
108
     *
109
     * @return mixed
110
     */
111
    public function getAttribute($attribute, $defaultValue = null)
112
    {
113
        return array_get($this->cart->attributes, $attribute, $defaultValue);
114
    }
115
116
    /**
117
     * Gets all the carts attributes
118
     *
119
     * @return mixed
120
     */
121
    public function getAttributes()
122
    {
123
        return $this->cart->attributes;
124
    }
125
126
    /**
127
     * Adds an Attribute to the cart
128
     *
129
     * @param $attribute
130
     * @param $value
131
     */
132
    public function setAttribute($attribute, $value)
133
    {
134
        array_set($this->cart->attributes, $attribute, $value);
135
136
        $this->update();
137
    }
138
139
    /**
140
     * Updates cart session
141
     */
142
    public function update()
143
    {
144
        $this->session->set($this->prefix . '.' . $this->cart->instance, $this->cart);
145
146
        if (config('laracart.cross_devices', false) && $this->authManager->check()) {
147
            $this->authManager->user()->cart_session_id = $this->session->getId();
148
            $this->authManager->user()->save();
149
        }
150
151
        $this->events->fire('laracart.update', $this->cart);
152
    }
153
154
    /**
155
     * Removes an attribute from the cart
156
     *
157
     * @param $attribute
158
     */
159
    public function removeAttribute($attribute)
160
    {
161
        array_forget($this->cart->attributes, $attribute);
162
163
        $this->update();
164
    }
165
166
    /**
167
     * Creates a CartItem and then adds it to cart
168
     *
169
     * @param string|int $itemID
170
     * @param null $name
171
     * @param int $qty
172
     * @param string $price
173
     * @param array $options
174
     * @param bool|true $taxable
175
     *
176
     * @return CartItem
177
     */
178
    public function addLine($itemID, $name = null, $qty = 1, $price = '0.00', $options = [], $taxable = true)
179
    {
180
        return $this->add($itemID, $name, $qty, $price, $options, $taxable, true);
181
    }
182
183
    /**
184
     * Creates a CartItem and then adds it to cart
185
     *
186
     * @param $itemID
187
     * @param null $name
188
     * @param int $qty
189
     * @param string $price
190
     * @param array $options
191
     * @param bool|false $taxable
192
     * @param bool|false $lineItem
193
     *
194
     * @return CartItem
195
     */
196
    public function add(
197
        $itemID,
198
        $name = null,
199
        $qty = 1,
200
        $price = '0.00',
201
        $options = [],
202
        $taxable = true,
203
        $lineItem = false
204
    ) {
205
206
        if ($this->isItemModel($itemModel = $itemID)) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
207
208
            $bindings = config('laracart.item_model_bindings');
209
210
            $itemID = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_ID]];
211
            $name = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_NAME]];
212
213
            if (empty($qty = $name) || !is_int($name)) {
214
                $qty = 1;
215
            }
216
217
            $price = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_PRICE]];
218
            $options = $this->getItemModelOptions($itemModel, $bindings[\LukePOLO\LaraCart\CartItem::ITEM_OPTIONS]);
219
            $taxable = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_TAXABLE]];
220
        }
221
222
        $item = $this->addItem(new CartItem(
223
            $itemID,
224
            $name,
225
            $qty,
226
            $price,
227
            $options,
228
            $taxable,
229
            $lineItem
230
        ));
231
232
        $this->update();
233
234
        return $this->getItem($item->getHash());
235
    }
236
237
    /**
238
     * Adds the cartItem into the cart session
239
     *
240
     * @param CartItem $cartItem
241
     *
242
     * @return CartItem
243
     */
244
    public function addItem(CartItem $cartItem)
245
    {
246
        $itemHash = $cartItem->generateHash();
247
248
        if ($this->getItem($itemHash)) {
249
            $this->getItem($itemHash)->qty += $cartItem->qty;
0 ignored issues
show
Documentation introduced by
The property qty does not exist on object<LukePOLO\LaraCart\CartItem>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
250
        } else {
251
            $this->cart->items[] = $cartItem;
252
        }
253
254
        $this->events->fire('laracart.addItem', $cartItem);
255
256
        return $cartItem;
257
    }
258
259
    /**
260
     * Increment the quantity of a cartItem based on the itemHash
261
     *
262
     * @param $itemHash
263
     *
264
     * @return CartItem | null
265
     */
266
    public function increment($itemHash)
267
    {
268
        $item = $this->getItem($itemHash);
269
        $item->qty++;
0 ignored issues
show
Documentation introduced by
The property qty does not exist on object<LukePOLO\LaraCart\CartItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
270
        $this->update();
271
272
        return $item;
273
    }
274
275
    /**
276
     * Decrement the quantity of a cartItem based on the itemHash
277
     *
278
     * @param $itemHash
279
     *
280
     * @return CartItem | null
281
     */
282
    public function decrement($itemHash)
283
    {
284
        $item = $this->getItem($itemHash);
285
        if ($item->qty > 1) {
0 ignored issues
show
Documentation introduced by
The property qty does not exist on object<LukePOLO\LaraCart\CartItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
286
            $item->qty--;
0 ignored issues
show
Documentation introduced by
The property qty does not exist on object<LukePOLO\LaraCart\CartItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
287
            $this->update();
288
289
            return $item;
290
        }
291
        $this->removeItem($itemHash);
292
        $this->update();
293
294
        return null;
295
    }
296
297
    /**
298
     * Find items in the cart matching a data set
299
     *
300
     *
301
     * param $data
302
     * @return array
303
     */
304
    public function find($data)
305
    {
306
        $matches = [];
307
308
        foreach ($this->getItems() as $item) {
309
            if ($item->find($data)) {
310
                $matches[] = $item;
311
            }
312
        }
313
314
        return $matches;
315
    }
316
317
    /**
318
     * Finds a cartItem based on the itemHash
319
     *
320
     * @param $itemHash
321
     *
322
     * @return CartItem | null
323
     */
324
    public function getItem($itemHash)
325
    {
326
        return array_get($this->getItems(), $itemHash);
327
    }
328
329
    /**
330
     * Gets all the items within the cart
331
     *
332
     * @return array
333
     */
334
    public function getItems()
335
    {
336
        $items = [];
337
        if (isset($this->cart->items) === true) {
338
            foreach ($this->cart->items as $item) {
339
                $items[$item->getHash()] = $item;
340
            }
341
        }
342
343
        return $items;
344
    }
345
346
    /**
347
     * Updates an items attributes
348
     *
349
     * @param $itemHash
350
     * @param $key
351
     * @param $value
352
     *
353
     * @return CartItem
354
     *
355
     * @throws Exceptions\InvalidPrice
356
     * @throws Exceptions\InvalidQuantity
357
     */
358
    public function updateItem($itemHash, $key, $value)
359
    {
360
        if (empty($item = $this->getItem($itemHash)) === false) {
361
            $item->$key = $value;
362
        }
363
364
        $item->generateHash();
365
366
        $this->update();
367
368
        return $item;
369
    }
370
371
    /**
372
     * Removes a CartItem based on the itemHash
373
     *
374
     * @param $itemHash
375
     */
376
    public function removeItem($itemHash)
377
    {
378
        foreach ($this->cart->items as $itemKey => $item) {
379
            if ($item->getHash() == $itemHash) {
380
                unset($this->cart->items[$itemKey]);
381
                break;
382
            }
383
        }
384
385
        $this->events->fire('laracart.removeItem', $itemHash);
386
387
        $this->update();
388
    }
389
390
    /**
391
     * Empties the carts items
392
     */
393
    public function emptyCart()
394
    {
395
        unset($this->cart->items);
396
397
        $this->update();
398
399
        $this->events->fire('laracart.empty', $this->cart->instance);
400
    }
401
402
    /**
403
     * Completely destroys cart and anything associated with it
404
     */
405
    public function destroyCart()
406
    {
407
        $instance = $this->cart->instance;
408
409
        $this->session->forget($this->prefix . '.' . $instance);
410
411
        $this->setInstance('default');
412
413
        $this->events->fire('laracart.destroy', $instance);
414
415
        $this->update();
416
    }
417
418
    /**
419
     * Gets the coupons for the current cart
420
     *
421
     * @return array
422
     */
423
    public function getCoupons()
424
    {
425
        return $this->cart->coupons;
426
    }
427
428
    /**
429
     * Finds a specific coupon in the cart
430
     *
431
     * @param $code
432
     * @return mixed
433
     */
434
    public function findCoupon($code)
435
    {
436
        return array_get($this->cart->coupons, $code);
437
    }
438
439
    /**
440
     * Applies a coupon to the cart
441
     *
442
     * @param CouponContract $coupon
443
     */
444
    public function addCoupon(CouponContract $coupon)
445
    {
446
        if (!$this->cart->multipleCoupons) {
447
            $this->cart->coupons = [];
448
        }
449
450
        $this->cart->coupons[$coupon->code] = $coupon;
0 ignored issues
show
Bug introduced by
Accessing code on the interface LukePOLO\LaraCart\Contracts\CouponContract suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
451
452
        $this->update();
453
    }
454
455
    /**
456
     * Removes a coupon in the cart
457
     *
458
     * @param $code
459
     */
460
    public function removeCoupon($code)
461
    {
462
        foreach ($this->getItems() as $item) {
463
            if (isset($item->code) && $item->code == $code) {
464
                $item->code = null;
465
                $item->discount = null;
466
                $item->couponInfo = [];
467
            }
468
        }
469
470
        array_forget($this->cart->coupons, $code);
471
472
        $this->update();
473
    }
474
475
    /**
476
     * Gets a speific fee from the fees array
477
     *
478
     * @param $name
479
     *
480
     * @return mixed
481
     */
482
    public function getFee($name)
483
    {
484
        return array_get($this->cart->fees, $name, new CartFee(null, false));
485
    }
486
487
    /**
488
     * Allows to charge for additional fees that may or may not be taxable
489
     * ex - service fee , delivery fee, tips
490
     *
491
     * @param $name
492
     * @param $amount
493
     * @param bool|false $taxable
494
     * @param array $options
495
     */
496
    public function addFee($name, $amount, $taxable = false, array $options = [])
497
    {
498
        array_set($this->cart->fees, $name, new CartFee($amount, $taxable, $options));
499
500
        $this->update();
501
    }
502
503
    /**
504
     * Reemoves a fee from the fee array
505
     *
506
     * @param $name
507
     */
508
    public function removeFee($name)
509
    {
510
        array_forget($this->cart->fees, $name);
511
512
        $this->update();
513
    }
514
515
    /**
516
     * Gets the total tax for the cart
517
     *
518
     * @param bool|true $format
519
     *
520
     * @return string
521
     */
522
    public function taxTotal($format = true)
523
    {
524
        $totalTax = 0;
525
        $discounted = 0;
526
        $totalDiscount = $this->totalDiscount(false);
527
528
        if ($this->count() != 0) {
529
            foreach ($this->getItems() as $item) {
530
                if ($discounted >= $totalDiscount) {
531
                    $totalTax += $item->tax();
532
                } else {
533
                    $itemPrice = $item->subTotal(false);
534
535
                    if (($discounted + $itemPrice) > $totalDiscount) {
536
                        $totalTax += $item->tax($totalDiscount - $discounted);
537
                    }
538
539
                    $discounted += $itemPrice;
540
                }
541
            }
542
        }
543
544
        foreach ($this->getFees() as $fee) {
545
            if ($fee->taxable) {
546
                $totalTax += $fee->amount * $fee->tax;
547
            }
548
        }
549
550
        return $this->formatMoney($totalTax, null, null, $format);
551
    }
552
553
    /**
554
     * Gets the total of the cart with or without tax
555
     *
556
     * @param boolean $format
557
     * @param boolean $withDiscount
558
     *
559
     * @return string
560
     */
561
    public function total($format = true, $withDiscount = true, $withTax = true)
562
    {
563
        $total = $this->subTotal(false) + $this->feeTotals(false);
564
565
        if ($withDiscount) {
566
            $total -= $this->totalDiscount(false);
567
        }
568
569
        if ($withTax) {
570
            $total += $this->taxTotal(false);
571
        }
572
573
        return $this->formatMoney($total, null, null, $format);
574
    }
575
576
    /**
577
     * Gets the subtotal of the cart with or without tax
578
     *
579
     * @param boolean $format
580
     * @param boolean $withDiscount
581
     *
582
     * @return string
583
     */
584
    public function subTotal($format = true, $withDiscount = true)
585
    {
586
        $total = 0;
587
588
        if ($this->count() != 0) {
589
            foreach ($this->getItems() as $item) {
590
                $total += $item->subTotal(false, $withDiscount);
591
            }
592
        }
593
594
        return $this->formatMoney($total, null, null, $format);
595
    }
596
597
    /**
598
     * Get the count based on qty, or number of unique items
599
     *
600
     * @param bool $withItemQty
601
     *
602
     * @return int
603
     */
604
    public function count($withItemQty = true)
605
    {
606
        $count = 0;
607
608
        foreach ($this->getItems() as $item) {
609
            if ($withItemQty) {
610
                $count += $item->qty;
611
            } else {
612
                $count++;
613
            }
614
        }
615
616
        return $count;
617
    }
618
619
    /**
620
     *
621
     * Formats the number into a money format based on the locale and international formats
622
     *
623
     * @param $number
624
     * @param $locale
625
     * @param $internationalFormat
626
     * @param $format
627
     *
628
     * @return string
629
     */
630
    public static function formatMoney($number, $locale = null, $internationalFormat = null, $format = true)
631
    {
632
        $number = number_format($number, 2, '.', '');
633
634
        if ($format) {
635
            setlocale(LC_MONETARY, null);
636
            setlocale(LC_MONETARY, empty($locale) ? config('laracart.locale', 'en_US.UTF-8') : $locale);
637
638
            if (empty($internationalFormat) === true) {
639
                $internationalFormat = config('laracart.international_format', false);
640
            }
641
642
            $number = money_format($internationalFormat ? '%i' : '%n', $number);
643
        }
644
645
        return $number;
646
    }
647
648
    /**
649
     * Gets all the fee totals
650
     *
651
     * @param boolean $format
652
     *
653
     * @return string
654
     */
655
    public function feeTotals($format = true, $withTax = false)
656
    {
657
        $feeTotal = 0;
658
659
        foreach ($this->getFees() as $fee) {
660
            $feeTotal += $fee->amount;
661
662
            if ($withTax && $fee->taxable && $fee->tax > 0) {
663
                $feeTotal += $fee->amount * $fee->tax;
664
            }
665
        }
666
667
        return $this->formatMoney($feeTotal, null, null, $format);
668
    }
669
670
    /**
671
     * Gets all the fees on the cart object
672
     *
673
     * @return mixed
674
     */
675
    public function getFees()
676
    {
677
        return $this->cart->fees;
678
    }
679
680
    /**
681
     * Gets the total amount discounted
682
     *
683
     * @param boolean $format
684
     *
685
     * @return string
686
     */
687
    public function totalDiscount($format = true)
688
    {
689
        $total = 0;
690
691
        foreach ($this->cart->coupons as $coupon) {
692
            if ($coupon->appliedToCart) {
693
                $total += $coupon->discount();
694
            }
695
        }
696
697
        return $this->formatMoney($total, null, null, $format);
698
    }
699
700
    /**
701
     * Checks to see if its an item model
702
     *
703
     * @param $itemModel
704
     *
705
     * @return bool
706
     */
707
    private function isItemModel($itemModel)
708
    {
709
        if (is_object($itemModel) && get_class($itemModel) == config('laracart.item_model')) {
710
            return true;
711
        }
712
    }
713
714
    /**
715
     * Gets the item models options based the config
716
     *
717
     * @param Model $itemModel
718
     * @param array $options
719
     *
720
     * @return array
721
     */
722
    private function getItemModelOptions(Model $itemModel, $options = [])
723
    {
724
        $itemOptions = [];
725
        foreach ($options as $option) {
726
            $itemOptions[$option] = $itemModel->$option;
727
        }
728
729
        return array_filter($itemOptions, function ($value) {
730
            if ($value !== false && empty($value)) {
731
                return false;
732
            }
733
734
            return true;
735
        });
736
    }
737
738
}
739