Failed Conditions
Pull Request — experimental/sf (#3225)
by Kentaro
58:20 queued 49:13
created

ShoppingController::confirm()   D

Complexity

Conditions 9
Paths 5

Size

Total Lines 43
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 9.8322

Importance

Changes 0
Metric Value
cc 9
eloc 24
nc 5
nop 1
dl 0
loc 43
rs 4.909
c 0
b 0
f 0
ccs 18
cts 23
cp 0.7826
crap 9.8322
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\CustomerAddressRepository;
32
use Eccube\Service\CartService;
33
use Eccube\Service\OrderHelper;
34
use Eccube\Service\Payment\PaymentDispatcher;
35
use Eccube\Service\PurchaseFlow\PurchaseContext;
36
use Eccube\Service\ShoppingService;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
39
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
40
use Symfony\Component\Form\FormError;
41
use Symfony\Component\HttpFoundation\ParameterBag;
42
use Symfony\Component\HttpFoundation\Request;
43
use Symfony\Component\HttpFoundation\Response;
44
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
45
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
46
47
class ShoppingController extends AbstractShoppingController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
48
{
49
    /**
50
     * @var BaseInfo
51
     */
52
    protected $BaseInfo;
53
54
    /**
55
     * @var OrderHelper
56
     */
57
    protected $orderHelper;
58
59
    /**
60
     * @var CartService
61
     */
62
    protected $cartService;
63
64
    /**
65
     * @var ShoppingService
66
     */
67
    protected $shoppingService;
68
69
    /**
70
     * @var CustomerAddressRepository
71
     */
72
    protected $customerAddressRepository;
73
74
    /**
75
     * @var ParameterBag
76
     */
77
    protected $parameterBag;
78
79
    /**
80
     * ShoppingController constructor.
81
     *
82
     * @param BaseInfo $BaseInfo
0 ignored issues
show
introduced by
Expected 18 spaces after parameter type; 1 found
Loading history...
83
     * @param OrderHelper $orderHelper
0 ignored issues
show
introduced by
Expected 15 spaces after parameter type; 1 found
Loading history...
84
     * @param CartService $cartService
0 ignored issues
show
introduced by
Expected 15 spaces after parameter type; 1 found
Loading history...
85
     * @param ShoppingService $shoppingService
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
86
     * @param CustomerAddressRepository $customerAddressRepository
87
     * @param ParameterBag $parameterBag
0 ignored issues
show
introduced by
Expected 14 spaces after parameter type; 1 found
Loading history...
88
     */
89 59
    public function __construct(
90
        BaseInfo $BaseInfo,
91
        OrderHelper $orderHelper,
92
        CartService $cartService,
93
        ShoppingService $shoppingService,
94
        CustomerAddressRepository $customerAddressRepository,
95
        ParameterBag $parameterBag
96
    ) {
97 59
        $this->BaseInfo = $BaseInfo;
98 59
        $this->orderHelper = $orderHelper;
99 59
        $this->cartService = $cartService;
100 59
        $this->shoppingService = $shoppingService;
101 59
        $this->customerAddressRepository = $customerAddressRepository;
102 59
        $this->parameterBag = $parameterBag;
103
    }
104
105
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
106
     * 購入画面表示
107
     *
108
     * @Route("/shopping", name="shopping")
109
     * @Template("Shopping/index.twig")
110
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
111 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...
112
    {
113
        // カートチェック
114 51
        $response = $this->forwardToRoute('shopping_check_to_cart');
115 51
        if ($response->isRedirection() || $response->getContent()) {
116 1
            return $response;
117
        }
118
119
        // 受注情報を初期化
120 50
        $response = $this->forwardToRoute('shopping_initialize_order');
121 50
        if ($response->isRedirection() || $response->getContent()) {
122
            return $response;
123
        }
124
125
        /** @var Order $Order */
126 50
        $Order = $this->parameterBag->get('Order');
127
128
        // 単価集計
129 50
        $flowResult = $this->executePurchaseFlow($Order);
130
131
        // 明細が丸められる場合に, カートから注文画面へ遷移できなくなるため, 集計の結果を保存する
132 50
        $this->entityManager->flush();
133
134
        // フォームを生成する
135 50
        $this->forwardToRoute('shopping_create_form');
136
137 50
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
138 10
            return $this->redirectToRoute('cart');
139
        }
140
141 45
        $form = $this->parameterBag->get(OrderType::class);
142
143
        return [
144 45
            'form' => $form->createView(),
145 45
            'Order' => $Order,
146
        ];
147
    }
148
149
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
150
     * 購入確認画面から, 他の画面へのリダイレクト.
151
     * 配送業者や支払方法、お問い合わせ情報をDBに保持してから遷移する.
152
     *
153
     * @Route("/shopping/redirect", name="shopping_redirect_to")
154
     * @Template("Shopping/index.twig")
155
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
156 20
    public function redirectTo(Request $request)
157
    {
158
        // カートチェック
159 20
        $response = $this->forwardToRoute('shopping_check_to_cart');
160 20
        if ($response->isRedirection() || $response->getContent()) {
161
            return $response;
162
        }
163
164
        // 受注の存在チェック
165 20
        $response = $this->forwardToRoute('shopping_exists_order');
166 20
        if ($response->isRedirection() || $response->getContent()) {
167
            return $response;
168
        }
169
170
        // フォームの生成
171 20
        $this->forwardToRoute('shopping_create_form');
172 20
        $form = $this->parameterBag->get(OrderType::class);
173 20
        $form->handleRequest($request);
174
175
        // 各種変更ページへリダイレクトする
176 20
        $response = $this->forwardToRoute('shopping_redirect_to_change');
177 20
        if ($response->isRedirection() || $response->getContent()) {
178 8
            return $response;
179
        }
180 12
        $form = $this->parameterBag->get(OrderType::class);
181 12
        $Order = $this->parameterBag->get('Order');
182
183
        return [
184 12
            'form' => $form->createView(),
185 12
            'Order' => $Order,
186
        ];
187
    }
188
189
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
190
     * 購入処理
191
     *
192
     * @Route("/shopping/confirm", name="shopping_confirm")
193
     * @Method("POST")
194
     * @Template("Shopping/confirm.twig")
195
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
196 5
    public function confirm(Request $request)
197
    {
198
        // カートチェック
199 5
        $response = $this->forwardToRoute('shopping_check_to_cart');
200 5
        if ($response->isRedirection() || $response->getContent()) {
201
            return $response;
202
        }
203
204
        // 受注の存在チェック
205 5
        $response = $this->forwardToRoute('shopping_exists_order');
206 5
        if ($response->isRedirection() || $response->getContent()) {
207
            return $response;
208
        }
209
210
        // フォームの生成
211 5
        $this->forwardToRoute('shopping_create_form');
212 5
        $form = $this->parameterBag->get(OrderType::class);
213 5
        $form->handleRequest($request);
214
215 5
        $form = $this->parameterBag->get(OrderType::class);
216 5
        $Order = $this->parameterBag->get('Order');
217
218 5
        $flowResult = $this->executePurchaseFlow($Order);
219 5
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
220
            return $this->redirectToRoute('shopping_error');
221
        }
222
223 5
        $paymentService = $this->createPaymentService($Order);
224 5
        $paymentMethod = $this->createPaymentMethod($Order, $form);
225
226 5
        $PaymentResult = $paymentService->doVerify($paymentMethod);
227
        // エラーの場合は注文入力画面に戻す?
228 5
        if ($PaymentResult instanceof PaymentResult && !$PaymentResult->isSuccess()) {
229
            $this->entityManager->getConnection()->rollback();
230
231
            $this->addError($PaymentResult->getErrors());
232
        }
233
234
        return [
235 5
            'form' => $form->createView(),
236 5
            'Order' => $Order,
237
        ];
238
    }
