CartItem   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 4
dl 0
loc 154
rs 10
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A buyable() 0 4 1
A newCollection() 0 4 1
A getDescriptionAttribute() 0 4 1
A getPriceAttribute() 0 4 1
A getSubtotalAttribute() 0 7 1
A getExtraFeesAttribute() 0 4 1
A getTotalAttribute() 0 7 1
A getIdentifierAttribute() 0 8 2
A setOptionsAttribute() 0 7 1
A validateOptions() 0 12 3
A makeIdentifier() 0 4 1
1
<?php
2
3
namespace Treestoneit\ShoppingCart\Models;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Arr;
7
8
/**
9
 * App\Cart\Models\CartItem.
10
 *
11
 * @property int $id
12
 * @property int $cart_id
13
 * @property int $buyable_id
14
 * @property string $buyable_type
15
 * @property int $quantity
16
 * @property array $options
17
 * @property \Illuminate\Support\Carbon|null $created_at
18
 * @property \Illuminate\Support\Carbon|null $updated_at
19
 * @property-read \Treestoneit\ShoppingCart\Buyable $buyable
20
 * @property-read mixed $description
21
 * @property-read float|int $extra_fees
22
 * @property-read float|null $price
23
 * @property-read float $subtotal
24
 * @property-read float $total
25
 * @property-read string $identifier
26
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem newModelQuery()
27
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem newQuery()
28
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem query()
29
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereBuyableId($value)
30
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereBuyableType($value)
31
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereCartId($value)
32
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereCreatedAt($value)
33
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereId($value)
34
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereQuantity($value)
35
 * @method static \Illuminate\Database\Eloquent\Builder|\Treestoneit\ShoppingCart\Models\CartItem whereUpdatedAt($value)
36
 * @mixin \Eloquent
37
 */
38
class CartItem extends Model
39
{
40
    /**
41
     * The attributes that aren't mass assignable.
42
     *
43
     * @var array
44
     */
45
    protected $guarded = ['id'];
46
47
    /**
48
     * The attributes that should be cast to native types.
49
     *
50
     * @var array
51
     */
52
    protected $casts = ['options' => 'array'];
53
54
    /**
55
     * The unique, option specific identifier for this cart item.
56
     *
57
     * @var string
58
     */
59
    protected $identifier;
60
61
    /**
62
     * The buyable instance.
63
     *
64
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
65
     */
66
    public function buyable()
67
    {
68
        return $this->morphTo('buyable');
69
    }
70
71
    /**
72
     * Create a new collection instance.
73
     *
74
     * @param  array  $models
75
     * @return \Treestoneit\ShoppingCart\Models\CartItemCollection
76
     */
77
    public function newCollection(array $models = [])
78
    {
79
        return new CartItemCollection($models);
80
    }
81
82
    /**
83
     * Get the name of the item.
84
     */
85
    public function getDescriptionAttribute()
86
    {
87
        return $this->buyable->getBuyableDescription();
88
    }
89
90
    /**
91
     * Get the base price of the item.
92
     *
93
     * @return float|null
94
     */
95
    public function getPriceAttribute()
96
    {
97
        return $this->buyable->getBuyablePrice($this->options);
0 ignored issues
show
Unused Code introduced by
The call to Buyable::getBuyablePrice() has too many arguments starting with $this->options.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
98
    }
99
100
    /**
101
     * Get the price * quantity.
102
     *
103
     * @return float
104
     */
105
    public function getSubtotalAttribute()
106
    {
107
        return round(
108
            $this->buyable->getBuyablePrice($this->options) * $this->attributes['quantity'],
0 ignored issues
show
Unused Code introduced by
The call to Buyable::getBuyablePrice() has too many arguments starting with $this->options.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
109
            2
110
        );
111
    }
112
113
    /**
114
     * Get the extra fees for this product.
115
     *
116
     * @return float|int
117
     */
118
    public function getExtraFeesAttribute()
119
    {
120
        return $this->buyable->getExtraFees();
121
    }
122
123
    /**
124
     * Get the total for this item.
125
     *
126
     * @return float
127
     */
128
    public function getTotalAttribute()
129
    {
130
        return round(
131
            $this->getSubtotalAttribute() + $this->getExtraFeesAttribute(),
132
            2
133
        );
134
    }
135
136
    /**
137
     * Get the unique identifier for this cart item.
138
     *
139
     * @return string
140
     */
141
    public function getIdentifierAttribute(): string
142
    {
143
        if (is_null($this->identifier)) {
144
            $this->identifier = $this->makeIdentifier();
145
        }
146
147
        return $this->identifier;
148
    }
149
150
    /**
151
     * Add options to this cart item.
152
     *
153
     * @param  array  $options
154
     */
155
    public function setOptionsAttribute(array $options)
156
    {
157
        $this->attributes['options'] = json_encode(array_merge(
158
            $this->options ?? [],
159
            $this->validateOptions($options)
160
        ));
161
    }
162
163
    /**
164
     * Make sure that only the enumerated option values for this buyable are present in the options array.
165
     *
166
     * @param  array  $options
167
     * @return array
168
     */
169
    protected function validateOptions(array $options): array
170
    {
171
        $defaults = $this->buyable->getOptions();
172
173
        return array_filter($options, function ($value, $key) use ($defaults) {
174
            if (! array_key_exists($key, $defaults)) {
175
                return false;
176
            }
177
178
            return $defaults[$key] == '*' || in_array($value, $defaults[$key]);
179
        }, ARRAY_FILTER_USE_BOTH);
180
    }
181
182
    /**
183
     * Create a unique identifier for this cart item.
184
     *
185
     * @return string
186
     */
187
    protected function makeIdentifier(): string
188
    {
189
        return md5($this->buyable_id.$this->buyable_type.serialize(Arr::sort($this->options)));
190
    }
191
}
192