Failed Conditions
Pull Request — experimental/3.1 (#2641)
by Kiyotaka
105:29 queued 74:48
created

CartService::setPrimary()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
nc 1
nop 1
dl 0
loc 10
ccs 0
cts 0
cp 0
crap 2
rs 9.4285
c 1
b 0
f 0
1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Service;
26
27
use Doctrine\ORM\EntityManager;
28
use Eccube\Annotation\Inject;
29
use Eccube\Annotation\Service;
30
use Eccube\Entity\Cart;
31
use Eccube\Entity\CartItem;
32
use Eccube\Entity\ItemHolderInterface;
33
use Eccube\Entity\ProductClass;
34
use Eccube\Repository\ProductClassRepository;
35
use Eccube\Service\Cart\CartItemAllocator;
36
use Eccube\Service\Cart\CartItemComparator;
37
use Symfony\Component\HttpFoundation\Session\Session;
38
39
/**
40
 * @Service
41
 */
42
class CartService
43
{
44
    /**
45
     * @var Session
46
     * @Inject("session")
47
     */
48
    protected $session;
49
50
    /**
51
     * @var EntityManager
52
     * @Inject("orm.em")
53
     */
54
    protected $em;
55
56
    /**
57
     * @var ItemHolderInterface
58
     * @deprecated
59
     */
60
    protected $cart;
61 86
62
    /**
63 86
     * @var ProductClassRepository
64 86
     * @Inject(ProductClassRepository::class)
65 86
     */
66
    protected $productClassRepository;
67
68 86
    /**
69
     * @var CartItemComparator
70
     * @Inject(CartItemComparator::class)
71 86
     */
72
    protected $cartItemComparator;
73
74 86
    /**
75
     * @var CartItemAllocator
76
     * @Inject(CartItemAllocator::class)
77
     */
78
    protected $cartItemAllocator;
79
80
    /**
81
     * @var Cart[]
82 34
     */
83
    protected $carts;
84 34
85 19
    public function getCarts()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
86 19
    {
87 19
        if (is_null($this->carts)) {
88 19
            $this->carts = $this->session->get('carts', []);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->session->get('carts', array()) of type * is incompatible with the declared type array<integer,object<Eccube\Entity\Cart>> of property $carts.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
89 19
            $this->loadItems();
90
        }
91
        return $this->carts;
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
92
    }
93 34
94 34
    /**
95
     * @return ItemHolderInterface|Cart
96
     */
97 34
    public function getCart()
98 34
    {
99
        $Carts = $this->getCarts();
100
        if (!$Carts) {
101
            if (!$this->cart) {
0 ignored issues
show
Deprecated Code introduced by
The property Eccube\Service\CartService::$cart has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
102 34
                $this->cart = new Cart();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Eccube\Entity\Cart() of type object<Eccube\Entity\Cart> is incompatible with the declared type object<Eccube\Entity\ItemHolderInterface> of property $cart.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Deprecated Code introduced by
The property Eccube\Service\CartService::$cart has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
103 34
            }
104
            return $this->cart;
0 ignored issues
show
Deprecated Code introduced by
The property Eccube\Service\CartService::$cart has been deprecated.

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
introduced by
Missing blank line before return statement
Loading history...
105 34
        }
106 3
        return current($this->getCarts());
0 ignored issues
show
introduced by
Missing blank line before return statement
Loading history...
107
    }
108 34
109 34
    protected function loadItems()
110 34
    {
111 34
        foreach ($this->getCarts() as $Cart) {
112 34
            /** @var CartItem $item */
113 34
            foreach ($Cart->getItems() as $item) {
114 34
                /** @var ProductClass $ProductClass */
115
                $ProductClass = $this->productClassRepository->find($item->getProductClassId());
116
                $item->setProductClass($ProductClass);
117 34
            }
118
        }
119
    }
120 2
121
    /**
122 2
     * @param CartItem[] $cartItems
123 1
     * @return CartItem[]
124 1
     */
125 1
    protected function mergeAllCartItems($cartItems = [])
126 1
    {
127 1
        /** @var CartItem[] $allCartItems */
128
        $allCartItems = $cartItems;
129
130
        foreach ($this->getCarts() as $Cart) {
131
            /** @var CartItem $item */
132
            foreach ($Cart->getItems() as $item) {
133 2
                $itemExists = false;
134 2
                foreach ($allCartItems as $itemInArray) {
135
                    // 同じ明細があればマージする
136 2
                    if ($this->cartItemComparator->compare($item, $itemInArray)) {
137
                        $itemInArray->setQuantity($itemInArray->getQuantity() + $item->getQuantity());
138
                        $itemExists = true;
139 31
                        break;
140
                    }
141 31
                }
142
                if (!$itemExists) {
143
                    $allCartItems[] = $item;
144 3
                }
145
            }
146 3
        }
147 3
148 3
        return $allCartItems;
149
    }
150
151 15
    protected function restoreCarts($cartItems)
152
    {
153 15
        /** @var Cart $Carts */
154 15
        $Carts = [];
155 15
156
        foreach ($cartItems as $item) {
157
            $cartId = $this->cartItemAllocator->allocate($item);
158
            if (isset($Carts[$cartId])) {
159
                $Carts[$cartId]->addCartItem($item);
160
            } else {
161 22
                $Cart = new Cart();
162
                $Cart->addCartItem($item);
163 22
                $Carts[$cartId] = $Cart;
164
            }
165
        }
166
167
        $this->session->set('carts', $Carts);
168
        // 配列のkeyを0からにする
169
        $this->carts = array_values($Carts);
170 12
    }
171
172 12
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$ProductClass" missing
Loading history...
introduced by
Doc comment for parameter "$quantity" missing
Loading history...
173
     * カートに商品を追加します.
174 12
     * @param $ProductClass ProductClass 商品規格
0 ignored issues
show
introduced by
Missing parameter name
Loading history...
175
     * @param $quantity int 数量
0 ignored issues
show
introduced by
Missing parameter name
Loading history...
176
     * @return bool 商品を追加できた場合はtrue
177
     */
178
    public function addProduct($ProductClass, $quantity = 1)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
179
    {
180 12 View Code Duplication
        if (!$ProductClass instanceof ProductClass) {
181
            $ProductClassId = $ProductClass;
182 12
            $ProductClass = $this->em
183
                ->getRepository(ProductClass::class)
184
                ->find($ProductClassId);
185
            if (is_null($ProductClass)) {
186
                return false;
187
            }
188 22
        }
189
190 22
        $ClassCategory1 = $ProductClass->getClassCategory1();
191 22
        if ($ClassCategory1 && !$ClassCategory1->isVisible()) {
192 22
            return false;
193 22
        }
194
        $ClassCategory2 = $ProductClass->getClassCategory2();
195 22
        if ($ClassCategory2 && !$ClassCategory2->isVisible()) {
196
            return false;
197
        }
198
199
        $newItem = new CartItem();
200
        $newItem->setQuantity($quantity);
201
        $newItem->setPrice($ProductClass->getPrice01IncTax());
202
        $newItem->setProductClass($ProductClass);
203
204
        $allCartItems = $this->mergeAllCartItems([$newItem]);
205
        $this->restoreCarts($allCartItems);
206
207
208
        return true;
209
    }
210
211
    public function removeProduct($ProductClass)
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
212
    {
213 View Code Duplication
        if (!$ProductClass instanceof ProductClass) {
214
            $ProductClassId = $ProductClass;
215
            $ProductClass = $this->em
216
                ->getRepository(ProductClass::class)
217
                ->find($ProductClassId);
218
            if (is_null($ProductClass)) {
219
                return false;
220
            }
221
        }
222
223
        $removeItem = new CartItem();
224
        $removeItem->setPrice($ProductClass->getPrice01IncTax());
225
        $removeItem->setProductClass($ProductClass);
226
227
        $allCartItems = $this->mergeAllCartItems();
228
        $foundIndex = -1;
229
        foreach ($allCartItems as $index=>$itemInCart) {
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "=>"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space after "=>"; 0 found
Loading history...
230
            if ($this->cartItemComparator->compare($itemInCart, $removeItem)) {
231
                $foundIndex = $index;
232
                break;
233
            }
234
        }
235
        array_splice($allCartItems, $foundIndex, 1);
236
        $this->restoreCarts($allCartItems);
237
238
        return true;
239
    }
240
241
    public function save()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
242
    {
243
        return $this->session->set('carts', $this->carts);
244
    }
245
246
    public function unlock()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
247
    {
248
        $this->getCart()
249
            ->setLock(false)
250
            ->setPreOrderId(null);
251
    }
252
253
    public function lock()
0 ignored issues
show
introduced by
Missing function doc comment
Loading history...
254
    {
255
        $this->getCart()
256
            ->setLock(true)
257
            ->setPreOrderId(null);
258
    }
259
260
    /**
261
     * @return bool
262
     */
263
    public function isLocked()
264
    {
265
        return $this->getCart()->getLock();
266
    }
267
268
    /**
269
     * @param  string $pre_order_id
270
     * @return \Eccube\Service\CartService
271
     */
272
    public function setPreOrderId($pre_order_id)
273
    {
274
        $this->getCart()->setPreOrderId($pre_order_id);
275
276
        return $this;
277
    }
278
279
    /**
280
     * @return string
281
     */
282
    public function getPreOrderId()
283
    {
284
        return $this->getCart()->getPreOrderId();
285
    }
286
287
    /**
288
     * @return \Eccube\Service\CartService
289
     */
290
    public function clear()
291
    {
292
        $Carts = $this->getCarts();
293
        $removed = array_splice($Carts, 0, 1);
294
        if (!empty($removed)) {
295
            $removedCart = $removed[0];
296
            $removedCart->setPreOrderId(null)
297
                ->setLock(false)
298
                ->setTotalPrice(0)
299
                ->clearCartItems();
300
        }
301
        $this->carts = $Carts;
302
303
        return $this;
304
    }
305
306
    /**
307
     * @param CartItemComparator $cartItemComparator
308
     */
309
    public function setCartItemComparator($cartItemComparator)
310
    {
311
        $this->cartItemComparator = $cartItemComparator;
312
    }
313
314
    /**
315
     * 指定したインデックスにあるカートを優先にする
316
     * @param int $index カートのインデックス
317
     */
318
    public function setPrimary($index = 0)
319
    {
320
        $Carts = $this->getCarts();
321
        $primary = $Carts[$index];
322
        $prev = $Carts[0];
323
        array_splice($Carts, 0, 1, [$primary]);
324
        array_splice($Carts, $index, 1, [$prev]);
325
        $this->carts = $Carts;
326
        $this->save();
327
    }
328
}
329