Failed Conditions
Branch experimental/sf (68db07)
by Kentaro
42:17 queued 33:39
created

ShoppingController::createShoppingForm()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 21
rs 9.584
c 0
b 0
f 0
ccs 11
cts 11
cp 1
crap 1
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\PurchaseFlow\PurchaseContext;
35
use Eccube\Service\ShoppingService;
36
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
37
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
38
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
39
use Symfony\Component\Form\FormError;
40
use Symfony\Component\HttpFoundation\ParameterBag;
41
use Symfony\Component\HttpFoundation\Request;
42
use Symfony\Component\HttpFoundation\Response;
43
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
44
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
45
46
class ShoppingController extends AbstractShoppingController
0 ignored issues
show
introduced by
Missing class doc comment
Loading history...
47
{
48
    /**
49
     * @var BaseInfo
50
     */
51
    protected $BaseInfo;
52
53
    /**
54
     * @var OrderHelper
55
     */
56
    protected $orderHelper;
57
58
    /**
59
     * @var CartService
60
     */
61
    protected $cartService;
62
63
    /**
64
     * @var ShoppingService
65
     */
66
    protected $shoppingService;
67
68
    /**
69
     * @var CustomerAddressRepository
70
     */
71
    protected $customerAddressRepository;
72
73
    /**
74
     * @var ParameterBag
75
     */
76
    protected $parameterBag;
77
78
    /**
79
     * ShoppingController constructor.
80
     *
81
     * @param BaseInfo $BaseInfo
0 ignored issues
show
introduced by
Expected 18 spaces after parameter type; 1 found
Loading history...
82
     * @param OrderHelper $orderHelper
0 ignored issues
show
introduced by
Expected 15 spaces after parameter type; 1 found
Loading history...
83
     * @param CartService $cartService
0 ignored issues
show
introduced by
Expected 15 spaces after parameter type; 1 found
Loading history...
84
     * @param ShoppingService $shoppingService
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
85
     * @param CustomerAddressRepository $customerAddressRepository
86
     * @param ParameterBag $parameterBag
0 ignored issues
show
introduced by
Expected 14 spaces after parameter type; 1 found
Loading history...
87
     */
88 59
    public function __construct(
89
        BaseInfo $BaseInfo,
90
        OrderHelper $orderHelper,
91
        CartService $cartService,
92
        ShoppingService $shoppingService,
93
        CustomerAddressRepository $customerAddressRepository,
94
        ParameterBag $parameterBag
95
    ) {
96 59
        $this->BaseInfo = $BaseInfo;
97 59
        $this->orderHelper = $orderHelper;
98 59
        $this->cartService = $cartService;
99 59
        $this->shoppingService = $shoppingService;
100 59
        $this->customerAddressRepository = $customerAddressRepository;
101 59
        $this->parameterBag = $parameterBag;
102
    }
103
104
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
105
     * 購入画面表示
106
     *
107
     * @Route("/shopping", name="shopping")
108
     * @Template("Shopping/index.twig")
109
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
110 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...
111
    {
112
        // カートチェック
113 51
        $response = $this->forwardToRoute('shopping_check_to_cart');
114 51
        if ($response->isRedirection() || $response->getContent()) {
115 1
            return $response;
116
        }
117
118
        // 受注情報を初期化
119 50
        $response = $this->forwardToRoute('shopping_initialize_order');
120 50
        if ($response->isRedirection() || $response->getContent()) {
121
            return $response;
122
        }
123
124
        /** @var Order $Order */
125 50
        $Order = $this->parameterBag->get('Order');
126
127
        // 単価集計
128 50
        $flowResult = $this->executePurchaseFlow($Order);
129
130
        // 明細が丸められる場合に, カートから注文画面へ遷移できなくなるため, 集計の結果を保存する
131 50
        $this->entityManager->flush();
132
133
        // フォームを生成する
134 50
        $this->forwardToRoute('shopping_create_form');
135
136 50
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
137 10
            return $this->redirectToRoute('cart');
138
        }
139
140 45
        $form = $this->parameterBag->get(OrderType::class);
141
142
        return [
143 45
            'form' => $form->createView(),
144 45
            'Order' => $Order,
145
        ];
146
    }
147
148
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
149
     * 購入確認画面から, 他の画面へのリダイレクト.
150
     * 配送業者や支払方法、お問い合わせ情報をDBに保持してから遷移する.
151
     *
