Completed
Pull Request — experimental/3.1 (#2479)
by chihiro
65:40 queued 24:05
created

ShoppingController   F

Complexity

Total Complexity 92

Size/Duplication

Total Lines 856
Duplicated Lines 14.6 %

Coupling/Cohesion

Components 1
Dependencies 22

Test Coverage

Coverage 54.55%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 125
loc 856
rs 1.263
c 2
b 0
f 0
ccs 180
cts 330
cp 0.5455
wmc 92
lcom 1
cbo 22

16 Methods

Rating   Name   Duplication   Size   Complexity  
C index() 36 36 7
C redirectTo() 32 32 7
C confirm() 36 36 7
B complete() 0 31 2
C shipping() 0 85 10
D shippingEdit() 7 110 15
B login() 6 35 5
A shoppingError() 0 14 2
A checkToCart() 0 20 3
B initializeOrder() 0 50 5
A createForm() 0 21 1
C redirectToChange() 0 36 8
B handleMultipleErrors() 0 24 4
A existsOrder() 0 13 2
C completeOrder() 0 90 11
A afterComplete() 8 48 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ShoppingController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ShoppingController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) 2000-2015 LOCKON CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.lockon.co.jp/
8
 *
9
 * This program is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU General Public License
11
 * as published by the Free Software Foundation; either version 2
