Completed
Push — 4.0 ( 39173f...75b7c7 )
by chihiro
12:37 queued 06:11
created

ShoppingController::confirm()   C

Complexity

Conditions 12
Paths 8

Size

Total Lines 52

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 18.5574

Importance

Changes 0
Metric Value
cc 12
c 0
b 0
f 0
nc 8
nop 1
dl 0
loc 52
ccs 18
cts 28
cp 0.6429
crap 18.5574
rs 6.9666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Annotation\ForwardOnly;
17
use Eccube\Entity\BaseInfo;
18
use Eccube\Entity\Customer;
19
use Eccube\Entity\CustomerAddress;
20
use Eccube\Entity\Master\OrderStatus;
21
use Eccube\Entity\Order;
22
use Eccube\Entity\Shipping;
23
use Eccube\Event\EccubeEvents;
24
use Eccube\Event\EventArgs;
25
use Eccube\Exception\CartException;
26
use Eccube\Exception\ShoppingException;
27
use Eccube\Form\Type\Front\CustomerLoginType;
28
use Eccube\Form\Type\Front\ShoppingShippingType;
29
use Eccube\Form\Type\Shopping\CustomerAddressType;
30
use Eccube\Form\Type\Shopping\OrderType;
31
use Eccube\Repository\BaseInfoRepository;
32
use Eccube\Repository\CustomerAddressRepository;
33
use Eccube\Repository\OrderRepository;
34
use Eccube\Service\CartService;
35
use Eccube\Service\OrderHelper;
36
use Eccube\Service\Payment\PaymentDispatcher;
37
use Eccube\Service\ShoppingService;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
39
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
40
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
41
use Symfony\Component\Form\FormError;
42
use Symfony\Component\Form\FormInterface;
43
use Symfony\Component\HttpFoundation\ParameterBag;
44
use Symfony\Component\HttpFoundation\Request;
45
use Symfony\Component\HttpFoundation\Response;
46
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
47
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
48
49
class ShoppingController extends AbstractShoppingController
50
{
51
    /**
52
     * @var BaseInfo
53
     */
54
    protected $BaseInfo;
55
56
    /**
57
     * @var OrderHelper
58
     */
59
    protected $orderHelper;
60
61
    /**
62
     * @var CartService
63
     */
64
    protected $cartService;
65
66
    /**
67
     * @var ShoppingService
68
     */
69
    protected $shoppingService;
70
71
    /**
72
     * @var CustomerAddressRepository
73
     */
74
    protected $customerAddressRepository;
75
76
    /**
77
     * @var ParameterBag
78
     */
79
    protected $parameterBag;
80
81
    /**
82
     * ShoppingController constructor.
83
     *
84
     * @param BaseInfoRepository $baseInfoRepository
85
     * @param OrderHelper $orderHelper
86
     * @param CartService $cartService
87
     * @param ShoppingService $shoppingService
88
     * @param CustomerAddressRepository $customerAddressRepository
89
     * @param ParameterBag $parameterBag
90
     */
91 59
    public function __construct(
92
        BaseInfoRepository $baseInfoRepository,
93
        OrderHelper $orderHelper,
94
        CartService $cartService,
95
        ShoppingService $shoppingService,
96
        CustomerAddressRepository $customerAddressRepository,
97
        OrderRepository $orderRepository,
98
        ParameterBag $parameterBag
99
    ) {
100 59
        $this->BaseInfo = $baseInfoRepository->get();
101 59
        $this->orderHelper = $orderHelper;
102 59
        $this->cartService = $cartService;
103 59
        $this->shoppingService = $shoppingService;
104 59
        $this->customerAddressRepository = $customerAddressRepository;
105 59
        $this->orderRepository = $orderRepository;
106 59
        $this->parameterBag = $parameterBag;
107
    }
108
109
    /**
110
     * 購入画面表示
111
     *
112
     * @Route("/shopping", name="shopping")
113
     * @Template("Shopping/index.twig")
114
     */
115 51
    public function index(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
116
    {
117
        // カートチェック
118 51
        $response = $this->forwardToRoute('shopping_check_to_cart');
119 51
        if ($response->isRedirection() || $response->getContent()) {
120 1
            return $response;
121
        }
122
123
        // 受注情報を初期化
124 50
        $response = $this->forwardToRoute('shopping_initialize_order');
125 50
        if ($response->isRedirection() || $response->getContent()) {
126
            return $response;
127
        }
128
129
        /** @var Order $Order */
130 50
        $Order = $this->parameterBag->get('Order');
131
132
        // 単価集計
133 50
        $flowResult = $this->validatePurchaseFlow($Order);
134
135
        // 明細が丸められる場合に, カートから注文画面へ遷移できなくなるため, 集計の結果を保存する
136 50
        $this->entityManager->flush();
137
138
        // フォームを生成する
139 50
        $this->forwardToRoute('shopping_create_form');
140
141 50
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
142 10
            return $this->redirectToRoute('cart');
143
        }
144
145 45
        $form = $this->parameterBag->get(OrderType::class);
146
147
        return [
148 45
            'form' => $form->createView(),
149 45
            'Order' => $Order,
150
        ];
151
    }
152
153
    /**
154
     * 購入確認画面から, 他の画面へのリダイレクト.
155
     * 配送業者や支払方法、お問い合わせ情報をDBに保持してから遷移する.
156
     *
157
     * @Route("/shopping/redirect", name="shopping_redirect_to")
158
     * @Template("Shopping/index.twig")
159
     */
160 20
    public function redirectTo(Request $request)
161
    {
162
        // カートチェック
163 20
        $response = $this->forwardToRoute('shopping_check_to_cart');
164 20
        if ($response->isRedirection() || $response->getContent()) {
165
            return $response;
166
        }
167
168
        // 受注の存在チェック
169 20
        $response = $this->forwardToRoute('shopping_exists_order');
170 20
        if ($response->isRedirection() || $response->getContent()) {
171
            return $response;
172
        }
173
174
        // フォームの生成
175 20
        $this->forwardToRoute('shopping_create_form');
176 20
        $form = $this->parameterBag->get(OrderType::class);
177 20
        $form->handleRequest($request);
178
179
        // 各種変更ページへリダイレクトする
180 20
        $response = $this->forwardToRoute('shopping_redirect_to_change');
181 20
        if ($response->isRedirection() || $response->getContent()) {
182 8
            return $response;
183
        }
184 12
        $form = $this->parameterBag->get(OrderType::class);
185 12
        $Order = $this->parameterBag->get('Order');
186
187
        return [
188 12
            'form' => $form->createView(),
189 12
            'Order' => $Order,
190
        ];
191
    }
192
193
    /**
194
     * 購入処理
195
     *
196
     * @Route("/shopping/confirm", name="shopping_confirm")
197
     * @Method("POST")
198
     * @Template("Shopping/confirm.twig")
199
     */
200 5
    public function confirm(Request $request)
201
    {
202
        // カートチェック
203 5
        $response = $this->forwardToRoute('shopping_check_to_cart');
204 5
        if ($response->isRedirection() || $response->getContent()) {
205
            return $response;
206
        }
207
208
        // 受注の存在チェック
209 5
        $response = $this->forwardToRoute('shopping_exists_order');
210 5
        if ($response->isRedirection() || $response->getContent()) {
211
            return $response;
212
        }
213
214
        // フォームの生成
215 5
        $this->forwardToRoute('shopping_create_form');
216 5
        $form = $this->parameterBag->get(OrderType::class);
217 5
        $form->handleRequest($request);
218
219 5
        $form = $this->parameterBag->get(OrderType::class);
220 5
        $Order = $this->parameterBag->get('Order');
221
222 5
        $flowResult = $this->validatePurchaseFlow($Order);
223 5
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
224
            return $this->redirectToRoute('shopping_error');
225
        }
226
227 5
        $paymentMethod = $this->createPaymentMethod($Order, $form);
228
229 5
        $PaymentResult = $paymentMethod->verify();
230
        // エラーの場合は注文入力画面に戻す?
231 5
        if ($PaymentResult instanceof PaymentResult) {
232
            if (!$PaymentResult->isSuccess()) {
233
                $this->entityManager->getConnection()->rollback();
234
235
                $this->addError($PaymentResult->getErrors());
236
            }
237
238
            $response = $PaymentResult->getResponse();
239
            if ($response && ($response->isRedirection() || $response->getContent())) {
240
                $this->entityManager->flush();
241
242
                return $response;
243
            }
244
        }
245 5
        $this->entityManager->flush();
246
247
        return [
248 5
            'form' => $form->createView(),
249 5
            'Order' => $Order,
250
        ];
251
    }