152
     * @Route("/shopping/redirect", name="shopping_redirect_to")
153
     * @Template("Shopping/index.twig")
154
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
155 20 View Code Duplication
    public function redirectTo(Request $request)
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...
156
    {
157
        // カートチェック
158 20
        $response = $this->forwardToRoute('shopping_check_to_cart');
159 20
        if ($response->isRedirection() || $response->getContent()) {
160
            return $response;
161
        }
162
163
        // 受注の存在チェック
164 20
        $response = $this->forwardToRoute('shopping_exists_order');
165 20
        if ($response->isRedirection() || $response->getContent()) {
166
            return $response;
167
        }
168
169
        // フォームの生成
170 20
        $this->forwardToRoute('shopping_create_form');
171 20
        $form = $this->parameterBag->get(OrderType::class);
172 20
        $form->handleRequest($request);
173
174
        // 各種変更ページへリダイレクトする
175 20
        $response = $this->forwardToRoute('shopping_redirect_to_change');
176 20
        if ($response->isRedirection() || $response->getContent()) {
177 8
            return $response;
178
        }
179 12
        $form = $this->parameterBag->get(OrderType::class);
180 12
        $Order = $this->parameterBag->get('Order');
181
182
        return [
183 12
            'form' => $form->createView(),
184 12
            'Order' => $Order,
185
        ];
186
    }
187
188
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
189
     * 購入処理
190
     *
191
     * @Route("/shopping/confirm", name="shopping_confirm")
192
     * @Method("POST")
193
     * @Template("Shopping/confirm.twig")
194
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
195 5 View Code Duplication
    public function confirm(Request $request)
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...
196
    {
197
        // カートチェック
198 5
        $response = $this->forwardToRoute('shopping_check_to_cart');
199 5
        if ($response->isRedirection() || $response->getContent()) {
200
            return $response;
201
        }
202
203
        // 受注の存在チェック
204 5
        $response = $this->forwardToRoute('shopping_exists_order');
205 5
        if ($response->isRedirection() || $response->getContent()) {
206
            return $response;
207
        }
208
209
        // フォームの生成
210 5
        $this->forwardToRoute('shopping_create_form');
211 5
        $form = $this->parameterBag->get(OrderType::class);
212 5
        $form->handleRequest($request);
213
214 5
        $form = $this->parameterBag->get(OrderType::class);
215 5
        $Order = $this->parameterBag->get('Order');
216
217 5
        $flowResult = $this->executePurchaseFlow($Order);
218 5
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
219
            return $this->redirectToRoute('shopping_error');
220
        }
221
222
        return [
223 5
            'form' => $form->createView(),
224 5
            'Order' => $Order,
225
        ];
226
    }
227
228
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
229
     * 購入処理
230
     *
231
     * @Route("/shopping/order", name="shopping_order")
232
     * @Method("POST")
233
     * @Template("Shopping/index.twig")
234
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
235 6
    public function order(Request $request)
236
    {
237
        // カートチェック
238 6
        $response = $this->forwardToRoute('shopping_check_to_cart');
239 6
        if ($response->isRedirection() || $response->getContent()) {
240
            return $response;
241
        }
242
243
        // 受注の存在チェック
244 6
        $response = $this->forwardToRoute('shopping_exists_order');
245 6
        if ($response->isRedirection() || $response->getContent()) {
246
            return $response;
247
        }
248
249
        // form作成
250
        // FIXME イベントハンドラを外から渡したい
251 6
        $this->forwardToRoute('shopping_create_form');
252
253 6
        $form = $this->parameterBag->get(OrderType::class);
254 6
        $Order = $this->parameterBag->get('Order');
255 6
        $usePoint = $Order->getUsePoint();
256
257 6
        $form->handleRequest($request);
258 6
        $Order->setUsePoint($usePoint);
259
260
        // 受注処理
261 6
        $response = $this->forwardToRoute('shopping_complete_order');
262 6
        if ($response->isRedirection() || $response->getContent()) {
263 6
            return $response;
264
        }
265
266
        log_info('購入チェックエラー', [$Order->getId()]);
267
268
        return [
269
            'form' => $form->createView(),
270
            'Order' => $Order,
271
        ];
272
    }
273
274
    /**
275
     * 支払方法バーリデト
276
     */
277
    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...
