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

ShoppingController::shippingEdit()   D

Complexity

Conditions 15
Paths 47

Size

Total Lines 109

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 0
Metric Value
cc 15
nc 47
nop 2
dl 0
loc 109
ccs 0
cts 55
cp 0
crap 240
rs 4.7333
c 0
b 0
f 0

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