252
253
    /**
254
     * 購入処理
255
     *
256
     * @Route("/shopping/order", name="shopping_order")
257
     * @Method("POST")
258
     * @Template("Shopping/index.twig")
259
     */
260 6
    public function order(Request $request)
261
    {
262
        // カートチェック
263 6
        $response = $this->forwardToRoute('shopping_check_to_cart');
264 6
        if ($response->isRedirection() || $response->getContent()) {
265
            return $response;
266
        }
267
268
        // 受注の存在チェック
269 6
        $response = $this->forwardToRoute('shopping_exists_order');
270 6
        if ($response->isRedirection() || $response->getContent()) {
271
            return $response;
272
        }
273
274
        // form作成
275
        // FIXME イベントハンドラを外から渡したい
276 6
        $this->forwardToRoute('shopping_create_form');
277
278 6
        $form = $this->parameterBag->get(OrderType::class);
279 6
        $Order = $this->parameterBag->get('Order');
280 6
        $usePoint = $Order->getUsePoint();
281
282 6
        $form->handleRequest($request);
283 6
        $Order->setUsePoint($usePoint);
284
285
        // 受注処理
286 6
        $response = $this->forwardToRoute('shopping_complete_order');
287 6
        if ($response->isRedirection() || $response->getContent()) {
288 6
            return $response;
289
        }
290
291
        log_info('購入チェックエラー', [$Order->getId()]);
292
293
        return [
294
            'form' => $form->createView(),
295
            'Order' => $Order,
296
        ];
297
    }