239
240
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
241
     * 購入処理
242
     *
243
     * @Route("/shopping/order", name="shopping_order")
244
     * @Method("POST")
245
     * @Template("Shopping/index.twig")
246
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
247 6
    public function order(Request $request)
248
    {
249
        // カートチェック
250 6
        $response = $this->forwardToRoute('shopping_check_to_cart');
251 6
        if ($response->isRedirection() || $response->getContent()) {
252
            return $response;
253
        }
254
255
        // 受注の存在チェック
256 6
        $response = $this->forwardToRoute('shopping_exists_order');
257 6
        if ($response->isRedirection() || $response->getContent()) {
258
            return $response;
259
        }
260
261
        // form作成
262
        // FIXME イベントハンドラを外から渡したい
263 6
        $this->forwardToRoute('shopping_create_form');
264
265 6
        $form = $this->parameterBag->get(OrderType::class);
266 6
        $Order = $this->parameterBag->get('Order');
267 6
        $usePoint = $Order->getUsePoint();
268
269 6
        $form->handleRequest($request);
270 6
        $Order->setUsePoint($usePoint);
271
272
        // 受注処理
273 6
        $response = $this->forwardToRoute('shopping_complete_order');
274 6
        if ($response->isRedirection() || $response->getContent()) {
275 6
            return $response;
276
        }
277
278
        log_info('購入チェックエラー', [$Order->getId()]);
279
280
        return [
281
            'form' => $form->createView(),
282
            'Order' => $Order,
283
        ];
284
    }
