CartItem   A
last analyzed

Complexity

Total Complexity 30

Size/Duplication

Total Lines 307
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 37
Bugs 4 Features 3
Metric Value
wmc 30
c 37
b 4
f 3
lcom 1
cbo 4
dl 0
loc 307
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A find() 0 10 3
A removeSubItem() 0 6 1
A price() 0 8 1
A subTotal() 0 10 2
A setModel() 0 9 2
A __construct() 0 16 2
B generateHash() 0 25 4
A getHash() 0 4 1
A findSubItem() 0 4 1
A addSubItem() 0 14 2
A subItemsTotal() 0 10 2
A getDiscount() 0 15 2
A tax() 0 9 2
A getModel() 0 10 2
A searchForSubItem() 0 12 3
1
<?php
2
3
namespace LukePOLO\LaraCart;
4
5
use LukePOLO\LaraCart\Exceptions\ModelNotFound;
6
use LukePOLO\LaraCart\Traits\CartOptionsMagicMethodsTrait;
7
8
/**
9
 * Class CartItem.
10
 *
11
 * @property int id
12
 * @property int qty
13
 * @property float tax
14
 * @property float price
15
 * @property string name
16
 * @property array options
17
 * @property bool taxable
18
 */
19
class CartItem
20
{
21
    const ITEM_ID = 'id';
22
    const ITEM_QTY = 'qty';
23
    const ITEM_TAX = 'tax';
24
    const ITEM_NAME = 'name';
25
    const ITEM_PRICE = 'price';
26
    const ITEM_TAXABLE = 'taxable';
27
    const ITEM_OPTIONS = 'options';
28
29
    use CartOptionsMagicMethodsTrait;
30
31
    protected $itemHash;
32
    protected $itemModel;
33
    protected $itemModelRelations;
34
35
    public $locale;
36
    public $lineItem;
37
    public $discount = 0;
38
    public $subItems = [];
39
    public $couponInfo = [];
40
    public $internationalFormat;
41
42
    /**
43
     * CartItem constructor.
44
     *
45
     * @param $id
46
     * @param $name
47
     * @param int        $qty
48
     * @param string     $price
49
     * @param array      $options
50
     * @param bool       $taxable
51
     * @param bool|false $lineItem
52
     */
53
    public function __construct($id, $name, $qty, $price, $options = [], $taxable = true, $lineItem = false)
54
    {
55
        $this->id = $id;
56
        $this->qty = $qty;
57
        $this->name = $name;
58
        $this->taxable = $taxable;
59
        $this->lineItem = $lineItem;
60
        $this->price = floatval($price);
61
        $this->tax = config('laracart.tax');
62
        $this->itemModel = config('laracart.item_model', null);
63
        $this->itemModelRelations = config('laracart.item_model_relations', []);
64
65
        foreach ($options as $option => $value) {
66
            $this->$option = $value;
67
        }
68
    }
69
70
    /**
71
     * Generates a hash based on the cartItem array.
72
     *
73
     * @param bool $force
74
     *
75
     * @return string itemHash
76
     */
77
    public function generateHash($force = false)
78
    {
79
        if ($this->lineItem === false) {
80
            $this->itemHash = null;
81
82
            $cartItemArray = (array) $this;
83
84
            unset($cartItemArray['options']['qty']);
85
86
            ksort($cartItemArray['options']);
87
88
            $this->itemHash = app(LaraCart::HASH, $cartItemArray);
89
        } elseif ($force || empty($this->itemHash) === true) {
90
            $this->itemHash = app(LaraCart::RANHASH);
91
        }
92
93
        app('events')->fire(
94
            'laracart.updateItem', [
95
                'item'    => $this,
96
                'newHash' => $this->itemHash,
97
            ]
98
        );
99
100
        return $this->itemHash;
101
    }
102
103
    /**
104
     * Gets the hash for the item.
105
     *
106
     * @return mixed
107
     */
108
    public function getHash()
109
    {
110
        return $this->itemHash;
111
    }
112
113
    /**
114
     * Search for matching options on the item.
115
     *
116
     * @return mixed
117
     */
118
    public function find($data)
119
    {
120
        foreach ($data as $key => $value) {
121
            if ($this->$key !== $value) {
122
                return false;
123
            }
124
        }
125
126
        return $this;
127
    }
128
129
    /**
130
     * Finds a sub item by its hash.
131
     *
132
     * @param $subItemHash
133
     *
134
     * @return mixed
135
     */
136
    public function findSubItem($subItemHash)
137
    {
138
        return array_get($this->subItems, $subItemHash);
139
    }
140
141
    /**
142
     * Adds an sub item to a item.
143
     *
144
     * @param array $subItem
145
     * @param bool  $autoUpdate
146
     *
147
     * @return CartSubItem
148
     */
149
    public function addSubItem(array $subItem, $autoUpdate = true)
150
    {
151
        $subItem = new CartSubItem($subItem);
152
153
        $this->subItems[$subItem->getHash()] = $subItem;
154
155
        $this->generateHash();
156
157
        if ($autoUpdate) {
158
            app('laracart')->update();
159
        }
160
161
        return $subItem;
162
    }
163
164
    /**
165
     * Removes a sub item from the item.
166
     *
167
     * @param $subItemHash
168
     */
169
    public function removeSubItem($subItemHash)
170
    {
171
        unset($this->subItems[$subItemHash]);
172
173
        $this->generateHash();
174
    }
175
176
    /**
177
     * Gets the price of the item with or without tax, with the proper format.
178
     *
179
     * @param bool $format
180
     * @param bool $taxedItemsOnly
181
     *
182
     * @return string
183
     */
184
    public function price($format = true, $taxedItemsOnly = false)
185
    {
186
        return LaraCart::formatMoney(
187
            $this->price + $this->subItemsTotal(false, $taxedItemsOnly),
188
            $this->locale,
189
            $this->internationalFormat, $format
190
        );
191
    }
192
193
    /**
194
     * Gets the sub total of the item based on the qty with or without tax in the proper format.
195
     *
196
     * @param bool $format
197
     * @param bool $withDiscount
198
     * @param bool $taxedItemsOnly
199
     *
200
     * @return string
201
     */
202
    public function subTotal($format = true, $withDiscount = true, $taxedItemsOnly = false)
203
    {
204
        $total = $this->price(false, $taxedItemsOnly) * $this->qty;
205
206
        if ($withDiscount) {
207
            $total -= $this->getDiscount(false);
208
        }
209
210
        return LaraCart::formatMoney($total, $this->locale, $this->internationalFormat, $format);
211
    }
212
213
    /**
214
     * Gets the totals for the options.
215
     *
216
     * @param bool $format
217
     * @param bool $taxedItemsOnly
218
     *
219
     * @return string
220
     */
221
    public function subItemsTotal($format = true, $taxedItemsOnly = false)
222
    {
223
        $total = 0;
224
225
        foreach ($this->subItems as $subItem) {
226
            $total += $subItem->price(false, $taxedItemsOnly);
227
        }
228
229
        return LaraCart::formatMoney($total, $this->locale, $this->internationalFormat, $format);
230
    }
231
232
    /**
233
     * Gets the discount of an item.
234
     *
235
     * @param bool $format
236
     *
237
     * @return string
238
     */
239
    public function getDiscount($format = true)
240
    {
241
        $amount = 0;
242
243
        if (app('laracart')->findCoupon($this->code)) {
0 ignored issues
show
Documentation introduced by
The property code 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...
244
            $amount = $this->discount;
245
        }
246
247
        return LaraCart::formatMoney(
248
            $amount,
249
            $this->locale,
250
            $this->internationalFormat,
251
            $format
252
        );
253
    }
254
255
    /**
256
     * Gets the tax for the item.
257
     *
258
     * @param int $amountNotTaxable
259
     *
260
     * @return int|mixed
261
     */
262
    public function tax($amountNotTaxable = 0)
263
    {
264
        if (!$this->taxable) {
265
            $amountNotTaxable = $amountNotTaxable + ($this->price * $this->qty);
266
        }
267
268
        return $this->tax * ($this->subTotal(false, config('laracart.discountTaxable', true),
269
                true) - $amountNotTaxable);
270
    }
271
272
    /**
273
     * Sets the related model to the item.
274
     *
275
     * @param $itemModel
276
     * @param array $relations
277
     *
278
     * @throws ModelNotFound
279
     */
280
    public function setModel($itemModel, $relations = [])
281
    {
282
        if (!class_exists($itemModel)) {
283
            throw new ModelNotFound('Could not find relation model');
284
        }
285
286
        $this->itemModel = $itemModel;
287
        $this->itemModelRelations = $relations;
288
    }
289
290
    /**
291
     * Returns a Model.
292
     *
293
     * @throws ModelNotFound
294
     */
295
    public function getModel()
296
    {
297
        $itemModel = (new $this->itemModel())->with($this->itemModelRelations)->find($this->id);
298
299
        if (empty($itemModel)) {
300
            throw new ModelNotFound('Could not find the item model for '.$this->id);
301
        }
302
303
        return $itemModel;
304
    }
305
306
    /**
307
     *  A way to find sub items.
308
     *
309
     * @param $data
310
     *
311
     * @return array
312
     */
313
    public function searchForSubItem($data)
314
    {
315
        $matches = [];
316
317
        foreach ($this->subItems as $subItem) {
318
            if ($subItem->find($data)) {
319
                $matches[] = $subItem;
320
            }
321
        }
322
323
        return $matches;
324
    }
325
}
326