298
299
    /**
300
     * 購入完了画面表示
301
     *
302
     * @Route("/shopping/complete", name="shopping_complete")
303
     * @Template("Shopping/complete.twig")
304
     */
305
    public function complete(Request $request)
306
    {
307
        // 受注IDを取得
308
        $orderId = $this->session->get($this->sessionOrderKey);
309
310
        if (empty($orderId)) {
311
            return $this->redirectToRoute('homepage');
312
        }
313
314
        $Order = $this->orderRepository->find($orderId);
315
316
        $event = new EventArgs(
317
            [
318
                'Order' => $Order,
319
            ],
320
            $request
321
        );
322
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE, $event);
323
324
        if ($event->getResponse() !== null) {
325
            return $event->getResponse();
326
        }
327
328
        // 受注に関連するセッションを削除
329
        $this->session->remove($this->sessionOrderKey);
330
        $this->session->remove($this->sessionKey);
331
        $this->session->remove($this->sessionCustomerAddressKey);
332
333
        log_info('購入処理完了', [$Order->getId()]);
334 1
335
        $hasNextCart = !empty($this->cartService->getCarts());
336
337 1
        return [
338
            'Order' => $Order,
339 1
            'hasNextCart' => $hasNextCart,
340
        ];
341
    }
342
343 1
    /**
344
     * お届け先の設定一覧からの選択
345 1
     *
346
     * @Route("/shopping/shipping/{id}", name="shopping_shipping", requirements={"id" = "\d+"})
347 1
     * @Template("Shopping/shipping.twig")
348
     */
349 1
    public function shipping(Request $request, Shipping $Shipping)