12
 * of the License, or (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
 */
23
24
25
namespace Eccube\Controller;
26
27
use Doctrine\ORM\EntityManager;
28
use Eccube\Annotation\Component;
29
use Eccube\Annotation\Inject;
30
use Eccube\Application;
31
use Eccube\Entity\Customer;
32
use Eccube\Entity\CustomerAddress;
33
use Eccube\Entity\Order;
34
use Eccube\Event\EccubeEvents;
35
use Eccube\Event\EventArgs;
36
use Eccube\Exception\CartException;
37
use Eccube\Exception\ShoppingException;
38
use Eccube\Form\Type\Front\CustomerLoginType;
39
use Eccube\Form\Type\Front\ShoppingShippingType;
40
use Eccube\Form\Type\Shopping\OrderType;
41
use Eccube\Repository\BaseInfoRepository;
42
use Eccube\Repository\CustomerAddressRepository;
43
use Eccube\Service\CartService;
44
use Eccube\Service\OrderHelper;
45
use Eccube\Service\ShoppingService;
46
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
47
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
48
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
49
use Symfony\Component\EventDispatcher\EventDispatcher;
50
use Symfony\Component\Form\FormFactory;
51
use Symfony\Component\HttpFoundation\ParameterBag;
52
use Symfony\Component\HttpFoundation\Request;
53
use Symfony\Component\HttpFoundation\Response;
54
use Symfony\Component\HttpFoundation\Session\Session;
55
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
56
57
/**
58
 * @Component
59
 * @Route(service=ShoppingController::class)
60
 */
61
class ShoppingController extends AbstractShoppingController
62
{
63
    /**
64
     * @Inject(BaseInfoRepository::class)
65
     * @var BaseInfoRepository
66
     */
67
    protected $baseInfoRepository;
68
69
    /**
70
     * @Inject(OrderHelper::class)
71
     * @var OrderHelper
72
     */
73
    protected $orderHelper;
74
75
    /**
76
     * @Inject(CartService::class)
77
     * @var CartService
78
     */
79
    protected $cartService;
80
81
    /**
82
     * @Inject("form.factory")
83
     * @var FormFactory
84
     */
85
    protected $formFactory;
86
87
    /**
88
     * @Inject("orm.em")
89
     * @var EntityManager
90
     */
91
    protected $entityManager;
92
93
    /**
94
     * @Inject("config")
95
     * @var array
96
     */
97
    protected $appConfig;
98
99
    /**
100
     * @Inject(ShoppingService::class)
101
     * @var ShoppingService
102
     */
103
    protected $shoppingService;
104
105
    /**
106
     * @Inject(CustomerAddressRepository::class)
107
     * @var CustomerAddressRepository
108
     */
109
    protected $customerAddressRepository;
110
111
    /**
112
     * @Inject("eccube.event.dispatcher")
113
     * @var EventDispatcher
114
     */
115
    protected $eventDispatcher;
116
117
    /**
118
     * @Inject("session")
119
     * @var Session
120
     */
121
    protected $session;
122
123
    /**
124
     * @Inject("request_scope")
125
     * @var ParameterBag
126
     */
127
    protected $parameterBag;
128
129
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
130
     * 購入画面表示
131
     *
132
     * @Route("/shopping", name="shopping")
133
     * @Template("Shopping/index.twig")
134
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
135 13 View Code Duplication
    public function index(Application $app, 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...
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...
136
    {
137
        // カートチェック
138 13
        $response = $app->forward($app->path("shopping_check_to_cart"));
139 13
        if ($response->isRedirection() || $response->getContent()) {
140 3
            return $response;
141
        }
142
143
        // 受注情報を初期化
144 10
        $response = $app->forward($app->path("shopping_initialize_order"));
145 10
        if ($response->isRedirection() || $response->getContent()) {
146
            return $response;
147
        }
148
149
        /** @var Order $Order */
150 10
        $Order = $this->parameterBag->get('Order');
151
152
        // 単価集計
153 10
        $flowResult = $this->executePurchaseFlow($app, $Order);
154
155
        // フォームを生成する
156 10
        $app->forward($app->path("shopping_create_form"));
157
158 10
        if ($flowResult->hasWarning() || $flowResult->hasError()) {
159
            return $app->redirect($app->url('cart'));
160
        }
161
162
        // 複数配送の場合、エラーメッセージを一度だけ表示
163 10
        $app->forward($app->path("shopping_handle_multiple_errors"));
164 10
        $form = $this->parameterBag->get(OrderType::class);
165
166
        return [
167 10
            'form' => $form->createView(),
168 10
            'Order' => $Order,
169
        ];
170
    }
171
172
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
173
     * 購入確認画面から, 他の画面へのリダイレクト.
174
     * 配送業者や支払方法、お問い合わせ情報をDBに保持してから遷移する.
175
     *
176
     * @Route("/shopping/redirect", name="shopping_redirect_to")
177
     * @Template("Shopping/index.twig")
178
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
179 5 View Code Duplication
    public function redirectTo(Application $app, 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...
180
    {
181
        // カートチェック
182 5
        $response = $app->forward($app->path("shopping_check_to_cart"));
183 5
        if ($response->isRedirection() || $response->getContent()) {
184
            return $response;
185
        }
186
187
        // 受注の存在チェック
188 5
        $response = $app->forward($app->path("shopping_exists_order"));
189 5
        if ($response->isRedirection() || $response->getContent()) {
190
            return $response;
191
        }
192
193
        // フォームの生成
194 5
        $app->forward($app->path("shopping_create_form"));
195 5
        $form = $this->parameterBag->get(OrderType::class);
196 5
        $form->handleRequest($request);
197
198
        // 各種変更ページへリダイレクトする
199 5
        $response = $app->forward($app->path("shopping_redirect_to_change"));
200 5
        if ($response->isRedirection() || $response->getContent()) {
201 2
            return $response;
202
        }
203 3
        $form = $this->parameterBag->get(OrderType::class);
204 3
        $Order = $this->parameterBag->get('Order');
205
206
        return [
207 3
            'form' => $form->createView(),
208 3
            'Order' => $Order,
209
        ];
210
    }
211
212
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
213
     * 購入処理
214
     *
215
     * @Route("/shopping/confirm", name="shopping_confirm")
216
     * @Method("POST")
217
     * @Template("Shopping/index.twig")
218
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
219 2 View Code Duplication
    public function confirm(Application $app, 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...
220
    {
221
        // カートチェック
222 2
        $response = $app->forward($app->path("shopping_check_to_cart"));
223 2
        if ($response->isRedirection() || $response->getContent()) {
224
            return $response;
225
        }
226
227
        // 受注の存在チェック
228 2
        $response = $app->forward($app->path("shopping_exists_order"));
229 2
        if ($response->isRedirection() || $response->getContent()) {
230
            return $response;
231
        }
232
233
        // form作成
234
        // FIXME イベントハンドラを外から渡したい
235 2
        $app->forward($app->path("shopping_create_form"));
236
237 2
        $form = $this->parameterBag->get(OrderType::class);
238 2
        $Order = $this->parameterBag->get('Order');
239
240 2
        $form->handleRequest($request);
241
242
        // 受注処理
243 2
        $response = $app->forward($app->path("shopping_complete_order"));
244 2
        if ($response->isRedirection() || $response->getContent()) {
245 2
            return $response;
246
        }
247
248
        log_info('購入チェックエラー', array($Order->getId()));
249
250
        return [
251
            'form' => $form->createView(),
252
            'Order' => $Order,
253
        ];
254
    }
255
256
257
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
258
     * 購入完了画面表示
259
     *
260
     * @Route("/shopping/complete", name="shopping_complete")
261
     * @Template("Shopping/complete.twig")
262
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
263 1
    public function complete(Application $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $app 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...
264
    {
265
        // 受注IDを取得
266 1
        $orderId = $this->session->get($this->sessionOrderKey);
267
268 1
        $event = new EventArgs(
269
            array(
270 1
                'orderId' => $orderId,
271
            ),
272 1
            $request
273
        );
274 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE, $event);
275
276 1
        if ($event->getResponse() !== null) {
277
            return $event->getResponse();
278
        }
279
280
        // 受注に関連するセッションを削除
281 1
        $this->session->remove($this->sessionOrderKey);
282 1
        $this->session->remove($this->sessionMultipleKey);
283
284
        // 非会員用セッション情報を空の配列で上書きする(プラグイン互換性保持のために削除はしない)
285 1
        $this->session->set($this->sessionKey, array());
286 1
        $this->session->set($this->sessionCustomerAddressKey, array());
287
288 1
        log_info('購入処理完了', array($orderId));
289
290
        return [
291 1
            'orderId' => $orderId,
292
        ];
293
    }
294
295
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
296
     * お届け先の設定一覧からの選択
297
     *
298
     * @Route("/shopping/shipping/{id}", name="shopping_shipping", requirements={"id" = "\d+"})
299
     * @Template("Shopping/shipping.twig")
300
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
301 2
    public function shipping(Application $app, Request $request, $id)
302
    {
303
        // カートチェック
304 2
        $response = $app->forward($app->path("shopping_check_to_cart"));
305 2
        if ($response->isRedirection() || $response->getContent()) {
306
            return $response;
307
        }
308
309 2
        if ('POST' === $request->getMethod()) {
310 2
            $address = $request->get('address');
311
312 2
            if (is_null($address)) {
313
                // 選択されていなければエラー
314 2
                log_info('お届け先入力チェックエラー');
315
316
                return [
317 2
                    'Customer' => $app->user(),
318 2
                    'shippingId' => $id,
319
                    'error' => true,
320
                ];
321
            }
322
323
            // 選択されたお届け先情報を取得
324
            $CustomerAddress = $this->customerAddressRepository->findOneBy(
325
                array(
326
                    'Customer' => $app->user(),
327
                    'id' => $address,
328
                )
329
            );
330
            if (is_null($CustomerAddress)) {
331
                throw new NotFoundHttpException('選択されたお届け先住所が存在しない');
332
            }
333
334
            /** @var Order $Order */
335
            $Order = $this->shoppingService->getOrder($this->appConfig['order_processing']);
336
            if (!$Order) {
337
                log_info('購入処理中の受注情報がないため購入エラー');
338
                $app->addError('front.shopping.order.error');
339
340
                return $app->redirect($app->url('shopping_error'));
341
            }
342
343
            $Shipping = $Order->findShipping($id);
344
            if (!$Shipping) {
345
                throw new NotFoundHttpException('お届け先情報が存在しない');
346
            }
347
348
            log_info('お届先情報更新開始', array($Shipping->getId()));
349
350
            // お届け先情報を更新
351
            $Shipping->setFromCustomerAddress($CustomerAddress);
352
353
            // 配送料金の設定
354
            $this->shoppingService->setShippingDeliveryFee($Shipping);
355
356
357
            // 合計金額の再計算
358
            $flowResult = $this->executePurchaseFlow($app, $Order);
359
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
360
                return $app->redirect($app->url('shopping_error'));
361
            }
362
363
            // 配送先を更新
364
            $this->entityManager->flush();
365
366
            $event = new EventArgs(
367
                array(
368
                    'Order' => $Order,
369
                    'shippingId' => $id,
370
                ),
371
                $request
372
            );
373
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_COMPLETE, $event);
374
375
            log_info('お届先情報更新完了', array($Shipping->getId()));
376
377
            return $app->redirect($app->url('shopping'));
378
        }
379
380
        return [
381 1
            'Customer' => $app->user(),
382 1
            'shippingId' => $id,
383
            'error' => false,
384
        ];
385
    }
386
387
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
introduced by
Doc comment for parameter "$id" missing
Loading history...
388
     * お届け先の設定(非会員でも使用する)
389
     *
390
     * @Route("/shopping/shipping_edit/{id}", name="shopping_shipping_edit", requirements={"id" = "\d+"})
391
     * @Template("Shopping/shipping_edit.twig")
392
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
393
    public function shippingEdit(Application $app, Request $request, $id)
394
    {
395
        // 配送先住所最大値判定
396
        $Customer = $app->user();
397 View Code Duplication
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
398
            $addressCurrNum = count($app->user()->getCustomerAddresses());
399
            $addressMax = $this->appConfig['deliv_addr_max'];
400
            if ($addressCurrNum >= $addressMax) {
401
                throw new NotFoundHttpException('配送先住所最大数エラー');
402
            }
403
        }
404
405
        // カートチェック
406
        $response = $app->forward($app->path("shopping_check_to_cart"));
407
        if ($response->isRedirection() || $response->getContent()) {
408
            return $response;
409
        }
410
411
        // 受注の存在チェック
412
        $response = $app->forward($app->path("shopping_exists_order"));
413
        if ($response->isRedirection() || $response->getContent()) {
414
            return $response;
415
        }
416
417
        /** @var Order $Order */
418
        $Order = $this->parameterBag->get('Order');
419
420
        $Shipping = $Order->findShipping($id);
421
        if (!$Shipping) {
422
            throw new NotFoundHttpException('設定されている配送先が存在しない');
423
        }
424
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
425
            $Shipping->clearCustomerAddress();
426
        }
427
428
        $CustomerAddress = new CustomerAddress();
429
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
430
            $CustomerAddress->setCustomer($Customer);
431
        } else {
432
            $CustomerAddress->setFromShipping($Shipping);
433
        }
434
435
        $builder = $this->formFactory->createBuilder(ShoppingShippingType::class, $CustomerAddress);
436
437
        $event = new EventArgs(
438
            array(
439
                'builder' => $builder,
440
                'Order' => $Order,
441
                'Shipping' => $Shipping,
442
                'CustomerAddress' => $CustomerAddress,
443
            ),
444
            $request
445
        );
446
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_INITIALIZE, $event);
447
448
        $form = $builder->getForm();
