Completed
Push — master ( 6494b1...504660 )
by Igor
02:00
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace yii2mod\cart;
3
4
use yii\base\Component;
5
use yii\base\InvalidParamException;
6
use yii\web\Session;
7
use yii2mod\cart\models\CartItemInterface;
8
9
/**
10
 * Provides basic cart functionality (adding, removing, clearing, listing items). You can extend this class and
11
 * override it in the application configuration to extend/customize the functionality
12
 * @package yii2mod\cart
13
 * @property int     $count
14
 * @property Session $session
15
 */
16
class Cart extends Component
17
{
18
19
    /**
20
     * @var interface class
21
     */
22
    const ITEM_PRODUCT = '\yii2mod\cart\models\CartItemInterface';
23
24
25
    /**
26
     * @var array
27
     */
28
    protected $items;
29
30
    /**
31
     * @var null
32
     */
33
    private $storage = null;
34
35
    /**
36
     * Override this to provide custom (e.g. database) storage for cart data
37
     * @var string|\yii2mod\cart\storage\StorageInterface
38
     */
39
    public $storageClass = '\yii2mod\cart\storage\SessionStorage';
40
41
    /**
42
     * @inheritdoc
43
     */
44
    public function init()
45
    {
46
        $this->clear(false);
47
        $this->setStorage(\Yii::createObject($this->storageClass));
48
        $this->items = $this->storage->load($this);
0 ignored issues
show
The method load cannot be called on $this->storage (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
49
    }
50
51
    /**
52
     * Assigns cart to logged in user
53
     *
54
     * @param string
55
     * @param string
56
     *
57
     * @return void
58
     */
59
    public function reassign($sessionId, $userId)
60
    {
61
        if (get_class($this->getStorage()) === 'yii2mod\cart\storage\DatabaseStorage') {
62
            if (!empty($this->items)) {
63
                $storage = $this->getStorage();
64
                $storage->reassign($sessionId, $userId);
65
                self::init();
66
            }
67
        }
68
    }
69
70
    /**
71
     * Delete all items from the cart
72
     *
73
     * @param bool $save
74
     *
75
     * @return $this
76
     */
77
    public function clear($save = true)
78
    {
79
        $this->items = [];
80
        $save && $this->storage->save($this);
0 ignored issues
show
The method save cannot be called on $this->storage (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
81
        return $this;
82
    }
83
84
    /**
85
     * Setter for the storage component
86
     *
87
     * @param \yii2mod\cart\storage\StorageInterface|string $storage
88
     *
89
     * @return Cart
90
     */
91
    public function setStorage($storage)
92
    {
93
        $this->storage = $storage;
0 ignored issues
show
Documentation Bug introduced by
It seems like $storage of type object<yii2mod\cart\storage\StorageInterface> or string is incompatible with the declared type null of property $storage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
94
        return $this;
95
    }
96
97
    /**
98
     * Add an item to the cart
99
     *
100
     * @param models\CartItemInterface $element
101
     * @param bool                     $save
102
     *
103
     * @return $this
104
     */
105
    public function add(CartItemInterface $element, $save = true)
106
    {
107
        $this->addItem($element);
108
        $save && $this->storage->save($this);
0 ignored issues
show
The method save cannot be called on $this->storage (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
109
        return $this;
110
    }
111
112
    /**
113
     * @param \yii2mod\cart\models\CartItemInterface $item
114
     *
115
     * @internal param $quantity
116
     */
117
    protected function addItem(CartItemInterface $item)
118
    {
119
        $uniqueId = $item->getUniqueId();
120
        $this->items[$uniqueId] = $item;
121
    }
122
123
    /**
124
     * Removes an item from the cart
125
     *
126
     * @param string $uniqueId
127
     * @param bool   $save
128
     *
129
     * @throws \yii\base\InvalidParamException
130
     * @return $this
131
     */
132
    public function remove($uniqueId, $save = true)
133
    {
134
        if (!isset($this->items[$uniqueId])) {
135
            throw new InvalidParamException('Item not found');
136
        }
137
        unset($this->items[$uniqueId]);
138
139
        $save && $this->storage->save($this);
0 ignored issues
show
The method save cannot be called on $this->storage (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
140
        return $this;
141
    }
142
143
    /**
144
     * @param string $itemType If specified, only items of that type will be counted
145
     *
146
     * @return int
147
     */
148
    public function getCount($itemType = null)
149
    {
150
        return count($this->getItems($itemType));
151
    }
152
153
    /**
154
     * Returns all items of a given type from the cart
155
     *
156
     * @param string $itemType One of self::ITEM_ constants
157
     *
158
     * @return CartItemInterface[]
159
     */
160
    public function getItems($itemType = null)
161
    {
162
        $items = $this->items;
163
        if (!is_null($itemType)) {
164
            $items = array_filter($items,
165
                function ($item) use ($itemType) {
166
                    /** @var $item CartItemInterface */
167
                    return is_subclass_of($item, $itemType);
168
                });
169
        }
170
        return $items;
171
    }
172
173
174
    /**
175
     * Finds all items of type $itemType, sums the values of $attribute of all models and returns the sum.
176
     *
177
     * @param string      $attribute
178
     * @param string|null $itemType
179
     *
180
     * @return integer
181
     */
182
    public function getAttributeTotal($attribute, $itemType = null)
183
    {
184
        $sum = 0;
185
        foreach ($this->getItems($itemType) as $model) {
186
            $sum += $model->{$attribute};
187
        }
188
        return $sum;
189
    }
190
191
192
    /**
193
     * @return \yii2mod\cart\storage\StorageInterface|string
194
     */
195
    protected function getStorage()
196
    {
197
        return $this->storage;
198
    }
199
}