350
    {
351 1
        // カートチェック
352
        $response = $this->forwardToRoute('shopping_check_to_cart');
353 1
        if ($response->isRedirection() || $response->getContent()) {
354
            return $response;
355
        }
356
357
        // 受注の存在チェック
358 1
        $response = $this->forwardToRoute('shopping_exists_order');
359 1
        if ($response->isRedirection() || $response->getContent()) {
360 1
            return $response;
361
        }
362 1
363
        // 受注に紐づくShippingかどうかのチェック.
364 1
        /** @var Order $Order */
365
        $Order = $this->parameterBag->get('Order');
366
        if (!$Order->findShipping($Shipping->getId())) {
367 1
            throw new NotFoundHttpException();
368 1
        }
369
370
        $builder = $this->formFactory->createBuilder(CustomerAddressType::class, null, [
371
            'customer' => $this->getUser(),
372
            'shipping' => $Shipping,
373
        ]);
374
375
        $form = $builder->getForm();
376
        $form->handleRequest($request);
377
378
        if ($form->isSubmitted() && $form->isValid()) {
379
            log_info('お届先情報更新開始', [$Shipping->getId()]);
380
381
            /** @var CustomerAddress $CustomerAddress */
382
            $CustomerAddress = $form['addresses']->getData();
383
384
            // お届け先情報を更新
385
            $Shipping->setFromCustomerAddress($CustomerAddress);
386
387
            // 合計金額の再計算
388
            $flowResult = $this->validatePurchaseFlow($Order);
389
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
390
                return $this->redirectToRoute('shopping_error');
391
            }
392
393
            // 配送先を更新
394
            $this->entityManager->flush();
395
396
            $event = new EventArgs(
397
                [
398
                    'Order' => $Order,
399
                    'Shipping' => $Shipping,
400
                ],
401
                $request
402
            );
403
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_COMPLETE, $event);
404
405
            log_info('お届先情報更新完了', [$Shipping->getId()]);
406
407
            return $this->redirectToRoute('shopping');
408
        }
409
410
        return [
411
            'form' => $form->createView(),
412
            'Customer' => $this->getUser(),
413
            'shippingId' => $Shipping->getId(),
414
        ];
415
    }
416
417
    /**
418
     * お届け先の設定(非会員でも使用する)
419
     *
420
     * @Route("/shopping/shipping_edit/{id}", name="shopping_shipping_edit", requirements={"id" = "\d+"})
421
     * @Template("Shopping/shipping_edit.twig")
422
     */
423
    public function shippingEdit(Request $request, $id)
424
    {
425
        // 配送先住所最大値判定
426
        $Customer = $this->getUser();
427
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
428
            $addressCurrNum = count($this->getUser()->getCustomerAddresses());
429
            $addressMax = $this->eccubeConfig['eccube_deliv_addr_max'];
430
            if ($addressCurrNum >= $addressMax) {
431
                throw new NotFoundHttpException(trans('shoppingcontroller.text.error.number_of_address'));
432
            }
433
        }
434
435
        // カートチェック
436
        $response = $this->forwardToRoute('shopping_check_to_cart');
437
        if ($response->isRedirection() || $response->getContent()) {
438
            return $response;
439
        }
440
441
        // 受注の存在チェック
442
        $response = $this->forwardToRoute('shopping_exists_order');
443
        if ($response->isRedirection() || $response->getContent()) {
444
            return $response;
445
        }
446
447
        /** @var Order $Order */
448
        $Order = $this->parameterBag->get('Order');
449
450
        $Shipping = $Order->findShipping($id);
451
        if (!$Shipping) {
452
            throw new NotFoundHttpException(trans('shoppingcontroller.text.error.set_address'));
453
        }
454
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
455
            $Shipping->clearCustomerAddress();
456
        }
457
458
        $CustomerAddress = new CustomerAddress();
459
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
460
            $CustomerAddress->setCustomer($Customer);