449
450
        $form->handleRequest($request);
451
452
        if ($form->isSubmitted() && $form->isValid()) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
453
454
            log_info('お届け先追加処理開始', array('id' => $Order->getId(), 'shipping' => $id));
455
456
            // 会員の場合、お届け先情報を新規登録
457
            $Shipping->setFromCustomerAddress($CustomerAddress);
458
459
            if ($Customer instanceof Customer) {
460
                $this->entityManager->persist($CustomerAddress);
461
                log_info(
462
                    '新規お届け先登録',
463
                    array(
464
                        'id' => $Order->getId(),
465
                        'shipping' => $id,
466
                        'customer address' => $CustomerAddress->getId(),
467
                    )
468
                );
469
            }
470
471
            // 配送料金の設定
472
            $this->shoppingService->setShippingDeliveryFee($Shipping);
473
474
            // 合計金額の再計算
475
            $flowResult = $this->executePurchaseFlow($app, $Order);
476
            if ($flowResult->hasWarning() || $flowResult->hasError()) {
477
                return $app->redirect($app->url('shopping_error'));
478
            }
479
480
            // 配送先を更新
481
            $this->entityManager->flush();
482
483
            $event = new EventArgs(
484
                array(
485
                    'form' => $form,
486
                    'Shipping' => $Shipping,
487
                    'CustomerAddress' => $CustomerAddress,
488
                ),
489
                $request
490
            );
