Cart::add()   B
last analyzed

Complexity

Conditions 7
Paths 6

Size

Total Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 66
rs 7.8084
c 0
b 0
f 0
cc 7
nc 6
nop 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Darryldecode\Cart;
2
3
use Darryldecode\Cart\Exceptions\InvalidConditionException;
4
use Darryldecode\Cart\Exceptions\InvalidItemException;
5
use Darryldecode\Cart\Helpers\Helpers;
6
use Darryldecode\Cart\Validators\CartItemValidator;
7
use Darryldecode\Cart\Exceptions\UnknownModelException;
8
9
/**
10
 * Class Cart
11
 * @package Darryldecode\Cart
12
 */
13
class Cart
14
{
15
16
    /**
17
     * the item storage
18
     *
19
     * @var
20
     */
21
    protected $session;
22
23
    /**
24
     * the event dispatcher
25
     *
26
     * @var
27
     */
28
    protected $events;
29
30
    /**
31
     * the cart session key
32
     *
33
     * @var
34
     */
35
    protected $instanceName;
36
37
    /**
38
     * the session key use for the cart
39
     *
40
     * @var
41
     */
42
    protected $sessionKey;
43
44
    /**
45
     * the session key use to persist cart items
46
     *
47
     * @var
48
     */
49
    protected $sessionKeyCartItems;
50
51
    /**
52
     * the session key use to persist cart conditions
53
     *
54
     * @var
55
     */
56
    protected $sessionKeyCartConditions;
57
58
    /**
59
     * Configuration to pass to ItemCollection
60
     *
61
     * @var
62
     */
63
    protected $config;
64
65
    /**
66
     * This holds the currently added item id in cart for association
67
     * 
68
     * @var
69
     */
70
    protected $currentItemId;
71
72
    /**
73
     * our object constructor
74
     *
75
     * @param $session
76
     * @param $events
77
     * @param $instanceName
78
     * @param $session_key
79
     * @param $config
80
     */
81
    public function __construct($session, $events, $instanceName, $session_key, $config)
82
    {
83
        $this->events = $events;
84
        $this->session = $session;
85
        $this->instanceName = $instanceName;
86
        $this->sessionKey = $session_key;
87
        $this->sessionKeyCartItems = $this->sessionKey . '_cart_items';
88
        $this->sessionKeyCartConditions = $this->sessionKey . '_cart_conditions';
89
        $this->config = $config;
90
        $this->currentItem = null;
0 ignored issues
show
Bug introduced by
The property currentItem does not seem to exist. Did you mean currentItemId?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
91
        $this->fireEvent('created');
92
    }
93
94
    /**
95
     * sets the session key
96
     *
97
     * @param string $sessionKey the session key or identifier
98
     * @return $this|bool
99
     * @throws \Exception
100
     */
101
    public function session($sessionKey)
102
    {
103
        if (!$sessionKey) throw new \Exception("Session key is required.");
104
105
        $this->sessionKey = $sessionKey;
106
        $this->sessionKeyCartItems = $this->sessionKey . '_cart_items';
107
        $this->sessionKeyCartConditions = $this->sessionKey . '_cart_conditions';
108
109
        return $this;
110
    }
111
112
    /**
113
     * get instance name of the cart
114
     *
115
     * @return string
116
     */
117
    public function getInstanceName()
118
    {
119
        return $this->instanceName;
120
    }
121
122
    /**
123
     * get an item on a cart by item ID
124
     *
125
     * @param $itemId
126
     * @return mixed
127
     */
128
    public function get($itemId)
129
    {
130
        return $this->getContent()->get($itemId);
131
    }
132
133
    /**
134
     * check if an item exists by item ID
135
     *
136
     * @param $itemId
137
     * @return bool
138
     */
139
    public function has($itemId)
140
    {
141
        return $this->getContent()->has($itemId);
142
    }
143
144
    /**
145
     * add item to the cart, it can be an array or multi dimensional array
146
     *
147
     * @param string|array $id
148
     * @param string $name
149
     * @param float $price
150
     * @param int $quantity
151
     * @param array $attributes
152
     * @param CartCondition|array $conditions
153
     * @param string $associatedModel
154
     * @return $this
155
     * @throws InvalidItemException
156
     */
157
    public function add($id, $name = null, $price = null, $quantity = null, $attributes = array(), $conditions = array(), $associatedModel = null)
158
    {
159
        // if the first argument is an array,
160
        // we will need to call add again
161
        if (is_array($id)) {
162
            // the first argument is an array, now we will need to check if it is a multi dimensional
163
            // array, if so, we will iterate through each item and call add again
164
            if (Helpers::isMultiArray($id)) {
165
                foreach ($id as $item) {
166
                    $this->add(
167
                        $item['id'],
168
                        $item['name'],
169
                        $item['price'],
170
                        $item['quantity'],
171
                        Helpers::issetAndHasValueOrAssignDefault($item['attributes'], array()),
172
                        Helpers::issetAndHasValueOrAssignDefault($item['conditions'], array()),
173
                        Helpers::issetAndHasValueOrAssignDefault($item['associatedModel'], null)
174
                    );
175
                }
176
            } else {
177
                $this->add(
178
                    $id['id'],
179
                    $id['name'],
180
                    $id['price'],
181
                    $id['quantity'],
182
                    Helpers::issetAndHasValueOrAssignDefault($id['attributes'], array()),
183
                    Helpers::issetAndHasValueOrAssignDefault($id['conditions'], array()),
184
                    Helpers::issetAndHasValueOrAssignDefault($id['associatedModel'], null)
185
                );
186
            }
187
188
            return $this;
189
        }
190
191
        $data = array(
192
            'id' => $id,
193
            'name' => $name,
194
            'price' => Helpers::normalizePrice($price),
195
            'quantity' => $quantity,
196
            'attributes' => new ItemAttributeCollection($attributes),
197
            'conditions' => $conditions
198
        );
199
200
        if (isset($associatedModel) && $associatedModel != '') {
201
            $data['associatedModel'] = $associatedModel;
202
        }
203
204
        // validate data
205
        $item = $this->validate($data);
206
207
        // get the cart
208
        $cart = $this->getContent();
209
210
        // if the item is already in the cart we will just update it
211
        if ($cart->has($id)) {
212
213
            $this->update($id, $item);
214
        } else {
215
216
            $this->addRow($id, $item);
217
        }
218
219
        $this->currentItemId = $id;
220
221
        return $this;
222
    }
223
224
    /**
225
     * update a cart
226
     *
227
     * @param $id
228
     * @param array $data
229
     *
230
     * the $data will be an associative array, you don't need to pass all the data, only the key value
231
     * of the item you want to update on it
232
     * @return bool
233
     */
234
    public function update($id, $data)
235
    {
236
        if ($this->fireEvent('updating', $data) === false) {
237
            return false;
238
        }
239
240
        $cart = $this->getContent();
241
242
        $item = $cart->pull($id);
243
244
        foreach ($data as $key => $value) {
245
            // if the key is currently "quantity" we will need to check if an arithmetic
246
            // symbol is present so we can decide if the update of quantity is being added
247
            // or being reduced.
248
            if ($key == 'quantity') {
249
                // we will check if quantity value provided is array,
250
                // if it is, we will need to check if a key "relative" is set
251
                // and we will evaluate its value if true or false,
252
                // this tells us how to treat the quantity value if it should be updated
253
                // relatively to its current quantity value or just totally replace the value
254
                if (is_array($value)) {
255
                    if (isset($value['relative'])) {
256
                        if ((bool)$value['relative']) {
257
                            $item = $this->updateQuantityRelative($item, $key, $value['value']);
258
                        } else {
259
                            $item = $this->updateQuantityNotRelative($item, $key, $value['value']);
260
                        }
261
                    }
262
                } else {
263
                    $item = $this->updateQuantityRelative($item, $key, $value);
264
                }
265
            } elseif ($key == 'attributes') {
266
                $item[$key] = new ItemAttributeCollection($value);
267
            } else {
268
                $item[$key] = $value;
269
            }
270
        }
271
272
        $cart->put($id, $item);
273
274
        $this->save($cart);
275
276
        $this->fireEvent('updated', $item);
277
        return true;
278
    }
279
280
    /**
281
     * add condition on an existing item on the cart
282
     *
283
     * @param int|string $productId
284
     * @param CartCondition $itemCondition
285
     * @return $this
286
     */
287
    public function addItemCondition($productId, $itemCondition)
288
    {
289
        if ($product = $this->get($productId)) {
290
            $conditionInstance = "\\Darryldecode\\Cart\\CartCondition";
291
292
            if ($itemCondition instanceof $conditionInstance) {
293
                // we need to copy first to a temporary variable to hold the conditions
294
                // to avoid hitting this error "Indirect modification of overloaded element of Darryldecode\Cart\ItemCollection has no effect"
295
                // this is due to laravel Collection instance that implements Array Access
296
                // // see link for more info: http://stackoverflow.com/questions/20053269/indirect-modification-of-overloaded-element-of-splfixedarray-has-no-effect
297
                $itemConditionTempHolder = $product['conditions'];
298
299
                if (is_array($itemConditionTempHolder)) {
300
                    array_push($itemConditionTempHolder, $itemCondition);
301
                } else {
302
                    $itemConditionTempHolder = $itemCondition;
303
                }
304
305
                $this->update($productId, array(
306
                    'conditions' => $itemConditionTempHolder // the newly updated conditions
307
                ));
308
            }
309
        }
310
311
        return $this;
312
    }
313
314
    /**
315
     * removes an item on cart by item ID
316
     *
317
     * @param $id
318
     * @return bool
319
     */
320
    public function remove($id)
321
    {
322
        $cart = $this->getContent();
323
324
        if ($this->fireEvent('removing', $id) === false) {
325
            return false;
326
        }
327
328
        $cart->forget($id);
329
330
        $this->save($cart);
331
332
        $this->fireEvent('removed', $id);
333
        return true;
334
    }
335
336
    /**
337
     * clear cart
338
     * @return bool
339
     */
340
    public function clear()
341
    {
342
        if ($this->fireEvent('clearing') === false) {
343
            return false;
344
        }
345
346
        $this->session->put(
347
            $this->sessionKeyCartItems,
348
            array()
349
        );
350
351
        $this->fireEvent('cleared');
352
        return true;
353
    }
354
355
    /**
356
     * add a condition on the cart
357
     *
358
     * @param CartCondition|array $condition
359
     * @return $this
360
     * @throws InvalidConditionException
361
     */
362
    public function condition($condition)
363
    {
364
        if (is_array($condition)) {
365
            foreach ($condition as $c) {
366
                $this->condition($c);
367
            }
368
369
            return $this;
370
        }
371
372
        if (!$condition instanceof CartCondition) throw new InvalidConditionException('Argument 1 must be an instance of \'Darryldecode\Cart\CartCondition\'');
373
374
        $conditions = $this->getConditions();
375
376
        // Check if order has been applied
377
        if ($condition->getOrder() == 0) {
378
            $last = $conditions->last();
379
            $condition->setOrder(!is_null($last) ? $last->getOrder() + 1 : 1);
380
        }
381
382
        $conditions->put($condition->getName(), $condition);
383
384
        $conditions = $conditions->sortBy(function ($condition, $key) {
0 ignored issues
show
Unused Code introduced by
The parameter $key is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
385
            return $condition->getOrder();
386
        });
387
388
        $this->saveConditions($conditions);
389
390
        return $this;
391
    }
392
393
    /**
394
     * get conditions applied on the cart
395
     *
396
     * @return CartConditionCollection
397
     */
398
    public function getConditions()
399
    {
400
        return new CartConditionCollection($this->session->get($this->sessionKeyCartConditions));
401
    }
402
403
    /**
404
     * get condition applied on the cart by its name
405
     *
406
     * @param $conditionName
407
     * @return CartCondition
408
     */
409
    public function getCondition($conditionName)
410
    {
411
        return $this->getConditions()->get($conditionName);
412
    }
413
414
    /**
415
     * Get all the condition filtered by Type
416
     * Please Note that this will only return condition added on cart bases, not those conditions added
417
     * specifically on an per item bases
418
     *
419
     * @param $type
420
     * @return CartConditionCollection
421
     */
422
    public function getConditionsByType($type)
423
    {
424
        return $this->getConditions()->filter(function (CartCondition $condition) use ($type) {
425
            return $condition->getType() == $type;
426
        });
427
    }
428
429
430
    /**
431
     * Remove all the condition with the $type specified
432
     * Please Note that this will only remove condition added on cart bases, not those conditions added
433
     * specifically on an per item bases
434
     *
435
     * @param $type
436
     * @return $this
437
     */
438
    public function removeConditionsByType($type)
439
    {
440
        $this->getConditionsByType($type)->each(function ($condition) {
441
            $this->removeCartCondition($condition->getName());
442
        });
443
    }
444
445
446
    /**
447
     * removes a condition on a cart by condition name,
448
     * this can only remove conditions that are added on cart bases not conditions that are added on an item/product.
449
     * If you wish to remove a condition that has been added for a specific item/product, you may
450
     * use the removeItemCondition(itemId, conditionName) method instead.
451
     *
452
     * @param $conditionName
453
     * @return void
454
     */
455
    public function removeCartCondition($conditionName)
456
    {
457
        $conditions = $this->getConditions();
458
459
        $conditions->pull($conditionName);
460
461
        $this->saveConditions($conditions);
462
    }
463
464
    /**
465
     * remove a condition that has been applied on an item that is already on the cart
466
     *
467
     * @param $itemId
468
     * @param $conditionName
469
     * @return bool
470
     */
471
    public function removeItemCondition($itemId, $conditionName)
472
    {
473
        if (!$item = $this->getContent()->get($itemId)) {
474
            return false;
475
        }
476
477
        if ($this->itemHasConditions($item)) {
478
            // NOTE:
479
            // we do it this way, we get first conditions and store
480
            // it in a temp variable $originalConditions, then we will modify the array there
481
            // and after modification we will store it again on $item['conditions']
482
            // This is because of ArrayAccess implementation
483
            // see link for more info: http://stackoverflow.com/questions/20053269/indirect-modification-of-overloaded-element-of-splfixedarray-has-no-effect
484
485
            $tempConditionsHolder = $item['conditions'];
486
487
            // if the item's conditions is in array format
488
            // we will iterate through all of it and check if the name matches
489
            // to the given name the user wants to remove, if so, remove it
490
            if (is_array($tempConditionsHolder)) {
491
                foreach ($tempConditionsHolder as $k => $condition) {
492
                    if ($condition->getName() == $conditionName) {
493
                        unset($tempConditionsHolder[$k]);
494
                    }
495
                }
496
497
                $item['conditions'] = $tempConditionsHolder;
498
            }
499
500
            // if the item condition is not an array, we will check if it is
501
            // an instance of a Condition, if so, we will check if the name matches
502
            // on the given condition name the user wants to remove, if so,
503
            // lets just make $item['conditions'] an empty array as there's just 1 condition on it anyway
504
            else {
505
                $conditionInstance = "Darryldecode\\Cart\\CartCondition";
506
507
                if ($item['conditions'] instanceof $conditionInstance) {
508
                    if ($tempConditionsHolder->getName() == $conditionName) {
509
                        $item['conditions'] = array();
510
                    }
511
                }
512
            }
513
        }
514
515
        $this->update($itemId, array(
516
            'conditions' => $item['conditions']
517
        ));
518
519
        return true;
520
    }
521
522
    /**
523
     * remove all conditions that has been applied on an item that is already on the cart
524
     *
525
     * @param $itemId
526
     * @return bool
527
     */
528
    public function clearItemConditions($itemId)
529
    {
530
        if (!$item = $this->getContent()->get($itemId)) {
531
            return false;
532
        }
533
534
        $this->update($itemId, array(
535
            'conditions' => array()
536
        ));
537
538
        return true;
539
    }
540
541
    /**
542
     * clears all conditions on a cart,
543
     * this does not remove conditions that has been added specifically to an item/product.
544
     * If you wish to remove a specific condition to a product, you may use the method: removeItemCondition($itemId, $conditionName)
545
     *
546
     * @return void
547
     */
548
    public function clearCartConditions()
549
    {
550
        $this->session->put(
551
            $this->sessionKeyCartConditions,
552
            array()
553
        );
554
    }
555
556
    /**
557
     * get cart sub total without conditions
558
     * @param bool $formatted
559
     * @return float
560
     */
561
    public function getSubTotalWithoutConditions($formatted = true)
562
    {
563
        $cart = $this->getContent();
564
565
        $sum = $cart->sum(function ($item) {
566
            return $item->getPriceSum();
567
        });
568
569
        return Helpers::formatValue(floatval($sum), $formatted, $this->config);
570
    }
571
572
    /**
573
     * get cart sub total
574
     * @param bool $formatted
575
     * @return float
576
     */
577
    public function getSubTotal($formatted = true)
578
    {
579
        $cart = $this->getContent();
580
581
        $sum = $cart->sum(function (ItemCollection $item) {
582
            return $item->getPriceSumWithConditions(false);
583
        });
584
585
        // get the conditions that are meant to be applied
586
        // on the subtotal and apply it here before returning the subtotal
587
        $conditions = $this
588
            ->getConditions()
589
            ->filter(function (CartCondition $cond) {
590
                return $cond->getTarget() === 'subtotal';
591
            });
592
593
        // if there is no conditions, lets just return the sum
594
        if (!$conditions->count()) return Helpers::formatValue(floatval($sum), $formatted, $this->config);
595
596
        // there are conditions, lets apply it
597
        $newTotal = 0.00;
598
        $process = 0;
599
600 View Code Duplication
        $conditions->each(function (CartCondition $cond) use ($sum, &$newTotal, &$process) {
601
602
            // if this is the first iteration, the toBeCalculated
603
            // should be the sum as initial point of value.
604
            $toBeCalculated = ($process > 0) ? $newTotal : $sum;
605
606
            $newTotal = $cond->applyCondition($toBeCalculated);
607
608
            $process++;
609
        });
610
611
        return Helpers::formatValue(floatval($newTotal), $formatted, $this->config);
612
    }
613
614
    /**
615
     * the new total in which conditions are already applied
616
     *
617
     * @return float
618
     */
619
    public function getTotal()
620
    {
621
        $subTotal = $this->getSubTotal(false);
622
623
        $newTotal = 0.00;
624
625
        $process = 0;
626
627
        $conditions = $this
628
            ->getConditions()
629
            ->filter(function (CartCondition $cond) {
630
                return $cond->getTarget() === 'total';
631
            });
632
633
        // if no conditions were added, just return the sub total
634
        if (!$conditions->count()) {
635
            return Helpers::formatValue($subTotal, $this->config['format_numbers'], $this->config);
636
        }
637
638
        $conditions
639 View Code Duplication
            ->each(function (CartCondition $cond) use ($subTotal, &$newTotal, &$process) {
640
                $toBeCalculated = ($process > 0) ? $newTotal : $subTotal;
641
642
                $newTotal = $cond->applyCondition($toBeCalculated);
643
644
                $process++;
645
            });
646
647
        return Helpers::formatValue($newTotal, $this->config['format_numbers'], $this->config);
648
    }
649
650
    /**
651
     * get total quantity of items in the cart
652
     *
653
     * @return int
654
     */
655
    public function getTotalQuantity()
656
    {
657
        $items = $this->getContent();
658
659
        if ($items->isEmpty()) return 0;
660
661
        $count = $items->sum(function ($item) {
662
            return $item['quantity'];
663
        });
664
665
        return $count;
666
    }
667
668
    /**
669
     * get the cart
670
     *
671
     * @return CartCollection
672
     */
673
    public function getContent()
674
    {
675
        return (new CartCollection($this->session->get($this->sessionKeyCartItems)))->reject(function($item) {
676
            return ! ($item instanceof ItemCollection);
677
        });
678
    }
679
680
    /**
681
     * check if cart is empty
682
     *
683
     * @return bool
684
     */
685
    public function isEmpty()
686
    {
687
        return $this->getContent()->isEmpty();
688
    }
689
690
    /**
691
     * validate Item data
692
     *
693
     * @param $item
694
     * @return array $item;
695
     * @throws InvalidItemException
696
     */
697 View Code Duplication
    protected function validate($item)
698
    {
699
        $rules = array(
700
            'id' => 'required',
701
            'price' => 'required|numeric',
702
            'quantity' => 'required|numeric|min:0.1',
703
            'name' => 'required',
704
        );
705
706
        $validator = CartItemValidator::make($item, $rules);
707
708
        if ($validator->fails()) {
709
            throw new InvalidItemException($validator->messages()->first());
710
        }
711
712
        return $item;
713
    }
714
715
    /**
716
     * add row to cart collection
717
     *
718
     * @param $id
719
     * @param $item
720
     * @return bool
721
     */
722
    protected function addRow($id, $item)
723
    {
724
        if ($this->fireEvent('adding', $item) === false) {
725
            return false;
726
        }
727
728
        $cart = $this->getContent();
729
730
        $cart->put($id, new ItemCollection($item, $this->config));
731
732
        $this->save($cart);
733
734
        $this->fireEvent('added', $item);
735
736
        return true;
737
    }
738
739
    /**
740
     * save the cart
741
     *
742
     * @param $cart CartCollection
743
     */
744
    protected function save($cart)
745
    {
746
        $this->session->put($this->sessionKeyCartItems, $cart);
747
    }
748
749
    /**
750
     * save the cart conditions
751
     *
752
     * @param $conditions
753
     */
754
    protected function saveConditions($conditions)
755
    {
756
        $this->session->put($this->sessionKeyCartConditions, $conditions);
757
    }
758
759
    /**
760
     * check if an item has condition
761
     *
762
     * @param $item
763
     * @return bool
764
     */
765
    protected function itemHasConditions($item)
766
    {
767
        if (!isset($item['conditions'])) return false;
768
769
        if (is_array($item['conditions'])) {
770
            return count($item['conditions']) > 0;
771
        }
772
773
        $conditionInstance = "Darryldecode\\Cart\\CartCondition";
774
775
        if ($item['conditions'] instanceof $conditionInstance) return true;
776
777
        return false;
778
    }
779
780
    /**
781
     * update a cart item quantity relative to its current quantity
782
     *
783
     * @param $item
784
     * @param $key
785
     * @param $value
786
     * @return mixed
787
     */
788
    protected function updateQuantityRelative($item, $key, $value)
789
    {
790
        if (preg_match('/\-/', $value) == 1) {
791
            $value = (int)str_replace('-', '', $value);
792
793
            // we will not allowed to reduced quantity to 0, so if the given value
794
            // would result to item quantity of 0, we will not do it.
795
            if (($item[$key] - $value) > 0) {
796
                $item[$key] -= $value;
797
            }
798
        } elseif (preg_match('/\+/', $value) == 1) {
799
            $item[$key] += (int)str_replace('+', '', $value);
800
        } else {
801
            $item[$key] += (int)$value;
802
        }
803
804
        return $item;
805
    }
806
807
    /**
808
     * update cart item quantity not relative to its current quantity value
809
     *
810
     * @param $item
811
     * @param $key
812
     * @param $value
813
     * @return mixed
814
     */
815
    protected function updateQuantityNotRelative($item, $key, $value)
816
    {
817
        $item[$key] = (int)$value;
818
819
        return $item;
820
    }
821
822
    /**
823
     * Setter for decimals. Change value on demand.
824
     * @param $decimals
825
     */
826
    public function setDecimals($decimals)
827
    {
828
        $this->decimals = $decimals;
0 ignored issues
show
Bug introduced by
The property decimals does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
829
    }
830
831
    /**
832
     * Setter for decimals point. Change value on demand.
833
     * @param $dec_point
834
     */
835
    public function setDecPoint($dec_point)
836
    {
837
        $this->dec_point = $dec_point;
0 ignored issues
show
Bug introduced by
The property dec_point does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
838
    }
839
840
    public function setThousandsSep($thousands_sep)
841
    {
842
        $this->thousands_sep = $thousands_sep;
0 ignored issues
show
Bug introduced by
The property thousands_sep does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
843
    }
844
845
    /**
846
     * @param $name
847
     * @param $value
848
     * @return mixed
849
     */
850
    protected function fireEvent($name, $value = [])
851
    {
852
        return $this->events->dispatch($this->getInstanceName() . '.' . $name, array_values([$value, $this]), true);
853
    }
854
855
    /**
856
     * Associate the cart item with the given id with the given model.
857
     *
858
     * @param string $id
0 ignored issues
show
Bug introduced by
There is no parameter named $id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
859
     * @param mixed  $model
860
     *
861
     * @return void
862
     */
863
    public function associate($model)
864
    {
865
        if (is_string($model) && !class_exists($model)) {
866
            throw new UnknownModelException("The supplied model {$model} does not exist.");
867
        }
868
869
        $cart = $this->getContent();
870
871
        $item = $cart->pull($this->currentItemId);
872
873
        $item['associatedModel'] = $model;
874
875
        $cart->put($this->currentItemId, new ItemCollection($item, $this->config));
876
877
        $this->save($cart);
878
879
        return $this;
880
    }
881
}
882