0 ignored issues
show
Bug introduced by
It seems like $Customer defined by $this->getUser() on line 426 can also be of type object; however, Eccube\Entity\CustomerAddress::setCustomer() does only seem to accept null|object<Eccube\Entity\Customer>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
461
        } else {
462
            $CustomerAddress->setFromShipping($Shipping);
463
        }
464
465
        $builder = $this->formFactory->createBuilder(ShoppingShippingType::class, $CustomerAddress);
466
467
        $event = new EventArgs(
468
            [
469
                'builder' => $builder,
470
                'Order' => $Order,
471
                'Shipping' => $Shipping,
472
                'CustomerAddress' => $CustomerAddress,
473
            ],
474
            $request
475
        );
476
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_INITIALIZE, $event);
477
478
        $form = $builder->getForm();
479
480
        $form->handleRequest($request);
481
482
        if ($form->isSubmitted() && $form->isValid()) {
483
            log_info('お届け先追加処理開始', ['id' => $Order->getId(), 'shipping' => $id]);
484
485
            // 会員の場合、お届け先情報を新規登録
486
            $Shipping->setFromCustomerAddress($CustomerAddress);
487
488
            if ($Customer instanceof Customer) {
489
                $this->entityManager->persist($CustomerAddress);
490
                log_info(
491
                    '新規お届け先登録',
492
                    [
493
                        'id' => $Order->getId(),
494
                        'shipping' => $id,
495
                        'customer address' => $CustomerAddress->getId(),
496
                    ]
497
                );
498
            }
499
500
            // 配送料金の設定
501
            $this->shoppingService->setShippingDeliveryFee($Shipping);
502
503
            // 合計金額の再計算
504
            $flowResult = $this->validatePurchaseFlow($Order);
505
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
506
                return $this->redirectToRoute('shopping_error');
507
            }
508
509
            // 配送先を更新
510
            $this->entityManager->flush();
511
512
            $event = new EventArgs(
513
                [
514
                    'form' => $form,
515
                    'Shipping' => $Shipping,
516
                    'CustomerAddress' => $CustomerAddress,
517
                ],
518
                $request
519
            );
520
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_COMPLETE, $event);
521
522
            log_info('お届け先追加処理完了', ['id' => $Order->getId(), 'shipping' => $id]);
523
524
            return $this->redirectToRoute('shopping');
525
        }
526
527
        return [
528
            'form' => $form->createView(),
529
            'shippingId' => $id,
530
        ];
531
    }
532
533
    /**
534
     * ログイン
535
     *
536
     * @Route("/shopping/login", name="shopping_login")
537
     * @Template("Shopping/login.twig")
538
     */
539
    public function login(Request $request, AuthenticationUtils $authenticationUtils)
540
    {
541
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
542
            return $this->redirectToRoute('shopping');
543
        }
544
545
        /* @var $form \Symfony\Component\Form\FormInterface */
546
        $builder = $this->formFactory->createNamedBuilder('', CustomerLoginType::class);
547
548
        if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
549
            $Customer = $this->getUser();
550
            if ($Customer) {
551
                $builder->get('login_email')->setData($Customer->getEmail());
552
            }
553
        }
554
555
        $event = new EventArgs(
556
            [
557
                'builder' => $builder,
558
            ],
559
            $request
560
        );
561
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_LOGIN_INITIALIZE, $event);
562
563
        $form = $builder->getForm();
564
565
        return [
566
            'error' => $authenticationUtils->getLastAuthenticationError(),
567
            'form' => $form->createView(),
568 2
        ];
569
    }
570 2
571
    /**
572
     * 購入エラー画面表示
573
     *
574
     * @Route("/shopping/error", name="shopping_error")
575 2
     * @Template("Shopping/shopping_error.twig")
576
     */
577 2
    public function shoppingError(Request $request)
578
    {
579
        $event = new EventArgs(
580
            [],
581
            $request
582
        );
583
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_ERROR_COMPLETE, $event);
584 2
585
        if ($event->getResponse() !== null) {
586 2
            return $event->getResponse();
587
        }
588 2
589
        return [];
590 2
    }