278
    {
279
        $data = $form->getData();
280
        $paymentId = $data['payment']->getId();
281
        $shippings = $data['shippings'];
282
        $validCount = count($shippings);
283
        foreach ($shippings as $Shipping) {
284
            $payments = $app['eccube.repository.payment']->findPayments($Shipping->getDelivery());
285
            if ($payments == null) {
286
                continue;
287
            }
288
            foreach ($payments as $payment) {
289
                if ($payment['id'] == $paymentId) {
290
                    $validCount--;
291
                    continue;
292
                }
293
            }
294
        }
295
        if ($validCount == 0) {
296
            return true;
297
        }
298
        $form->get('payment')->addError(new FormError('front.shopping.payment.error'));
299
300
        return false;
301
    }
302
303
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
304
     * 購入完了画面表示
305
     *
306
     * @Route("/shopping/complete", name="shopping_complete")
307
     * @Template("Shopping/complete.twig")
308
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
309 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...
310
    {
311
        // 受注IDを取得
312 1
        $orderId = $this->session->get($this->sessionOrderKey);
313
314 1
        $event = new EventArgs(
315
            [
316 1
                'orderId' => $orderId,
317
            ],
318 1
            $request
319
        );
320 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE, $event);
321
322 1
        if ($event->getResponse() !== null) {
323
            return $event->getResponse();
324
        }
325
326
        // 受注に関連するセッションを削除
327 1
        $this->session->remove($this->sessionOrderKey);
328 1
        $this->session->remove($this->sessionKey);
329 1
        $this->session->remove($this->sessionCustomerAddressKey);
330
331 1
        log_info('購入処理完了', [$orderId]);
332
333 1
        $hasNextCart = !empty($this->cartService->getCarts());
334
335
        return [
336 1
            'orderId' => $orderId,
337 1
            'hasNextCart' => $hasNextCart,
338
        ];
339
    }
340
341
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$Shipping" missing
Loading history...
342
     * お届け先の設定一覧からの選択
343
     *
344
     * @Route("/shopping/shipping/{id}", name="shopping_shipping", requirements={"id" = "\d+"})
345
     * @Template("Shopping/shipping.twig")
346
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
347
    public function shipping(Request $request, Shipping $Shipping)
348
    {
349
        // カートチェック
350
        $response = $this->forwardToRoute('shopping_check_to_cart');
351
        if ($response->isRedirection() || $response->getContent()) {
352
            return $response;
353
        }
354
355
        // 受注の存在チェック
356
        $response = $this->forwardToRoute('shopping_exists_order');
357
        if ($response->isRedirection() || $response->getContent()) {
358
            return $response;
359
        }
360
361
        // 受注に紐づくShippingかどうかのチェック.
362
        /** @var Order $Order */
363
        $Order = $this->parameterBag->get('Order');
364
        if (!$Order->findShipping($Shipping->getId())) {
365
            throw new NotFoundHttpException();
366
        }
367
368
        $builder = $this->formFactory->createBuilder(CustomerAddressType::class, null, [
369
            'customer' => $this->getUser(),
370
            'shipping' => $Shipping,
371
        ]);
372
373
        $form = $builder->getForm();
374
        $form->handleRequest($request);
375
376
        if ($form->isSubmitted() && $form->isValid()) {
377
            log_info('お届先情報更新開始', [$Shipping->getId()]);
378
379
            /** @var CustomerAddress $CustomerAddress */
380
            $CustomerAddress = $form['addresses']->getData();
381
382
            // お届け先情報を更新
383
            $Shipping->setFromCustomerAddress($CustomerAddress);
384
385
            // 合計金額の再計算
386
            $flowResult = $this->executePurchaseFlow($Order);
387
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
388
                return $this->redirectToRoute('shopping_error');
389
            }
390
391
            // 配送先を更新
392
            $this->entityManager->flush();
393
394
            $event = new EventArgs(
395
                [
396
                    'Order' => $Order,
397
                    'Shipping' => $Shipping,
398
                ],
399
                $request
400
            );
401
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_COMPLETE, $event);
402
403
            log_info('お届先情報更新完了', [$Shipping->getId()]);
404
405
            return $this->redirectToRoute('shopping');
406
        }
407
408
        return [
409
            'form' => $form->createView(),
410
            'Customer' => $this->getUser(),
411
            'shippingId' => $Shipping->getId(),
412
        ];
413
    }
414
415
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
416
     * お届け先の設定(非会員でも使用する)
417
     *
418
     * @Route("/shopping/shipping_edit/{id}", name="shopping_shipping_edit", requirements={"id" = "\d+"})
