CartComponent::clear()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license.
17
 */
18
19
namespace Cart\Controller\Component;
20
21
use Cake\Controller\Component;
22
use Cake\Controller\ComponentRegistry;
23
use Cart\Exception\BuyableLimitExceededException;
24
25
/**
26
 * @author Rafael Queiroz <[email protected]>
27
 */
28
class CartComponent extends Component
29
{
30
31
    /**
32
     * @var array
33
     */
34
    protected $_defaultConfig = [
35
        'storage' => \Cart\Storage\SessionStorage::class
36
    ];
37
38
    /**
39
     * @var \Cart\Storage\StorageInterface
40
     */
41
    protected $_storage;
42
43
    /**
44
     * @param array $config
45
     */
46
    public function initialize(array $config)
47
    {
48
        parent::initialize($config);
49
        $this->storage(new $this->_config['storage']($this->_registry->getController()->request));
50
    }
51
52
    /**
53
     * @param \Cart\Entity\EntityBuyableAwareInterface $entity
54
     * @param int $quantity
55
     * @return bool
56
     * @throws \Cart\Exception\BuyableLimitExceededException
57
     */
58
    public function add(\Cart\Entity\EntityBuyableAwareInterface $entity, $quantity = 1)
59
    {
60
        $this->_validate($entity, $quantity);
61
        if ($this->_entityExists($entity)) {
62
            return $this->edit($entity, $this->count($entity) + $quantity);
63
        }
64
65
        $this->_ensureBuyable($entity, $quantity);
66
67
        $objects = $this->get();
68
        $objects[] = [
69
            'entity' => $entity,
70
            'quantity' => $quantity,
71
            'total' => $entity->getPrice() * $quantity,
72
        ];
73
74
        $this->storage()->write($objects);
75
        return true;
76
    }
77
78
    /**
79
     * @param \Cart\Entity\EntityBuyableAwareInterface $entity
80
     * @param int $quantity
81
     * @return bool
82
     * @throws \Cart\Exception\BuyableLimitExceededException
83
     */
84
    public function edit(\Cart\Entity\EntityBuyableAwareInterface $entity, $quantity = 1)
85
    {
86
        $this->_validate($entity, $quantity);
87
88
        $objects = $this->get();
89
        foreach ($objects as &$object) {
90
            if ($object['entity'] == $entity) {
91
92
                $this->_ensureBuyable($entity, $quantity);
93
94
                $object['quantity'] = $quantity;
95
                $object['total'] = $entity->getPrice() * $object['quantity'];
96
                $this->storage()->write($objects);
97
98
                return true;
99
            }
100
        }
101
102
        throw new \Exception();
103
    }
104
105
    /**
106
     * @param \Cart\Entity\EntityBuyableAwareInterface $entity
107
     * @return bool
108
     * @throws \Exception
109
     */
110
    public function delete(\Cart\Entity\EntityBuyableAwareInterface $entity)
111
    {
112
        $objects = $this->get();
113
        foreach ($objects as $key => $object) {
114
            if ($object['entity'] == $entity) {
115
                unset ($objects[$key]);
116
                $this->storage()->write($objects);
117
                return true;
118
            }
119
        }
120
121
        throw new \Exception();
122
    }
123
124
    /**
125
     * @param \Cart\Entity\EntityBuyableAwareInterface|null $entity
126
     * @return mixed
127
     * @throws \Exception
128
     */
129
    public function get(\Cart\Entity\EntityBuyableAwareInterface $entity = null)
130
    {
131
        $objects = $this->storage()->read();
132
133
        if ($entity) {
134
            foreach ($objects as $object) {
135
                if ($object['entity'] == $entity) {
136
                    return $object;
137
                }
138
            }
139
140
            throw new \Exception();
141
        }
142
143
        return $objects;
144
    }
145
146
    /**
147
     * @param \Cart\Entity\EntityBuyableAwareInterface|null $entity
148
     * @return mixed
149
     * @throws \Exception
150
     */
151
    public function count(\Cart\Entity\EntityBuyableAwareInterface $entity = null)
152
    {
153
        if ($entity) {
154
            return $this->get($entity)['quantity'];
155
        }
156
157
        return array_reduce($this->get(), function ($count, $object) {
158
            return $count + $object['quantity'];
159
        }, 0);
160
    }
161
162
    /**
163
     * @return void
164
     */
165
    public function clear()
166
    {
167
        $this->storage()->delete();
168
    }
169
170
    /**
171
     * @param \Cart\Entity\EntityBuyableAwareInterface|null $entity
172
     * @return mixed
173
     * @throws \Exception
174
     */
175
    public function total(\Cart\Entity\EntityBuyableAwareInterface $entity = null)
176
    {
177
        if ($entity) {
178
            return $this->get($entity)['total'];
179
        }
180
181
        return array_reduce($this->get(), function ($total, $object) {
182
            return $total + $object['total'];
183
        }, 0);
184
    }
185
186
    /**
187
     * @param \Cart\Storage\StorageInterface $storage
188
     * @return \Cart\Storage\StorageInterface
189
     */
190
    public function storage(\Cart\Storage\StorageInterface $storage = null)
191
    {
192
        if (!$this->_storage instanceof \Cart\Storage\StorageInterface) {
0 ignored issues
show
introduced by
$this->_storage is always a sub-type of Cart\Storage\StorageInterface.
Loading history...
193
            $this->_storage = $storage;
194
        }
195
196
        return $this->_storage;
197
    }
198
199
    /**
200
     * @param $entity
201
     * @param $quantity
202
     * @throws \Exception
203
     */
204
    protected function _validate($entity, $quantity)
205
    {
206
        if (!$entity instanceof \Cart\Entity\EntityBuyableAwareInterface) {
207
            throw new \Exception();
208
        }
209
        if ($quantity < 1) {
210
            throw new \Exception();
211
        }
212
    }
213
214
    /**
215
     * @param \Cart\Entity\EntityBuyableAwareInterface $entity
216
     * @return bool
217
     */
218
    protected function _entityExists(\Cart\Entity\EntityBuyableAwareInterface $entity)
219
    {
220
        try {
221
            $this->get($entity);
222
            return true;
223
        } catch (\Exception $e) {
224
            return false;
225
        }
226
    }
227
228
    /**
229
     * @param \Cart\Entity\EntityBuyableAwareInterface $entity
230
     * @param $quantity
231
     * @return bool
232
     * @throws \Cart\Exception\BuyableLimitExceededException
233
     */
234
    protected function _ensureBuyable(\Cart\Entity\EntityBuyableAwareInterface $entity, $quantity)
235
    {
236
        if ($quantity > $entity->getBuyableLimit()) {
237
            throw  new BuyableLimitExceededException();
238
        }
239
240
        return true;
241
    }
242
}
243