285
286
    /**
287
     * 支払方法バーリデト
288
     */
289
    private function isValidPayment(Application $app, $form)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
290
    {
291
        $data = $form->getData();
292
        $paymentId = $data['payment']->getId();
293
        $shippings = $data['shippings'];
294
        $validCount = count($shippings);
295
        foreach ($shippings as $Shipping) {
296
            $payments = $app['eccube.repository.payment']->findPayments($Shipping->getDelivery());
297
            if ($payments == null) {
298
                continue;
299
            }
300
            foreach ($payments as $payment) {
301
                if ($payment['id'] == $paymentId) {
302
                    $validCount--;
303
                    continue;
304
                }
305
            }
306
        }
307
        if ($validCount == 0) {
308
            return true;
309
        }
310
        $form->get('payment')->addError(new FormError('front.shopping.payment.error'));
311
312
        return false;
313
    }
314
315
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
316
     * 購入完了画面表示
317
     *
318
     * @Route("/shopping/complete", name="shopping_complete")
319
     * @Template("Shopping/complete.twig")
320
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
321 1
    public function complete(Request $request)
0 ignored issues
show
introduced by
Declare public methods first, then protected ones and finally private ones
Loading history...
322
    {
323
        // 受注IDを取得
324 1
        $orderId = $this->session->get($this->sessionOrderKey);
325
326 1
        $event = new EventArgs(
327
            [
328 1
                'orderId' => $orderId,
329
            ],
330 1
            $request
331
        );
332 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE, $event);
333
334 1
        if ($event->getResponse() !== null) {
335
            return $event->getResponse();
336
        }
337
338
        // 受注に関連するセッションを削除
339 1
        $this->session->remove($this->sessionOrderKey);
340 1
        $this->session->remove($this->sessionKey);
341 1
        $this->session->remove($this->sessionCustomerAddressKey);
342
343 1
        log_info('購入処理完了', [$orderId]);
344
345 1
        $hasNextCart = !empty($this->cartService->getCarts());
346
347
        return [
348 1
            'orderId' => $orderId,
349 1
            'hasNextCart' => $hasNextCart,
350
        ];
351
    }
352
353
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$Shipping" missing
Loading history...
354
     * お届け先の設定一覧からの選択
355
     *
356
     * @Route("/shopping/shipping/{id}", name="shopping_shipping", requirements={"id" = "\d+"})
357
     * @Template("Shopping/shipping.twig")
358
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
359
    public function shipping(Request $request, Shipping $Shipping)
360
    {
361
        // カートチェック
362
        $response = $this->forwardToRoute('shopping_check_to_cart');
363
        if ($response->isRedirection() || $response->getContent()) {
364
            return $response;
365
        }
366
367
        // 受注の存在チェック
368
        $response = $this->forwardToRoute('shopping_exists_order');
369
        if ($response->isRedirection() || $response->getContent()) {
370
            return $response;
371
        }
372
373
        // 受注に紐づくShippingかどうかのチェック.
374
        /** @var Order $Order */
375
        $Order = $this->parameterBag->get('Order');
376
        if (!$Order->findShipping($Shipping->getId())) {
377
            throw new NotFoundHttpException();
378
        }
379
380
        $builder = $this->formFactory->createBuilder(CustomerAddressType::class, null, [
381
            'customer' => $this->getUser(),
382
            'shipping' => $Shipping,
383
        ]);
384
385
        $form = $builder->getForm();
386
        $form->handleRequest($request);
387
388
        if ($form->isSubmitted() && $form->isValid()) {
389
            log_info('お届先情報更新開始', [$Shipping->getId()]);
390
391
            /** @var CustomerAddress $CustomerAddress */
392
            $CustomerAddress = $form['addresses']->getData();
393
394
            // お届け先情報を更新
395
            $Shipping->setFromCustomerAddress($CustomerAddress);
396
397
            // 合計金額の再計算
398
            $flowResult = $this->executePurchaseFlow($Order);
399
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
400
                return $this->redirectToRoute('shopping_error');
401
            }
402
403
            // 配送先を更新
404
            $this->entityManager->flush();
405
406
            $event = new EventArgs(
407
                [
408
                    'Order' => $Order,
409
                    'Shipping' => $Shipping,
410
                ],
411
                $request
412
            );
413
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_COMPLETE, $event);
414
415
            log_info('お届先情報更新完了', [$Shipping->getId()]);
416
417
            return $this->redirectToRoute('shopping');
418
        }
419
420
        return [
421
            'form' => $form->createView(),
422
            'Customer' => $this->getUser(),
423
            'shippingId' => $Shipping->getId(),
424
        ];