419
     * @Template("Shopping/shipping_edit.twig")
420
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
421
    public function shippingEdit(Request $request, $id)
422
    {
423
        // 配送先住所最大値判定
424
        $Customer = $this->getUser();
425
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
426
            $addressCurrNum = count($this->getUser()->getCustomerAddresses());
427
            $addressMax = $this->eccubeConfig['eccube_deliv_addr_max'];
428
            if ($addressCurrNum >= $addressMax) {
429
                throw new NotFoundHttpException(trans('shoppingcontroller.text.error.number_of_address'));
430
            }
431
        }
432
433
        // カートチェック
434
        $response = $this->forwardToRoute('shopping_check_to_cart');
435
        if ($response->isRedirection() || $response->getContent()) {
436
            return $response;
437
        }
438
439
        // 受注の存在チェック
440
        $response = $this->forwardToRoute('shopping_exists_order');
441
        if ($response->isRedirection() || $response->getContent()) {
442
            return $response;
443
        }
444
445
        /** @var Order $Order */
446
        $Order = $this->parameterBag->get('Order');
447
448
        $Shipping = $Order->findShipping($id);
449
        if (!$Shipping) {
450
            throw new NotFoundHttpException(trans('shoppingcontroller.text.error.set_address'));
451
        }
452
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
453
            $Shipping->clearCustomerAddress();
454
        }
455
456
        $CustomerAddress = new CustomerAddress();
457
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
458
            $CustomerAddress->setCustomer($Customer);
459
        } else {
460
            $CustomerAddress->setFromShipping($Shipping);
461
        }
462
463
        $builder = $this->formFactory->createBuilder(ShoppingShippingType::class, $CustomerAddress);
464
465
        $event = new EventArgs(
466
            [
467
                'builder' => $builder,
468
                'Order' => $Order,
469
                'Shipping' => $Shipping,
470
                'CustomerAddress' => $CustomerAddress,
471
            ],
472
            $request
473
        );
474
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_INITIALIZE, $event);
475
476
        $form = $builder->getForm();
477
478
        $form->handleRequest($request);
479
480
        if ($form->isSubmitted() && $form->isValid()) {
481
            log_info('お届け先追加処理開始', ['id' => $Order->getId(), 'shipping' => $id]);
482
483
            // 会員の場合、お届け先情報を新規登録
484
            $Shipping->setFromCustomerAddress($CustomerAddress);
485
486
            if ($Customer instanceof Customer) {
487
                $this->entityManager->persist($CustomerAddress);
488
                log_info(
489
                    '新規お届け先登録',
490
                    [
491
                        'id' => $Order->getId(),
492
                        'shipping' => $id,
493
                        'customer address' => $CustomerAddress->getId(),
494
                    ]
495
                );
496
            }
497
498
            // 配送料金の設定
499
            $this->shoppingService->setShippingDeliveryFee($Shipping);
500
501
            // 合計金額の再計算
502
            $flowResult = $this->executePurchaseFlow($Order);
503
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
504
                return $this->redirectToRoute('shopping_error');
505
            }
506
507
            // 配送先を更新
508
            $this->entityManager->flush();
509
510
            $event = new EventArgs(
511
                [
512
                    'form' => $form,
513
                    'Shipping' => $Shipping,
514
                    'CustomerAddress' => $CustomerAddress,
515
                ],
516
                $request
517
            );
518
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_COMPLETE, $event);
519
520
            log_info('お届け先追加処理完了', ['id' => $Order->getId(), 'shipping' => $id]);
521
522
            return $this->redirectToRoute('shopping');
523
        }
524
525
        return [
526
            'form' => $form->createView(),
527
            'shippingId' => $id,
528
        ];
529
    }
530
531
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$authenticationUtils" missing
Loading history...
532
     * ログイン
533
     *
534
     * @Route("/shopping/login", name="shopping_login")
535
     * @Template("Shopping/login.twig")
536
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
537 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...
538
    {
539 2
        if ($this->isGranted('IS_AUTHENTICATED_FULLY')) {
540
            return $this->redirectToRoute('shopping');
541
        }
542
543
        /* @var $form \Symfony\Component\Form\FormInterface */
544 2
        $builder = $this->formFactory->createNamedBuilder('', CustomerLoginType::class);
545
546 2
        if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
547
            $Customer = $this->getUser();
548
            if ($Customer) {
549
                $builder->get('login_email')->setData($Customer->getEmail());
550
            }
551
        }
