Completed
Pull Request — master (#20)
by Klochok
12:09
created

ShoppingCart::getCount()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 11
c 0
b 0
f 0
ccs 6
cts 6
cp 1
rs 9.9
cc 3
nc 3
nop 0
crap 3
1
<?php
2
3
/*
4
 * Cart module for Yii2
5
 *
6
 * @link      https://github.com/hiqdev/yii2-cart
7
 * @package   yii2-cart
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2015-2016, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\yii2\cart;
13
14
use hipanel\modules\finance\cart\AbstractCartPosition;
15
use Yii;
16
use yii\base\Event;
17
use yz\shoppingcart\CartActionEvent;
18
19
/**
20
 * Class ShoppingCart.
21
 * @property AbstractCartPosition[] $positions
22
 */
23
class ShoppingCart extends \yz\shoppingcart\ShoppingCart
24
{
25
    /**
26
     * @var AbstractCartPosition[]
27
     * TODO make local AbstractCartPosition
28
     */
29
    protected $_positions = [];
30
31
    /**
32
     * The cart module.
33
     */
34
    public $module;
35
36
    /**
37
     * @return integer
38
     */
39 1
    public function getCount(): int
40
    {
41 1
        $count = 0;
42
        foreach ($this->_positions as $position) {
43
            if (!$position->hasParent()) {
44 1
                $count += 1;
45
            }
46 1
        }
47 1
48 1
        return $count;
49
    }
50
51 1
    public function findRelatedFor(CartPositionInterface $parent): ?CartPositionInterface
52
    {
53
        foreach ($this->_positions as $position) {
54 2
            if ($position->hasParent() && $position->parent_id === $parent->getCalculationModel()->calculation_id) {
0 ignored issues
show
Bug introduced by
The method getCalculationModel() does not seem to exist on object<hiqdev\yii2\cart\CartPositionInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
55
                return $position;
56 2
            }
57
        }
58
59 2
        return null;
60
    }
61 2
62
    public function getQuantity()
63
    {
64 1
        $count = 0;
65
        foreach ($this->_positions as $position) {
66 1
            $count += $position->getQuantity();
67
        }
68
69 1
        return $count;
70
    }
71 1
72
    public function getSubtotal()
73
    {
74
        return $this->getCost(false);
75
    }
76
77
    public function getTotal()
78
    {
79
        return $this->getCost(true);
80
    }
81
82
    public function getDiscount()
83
    {
84
        return $this->getTotal() - $this->getSubtotal();
85
    }
86
87
    public function formatCurrency($sum, $currency = null)
88
    {
89
        return $sum !== null ? Yii::$app->formatter->format($sum, ['currency', $currency ?? $this->getCurrency()]) : '--';
90
    }
91
92
    /**
93
     * Sets cart from serialized string
94
     * @param string $serialized
95
     */
96
    public function setSerialized($serialized)
97
    {
98
        try {
99
            parent::setSerialized($serialized);
100
        } catch (\Exception $e) {
101
            Yii::error('Failed to unserlialize cart: ' . $e->getMessage(), __METHOD__);
102
            $this->_positions = [];
103
            $this->saveToSession();
104
        }
105
    }
106
107
    /**
108
     * Checks whether any of cart positions has error in `id` attribute.
109
     * @return boolean
110
     */
111
    public function hasErrors()
112
    {
113
        foreach ($this->_positions as $position) {
114
            if ($position->hasErrors('id')) {
115
                return true;
116
            }
117
        }
118
119
        return false;
120
    }
121
122
    /**
123
     * @param CartPositionInterface[] $positions
124
     */
125
    public function putPositions($positions)
126
    {
127
        foreach ($positions as $position) {
128
            if (isset($this->_positions[$position->getId()])) {
129
                if ($position instanceof DontIncrementQuantityWhenAlreadyInCart) {
130
                    continue;
131
                }
132
                $existingPosition = $this->_positions[$position->getId()];
133
                $existingPosition->setQuantity($existingPosition->getQuantity() + 1);
134
            } else {
135
                if ($position->getQuantity() <= 0) {
136
                    $position->setQuantity(1);
137
                }
138
                $this->_positions[$position->getId()] = $position;
139
            }
140
        }
141
142
        $this->trigger(self::EVENT_CART_CHANGE, new CartActionEvent([
143
            'action' => CartActionEvent::ACTION_POSITION_PUT,
144
        ]));
145
        if ($this->storeInSession)
146
            $this->saveToSession();
147
    }
148
149
    public function getCurrency(): ?string
150
    {
151
        if (!empty($this->_positions)) {
152
            return reset($this->_positions)->currency;
153
        }
154
155
        return Yii::$app->params['currency'];
156
    }
157
158
    /**
159
     * @return array
160
     */
161
    public function getAdditionalLinks(): array
162
    {
163
        $links = [];
164
        $positions = $this->_positions;
165
        if (empty($positions)) {
166
            return $links;
167
        }
168
169
        foreach ($positions as $position) {
170
            $additionalLinks = $position->getAdditionalLinks();
171
            if (!empty($additionalLinks)) {
172
                foreach ($additionalLinks as $link) {
173
                    [$url, $label] = $link;
0 ignored issues
show
Bug introduced by
The variable $url does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $label does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
174
                    if ($url && $label && !isset($links[$url])) {
175
                        $links[$url] = $label;
176
                    }
177
                }
178
            }
179
        }
180
181
        return $links;
182
    }
183
184
    /**
185
     * @var CartActionEvent[]|null
186
     */
187
    private $_accumulatedEvents;
188
    public function trigger($name, Event $event = null)
189
    {
190
        if (is_array($this->_accumulatedEvents)) {
191
            \Yii::info("Shopping cart accumulates event $name");
192
            $this->_accumulatedEvents[] = [$name, $event];
193
        } else {
194
            parent::trigger($name, $event);
195
        }
196
    }
197
198
    /**
199
     * Runs $closure and accumulates all events occurred during $closure run.
200
     * Events get released immediately after a success $closure run.
201
     *
202
     * The method can be used to prevent useless calculations that happen after
203
     * bunch of similar updates on a cart.
204
     *
205
     * @param \Closure $closure
206
     */
207
    public function accumulateEvents(\Closure $closure): void
208
    {
209
        $this->_accumulatedEvents = [];
210
        try {
211
            $closure();
212
            $events = $this->_accumulatedEvents;
213
            $this->_accumulatedEvents = null;
214
            foreach ($events as [$name, $event]) {
215
                \Yii::info("Releases event $name");
0 ignored issues
show
Bug introduced by
The variable $name does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
216
                $this->trigger($name, $event);
0 ignored issues
show
Bug introduced by
The variable $event does not exist. Did you mean $events?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
217
            }
218
        } finally {
219
            $this->_accumulatedEvents = null;
220
        }
221
    }
222
}
223