425
    }
426
427
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
428
     * お届け先の設定(非会員でも使用する)
429
     *
430
     * @Route("/shopping/shipping_edit/{id}", name="shopping_shipping_edit", requirements={"id" = "\d+"})
431
     * @Template("Shopping/shipping_edit.twig")
432
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
433
    public function shippingEdit(Request $request, $id)
434
    {
435
        // 配送先住所最大値判定
436
        $Customer = $this->getUser();
437
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
438
            $addressCurrNum = count($this->getUser()->getCustomerAddresses());
439
            $addressMax = $this->eccubeConfig['eccube_deliv_addr_max'];
440
            if ($addressCurrNum >= $addressMax) {
441
                throw new NotFoundHttpException(trans('shoppingcontroller.text.error.number_of_address'));
442
            }
443
        }
444
445
        // カートチェック
446
        $response = $this->forwardToRoute('shopping_check_to_cart');
447
        if ($response->isRedirection() || $response->getContent()) {
448
            return $response;
449
        }
450
451
        // 受注の存在チェック
452
        $response = $this->forwardToRoute('shopping_exists_order');
453
        if ($response->isRedirection() || $response->getContent()) {
454
            return $response;
455
        }
456
457
        /** @var Order $Order */
458
        $Order = $this->parameterBag->get('Order');
459
460
        $Shipping = $Order->findShipping($id);
461
        if (!$Shipping) {
462
            throw new NotFoundHttpException(trans('shoppingcontroller.text.error.set_address'));
463
        }
464
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
465
            $Shipping->clearCustomerAddress();
466
        }
467
468
        $CustomerAddress = new CustomerAddress();
469
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
470
            $CustomerAddress->setCustomer($Customer);
471
        } else {
472
            $CustomerAddress->setFromShipping($Shipping);
473
        }
474
475
        $builder = $this->formFactory->createBuilder(ShoppingShippingType::class, $CustomerAddress);
476
477
        $event = new EventArgs(
478
            [
479
                'builder' => $builder,
480
                'Order' => $Order,
481
                'Shipping' => $Shipping,
482
                'CustomerAddress' => $CustomerAddress,
483
            ],
484
            $request
485
        );
486
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_INITIALIZE, $event);
487
488
        $form = $builder->getForm();
489
490
        $form->handleRequest($request);
491
492
        if ($form->isSubmitted() && $form->isValid()) {
493
            log_info('お届け先追加処理開始', ['id' => $Order->getId(), 'shipping' => $id]);
494
495
            // 会員の場合、お届け先情報を新規登録
496
            $Shipping->setFromCustomerAddress($CustomerAddress);
497
498
            if ($Customer instanceof Customer) {
499
                $this->entityManager->persist($CustomerAddress);
500
                log_info(
501
                    '新規お届け先登録',
502
                    [
503
                        'id' => $Order->getId(),
504
                        'shipping' => $id,
505
                        'customer address' => $CustomerAddress->getId(),
506
                    ]
507
                );
508
            }
509
510
            // 配送料金の設定
511
            $this->shoppingService->setShippingDeliveryFee($Shipping);
512
513
            // 合計金額の再計算
514
            $flowResult = $this->executePurchaseFlow($Order);
515
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
516
                return $this->redirectToRoute('shopping_error');
517
            }
518
519
            // 配送先を更新
520
            $this->entityManager->flush();
521
522
            $event = new EventArgs(
523
                [
524
                    'form' => $form,
525
                    'Shipping' => $Shipping,
526
                    'CustomerAddress' => $CustomerAddress,
527
                ],
528
                $request
529
            );
530
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_COMPLETE, $event);
531
532
            log_info('お届け先追加処理完了', ['id' => $Order->getId(), 'shipping' => $id]);
533
534
            return $this->redirectToRoute('shopping');
535
        }
536
537
        return [
538
            'form' => $form->createView(),
539
            'shippingId' => $id,
540
        ];
541
    }
542
543
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$authenticationUtils" missing
Loading history...
544
     * ログイン
545
     *
546
     * @Route("/shopping/login", name="shopping_login")
547
     * @Template("Shopping/login.twig")
548
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
549 2 View Code Duplication
    public function login(Request $request, AuthenticationUtils $authenticationUtils)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
550
    {
551 2
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
552
            return $this->redirectToRoute('shopping');
553
        }
554
555
        /* @var $form \Symfony\Component\Form\FormInterface */
556 2
        $builder = $this->formFactory->createNamedBuilder('', CustomerLoginType::class);
557
558 2
        if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
559
            $Customer = $this->getUser();
560
            if ($Customer) {
561
                $builder->get('login_email')->setData($Customer->getEmail());
562
            }