552
553 2
        $event = new EventArgs(
554
            [
555 2
                'builder' => $builder,
556
            ],
557 2
            $request
558
        );
559 2
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_LOGIN_INITIALIZE, $event);
560
561 2
        $form = $builder->getForm();
562
563
        return [
564 2
            'error' => $authenticationUtils->getLastAuthenticationError(),
565 2
            'form' => $form->createView(),
566
        ];
567
    }
568
569
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
570
     * 購入エラー画面表示
571
     *
572
     * @Route("/shopping/error", name="shopping_error")
573
     * @Template("Shopping/shopping_error.twig")
574
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
575 1
    public function shoppingError(Request $request)
576
    {
577 1
        $event = new EventArgs(
578 1
            [],
579 1
            $request
580
        );
581 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_ERROR_COMPLETE, $event);
582
583 1
        if ($event->getResponse() !== null) {
584
            return $event->getResponse();
585
        }
586
587 1
        return [];
588
    }
589
590
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
591
     * カート画面のチェック
592
     *
593
     * @ForwardOnly
594
     * @Route("/shopping/check_to_cart", name="shopping_check_to_cart")
595
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
596 55
    public function checkToCart(Request $request)
597
    {
598 55
        $Cart = $this->cartService->getCart();
599 55
        if ($Cart && count($Cart->getCartItems()) > 0) {
600 53
            $divide = $request->getSession()->get('cart.divide');
601 53
            if ($divide) {
602
                log_info('種別が異なる商品がカートと結合されたためカート画面にリダイレクト');
603
604
                return $this->redirectToRoute('cart');
605
            }
606
607 53
            return new Response();
608
        }
609 2
        log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
610
611
        // カートが存在しない時はエラー
612 2
        return $this->redirectToRoute('cart');
613
    }
614
615
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
616
     * 受注情報を初期化する.
617
     *
618
     * @ForwardOnly
619
     * @Route("/shopping/initialize_order", name="shopping_initialize_order")
620
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
621 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...
622
    {
623
        // 購入処理中の受注情報を取得
624 50
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
625
626
        // 初回アクセス(受注情報がない)の場合は, 受注情報を作成
627 50
        if (is_null($Order)) {
628
            // 未ログインの場合, ログイン画面へリダイレクト.
629 34
            if (!$this->isGranted('IS_AUTHENTICATED_FULLY')) {
630
                // 非会員でも一度会員登録されていればショッピング画面へ遷移
631
                $Customer = $this->shoppingService->getNonMember($this->sessionKey);
632
633
                if (is_null($Customer)) {
634
                    log_info('未ログインのためログイン画面にリダイレクト');
635
636
                    return $this->redirectToRoute('shopping_login');
637
                }
638
            } else {
639 34
                $Customer = $this->getUser();
640
            }
641
642
            try {
643
                // 受注情報を作成
644
                //$Order = $app['eccube.service.shopping']->createOrder($Customer);
645 34
                $Order = $this->orderHelper->createProcessingOrder(
646 34
                    $Customer,
647 34
                    $this->cartService->getCart()->getCartItems()
648
                );
649 34
                $this->cartService->setPreOrderId($Order->getPreOrderId());
650 34
                $this->cartService->save();
651
            } catch (CartException $e) {
652
                log_error('初回受注情報作成エラー', [$e->getMessage()]);
653
                $this->addRequestError($e->getMessage());
654
655
                return $this->redirectToRoute('cart');
656
            }
657
658
            // セッション情報を削除
659 34
            $this->session->remove($this->sessionOrderKey);
660
        }
661
662
        // 受注関連情報を最新状態に更新
663 50
        $this->entityManager->refresh($Order);
664
665 50
        $this->parameterBag->set('Order', $Order);
666
667 50
        return new Response();
668
    }
669
670
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
671
     * フォームを作成し, イベントハンドラを設定する
672
     *
673
     * @ForwardOnly
674
     * @Route("/shopping/create_form", name="shopping_create_form")
675
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
676 50
    public function createShoppingForm(Request $request)
677
    {
678 50
        $Order = $this->parameterBag->get('Order');
679
        // フォームの生成
680 50
        $builder = $this->formFactory->createBuilder(OrderType::class, $Order);
681
682 50
        $event = new EventArgs(
683
             [
684 50
                 'builder' => $builder,
685 50
                 'Order' => $Order,
686
             ],
687 50
             $request
688
         );
689 50
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);
690
691 50
        $form = $builder->getForm();