491
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_COMPLETE, $event);
492
493
            log_info('お届け先追加処理完了', array('id' => $Order->getId(), 'shipping' => $id));
494
495
            return $app->redirect($app->url('shopping'));
496
        }
497
498
        return [
499
            'form' => $form->createView(),
500
            'shippingId' => $id,
501
        ];
502
    }
503
504
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
505
     * ログイン
506
     *
507
     * @Route("/shopping/login", name="shopping_login")
508
     * @Template("Shopping/login.twig")
509
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
510 2
    public function login(Application $app, Request $request)
511
    {
512 2
        if (!$this->cartService->isLocked()) {
513 2
            return $app->redirect($app->url('cart'));
514
        }
515
516
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
517
            return $app->redirect($app->url('shopping'));
518
        }
519
520
        /* @var $form \Symfony\Component\Form\FormInterface */
521
        $builder = $this->formFactory->createNamedBuilder('', CustomerLoginType::class);
522
523 View Code Duplication
        if ($app->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
524
            $Customer = $app->user();
525
            if ($Customer) {
526
                $builder->get('login_email')->setData($Customer->getEmail());
527
            }
528
        }
529
530
        $event = new EventArgs(
531
            array(
532
                'builder' => $builder,
533
            ),
534
            $request
535
        );
536
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_LOGIN_INITIALIZE, $event);
537
538
        $form = $builder->getForm();