563
        }
564
565 2
        $event = new EventArgs(
566
            [
567 2
                'builder' => $builder,
568
            ],
569 2
            $request
570
        );
571 2
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_LOGIN_INITIALIZE, $event);
572
573 2
        $form = $builder->getForm();
574
575
        return [
576 2
            'error' => $authenticationUtils->getLastAuthenticationError(),
577 2
            'form' => $form->createView(),
578
        ];
579
    }
580
581
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
582
     * 購入エラー画面表示
583
     *
584
     * @Route("/shopping/error", name="shopping_error")
585
     * @Template("Shopping/shopping_error.twig")
586
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
587 1
    public function shoppingError(Request $request)
588
    {
589 1
        $event = new EventArgs(
590 1
            [],
591 1
            $request
592
        );
593 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_ERROR_COMPLETE, $event);
594
595 1
        if ($event->getResponse() !== null) {
596
            return $event->getResponse();
597
        }
598
599 1
        return [];
600
    }
601
602
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
603
     * カート画面のチェック
604
     *
605
     * @ForwardOnly
606
     * @Route("/shopping/check_to_cart", name="shopping_check_to_cart")
607
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
608 55
    public function checkToCart(Request $request)
609
    {
610 55
        $Cart = $this->cartService->getCart();
611 55
        if ($Cart && count($Cart->getCartItems()) > 0) {
612 53
            $divide = $request->getSession()->get('cart.divide');
613 53
            if ($divide) {
614
                log_info('種別が異なる商品がカートと結合されたためカート画面にリダイレクト');
615
616
                return $this->redirectToRoute('cart');
617
            }
618
619 53
            return new Response();
620
        }
621 2
        log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
622
623
        // カートが存在しない時はエラー
624 2
        return $this->redirectToRoute('cart');
625
    }
626
627
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
628
     * 受注情報を初期化する.
629
     *
630
     * @ForwardOnly
631
     * @Route("/shopping/initialize_order", name="shopping_initialize_order")
632
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
633 50
    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...
634
    {
635
        // 購入処理中の受注情報を取得
636 50
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
637
638
        // 初回アクセス(受注情報がない)の場合は, 受注情報を作成
639 50
        if (is_null($Order)) {
640
            // 未ログインの場合, ログイン画面へリダイレクト.
641 34
            if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
642
                // 非会員でも一度会員登録されていればショッピング画面へ遷移
643
                $Customer = $this->shoppingService->getNonMember($this->sessionKey);
644
645
                if (is_null($Customer)) {
646
                    log_info('未ログインのためログイン画面にリダイレクト');
647
648
                    return $this->redirectToRoute('shopping_login');
649
                }
650
            } else {
651 34
                $Customer = $this->getUser();
652
            }
653
654
            try {
655
                // 受注情報を作成
656
                //$Order = $app['eccube.service.shopping']->createOrder($Customer);
657 34
                $Order = $this->orderHelper->createProcessingOrder(
658 34
                    $Customer,
659 34
                    $this->cartService->getCart()->getCartItems()
660
                );
661 34
                $this->cartService->setPreOrderId($Order->getPreOrderId());
662 34
                $this->cartService->save();
663
            } catch (CartException $e) {
664
                log_error('初回受注情報作成エラー', [$e->getMessage()]);
665
                $this->addRequestError($e->getMessage());
666
667
                return $this->redirectToRoute('cart');
668
            }
669
670
            // セッション情報を削除
671 34
            $this->session->remove($this->sessionOrderKey);
672
        }
673
674
        // 受注関連情報を最新状態に更新
675 50
        $this->entityManager->refresh($Order);
676
677 50
        $this->parameterBag->set('Order', $Order);
678
679 50
        return new Response();
680
    }
681
682
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
683
     * フォームを作成し, イベントハンドラを設定する
684
     *
685
     * @ForwardOnly
686
     * @Route("/shopping/create_form", name="shopping_create_form")
687
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
688 50
    public function createShoppingForm(Request $request)
689
    {
690 50
        $Order = $this->parameterBag->get('Order');
691
        // フォームの生成
692 50
        $builder = $this->formFactory->createBuilder(OrderType::class, $Order);
693
694 50
        $event = new EventArgs(
695
             [
696 50
                 'builder' => $builder,
697 50
                 'Order' => $Order,
698
             ],
699 50
             $request
700
         );
701 50
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);
702
703 50
        $form = $builder->getForm();
704
705 50
        $this->parameterBag->set(OrderType::class, $form);
706
707 50
        return new Response();
708
    }
709
710
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
711
     * mode に応じて各変更ページへリダイレクトする.
712
     *
713
     * @ForwardOnly