692
693 50
        $this->parameterBag->set(OrderType::class, $form);
694
695 50
        return new Response();
696
    }
697
698
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
699
     * mode に応じて各変更ページへリダイレクトする.
700
     *
701
     * @ForwardOnly
702
     * @Route("/shopping/redirect_to_change", name="shopping_redirect_to_change")
703
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
704 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...
705
    {
706 20
        $form = $this->parameterBag->get(OrderType::class);
707
708
        // requestのバインド後、Calculatorに再集計させる
709
        //$app['eccube.service.calculate']($Order, $Order->getCustomer())->calculate();
710
711
        // 支払い方法の変更や配送業者の変更があった場合はDBに保持する.
712 20
        if ($form->isSubmitted() && $form->isValid()) {
713
            // POSTされたデータをDBに保持.
714 8
            $this->entityManager->flush();
715
716 8
            $mode = $form['mode']->getData();
717 8
            switch ($mode) {
718 7
                case 'shipping_change':
719
                    // お届け先設定一覧へリダイレクト
720 1
                    $param = $form['param']->getData();
721
722 1
                    return $this->redirectToRoute('shopping_shipping', ['id' => $param]);
723 7
                case 'shipping_edit_change':
724
                    // お届け先設定一覧へリダイレクト
725
                    $param = $form['param']->getData();
726
727
                    return $this->redirectToRoute('shopping_shipping_edit', ['id' => $param]);
728 7
                case 'shipping_multiple_change':
729
                    // 複数配送設定へリダイレクト
730
                    return $this->redirectToRoute('shopping_shipping_multiple');
731 7
                case 'payment':
732 7
                case 'delivery':
733
                default:
734 7
                    return $this->redirectToRoute('shopping');
735
            }
736
        }
737
738 12
        return new Response();
739
    }
740
741
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
742
     * 受注の存在チェック
743
     *
744
     * @ForwardOnly
745
     * @Route("/shopping/exists_order", name="shopping_exists_order")
746
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
747 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...
748
    {
749 26
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
750 26
        if (!$Order) {
751
            log_info('購入処理中の受注情報がないため購入エラー');
752
            $this->addError('front.shopping.order.error');
753
754
            return $this->redirectToRoute('shopping_error');
755
        }
756 26
        $this->parameterBag->set('Order', $Order);
757
758 26
        return new Response();
759
    }
760
761
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
762
     * 受注完了処理
763
     *
764
     * @ForwardOnly
765
     * @Route("/shopping/complete_order", name="shopping_complete_order")
766
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
767 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...
768
    {
769 6
        $form = $this->parameterBag->get(OrderType::class);
770
771 6
        if ($form->isSubmitted() && $form->isValid()) {
772
            /** @var Order $Order */
773 6
            $Order = $form->getData();
774 6
            log_info('購入処理開始', [$Order->getId()]);
775
776
            // トランザクション制御
777 6
            $em = $this->entityManager;
778 6
            $em->getConnection()->beginTransaction();
779
            try {
780
                // お問い合わせ、配送時間などのフォーム項目をセット
781
                // FormTypeで更新されるため不要
782
                //$app['eccube.service.shopping']->setFormData($Order, $data);
783
784 6
                $flowResult = $this->executePurchaseFlow($Order);
785 6
                if ($flowResult->hasWarning() || $flowResult->hasError()) {
786
                    // TODO エラーメッセージ
787
                    throw new ShoppingException();
788
                }
789
                try {
790 6
                    $this->purchaseFlow->purchase($Order, new PurchaseContext($Order, $Order->getCustomer())); // TODO 変更前の Order を渡す必要がある?
791
                } 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...
792
                    $this->addError($e->getMessage(), 'front');
793
                }
794
795
                // 購入処理
796 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...
797
798
                // Order も引数で渡すのがベスト??
799 6
                $paymentService = $this->createPaymentService($Order);
800 6
                $paymentMethod = $this->createPaymentMethod($Order, $form);
801
802
                // 必要に応じて別のコントローラへ forward or redirect(移譲)
803
                // forward の処理はプラグイン内で書けるようにしておく
804
                // dispatch をしたら, パスを返して forwardする
805
                // http://silex.sensiolabs.org/doc/cookbook/sub_requests.html
806
                // 確認画面も挟める
807
                // Request をセッションに入れるべし
808 6
                $dispatcher = $paymentService->dispatch($paymentMethod); // 決済処理中.
809
                // 一旦、決済処理中になった後は、購入処理中に戻せない。キャンセル or 購入完了の仕様とする
810
                // ステータス履歴も保持しておく? 在庫引き当ての仕様もセットで。
811 6
                if ($dispatcher instanceof Response
812 6
                    && ($dispatcher->isRedirection() || $dispatcher->getContent())
813
                ) { // $paymentMethod->apply() が Response を返した場合は画面遷移
814
                    return $dispatcher;                // 画面遷移したいパターンが複数ある場合はどうする? 引数で制御?
815
                }
816 6
                $PaymentResult = $paymentService->doCheckout($paymentMethod); // 決済実行
817 6
                if (!$PaymentResult->isSuccess()) {
818
                    $this->entityManager->getConnection()->rollback();
819
820
                    return $this->redirectToRoute('shopping_error');
821
                }
822
823 6
                $this->entityManager->flush();
824 6
                $this->entityManager->getConnection()->commit();
825
826 6
                log_info('購入処理完了', [$Order->getId()]);
827
            } catch (ShoppingException $e) {
828
                log_error('購入エラー', [$e->getMessage()]);
829
830
                $this->entityManager->getConnection()->rollback();
831
832
                $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...
833
                $this->addError($e->getMessage());
834
835
                return $this->redirectToRoute('shopping_error');
836
            } catch (\Exception $e) {
837
                log_error('予期しないエラー', [$e->getMessage()]);
838
839
                $this->entityManager->getConnection()->rollback();
840
841
                $this->addError('front.shopping.system.error');
842
843
                return $this->redirectToRoute('shopping_error');
844
            }
845
846 6
            return $this->forwardToRoute('shopping_after_complete');
847
        }