591
592 2
    /**
593
     * カート画面のチェック
594
     *
595 2
     * @ForwardOnly
596 2
     * @Route("/shopping/check_to_cart", name="shopping_check_to_cart")
597
     */
598
    public function checkToCart(Request $request)
599
    {
600
        $Cart = $this->cartService->getCart();
601
        if ($Cart && count($Cart->getCartItems()) > 0) {
602
            $divide = $request->getSession()->get('cart.divide');
603
            if ($divide) {
604
                log_info('種別が異なる商品がカートと結合されたためカート画面にリダイレクト');
605
606 1
                return $this->redirectToRoute('cart');
607
            }
608 1
609 1
            return new Response();
610 1
        }
611
        log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
612 1
613
        // カートが存在しない時はエラー
614 1
        return $this->redirectToRoute('cart');
615
    }
616
617
    /**
618 1
     * 受注情報を初期化する.
619
     *
620
     * @ForwardOnly
621
     * @Route("/shopping/initialize_order", name="shopping_initialize_order")
622
     */
623
    public function initializeOrder(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
624
    {
625
        // 購入処理中の受注情報を取得
626
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
627 55
628
        // 初回アクセス(受注情報がない)の場合は, 受注情報を作成
629 55
        if (is_null($Order)) {
630 55
            // 未ログインの場合, ログイン画面へリダイレクト.
631 53
            if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
632 53
                // 非会員でも一度会員登録されていればショッピング画面へ遷移
633
                $Customer = $this->shoppingService->getNonMember($this->sessionKey);
634
635
                if (is_null($Customer)) {
636
                    log_info('未ログインのためログイン画面にリダイレクト');
637
638 53
                    return $this->redirectToRoute('shopping_login');
639
                }
640 2
            } else {
641
                $Customer = $this->getUser();
642
            }
643 2
644
            try {
645
                // 受注情報を作成
646
                $Order = $this->orderHelper->createProcessingOrder(
647
                    $Customer,
648
                    $this->cartService->getCart()->getCartItems()
649
                );
650
                $this->cartService->setPreOrderId($Order->getPreOrderId());
651
                $this->cartService->save();
652 50
            } catch (CartException $e) {
653
                log_error('初回受注情報作成エラー', [$e->getMessage()]);
654
                $this->addRequestError($e->getMessage());
655 50
656
                return $this->redirectToRoute('cart');
657
            }
658 50
659
            // セッション情報を削除
660 34
            $this->session->remove($this->sessionOrderKey);
661
        }
662
663
        // 受注関連情報を最新状態に更新
664
        $this->entityManager->refresh($Order);
665
666
        $this->parameterBag->set('Order', $Order);
667
668
        return new Response();
669
    }
670 34
671
    /**
672
     * フォームを作成し, イベントハンドラを設定する
673
     *
674
     * @ForwardOnly
675
     * @Route("/shopping/create_form", name="shopping_create_form")
676 34
     */
677 34
    public function createShoppingForm(Request $request)
678 34
    {
679
        $Order = $this->parameterBag->get('Order');
680 34
        // フォームの生成
681 34
        $builder = $this->formFactory->createBuilder(OrderType::class, $Order);
682
683
        $event = new EventArgs(
684
                [
685
                    'builder' => $builder,
686
                    'Order' => $Order,
687
                ],
688
                $request
689
            );
690 34
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);
691
692
        $form = $builder->getForm();
693
694 50
        $this->parameterBag->set(OrderType::class, $form);
695
696 50
        return new Response();
697
    }
698 50
699
    /**
700
     * mode に応じて各変更ページへリダイレクトする.
701
     *
702
     * @ForwardOnly
703
     * @Route("/shopping/redirect_to_change", name="shopping_redirect_to_change")
704
     */