714
     * @Route("/shopping/redirect_to_change", name="shopping_redirect_to_change")
715
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
716 20
    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...
717
    {
718 20
        $form = $this->parameterBag->get(OrderType::class);
719
720
        // requestのバインド後、Calculatorに再集計させる
721
        //$app['eccube.service.calculate']($Order, $Order->getCustomer())->calculate();
722
723
        // 支払い方法の変更や配送業者の変更があった場合はDBに保持する.
724 20
        if ($form->isSubmitted() && $form->isValid()) {
725
            // POSTされたデータをDBに保持.
726 8
            $this->entityManager->flush();
727
728 8
            $mode = $form['mode']->getData();
729 8
            switch ($mode) {
730 7
                case 'shipping_change':
731
                    // お届け先設定一覧へリダイレクト
732 1
                    $param = $form['param']->getData();
733
734 1
                    return $this->redirectToRoute('shopping_shipping', ['id' => $param]);
735 7
                case 'shipping_edit_change':
736
                    // お届け先設定一覧へリダイレクト
737
                    $param = $form['param']->getData();
738
739
                    return $this->redirectToRoute('shopping_shipping_edit', ['id' => $param]);
740 7
                case 'shipping_multiple_change':
741
                    // 複数配送設定へリダイレクト
742
                    return $this->redirectToRoute('shopping_shipping_multiple');
743 7
                case 'payment':
744 7
                case 'delivery':
745
                default:
746 7
                    return $this->redirectToRoute('shopping');
747
            }
748
        }
749
750 12
        return new Response();
751
    }
752
753
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
754
     * 受注の存在チェック
755
     *
756
     * @ForwardOnly
757
     * @Route("/shopping/exists_order", name="shopping_exists_order")
758
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
759 26
    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...
760
    {
761 26
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
762 26
        if (!$Order) {
763
            log_info('購入処理中の受注情報がないため購入エラー');
764
            $this->addError('front.shopping.order.error');
765
766
            return $this->redirectToRoute('shopping_error');
767
        }
768 26
        $this->parameterBag->set('Order', $Order);
769
770 26
        return new Response();
771
    }
772
773
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
774
     * 受注完了処理
775
     *
776
     * @ForwardOnly
777
     * @Route("/shopping/complete_order", name="shopping_complete_order")
778
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
779 6
    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...
780
    {
781 6
        $form = $this->parameterBag->get(OrderType::class);
782
783 6
        if ($form->isSubmitted() && $form->isValid()) {
784
            /** @var Order $Order */
785 6
            $Order = $form->getData();
786 6
            log_info('購入処理開始', [$Order->getId()]);
787
788
            // トランザクション制御
789 6
            $em = $this->entityManager;
790 6
            $em->getConnection()->beginTransaction();
791
            try {
792
                // お問い合わせ、配送時間などのフォーム項目をセット
793
                // FormTypeで更新されるため不要
794
                //$app['eccube.service.shopping']->setFormData($Order, $data);
795
796 6
                $flowResult = $this->executePurchaseFlow($Order);
797 6
                if ($flowResult->hasWarning() || $flowResult->hasError()) {
798
                    // TODO エラーメッセージ
799
                    throw new ShoppingException();
800
                }
801
                try {
802 6
                    $this->purchaseFlow->purchase($Order, new PurchaseContext($Order, $Order->getCustomer())); // TODO 変更前の Order を渡す必要がある?
803
                } catch (PurchaseException $e) {
0 ignored issues
show
Bug introduced by
The class Eccube\Controller\PurchaseException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
804
                    $this->addError($e->getMessage(), 'front');
805
                }
806
807
                // 購入処理
808 6
                $this->shoppingService->processPurchase($Order); // XXX フロント画面に依存してるので管理画面では使えない
0 ignored issues
show
Deprecated Code introduced by
The method Eccube\Service\ShoppingService::processPurchase() has been deprecated with message: PurchaseFlow::purchase() を使用してください

This method 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 method will be removed from the class and what other method or class to use instead.

Loading history...
809
810
                // Order も引数で渡すのがベスト??
811 6
                $paymentService = $this->createPaymentService($Order);
812 6
                $paymentMethod = $this->createPaymentMethod($Order, $form);
813
814
                // 必要に応じて別のコントローラへ forward or redirect(移譲)
815 6
                $dispatcher = $paymentService->dispatch($paymentMethod); // 決済処理中.
816
                // 一旦、決済処理中になった後は、購入処理中に戻せない。キャンセル or 購入完了の仕様とする
817
                // ステータス履歴も保持しておく? 在庫引き当ての仕様もセットで。
818 6
                if ($dispatcher instanceof PaymentDispatcher) {
819
                    if ($dispatcher->isForward()) {
820
                        return $this->forwardToRoute($dispatcher->getRoute(), $dispatcher->getPathParameters(), $dispatcher->getQueryParameters());
821
                    } else {
822
                        return $this->redirectToRoute($dispatcher->getRoute(), $dispatcher->getQueryParameters());
823
                    }
824
                }
825
826
                // 決済実行
827 6
                $response = $this->forwardToRoute('shopping_do_checkout_order');
828 6
                if ($response->isRedirection() || $response->getContent()) {
829
                    return $response;
830
                }
831
832 6
                $this->entityManager->flush();
833 6
                $this->entityManager->getConnection()->commit();
834
835 6
                log_info('購入処理完了', [$Order->getId()]);
836
            } catch (ShoppingException $e) {
837
                log_error('購入エラー', [$e->getMessage()]);
838
839
                $this->entityManager->getConnection()->rollback();
840
841
                $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...
842
                $this->addError($e->getMessage());
843
844
                return $this->redirectToRoute('shopping_error');
845
            } catch (\Exception $e) {
846
                log_error('予期しないエラー', [$e->getMessage()]);
847
848
                $this->entityManager->getConnection()->rollback();
849
850
                $this->addError('front.shopping.system.error');
851
852
                return $this->redirectToRoute('shopping_error');
853
            }
854
855 6
            return $this->forwardToRoute('shopping_after_complete');
856
        }
857
858
        return new Response();
859
    }