848
849
        return new Response();
850
    }
851
852
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$request" missing
Loading history...
853
     * 受注完了の後処理
854
     *
855
     * @ForwardOnly
856
     * @Route("/shopping/after_complete", name="shopping_after_complete")
857
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
858 6
    public function afterComplete(Request $request)
859
    {
860 6
        $form = $this->parameterBag->get(OrderType::class);
861 6
        $Order = $this->parameterBag->get('Order');
862
863
        // カート削除
864 6
        $this->cartService->clear()->save();
865
866 6
        $event = new EventArgs(
867
            [
868 6
                'form' => $form,
869 6
                'Order' => $Order,
870
            ],
871 6
            $request
872
        );
873 6
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING, $event);
874
875 6 View Code Duplication
        if ($event->getResponse() !== null) {
876
            log_info('イベントレスポンス返却', [$Order->getId()]);
877
878
            return $event->getResponse();
879
        }
880
881
        // 受注IDをセッションにセット
882 6
        $this->session->set($this->sessionOrderKey, $Order->getId());
883
884
        // メール送信
885 6
        $MailHistory = $this->shoppingService->sendOrderMail($Order);
886
887 6
        $event = new EventArgs(
888
            [
889 6
                'form' => $form,
890 6
                'Order' => $Order,
891 6
                'MailHistory' => $MailHistory,
892
            ],
893 6
            $request
894
        );
895 6
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_COMPLETE, $event);
896
897 6 View Code Duplication
        if ($event->getResponse() !== null) {
898
            log_info('イベントレスポンス返却', [$Order->getId()]);
899
900
            return $event->getResponse();
901
        }
902
903
        // 完了画面表示
904 6
        return $this->redirectToRoute('shopping_complete');
905
    }
906
907 6
    private function createPaymentService(Order $Order)
908
    {
909 6
        $serviceClass = $Order->getPayment()->getServiceClass();
910 6
        $paymentService = new $serviceClass($this->container->get('request_stack'));
911
912 6
        return $paymentService;
913
    }
914
915 6
    private function createPaymentMethod(Order $Order, $form)
916
    {
917 6
        $methodClass = $Order->getPayment()->getMethodClass();
918 6
        $PaymentMethod = new $methodClass();
919 6
        $PaymentMethod->setFormType($form);
920 6
        $PaymentMethod->setRequest($this->container->get('request_stack')->getCurrentRequest());
921
922 6
        return $PaymentMethod;
923
    }
924
925
    /**
926
     * 非会員でのお客様情報変更時の入力チェック
927
     *
928
     * TODO https://github.com/EC-CUBE/ec-cube/issues/565
929
     *
930
     * @param Application $app
931
     * @param array $data リクエストパラメータ
932
     *
933
     * @return array
934
     */
