Completed
Push — master ( 5d6718...fa3814 )
by Luke
02:15
created

CartItem   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 302
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 36
Bugs 3 Features 3
Metric Value
wmc 29
c 36
b 3
f 3
lcom 1
cbo 4
dl 0
loc 302
rs 10

15 Methods

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