860
861
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
862
     * 決済完了処理
863
     *
864
     * @ForwardOnly
865
     * @Route("/shopping/do_checkout_order", name="shopping_do_checkout_order")
866
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
867 6
    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...
868
    {
869 6
        $form = $this->parameterBag->get(OrderType::class);
870 6
        $Order = $this->parameterBag->get('Order');
871
872 6
        $paymentService = $this->createPaymentService($Order);
873 6
        $paymentMethod = $this->createPaymentMethod($Order, $form);
874
875
        // 決済実行
876 6
        $PaymentResult = $paymentService->doCheckout($paymentMethod);
877 6
        if (!$PaymentResult->isSuccess()) {
878
            $this->entityManager->getConnection()->rollback();
879
880
            $this->addError($PaymentResult->getErrors());
881
        }
882
883 6
        return new Response();
884
    }
885
886
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
887
     * 受注完了の後処理
888
     *
889
     * @ForwardOnly
890
     * @Route("/shopping/after_complete", name="shopping_after_complete")
891
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
892 6
    public function afterComplete(Request $request)
893
    {
894 6
        $form = $this->parameterBag->get(OrderType::class);
895 6
        $Order = $this->parameterBag->get('Order');
896
897
        // カート削除
898 6
        $this->cartService->clear()->save();
899
900 6
        $event = new EventArgs(
901
            [
902 6
                'form' => $form,
903 6
                'Order' => $Order,
904
            ],
905 6
            $request
906
        );
907 6
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING, $event);
908
909 6 View Code Duplication
        if ($event->getResponse() !== null) {
910
            log_info('イベントレスポンス返却', [$Order->getId()]);
911
912
            return $event->getResponse();
913
        }
914
915
        // 受注IDをセッションにセット
916 6
        $this->session->set($this->sessionOrderKey, $Order->getId());
917
918
        // メール送信
919 6
        $MailHistory = $this->shoppingService->sendOrderMail($Order);
920
921 6
        $event = new EventArgs(
922
            [
923 6
                'form' => $form,
924 6
                'Order' => $Order,
925 6
                'MailHistory' => $MailHistory,
926
            ],
927 6
            $request
928
        );
929 6
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_COMPLETE, $event);
930
931 6 View Code Duplication
        if ($event->getResponse() !== null) {
932
            log_info('イベントレスポンス返却', [$Order->getId()]);
933
934
            return $event->getResponse();
935
        }
936
937
        // 完了画面表示
938 6
        return $this->redirectToRoute('shopping_complete');
939
    }
940
941 6
    private function createPaymentService(Order $Order)
942
    {
943 6
        $serviceClass = $Order->getPayment()->getServiceClass();
944 6
        $paymentService = new $serviceClass($this->container->get('request_stack')); // コンテナから取得したい
945
946 6
        return $paymentService;
947
    }
948
949 6
    private function createPaymentMethod(Order $Order, $form)
950
    {
951 6
        $methodClass = $Order->getPayment()->getMethodClass();
952 6
        $PaymentMethod = new $methodClass(); // コンテナから取得したい
953 6
        $PaymentMethod->setOrder($Order);
954 6
        $PaymentMethod->setFormType($form);
955
956 6
        return $PaymentMethod;
957
    }
