These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of EC-CUBE |
||
5 | * |
||
6 | * Copyright(c) LOCKON CO.,LTD. All Rights Reserved. |
||
7 | * |
||
8 | * http://www.lockon.co.jp/ |
||
9 | * |
||
10 | * For the full copyright and license information, please view the LICENSE |
||
11 | * file that was distributed with this source code. |
||
12 | */ |
||
13 | |||
14 | namespace Eccube\Controller; |
||
15 | |||
16 | use Eccube\Entity\BaseInfo; |
||
17 | use Eccube\Entity\ProductClass; |
||
18 | use Eccube\Event\EccubeEvents; |
||
19 | use Eccube\Event\EventArgs; |
||
20 | use Eccube\Repository\BaseInfoRepository; |
||
21 | use Eccube\Repository\ProductClassRepository; |
||
22 | use Eccube\Service\CartService; |
||
23 | use Eccube\Service\PurchaseFlow\PurchaseContext; |
||
24 | use Eccube\Service\PurchaseFlow\PurchaseFlow; |
||
25 | use Eccube\Service\PurchaseFlow\PurchaseFlowResult; |
||
26 | use Eccube\Service\OrderHelper; |
||
27 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; |
||
28 | use Symfony\Component\HttpFoundation\Request; |
||
29 | use Symfony\Component\Routing\Annotation\Route; |
||
30 | |||
31 | class CartController extends AbstractController |
||
32 | { |
||
33 | /** |
||
34 | * @var ProductClassRepository |
||
35 | */ |
||
36 | protected $productClassRepository; |
||
37 | |||
38 | /** |
||
39 | * @var CartService |
||
40 | */ |
||
41 | protected $cartService; |
||
42 | |||
43 | /** |
||
44 | * @var PurchaseFlow |
||
45 | */ |
||
46 | protected $purchaseFlow; |
||
47 | |||
48 | /** |
||
49 | * @var BaseInfo |
||
50 | */ |
||
51 | protected $baseInfo; |
||
52 | |||
53 | /** |
||
54 | * CartController constructor. |
||
55 | * |
||
56 | * @param ProductClassRepository $productClassRepository |
||
57 | * @param CartService $cartService |
||
58 | * @param PurchaseFlow $cartPurchaseFlow |
||
59 | * @param BaseInfoRepository $baseInfoRepository |
||
60 | */ |
||
61 | View Code Duplication | public function __construct( |
|
0 ignored issues
–
show
|
|||
62 | 77 | ProductClassRepository $productClassRepository, |
|
63 | CartService $cartService, |
||
64 | PurchaseFlow $cartPurchaseFlow, |
||
65 | BaseInfoRepository $baseInfoRepository |
||
66 | ) { |
||
67 | $this->productClassRepository = $productClassRepository; |
||
68 | 77 | $this->cartService = $cartService; |
|
69 | 77 | $this->purchaseFlow = $cartPurchaseFlow; |
|
70 | 77 | $this->baseInfo = $baseInfoRepository->get(); |
|
71 | 77 | } |
|
72 | |||
73 | /** |
||
74 | * カート画面. |
||
75 | * |
||
76 | * @Route("/cart", name="cart") |
||
77 | * @Template("Cart/index.twig") |
||
78 | */ |
||
79 | public function index(Request $request) |
||
80 | 36 | { |
|
81 | // カートを取得して明細の正規化を実行 |
||
82 | $Carts = $this->cartService->getCarts(); |
||
83 | 36 | $this->execPurchaseFlow($Carts); |
|
84 | 36 | ||
85 | // TODO itemHolderから取得できるように |
||
86 | $least = []; |
||
87 | 36 | $quantity = []; |
|
88 | 36 | $isDeliveryFree = []; |
|
89 | 36 | $totalPrice = 0; |
|
90 | 36 | $totalQuantity = 0; |
|
91 | 36 | ||
92 | foreach ($Carts as $Cart) { |
||
93 | 36 | $quantity[$Cart->getCartKey()] = 0; |
|
94 | 35 | $isDeliveryFree[$Cart->getCartKey()] = false; |
|
95 | 35 | ||
96 | if ($this->baseInfo->getDeliveryFreeQuantity()) { |
||
97 | 35 | if ($this->baseInfo->getDeliveryFreeQuantity() > $Cart->getQuantity()) { |
|
98 | $quantity[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeQuantity() - $Cart->getQuantity(); |
||
99 | } else { |
||
100 | $isDeliveryFree[$Cart->getCartKey()] = true; |
||
101 | } |
||
102 | } |
||
103 | |||
104 | if ($this->baseInfo->getDeliveryFreeAmount()) { |
||
105 | 35 | if (!$isDeliveryFree[$Cart->getCartKey()] && $this->baseInfo->getDeliveryFreeAmount() <= $Cart->getTotalPrice()) { |
|
106 | $isDeliveryFree[$Cart->getCartKey()] = true; |
||
107 | } else { |
||
108 | $least[$Cart->getCartKey()] = $this->baseInfo->getDeliveryFreeAmount() - $Cart->getTotalPrice(); |
||
109 | } |
||
110 | } |
||
111 | |||
112 | $totalPrice += $Cart->getTotalPrice(); |
||
113 | 35 | $totalQuantity += $Cart->getQuantity(); |
|
114 | 35 | } |
|
115 | |||
116 | // カートが分割された時のセッション情報を削除 |
||
117 | $request->getSession()->remove(OrderHelper::SESSION_CART_DIVIDE_FLAG); |
||
118 | 36 | ||
119 | return [ |
||
120 | 'totalPrice' => $totalPrice, |
||
121 | 36 | 'totalQuantity' => $totalQuantity, |
|
122 | 36 | // 空のカートを削除し取得し直す |
|
123 | 36 | 'Carts' => $this->cartService->getCarts(true), |
|
124 | 36 | 'least' => $least, |
|
125 | 36 | 'quantity' => $quantity, |
|
126 | 36 | 'is_delivery_free' => $isDeliveryFree, |
|
127 | ]; |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * @param $Carts |
||
132 | * |
||
133 | * @return \Symfony\Component\HttpFoundation\RedirectResponse |
||
134 | */ |
||
135 | protected function execPurchaseFlow($Carts) |
||
136 | { |
||
137 | /** @var PurchaseFlowResult[] $flowResults */ |
||
138 | 77 | $flowResults = array_map(function ($Cart) { |
|
139 | 75 | $purchaseContext = new PurchaseContext($Cart, $this->getUser()); |
|
140 | |||
141 | 75 | return $this->purchaseFlow->validate($Cart, $purchaseContext); |
|
142 | 77 | }, $Carts); |
|
143 | |||
144 | // 復旧不可のエラーが発生した場合はカートをクリアして再描画 |
||
145 | 77 | $hasError = false; |
|
146 | 77 | foreach ($flowResults as $result) { |
|
147 | 75 | if ($result->hasError()) { |
|
148 | 1 | $hasError = true; |
|
149 | 1 | foreach ($result->getErrors() as $error) { |
|
150 | 75 | $this->addRequestError($error->getMessage()); |
|
151 | } |
||
152 | } |
||
153 | } |
||
154 | 77 | if ($hasError) { |
|
155 | 1 | $this->cartService->clear(); |
|
156 | |||
157 | 1 | return $this->redirectToRoute('cart'); |
|
158 | } |
||
159 | |||
160 | 76 | $this->cartService->save(); |
|
161 | |||
162 | 76 | foreach ($flowResults as $index => $result) { |
|
163 | 74 | foreach ($result->getWarning() as $warning) { |
|
164 | 74 | if ($Carts[$index]->getItems()->count() > 0) { |
|
165 | $cart_key = $Carts[$index]->getCartKey(); |
||
166 | $this->addRequestError($warning->getMessage(), "front.cart.${cart_key}"); |
||
167 | } else { |
||
168 | // キーが存在しない場合はグローバルにエラーを表示する |
||
169 | $this->addRequestError($warning->getMessage()); |
||
170 | } |
||
171 | } |
||
172 | } |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * カート明細の加算/減算/削除を行う. |
||
177 | * |
||
178 | * - 加算 |
||
179 | * - 明細の個数を1増やす |
||
180 | * - 減算 |
||
181 | * - 明細の個数を1減らす |
||
182 | * - 個数が0になる場合は、明細を削除する |
||
183 | * - 削除 |
||
184 | * - 明細を削除する |
||
185 | * |
||
186 | * @Route( |
||
187 | * path="/cart/{operation}/{productClassId}", |
||
188 | * name="cart_handle_item", |
||
189 | * methods={"PUT"}, |
||
190 | * requirements={ |
||
191 | * "operation": "up|down|remove", |
||
192 | 51 | * "productClassId": "\d+" |
|
193 | * } |
||
194 | 51 | * ) |
|
195 | */ |
||
196 | public function handleCartItem($operation, $productClassId) |
||
197 | 51 | { |
|
198 | log_info('カート明細操作開始', ['operation' => $operation, 'product_class_id' => $productClassId]); |
||
199 | 51 | ||
200 | $this->isTokenValid(); |
||
201 | |||
202 | /** @var ProductClass $ProductClass */ |
||
203 | $ProductClass = $this->productClassRepository->find($productClassId); |
||
204 | |||
205 | if (is_null($ProductClass)) { |
||
206 | 51 | log_info('商品が存在しないため、カート画面へredirect', ['operation' => $operation, 'product_class_id' => $productClassId]); |
|
207 | |||
208 | 44 | return $this->redirectToRoute('cart'); |
|
209 | 44 | } |
|
210 | |||
211 | 6 | // 明細の増減・削除 |
|
212 | 6 | switch ($operation) { |
|
213 | case 'up': |
||
214 | 1 | $this->cartService->addProduct($ProductClass, 1); |
|
215 | 1 | break; |
|
216 | case 'down': |
||
217 | $this->cartService->addProduct($ProductClass, -1); |
||
218 | break; |
||
219 | 51 | case 'remove': |
|
220 | 51 | $this->cartService->removeProduct($ProductClass); |
|
221 | break; |
||
222 | 51 | } |
|
223 | |||
224 | 51 | // カートを取得して明細の正規化を実行 |
|
225 | $Carts = $this->cartService->getCarts(); |
||
226 | $this->execPurchaseFlow($Carts); |
||
227 | |||
228 | log_info('カート演算処理終了', ['operation' => $operation, 'product_class_id' => $productClassId]); |
||
229 | |||
230 | return $this->redirectToRoute('cart'); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | 53 | * カートをロック状態に設定し、購入確認画面へ遷移する. |
|
235 | 53 | * |
|
236 | * @Route("/cart/buystep/{cart_key}", name="cart_buystep", requirements={"cart_key" = "[a-zA-Z0-9]+[_][\x20-\x7E]+"}) |
||
237 | */ |
||
238 | public function buystep(Request $request, $cart_key) |
||
239 | 53 | { |
|
240 | 53 | $Carts = $this->cartService->getCart(); |
|
241 | 53 | if (!is_object($Carts)) { |
|
242 | return $this->redirectToRoute('cart'); |
||
243 | 53 | } |
|
244 | // FRONT_CART_BUYSTEP_INITIALIZE |
||
245 | 53 | $event = new EventArgs( |
|
246 | 53 | [], |
|
247 | $request |
||
248 | ); |
||
249 | 53 | $this->eventDispatcher->dispatch(EccubeEvents::FRONT_CART_BUYSTEP_INITIALIZE, $event); |
|
250 | 53 | ||
251 | 53 | $this->cartService->setPrimary($cart_key); |
|
252 | $this->cartService->save(); |
||
253 | 53 | ||
254 | // FRONT_CART_BUYSTEP_COMPLETE |
||
255 | 53 | $event = new EventArgs( |
|
256 | [], |
||
257 | $request |
||
258 | ); |
||
259 | 53 | $this->eventDispatcher->dispatch(EccubeEvents::FRONT_CART_BUYSTEP_COMPLETE, $event); |
|
260 | |||
261 | if ($event->hasResponse()) { |
||
262 | return $event->getResponse(); |
||
263 | } |
||
264 | |||
265 | return $this->redirectToRoute('shopping'); |
||
266 | } |
||
267 | } |
||
268 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.