935
    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...
936
    {
937
        // 入力チェック
938
        $errors = [];
939
940
        $errors[] = $app['validator']->validateValue($data['customer_name01'], [
941
            new Assert\NotBlank(),
942
            new Assert\Length(['max' => $app['config']['name_len']]),
943
            new Assert\Regex(['pattern' => '/^[^\s ]+$/u', 'message' => 'form.type.name.firstname.nothasspace']),
944
        ]);
945
946
        $errors[] = $app['validator']->validateValue($data['customer_name02'], [
947
            new Assert\NotBlank(),
948
            new Assert\Length(['max' => $app['config']['name_len']]),
949
            new Assert\Regex(['pattern' => '/^[^\s ]+$/u', 'message' => 'form.type.name.firstname.nothasspace']),
950
        ]);
951
952
        // 互換性確保のためキーが存在する場合にのみバリデーションを行う(kana01は3.0.15から追加)
953 View Code Duplication
        if (array_key_exists('customer_kana01', $data)) {
954
            $data['customer_kana01'] = mb_convert_kana($data['customer_kana01'], 'CV', 'utf-8');
955
            $errors[] = $app['validator']->validateValue($data['customer_kana01'], [
956
                new Assert\NotBlank(),
957
                new Assert\Length(['max' => $app['config']['kana_len']]),
958
                new Assert\Regex(['pattern' => '/^[ァ-ヶヲ-゚ー]+$/u']),
959
            ]);
960
        }
961
962
        // 互換性確保のためキーが存在する場合にのみバリデーションを行う(kana01は3.0.15から追加)
963 View Code Duplication
        if (array_key_exists('customer_kana02', $data)) {
964
            $data['customer_kana02'] = mb_convert_kana($data['customer_kana02'], 'CV', 'utf-8');
965
            $errors[] = $app['validator']->validateValue($data['customer_kana02'], [
966
                new Assert\NotBlank(),
967
                new Assert\Length(['max' => $app['config']['kana_len']]),
968
                new Assert\Regex(['pattern' => '/^[ァ-ヶヲ-゚ー]+$/u']),
969
            ]);
970
        }
971
972
        $errors[] = $app['validator']->validateValue($data['customer_company_name'], [
973
            new Assert\Length(['max' => $app['config']['stext_len']]),
974
        ]);
975
976
        $errors[] = $app['validator']->validateValue($data['customer_tel01'], [
977
            new Assert\NotBlank(),
978
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
979
            new Assert\Length(['max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min']]),
980
        ]);
981
982
        $errors[] = $app['validator']->validateValue($data['customer_tel02'], [
983
            new Assert\NotBlank(),
984
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
985
            new Assert\Length(['max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min']]),
986
        ]);
987
988
        $errors[] = $app['validator']->validateValue($data['customer_tel03'], [
989
            new Assert\NotBlank(),
990
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
991
            new Assert\Length(['max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min']]),
992
        ]);
993
994
        $errors[] = $app['validator']->validateValue($data['customer_zip01'], [
995
            new Assert\NotBlank(),
996
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
997
            new Assert\Length(['min' => $app['config']['zip01_len'], 'max' => $app['config']['zip01_len']]),
998
        ]);
999
1000
        $errors[] = $app['validator']->validateValue($data['customer_zip02'], [
1001
            new Assert\NotBlank(),
1002
            new Assert\Type(['type' => 'numeric', 'message' => 'form.type.numeric.invalid']),
1003
            new Assert\Length(['min' => $app['config']['zip02_len'], 'max' => $app['config']['zip02_len']]),
1004
        ]);
1005
1006
        $errors[] = $app['validator']->validateValue($data['customer_addr01'], [
1007
            new Assert\NotBlank(),
1008
            new Assert\Length(['max' => $app['config']['address1_len']]),
1009
        ]);
1010
1011
        $errors[] = $app['validator']->validateValue($data['customer_addr02'], [
1012
            new Assert\NotBlank(),
1013
            new Assert\Length(['max' => $app['config']['address2_len']]),
1014
        ]);
1015
1016
        $errors[] = $app['validator']->validateValue($data['customer_email'], [
1017
            new Assert\NotBlank(),
1018
            new Assert\Email(['strict' => true]),
1019
        ]);
1020
1021
        return $errors;
1022
    }
1023
}
1024