958
959
    /**
960
     * 非会員でのお客様情報変更時の入力チェック
961
     *
962
     * TODO https://github.com/EC-CUBE/ec-cube/issues/565
963
     *
964
     * @param Application $app
965
     * @param array $data リクエストパラメータ
966
     *
967
     * @return array
968
     */
969
    private function customerValidation(Application $app, array &$data)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
970
    {
971
        // 入力チェック
972
        $errors = [];
973
974
        $errors[] = $app['validator']->validateValue($data['customer_name01'], [
975
            new Assert\NotBlank(),
976
            new Assert\Length(['max' => $app['config']['name_len']]),
977
            new Assert\Regex(['pattern' => '/^[^\s ]+$/u', 'message' => 'form.type.name.firstname.nothasspace']),
978
        ]);
979
980
        $errors[] = $app['validator']->validateValue($data['customer_name02'], [
981
            new Assert\NotBlank(),
982
            new Assert\Length(['max' => $app['config']['name_len']]),
983
            new Assert\Regex(['pattern' => '/^[^\s ]+$/u', 'message' => 'form.type.name.firstname.nothasspace']),
984
        ]);
985
986
        // 互換性確保のためキーが存在する場合にのみバリデーションを行う(kana01は3.0.15から追加)
987 View Code Duplication
        if (array_key_exists('customer_kana01', $data)) {
988
            $data['customer_kana01'] = mb_convert_kana($data['customer_kana01'], 'CV', 'utf-8');
989
            $errors[] = $app['validator']->validateValue($data['customer_kana01'], [
990
                new Assert\NotBlank(),
991
                new Assert\Length(['max' => $app['config']['kana_len']]),
992
                new Assert\Regex(['pattern' => '/^[ァ-ヶヲ-゚ー]+$/u']),
993
            ]);
994
        }
995
996
        // 互換性確保のためキーが存在する場合にのみバリデーションを行う(kana01は3.0.15から追加)
997 View Code Duplication
        if (array_key_exists('customer_kana02', $data)) {
998
            $data['customer_kana02'] = mb_convert_kana($data['customer_kana02'], 'CV', 'utf-8');
999
            $errors[] = $app['validator']->validateValue($data['customer_kana02'], [
1000
                new Assert\NotBlank(),
1001
                new Assert\Length(['max' => $app['config']['kana_len']]),
1002
                new Assert\Regex(['pattern' => '/^[ァ-ヶヲ-゚ー]+$/u']),
1003
            ]);
1004
        }
1005
1006
        $errors[] = $app['validator']->validateValue($data['customer_company_name'], [
1007
            new Assert\Length(['max' => $app['config']['stext_len']]),
1008
        ]);
1009
1010
        $errors[] = $app['validator']->validateValue($data['customer_tel01'], [
1011
            new Assert\NotBlank(),
1012
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
1013
            new Assert\Length(['max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min']]),
1014
        ]);
1015
1016
        $errors[] = $app['validator']->validateValue($data['customer_tel02'], [
1017
            new Assert\NotBlank(),
1018
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
1019
            new Assert\Length(['max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min']]),
1020
        ]);
1021
1022
        $errors[] = $app['validator']->validateValue($data['customer_tel03'], [
1023
            new Assert\NotBlank(),
1024
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
1025
            new Assert\Length(['max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min']]),
1026
        ]);
1027
1028
        $errors[] = $app['validator']->validateValue($data['customer_zip01'], [
1029
            new Assert\NotBlank(),
1030
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
1031
            new Assert\Length(['min' => $app['config']['zip01_len'], 'max' => $app['config']['zip01_len']]),
1032
        ]);
1033
1034
        $errors[] = $app['validator']->validateValue($data['customer_zip02'], [
1035
            new Assert\NotBlank(),
1036
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
1037
            new Assert\Length(['min' => $app['config']['zip02_len'], 'max' => $app['config']['zip02_len']]),
1038
        ]);
1039
1040
        $errors[] = $app['validator']->validateValue($data['customer_addr01'], [
1041
            new Assert\NotBlank(),
1042
            new Assert\Length(['max' => $app['config']['address1_len']]),
1043
        ]);
1044
1045
        $errors[] = $app['validator']->validateValue($data['customer_addr02'], [
1046
            new Assert\NotBlank(),
1047
            new Assert\Length(['max' => $app['config']['address2_len']]),
1048
        ]);
1049
1050
        $errors[] = $app['validator']->validateValue($data['customer_email'], [
1051
            new Assert\NotBlank(),
1052
            new Assert\Email(['strict' => true]),
1053
        ]);
1054
1055
        return $errors;
1056
    }
1057
}
1058