Passed
Push — master ( 9c20ed...a7d58a )
by Carsten
07:10
created

Item::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 9.9332
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 3
1
<?php
2
3
/**
4
 * This file is part of Lenius Basket, a PHP package to handle
5
 * your shopping basket.
6
 *
7
 * Copyright (c) 2017 Lenius.
8
 * https://github.com/lenius/basket
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 *
13
 * @author Carsten Jonstrup<[email protected]>
14
 * @copyright 2017 Lenius.
15
 *
16
 * @version production
17
 *
18
 * @see https://github.com/lenius/basket
19
 */
20
21
namespace Lenius\Basket;
22
23
/**
24
 * Class Item.
25
 *
26
 * @property string $identifier
27
 * @property float  $price
28
 * @property int    $quantity
29
 * @property float  $weight
30
 */
31
class Item implements ItemInterface
32
{
33
    /** @var string */
34
    protected string $identifier;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
35
36
    /** @var Tax */
37
    protected Tax $tax;
38
39
    /** @var array */
40
    protected array $data = [];
41
42
    /**
43
     * Construct the item.
44
     * @param array $item
45
     */
46 25
    public function __construct(array $item)
47
    {
48 25
        foreach ($item as $key => $value) {
49 25
            $this->data[$key] = $value;
50
        }
51
52 25
        $item['tax'] = isset($item['tax']) ? $item['tax'] : 0;
53
54 25
        $this->tax = new Tax($item['tax']);
55 25
    }
56
57
    /**
58
     * Set identifier.
59
     *
60
     * @param string $identifier
61
     */
62 18
    public function setIdentifier(string $identifier)
63
    {
64 18
        $this->identifier = $identifier;
65 18
    }
66
67
    /**
68
     * Return the value of protected methods.
69
     *
70
     * @param string $param
71
     *
72
     * @return mixed
73
     */
74 23
    public function __get(string $param)
75
    {
76 23
        return 'identifier' === $param ? $this->identifier : $this->data[$param];
77
    }
78
79
    /**
80
     * Update data array using set magic method.
81
     *
82
     * @param mixed $param The key to set
83
     * @param mixed $value The value to set $param to
84
     */
85 19
    public function __set($param, $value)
86
    {
87 19
        $this->data[$param] = $value;
88
89 19
        if ('tax' == $param) {
90 1
            $this->tax = new Tax($value);
91
        }
92 19
    }
93
94
    /**
95
     * Return the total tax for this item.
96
     *
97
     * @return float
98
     */
99 3
    public function tax(): float
100
    {
101 3
        $price = $this->totalPrice();
102 3
        $quantity = $this->quantity;
103
104 3
        return (float) $this->tax->rate($price * $quantity);
105
    }
106
107
    /**
108
     * Return the total price for this item.
109
     *
110
     * @return float
111
     */
112 11
    private function totalPrice(): float
113
    {
114 11
        $price = $this->price;
115
116 11
        if ($this->hasOptions()) {
117 3
            foreach ($this->data['options'] as $item) {
118 3
                if (array_key_exists('price', $item)) {
119 3
                    $price += $item['price'];
120
                }
121
            }
122
        }
123
124 11
        return (float) $price;
125
    }
126
127
    /**
128
     * Return the total of the item, with or without tax.
129
     *
130
     * @param bool $includeTax Whether or not to include tax
131
     *
132
     * @return float The total, as a float
133
     */
134 7
    public function total($includeTax = true): float
135
    {
136 7
        $price = $this->totalPrice();
137
138 7
        if ($includeTax) {
139 7
            $price = $this->tax->add($price);
140
        }
141
142 7
        return (float) ($price * $this->quantity);
143
    }
144
145
    /**
146
     * Return the total weight of the item.
147
     *
148
     * @return float The weight, as a float
149
     */
150 4
    public function weight(): float
151
    {
152 4
        $weight = $this->weight;
153
154 4
        if ($this->hasOptions()) {
155 3
            foreach ($this->data['options'] as $item) {
156 3
                if (array_key_exists('weight', $item)) {
157 2
                    $weight += $item['weight'];
158
                }
159
            }
160
        }
161
162 4
        return (float) ($weight * $this->quantity);
163
    }
164
165
    /**
166
     * Return the total of the item, with or without tax.
167
     *
168
     * @param bool $includeTax Whether or not to include tax
169
     *
170
     * @return float The total, as a float
171
     */
172 1
    public function single($includeTax = true): float
173
    {
174 1
        $price = $this->totalPrice();
175
176 1
        if ($includeTax) {
177 1
            $price = $this->tax->add($price);
178
        }
179
180 1
        return (float) $price;
181
    }
182
183
    /**
184
     * Update a single key for this item, or multiple.
185
     *
186
     * @param mixed $key   The array key to update, or an array of key-value pairs to update
187
     * @param mixed $value
188
     */
189 4
    public function update($key, $value = null)
190
    {
191 4
        if ($key instanceof ItemInterface) {
192 1
            foreach ($key->toArray() as $updateKey => $updateValue) {
193 1
                $this->update($updateKey, $updateValue);
194
            }
195
        } else {
196 4
            if ('tax' == $key && is_numeric($value)) {
197 2
                $this->tax = new Tax((float)$value);
198
            } else {
199
                // update the item
200 2
                $this->data[$key] = $value;
201
            }
202
        }
203 4
    }
204
205
    /**
206
     * Check if this item has options.
207
     *
208
     * @return bool Yes or no?
209
     */
210 17
    public function hasOptions(): bool
211
    {
212 17
        return array_key_exists('options', $this->data) && ! empty($this->data['options']);
213
    }
214
215
    /**
216
     * Convert the item into an array.
217
     *
218
     * @return array The item data
219
     */
220 18
    public function toArray(): array
221
    {
222 18
        return $this->data;
223
    }
224
}
225