539
540
        return [
541
            'error' => $app['security.last_error']($request),
542
            'form' => $form->createView(),
543
        ];
544
    }
545
546
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
547
     * 購入エラー画面表示
548
     *
549
     * @Route("/shopping/error", name="shopping_error")
550
     * @Template("Shopping/shopping_error.twig")
551
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
552 1
    public function shoppingError(Application $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $app 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...
553
    {
554 1
        $event = new EventArgs(
555 1
            array(),
556 1
            $request
557
        );
558 1
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_ERROR_COMPLETE, $event);
559
560 1
        if ($event->getResponse() !== null) {
561
            return $event->getResponse();
562
        }
563
564 1
        return [];
565
    }
566
567
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
568
     * カート画面のチェック
569
     *
570
     * @Route("/shopping/check_to_cart", name="shopping_check_to_cart")
571
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
572 17
    public function checkToCart(Application $app, 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...
573
    {
574
        // カートチェック
575 17
        if (!$this->cartService->isLocked()) {
576 3
            log_info('カートが存在しません');
577
578
            // カートが存在しない、カートがロックされていない時はエラー
579 3
            return $app->redirect($app->url('cart'));
580
        }
581
582
        // カートチェック
583 14
        if (count($this->cartService->getCart()->getCartItems()) <= 0) {
584 1
            log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
585
586
            // カートが存在しない時はエラー
587 1
            return $app->redirect($app->url('cart'));
588
        }
589
590 13
        return new Response();
591
    }
592
593
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
594
     * 受注情報を初期化する.
595
     *
596
     * @Route("/shopping/initialize_order", name="shopping_initialize_order")
597
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
598 10
    public function initializeOrder(Application $app, 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...
599
    {
600
        // 購入処理中の受注情報を取得
601 10
        $Order = $this->shoppingService->getOrder($this->appConfig['order_processing']);
602
603
        // 初回アクセス(受注情報がない)の場合は, 受注情報を作成
604 10
        if (is_null($Order)) {
605
            // 未ログインの場合, ログイン画面へリダイレクト.
606 10
            if (!$app->isGranted('IS_AUTHENTICATED_FULLY')) {
607
                // 非会員でも一度会員登録されていればショッピング画面へ遷移
608 2
                $Customer = $this->shoppingService->getNonMember($this->sessionKey);
609
610 2
                if (is_null($Customer)) {
611
                    log_info('未ログインのためログイン画面にリダイレクト');
612
613 2
                    return $app->redirect($app->url('shopping_login'));
614
                }
615
            } else {
616 8
                $Customer = $app->user();
617
            }
618
619
            try {
620
                // 受注情報を作成
621
                //$Order = $app['eccube.service.shopping']->createOrder($Customer);
622 10
                $Order = $this->orderHelper->createProcessingOrder(
623 10
                    $Customer,
624 10
                    $Customer->getCustomerAddresses()->current(),
625 10
                    $this->cartService->getCart()->getCartItems()
626
                );
627 10
                $this->cartService->setPreOrderId($Order->getPreOrderId());
628 10
                $this->cartService->save();
629
            } catch (CartException $e) {
630
                log_error('初回受注情報作成エラー', array($e->getMessage()));
631
                $app->addRequestError($e->getMessage());
632
633
                return $app->redirect($app->url('cart'));
634
            }
635
636
            // セッション情報を削除
637 10
            $this->session->remove($this->sessionOrderKey);
638 10
            $this->session->remove($this->sessionMultipleKey);
639
        }
640
641
        // 受注関連情報を最新状態に更新
642 10
        $this->entityManager->refresh($Order);
643
644 10
        $this->parameterBag->set('Order', $Order);
645
646 10
        return new Response();
647
    }
648
649
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
650
     * フォームを作成し, イベントハンドラを設定する
651
     *
652
     * @Route("/shopping/create_form", name="shopping_create_form")
653
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
654 10
    public function createForm(Application $app, Request $request)
0 ignored issues
show
Unused Code introduced by
The parameter $app 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...
655
    {
656 10
        $Order = $this->parameterBag->get('Order');
657
        // フォームの生成
658 10
        $builder = $this->formFactory->createBuilder(OrderType::class, $Order);
659
660 10
        $event = new EventArgs(
661
            array(
662 10
                'builder' => $builder,
663 10
                'Order' => $Order,
664
            ),
665 10
            $request
666
        );
667 10
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);
668
669 10
        $form = $builder->getForm();
670
671 10
        $this->parameterBag->set(OrderType::class, $form);
672
673 10
        return new Response();
674
    }
675
676
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
677
     * mode に応じて各変更ページへリダイレクトする.
678
     *
679
     * @Route("/shopping/redirect_to_change", name="shopping_redirect_to_change")
680
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
681 5
    public function redirectToChange(Application $app, 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...
682
    {
683 5
        $form = $this->parameterBag->get(OrderType::class);
684
685
        // requestのバインド後、Calculatorに再集計させる
686
        //$app['eccube.service.calculate']($Order, $Order->getCustomer())->calculate();
687
688
        // 支払い方法の変更や配送業者の変更があった場合はDBに保持する.
689 5
        if ($form->isSubmitted() && $form->isValid()) {
690
            // POSTされたデータをDBに保持.
691 2
            $this->entityManager->flush();
692
693 2
            $mode = $form['mode']->getData();
694
            switch ($mode) {
695 2
                case 'shipping_change':
696
                    // お届け先設定一覧へリダイレクト
697
                    $param = $form['param']->getData();
698
699
                    return $app->redirect($app->url('shopping_shipping', array('id' => $param)));
700 2
                case 'shipping_edit_change':
701
                    // お届け先設定一覧へリダイレクト
702
                    $param = $form['param']->getData();
703
704
                    return $app->redirect($app->url('shopping_shipping_edit', array('id' => $param)));
705 2
                case 'shipping_multiple_change':
706
                    // 複数配送設定へリダイレクト
707
                    return $app->redirect($app->url('shopping_shipping_multiple'));
708 2
                case 'payment':
709 2
                case 'delivery':
710
                default:
711 2
                    return $app->redirect($app->url('shopping'));
712
            }
713
        }
714
715 3
        return new Response();
716
    }
717
718
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
719
     * 複数配送時のエラーを表示する
720
     *
721
     * @Route("/shopping/handle_multiple_errors", name="shopping_handle_multiple_errors")
722
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
723 10
    public function handleMultipleErrors(Application $app, 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...
724
    {
725 10
        $Order = $this->parameterBag->get('Order');
726
727
        // 複数配送の場合、エラーメッセージを一度だけ表示
728 10
        if (!$this->session->has($this->sessionMultipleKey)) {
729 10
            if (count($Order->getShippings()) > 1) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
730
731
                $BaseInfo = $this->baseInfoRepository->get();
732
733
                if (!$BaseInfo->getOptionMultipleShipping()) {
734
                    // 複数配送に設定されていないのに複数配送先ができればエラー
735
                    $app->addRequestError('cart.product.type.kind');
736
737
                    return $app->redirect($app->url('cart'));
738
                }
739
740
                $app->addError('shopping.multiple.delivery');
741
            }
742 10
            $this->session->set($this->sessionMultipleKey, 'multiple');
743
        }
744
745 10
        return new Response();
746
    }
747
748
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
749
     * 受注の存在チェック
750
     *
751
     * @Route("/shopping/exists_order", name="shopping_exists_order")
752
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
753 7
    public function existsOrder(Application $app, 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...
754
    {
755 7
        $Order = $this->shoppingService->getOrder($this->appConfig['order_processing']);
756 7
        if (!$Order) {
757
            log_info('購入処理中の受注情報がないため購入エラー');
758
            $app->addError('front.shopping.order.error');
759
760
            return $app->redirect($app->url('shopping_error'));
761
        }
762 7
        $this->parameterBag->set('Order', $Order);
763
764 7
        return new Response();
765
    }
766
767
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
768
     * 受注完了処理
769
     *
770
     * @Route("/shopping/complete_order", name="shopping_complete_order")
771
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
772 2
    public function completeOrder(Application $app, Request $request)
773
    {
774 2
        $form = $this->parameterBag->get(OrderType::class);
775
776 2
        if ($form->isSubmitted() && $form->isValid()) {
777
778
            /** @var Order $Order */
779 2
            $Order = $form->getData();
780 2
            log_info('購入処理開始', array($Order->getId()));
781
782
            // トランザクション制御
783 2
            $em = $this->entityManager;
784 2
            $em->getConnection()->beginTransaction();
785
            try {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
786
787
                // お問い合わせ、配送時間などのフォーム項目をセット
788
                // FormTypeで更新されるため不要
789
                //$app['eccube.service.shopping']->setFormData($Order, $data);
790
791 2
                $flowResult = $this->executePurchaseFlow($app, $Order);
792 2
                if ($flowResult->hasWarning() || $flowResult->hasError()) {
793
                    // TODO エラーメッセージ
794
                    throw new ShoppingException();
795
                }
796
797
                // 購入処理
798 2
                $this->shoppingService->processPurchase($Order); // XXX フロント画面に依存してるので管理画面では使えない
799
800
                // Order も引数で渡すのがベスト??
801 2
                $paymentService = $app['eccube.service.payment']($Order->getPayment()->getServiceClass());
802
803 2
                $paymentMethod = $app['payment.method.request'](
804 2
                    $Order->getPayment()->getMethodClass(),
805 2
                    $form,
806 2
                    $request
807
                );
808
                // 必要に応じて別のコントローラへ forward or redirect(移譲)
809
                // forward の処理はプラグイン内で書けるようにしておく
810
                // dispatch をしたら, パスを返して forwardする
811
                // http://silex.sensiolabs.org/doc/cookbook/sub_requests.html
812
                // 確認画面も挟める
813
                // Request をセッションに入れるべし
814 2
                $dispatcher = $paymentService->dispatch($paymentMethod); // 決済処理中.
815
                // 一旦、決済処理中になった後は、購入処理中に戻せない。キャンセル or 購入完了の仕様とする
816
                // ステータス履歴も保持しておく? 在庫引き当ての仕様もセットで。
817 2
                if ($dispatcher instanceof Response
818 2
                    && ($dispatcher->isRedirection() || $dispatcher->getContent())
819
                ) { // $paymentMethod->apply() が Response を返した場合は画面遷移
820
                    return $dispatcher;                // 画面遷移したいパターンが複数ある場合はどうする? 引数で制御?
821
                }
822 2
                $PaymentResult = $paymentService->doCheckout($paymentMethod); // 決済実行
823 2
                if (!$PaymentResult->isSuccess()) {
824
                    $em->getConnection()->rollback();
825
826
                    return $app->redirect($app->url('shopping_error'));
827
                }
828
829 2
                $em->flush();
830 2
                $em->getConnection()->commit();
831
832 2
                log_info('購入処理完了', array($Order->getId()));
833
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
834
            } catch (ShoppingException $e) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
835
836
                log_error('購入エラー', array($e->getMessage()));
837
838
                $em->getConnection()->rollback();
839
840
                $app->log($e);
841
                $app->addError($e->getMessage());
842
843
                return $app->redirect($app->url('shopping_error'));
844
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style introduced by
Blank line found at start of control structure
Loading history...
845
846
                log_error('予期しないエラー', array($e->getMessage()));
847
848
                $em->getConnection()->rollback();
849
850
                $app->log($e);
851
852
                $app->addError('front.shopping.system.error');
853
854
                return $app->redirect($app->url('shopping_error'));
855
            }
856
857 2
            return $app->forward($app->path('shopping_after_complete'));
858
        }
859
860
        return new Response();
861
    }
862
863
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$app" missing
Loading history...
introduced by
Doc comment for parameter "$request" missing
Loading history...
864
     * 受注完了の後処理
865
     *
866
     * @Route("/shopping/after_complete", name="shopping_after_complete")
867
     */
0 ignored issues
show
introduced by
Missing @return tag in function comment
Loading history...
868 2
    public function afterComplete(Application $app, Request $request)
869
    {
870 2
        $form = $this->parameterBag->get(OrderType::class);
871 2
        $Order = $this->parameterBag->get('Order');
872
873
        // カート削除
874 2
        $this->cartService->clear()->save();
875
876 2
        $event = new EventArgs(
877
            array(
878 2
                'form' => $form,
879 2
                'Order' => $Order,
880
            ),
881 2
            $request
882
        );
883 2
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING, $event);
884
885 2 View Code Duplication
        if ($event->getResponse() !== null) {
886
            log_info('イベントレスポンス返却', array($Order->getId()));
887
888
            return $event->getResponse();
889
        }
890
891
        // 受注IDをセッションにセット
892 2
        $this->session->set($this->sessionOrderKey, $Order->getId());
893
894
        // メール送信
895 2
        $MailHistory = $this->shoppingService->sendOrderMail($Order);
896
897 2
        $event = new EventArgs(
898
            array(
899 2
                'form' => $form,
900 2
                'Order' => $Order,
901 2
                'MailHistory' => $MailHistory,
902
            ),
903 2
            $request
904
        );
905 2
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_COMPLETE, $event);
906
907 2 View Code Duplication
        if ($event->getResponse() !== null) {
908
            log_info('イベントレスポンス返却', array($Order->getId()));
909
910
            return $event->getResponse();
911
        }
912
913
        // 完了画面表示
914 2
        return $app->redirect($app->url('shopping_complete'));
915
    }
916
}
917