705
    public function redirectToChange(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
706
    {
707 50
        $form = $this->parameterBag->get(OrderType::class);
708
709 50
        // 支払い方法の変更や配送業者の変更があった場合はDBに保持する.
710
        if ($form->isSubmitted() && $form->isValid()) {
711 50
            // POSTされたデータをDBに保持.
712
            $this->entityManager->flush();
713 50
714
            $mode = $form['mode']->getData();
715 50
            switch ($mode) {
716 50
                case 'shipping_change':
717
                    // お届け先設定一覧へリダイレクト
718 50
                    $param = $form['param']->getData();
719
720 50
                    return $this->redirectToRoute('shopping_shipping', ['id' => $param]);
721
                case 'shipping_edit_change':
722 50
                    // お届け先設定一覧へリダイレクト
723
                    $param = $form['param']->getData();
724 50
725
                    return $this->redirectToRoute('shopping_shipping_edit', ['id' => $param]);
726 50
                case 'shipping_multiple_change':
727
                    // 複数配送設定へリダイレクト
728
                    return $this->redirectToRoute('shopping_shipping_multiple');
729
                case 'payment':
730
                case 'delivery':
731
                default:
732
                    return $this->redirectToRoute('shopping');
733
            }
734
        }
735 20
736
        return new Response();
737 20
    }
738
739
    /**
740
     * 受注の存在チェック
741
     *
742
     * @ForwardOnly
743 20
     * @Route("/shopping/exists_order", name="shopping_exists_order")
744
     */
745 8
    public function existsOrder(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
746
    {
747 8
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
748 8
        if (!$Order) {
749 7
            log_info('購入処理中の受注情報がないため購入エラー');
750
            $this->addError('front.shopping.order.error');
751 1
752
            return $this->redirectToRoute('shopping_error');
753 1
        }
754 7
        $this->parameterBag->set('Order', $Order);
755
756
        return new Response();
757
    }
758
759 7
    /**
760
     * 受注完了処理
761
     *
762 7
     * @ForwardOnly
763 7
     * @Route("/shopping/complete_order", name="shopping_complete_order")
764
     */
765 7
    public function completeOrder(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
766
    {
767
        $form = $this->parameterBag->get(OrderType::class);
768
769 12
        if ($form->isSubmitted() && $form->isValid()) {
770
            /** @var Order $Order */
771
            $Order = $form->getData();
772
            log_info('購入処理開始', [$Order->getId()]);
773
774
            // トランザクション制御
775
            $em = $this->entityManager;
776
            $em->getConnection()->beginTransaction();
777
            try {
778 26
                $flowResult = $this->validatePurchaseFlow($Order);
779
                if ($flowResult->hasWarning() || $flowResult->hasError()) {
780 26
                    // TODO エラーメッセージ
781 26
                    throw new ShoppingException();
782
                }
783
784
                $paymentMethod = $this->createPaymentMethod($Order, $form);
785
786
                // 必要に応じて別のコントローラへ forward or redirect(移譲)
787 26
                $dispatcher = $paymentMethod->apply(); // 決済処理中.
788
                // 一旦、決済処理中になった後は、購入処理中に戻せない。キャンセル or 購入完了の仕様とする
789 26
                // ステータス履歴も保持しておく? 在庫引き当ての仕様もセットで。
790
                if ($dispatcher instanceof PaymentDispatcher) {
791
                    $response = $dispatcher->getResponse();
792
                    $this->entityManager->flush();
793
                    $this->entityManager->commit();
794
795
                    if ($response && ($response->isRedirection() || $response->getContent())) {
796
                        return $response;
797
                    }
798 6
799
                    if ($dispatcher->isForward()) {
800 6
                        return $this->forwardToRoute($dispatcher->getRoute(), $dispatcher->getPathParameters(), $dispatcher->getQueryParameters());
801
                    } else {
802 6
                        return $this->redirectToRoute($dispatcher->getRoute(), array_merge($dispatcher->getPathParameters(), $dispatcher->getQueryParameters()));
803
                    }
804 6
                }
805 6
806
                // 決済実行
807
                $response = $this->forwardToRoute('shopping_do_checkout_order');
808 6
                $this->entityManager->flush();
809 6
                $this->entityManager->commit();
810
811
                if ($response->isRedirection() || $response->getContent()) {
812
                    return $response;
813
                }
814
815 6
                log_info('購入処理完了', [$Order->getId()]);
816 6
            } catch (ShoppingException $e) {
817
                log_error('購入エラー', [$e->getMessage()]);
818
819
                $this->entityManager->getConnection()->rollback();
820
821 6
                $this->log($e);
0 ignored issues
show
Bug introduced by
The method log() does not seem to exist on object<Eccube\Controller\ShoppingController>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
822
                $this->addError($e->getMessage());
823
824 6
                return $this->redirectToRoute('shopping_error');
825
            } catch (\Exception $e) {
826
                log_error('予期しないエラー', [$e->getMessage()]);
827 6
828
                $this->entityManager->getConnection()->rollback();
829
830
                $this->addError('front.shopping.system.error');
831
832
                return $this->redirectToRoute('shopping_error');
833
            }
834
835
            return $this->forwardToRoute('shopping_after_complete');
836
        }
837
838
        return new Response();
839
    }
840
841
    /**
842
     * 決済完了処理
843
     *
844 6
     * @ForwardOnly
845 6
     * @Route("/shopping/do_checkout_order", name="shopping_do_checkout_order")
846 6
     */
847
    public function doCheckoutOrder(Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
848 6
    {
849
        $form = $this->parameterBag->get(OrderType::class);
850
        $Order = $this->parameterBag->get('Order');
851
852 6
        $paymentMethod = $this->createPaymentMethod($Order, $form);
853
854
        // 決済実行
855
        $PaymentResult = $paymentMethod->checkout();
856
        $response = $PaymentResult->getResponse();
857
        if ($response && ($response->isRedirection() || $response->getContent())) {
858
            return $response;
859
        }
860
861
        if (!$PaymentResult->isSuccess()) {
862
            $this->entityManager->getConnection()->rollback();
863
864
            $this->addError($PaymentResult->getErrors());
865
        }
866
867
        return new Response();
868
    }
869
870
    /**
871
     * 受注完了の後処理
872 6
     *
873
     * @ForwardOnly
874
     * @Route("/shopping/after_complete", name="shopping_after_complete")
875
     */
876
    public function afterComplete(Request $request)
877
    {
878
        $form = $this->parameterBag->get(OrderType::class);
879
        $Order = $this->parameterBag->get('Order');
880
881
        // カート削除
882
        $this->cartService->clear();
883
884 6
        $event = new EventArgs(
885
            [
886 6
                'form' => $form,
887 6
                'Order' => $Order,
888
            ],
889 6
            $request
890
        );
891
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING, $event);
892 6
893 6 View Code Duplication
        if ($event->getResponse() !== null) {
894 6
            log_info('イベントレスポンス返却', [$Order->getId()]);
895
896
            return $event->getResponse();
897
        }
898 6
899
        // 受注IDをセッションにセット
900
        $this->session->set($this->sessionOrderKey, $Order->getId());
901
902
        // メール送信
903
        $MailHistory = $this->shoppingService->sendOrderMail($Order);
904 6
905
        $event = new EventArgs(
906
            [
907
                'form' => $form,
908
                'Order' => $Order,
909
                'MailHistory' => $MailHistory,
910
            ],
911
            $request
912
        );
913 6
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_COMPLETE, $event);
914
915 6 View Code Duplication
        if ($event->getResponse() !== null) {
916 6
            log_info('イベントレスポンス返却', [$Order->getId()]);
917
918
            return $event->getResponse();
919 6
        }
920
921 6
        // 完了画面表示
922
        return $this->redirectToRoute('shopping_complete');
923 6
    }
924 6
925
    private function createPaymentMethod(Order $Order, FormInterface $form)
926 6
    {
927
        $PaymentMethod = $this->container->get($Order->getPayment()->getMethodClass());
928 6
        $PaymentMethod->setOrder($Order);
929
        $PaymentMethod->setFormType($form);
930 6
931
        return $PaymentMethod;
932
    }
933
}
934