ShoppingController::shippingEdit()   C
last analyzed

Complexity

Conditions 11
Paths 31

Size

Total Lines 101

Duplication

Lines 7
Ratio 6.93 %

Importance

Changes 0
Metric Value
cc 11
nc 31
nop 3
dl 7
loc 101
rs 5.8533
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/*
3
 * This file is part of EC-CUBE
4
 *
5
 * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
6
 *
7
 * http://www.ec-cube.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 Eccube\Application;
28
use Eccube\Common\Constant;
29
use Eccube\Entity\Customer;
30
use Eccube\Entity\CustomerAddress;
31
use Eccube\Entity\Order;
32
use Eccube\Entity\ShipmentItem;
33
use Eccube\Entity\Shipping;
34
use Eccube\Event\EccubeEvents;
35
use Eccube\Event\EventArgs;
36
use Eccube\Exception\CartException;
37
use Eccube\Exception\ShoppingException;
38
use Symfony\Component\HttpFoundation\Request;
39
use Symfony\Component\HttpFoundation\Response;
40
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
41
use Symfony\Component\Validator\Constraints as Assert;
42
43
class ShoppingController extends AbstractController
44
{
45
46
    /**
47
     * @var string 非会員用セッションキー
48
     */
49
    private $sessionKey = 'eccube.front.shopping.nonmember';
50
51
    /**
52
     * @var string 非会員用セッションキー
53
     */
54
    private $sessionCustomerAddressKey = 'eccube.front.shopping.nonmember.customeraddress';
55
56
    /**
57
     * @var string 複数配送警告メッセージ
58
     */
59
    private $sessionMultipleKey = 'eccube.front.shopping.multiple';
60
61
    /**
62
     * @var string 受注IDキー
63
     */
64
    private $sessionOrderKey = 'eccube.front.shopping.order.id';
65
66
    /**
67
     * 購入画面表示
68
     *
69
     * @param Application $app
70
     * @param Request $request
71
     * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
72
     */
73
    public function index(Application $app, Request $request)
74
    {
75
        $cartService = $app['eccube.service.cart'];
76
77
        // カートチェック
78
        if (!$cartService->isLocked()) {
79
            log_info('カートが存在しません');
80
            // カートが存在しない、カートがロックされていない時はエラー
81
            return $app->redirect($app->url('cart'));
82
        }
83
84
        // カートチェック
85 View Code Duplication
        if (count($cartService->getCart()->getCartItems()) <= 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
86
            log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
87
            // カートが存在しない時はエラー
88
            return $app->redirect($app->url('cart'));
89
        }
90
91
        // 登録済みの受注情報を取得
92
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
93
94
        // 初回アクセス(受注情報がない)の場合は, 受注情報を作成
95
        if (is_null($Order)) {
96
            // 未ログインの場合, ログイン画面へリダイレクト.
97
            if (!$app->isGranted('IS_AUTHENTICATED_FULLY')) {
98
                // 非会員でも一度会員登録されていればショッピング画面へ遷移
99
                $Customer = $app['eccube.service.shopping']->getNonMember($this->sessionKey);
100
101
                if (is_null($Customer)) {
102
                    log_info('未ログインのためログイン画面にリダイレクト');
103
                    return $app->redirect($app->url('shopping_login'));
104
                }
105
            } else {
106
                $Customer = $app->user();
107
            }
108
109
            try {
110
                // 受注情報を作成
111
                $Order = $app['eccube.service.shopping']->createOrder($Customer);
112
            } catch (CartException $e) {
113
                log_error('初回受注情報作成エラー', array($e->getMessage()));
114
                $app->addRequestError($e->getMessage());
115
                return $app->redirect($app->url('cart'));
116
            }
117
118
            // セッション情報を削除
119
            $app['session']->remove($this->sessionOrderKey);
120
            $app['session']->remove($this->sessionMultipleKey);
121
        }
122
123
        // 受注関連情報を最新状態に更新
124
        $app['orm.em']->refresh($Order);
125
126
        // form作成
127
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
128
129
        $event = new EventArgs(
130
            array(
131
                'builder' => $builder,
132
                'Order' => $Order,
133
            ),
134
            $request
135
        );
136
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event);
137
138
        $form = $builder->getForm();
139
140
        if ($Order->getTotalPrice() < 0) {
141
            // 合計金額がマイナスの場合、エラー
142
            log_info('受注金額マイナスエラー', array($Order->getId()));
143
            $message = $app->trans('shopping.total.price', array('totalPrice' => number_format($Order->getTotalPrice())));
144
            $app->addError($message);
145
146
            return $app->redirect($app->url('shopping_error'));
147
        }
148
149
        // 複数配送の場合、エラーメッセージを一度だけ表示
150
        if (!$app['session']->has($this->sessionMultipleKey)) {
151
            if (count($Order->getShippings()) > 1) {
152
153
                $BaseInfo = $app['eccube.repository.base_info']->get();
154
155
                if (!$BaseInfo->getOptionMultipleShipping()) {
156
                    // 複数配送に設定されていないのに複数配送先ができればエラー
157
                    $app->addRequestError('cart.product.type.kind');
158
                    return $app->redirect($app->url('cart'));
159
                }
160
161
                $app->addError('shopping.multiple.delivery');
162
            }
163
            $app['session']->set($this->sessionMultipleKey, 'multiple');
164
        }
165
166
        return $app->render('Shopping/index.twig', array(
167
            'form' => $form->createView(),
168
            'Order' => $Order,
169
        ));
170
    }
171
172
    /**
173
     * 購入処理
174
     */
175
    public function confirm(Application $app, Request $request)
176
    {
177
        $cartService = $app['eccube.service.cart'];
178
179
        // カートチェック
180
        if (!$cartService->isLocked()) {
181
            // カートが存在しない、カートがロックされていない時はエラー
182
            log_info('カートが存在しません');
183
            return $app->redirect($app->url('cart'));
184
        }
185
186
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
187
        if (!$Order) {
188
            log_info('購入処理中の受注情報がないため購入エラー');
189
            $app->addError('front.shopping.order.error');
190
            return $app->redirect($app->url('shopping_error'));
191
        }
192
193
        if ('POST' !== $request->getMethod()) {
194
            return $app->redirect($app->url('cart'));
195
        }
196
197
        // form作成
198
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
199
200
        $event = new EventArgs(
201
            array(
202
                'builder' => $builder,
203
                'Order' => $Order,
204
            ),
205
            $request
206
        );
207
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_INITIALIZE, $event);
208
209
        $form = $builder->getForm();
210
211
        $form->handleRequest($request);
212
213
        if ($form->isSubmitted() && $form->isValid()) {
214
            $data = $form->getData();
215
216
            log_info('購入処理開始', array($Order->getId()));
217
218
            // トランザクション制御
219
            $em = $app['orm.em'];
220
            $em->getConnection()->beginTransaction();
221
            try {
222
                // 支払方法を検証
223
                $this->checkPaymentType($Order, $data);
224
                // お問い合わせ、配送時間などのフォーム項目をセット
225
                $app['eccube.service.shopping']->setFormData($Order, $data);
226
                // 購入処理
227
                $app['eccube.service.shopping']->processPurchase($Order);
228
229
                $em->flush();
230
                $em->getConnection()->commit();
231
232
                log_info('購入処理完了', array($Order->getId()));
233
234
            } catch (ShoppingException $e) {
235
236
                log_error('購入エラー', array($e->getMessage()));
237
238
                $em->getConnection()->rollback();
239
240
                $app->log($e);
241
                $app->addError($e->getMessage());
242
243
                return $app->redirect($app->url('shopping_error'));
244
            } catch (\Exception $e) {
245
246
                log_error('予期しないエラー', array($e->getMessage()));
247
248
                $em->getConnection()->rollback();
249
250
                $app->log($e);
251
252
                $app->addError('front.shopping.system.error');
253
                return $app->redirect($app->url('shopping_error'));
254
            }
255
256
            // カート削除
257
            $app['eccube.service.cart']->clear()->save();
258
259
            $event = new EventArgs(
260
                array(
261
                    'form' => $form,
262
                    'Order' => $Order,
263
                ),
264
                $request
265
            );
266
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING, $event);
267
268 View Code Duplication
            if ($event->getResponse() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
269
                log_info('イベントレスポンス返却', array($Order->getId()));
270
                return $event->getResponse();
271
            }
272
273
            // 受注IDをセッションにセット
274
            $app['session']->set($this->sessionOrderKey, $Order->getId());
275
276
            // メール送信
277
            $MailHistory = $app['eccube.service.shopping']->sendOrderMail($Order);
278
279
            $event = new EventArgs(
280
                array(
281
                    'form' => $form,
282
                    'Order' => $Order,
283
                    'MailHistory' => $MailHistory,
284
                ),
285
                $request
286
            );
287
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_COMPLETE, $event);
288
289 View Code Duplication
            if ($event->getResponse() !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
290
                log_info('イベントレスポンス返却', array($Order->getId()));
291
                return $event->getResponse();
292
            }
293
294
            // 完了画面表示
295
            return $app->redirect($app->url('shopping_complete'));
296
        }
297
298
        log_info('購入チェックエラー', array($Order->getId()));
299
300
        return $app->render('Shopping/index.twig', array(
301
            'form' => $form->createView(),
302
            'Order' => $Order,
303
        ));
304
    }
305
306
307
    /**
308
     * 支払方法がOrderに保持している支払方法と一致することを確認する
309
     *
310
     * @param $Order Order
311
     * @param $data array
312
     * @throws \Eccube\Exception\ShoppingException
313
     */
314
    private function checkPaymentType($Order, $data)
315
    {
316
        $orderPaymentId = $Order->getPayment()->getId();
317
        $formPaymentId = $data['payment']->getId();
318
319
        if (empty($orderPaymentId) || empty($formPaymentId)) {
320
            throw new ShoppingException('front.shopping.system.error');
321
        }
322
        if ($orderPaymentId != $formPaymentId) {
323
            throw new ShoppingException('front.shopping.system.error');
324
        }
325
    }
326
327
328
    /**
329
     * 購入完了画面表示
330
     */
331
    public function complete(Application $app, Request $request)
332
    {
333
        // 受注IDを取得
334
        $orderId = $app['session']->get($this->sessionOrderKey);
335
336
        $event = new EventArgs(
337
            array(
338
                'orderId' => $orderId,
339
            ),
340
            $request
341
        );
342
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE, $event);
343
344
        if ($event->getResponse() !== null) {
345
            return $event->getResponse();
346
        }
347
348
        // 受注に関連するセッションを削除
349
        $app['session']->remove($this->sessionOrderKey);
350
        $app['session']->remove($this->sessionMultipleKey);
351
        // 非会員用セッション情報を空の配列で上書きする(プラグイン互換性保持のために削除はしない)
352
        $app['session']->set($this->sessionKey, array());
353
        $app['session']->set($this->sessionCustomerAddressKey, array());
354
355
        log_info('購入処理完了', array($orderId));
356
357
        return $app->render('Shopping/complete.twig', array(
358
            'orderId' => $orderId,
359
        ));
360
    }
361
362
363
    /**
364
     * 配送業者選択処理
365
     */
366
    public function delivery(Application $app, Request $request)
367
    {
368
        // カートチェック
369
        if (!$app['eccube.service.cart']->isLocked()) {
370
            // カートが存在しない、カートがロックされていない時はエラー
371
            log_info('カートが存在しません');
372
            return $app->redirect($app->url('cart'));
373
        }
374
375
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
376
        if (!$Order) {
377
            log_info('購入処理中の受注情報がないため購入エラー');
378
            $app->addError('front.shopping.order.error');
379
            return $app->redirect($app->url('shopping_error'));
380
        }
381
382
        if ('POST' !== $request->getMethod()) {
383
            return $app->redirect($app->url('shopping'));
384
        }
385
386
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
387
388
        $event = new EventArgs(
389
            array(
390
                'builder' => $builder,
391
                'Order' => $Order,
392
            ),
393
            $request
394
        );
395
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_DELIVERY_INITIALIZE, $event);
396
397
        $form = $builder->getForm();
398
399
        $form->handleRequest($request);
400
401
        if ($form->isSubmitted() && $form->isValid()) {
402
            log_info('配送業者変更処理開始', array($Order->getId()));
403
404
            $data = $form->getData();
405
406
            $shippings = $data['shippings'];
407
408
            $productDeliveryFeeTotal = 0;
409
            $BaseInfo = $app['eccube.repository.base_info']->get();
410
411
            foreach ($shippings as $Shipping) {
412
                $Delivery = $Shipping->getDelivery();
413
414
                if ($Delivery) {
415
                    $deliveryFee = $app['eccube.repository.delivery_fee']->findOneBy(array(
416
                        'Delivery' => $Delivery,
417
                        'Pref' => $Shipping->getPref()
418
                    ));
419
420
                    // 商品ごとの配送料合計
421
                    if ($BaseInfo->getOptionProductDeliveryFee() === Constant::ENABLED) {
422
                        $productDeliveryFeeTotal += $app['eccube.service.shopping']->getProductDeliveryFee($Shipping);
423
                    }
424
425
                    $Shipping->setDeliveryFee($deliveryFee);
426
                    $Shipping->setShippingDeliveryFee($deliveryFee->getFee() + $productDeliveryFeeTotal);
427
                    $Shipping->setShippingDeliveryName($Delivery->getName());
428
                }
429
            }
430
431
            // 支払い情報をセット
432
            $payment = $data['payment'];
433
            $message = $data['message'];
434
435
            $Order->setPayment($payment);
436
            $Order->setPaymentMethod($payment->getMethod());
437
            $Order->setMessage($message);
438
            $Order->setCharge($payment->getCharge());
439
440
            $Order->setDeliveryFeeTotal($app['eccube.service.shopping']->getShippingDeliveryFeeTotal($shippings));
441
442
            // 合計金額の再計算
443
            $Order = $app['eccube.service.shopping']->getAmount($Order);
444
445
            // 受注関連情報を最新状態に更新
446
            $app['orm.em']->flush();
447
448
            $event = new EventArgs(
449
                array(
450
                    'form' => $form,
451
                    'Order' => $Order,
452
                ),
453
                $request
454
            );
455
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_DELIVERY_COMPLETE, $event);
456
457
            log_info('配送業者変更処理完了', array($Order->getId()));
458
            return $app->redirect($app->url('shopping'));
459
        }
460
461
        log_info('配送業者変更入力チェックエラー', array($Order->getId()));
462
        return $app->render('Shopping/index.twig', array(
463
            'form' => $form->createView(),
464
            'Order' => $Order,
465
        ));
466
    }
467
468
    /**
469
     * 支払い方法選択処理
470
     */
471
    public function payment(Application $app, Request $request)
472
    {
473
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
474
        if (!$Order) {
475
            log_info('購入処理中の受注情報がないため購入エラー');
476
            $app->addError('front.shopping.order.error');
477
            return $app->redirect($app->url('shopping_error'));
478
        }
479
480
        if ('POST' !== $request->getMethod()) {
481
            return $app->redirect($app->url('shopping'));
482
        }
483
484
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
485
486
        $event = new EventArgs(
487
            array(
488
                'builder' => $builder,
489
                'Order' => $Order,
490
            ),
491
            $request
492
        );
493
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_PAYMENT_INITIALIZE, $event);
494
495
        $form = $builder->getForm();
496
497
        $form->handleRequest($request);
498
499
        if ($form->isSubmitted() && $form->isValid()) {
500
501
            log_info('支払い方法変更処理開始', array("id" => $Order->getId()));
502
503
            $data = $form->getData();
504
            $payment = $data['payment'];
505
            $message = $data['message'];
506
507
            $Order->setPayment($payment);
508
            $Order->setPaymentMethod($payment->getMethod());
509
            $Order->setMessage($message);
510
            $Order->setCharge($payment->getCharge());
511
512
            // 合計金額の再計算
513
            $Order = $app['eccube.service.shopping']->getAmount($Order);
514
515
            // 受注関連情報を最新状態に更新
516
            $app['orm.em']->flush();
517
518
            $event = new EventArgs(
519
                array(
520
                    'form' => $form,
521
                    'Order' => $Order,
522
                ),
523
                $request
524
            );
525
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_PAYMENT_COMPLETE, $event);
526
527
            log_info('支払い方法変更処理完了', array("id" => $Order->getId(), "payment" => $payment->getId()));
528
529
            return $app->redirect($app->url('shopping'));
530
        }
531
532
        log_info('支払い方法変更入力チェックエラー', array("id" => $Order->getId()));
533
        return $app->render('Shopping/index.twig', array(
534
            'form' => $form->createView(),
535
            'Order' => $Order,
536
        ));
537
    }
538
539
    /**
540
     * お届け先変更がクリックされた場合の処理
541
     */
542 View Code Duplication
    public function shippingChange(Application $app, Request $request, $id)
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...
543
    {
544
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
545
        if (!$Order) {
546
            $app->addError('front.shopping.order.error');
547
            return $app->redirect($app->url('shopping_error'));
548
        }
549
550
        if ('POST' !== $request->getMethod()) {
551
            return $app->redirect($app->url('shopping'));
552
        }
553
554
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
555
556
        $event = new EventArgs(
557
            array(
558
                'builder' => $builder,
559
                'Order' => $Order,
560
            ),
561
            $request
562
        );
563
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_CHANGE_INITIALIZE, $event);
564
565
        $form = $builder->getForm();
566
567
        $form->handleRequest($request);
568
569
        if ($form->isSubmitted() && $form->isValid()) {
570
            $data = $form->getData();
571
            $message = $data['message'];
572
            $Order->setMessage($message);
573
            // 受注情報を更新
574
            $app['orm.em']->flush();
575
576
            // お届け先設定一覧へリダイレクト
577
            return $app->redirect($app->url('shopping_shipping', array('id' => $id)));
578
        }
579
580
        return $app->render('Shopping/index.twig', array(
581
            'form' => $form->createView(),
582
            'Order' => $Order,
583
        ));
584
    }
585
586
    /**
587
     * お届け先の設定一覧からの選択
588
     */
589
    public function shipping(Application $app, Request $request, $id)
590
    {
591
        // カートチェック
592
        if (!$app['eccube.service.cart']->isLocked()) {
593
            // カートが存在しない、カートがロックされていない時はエラー
594
            log_info('カートが存在しません');
595
            return $app->redirect($app->url('cart'));
596
        }
597
598
        if ('POST' === $request->getMethod()) {
599
            $address = $request->get('address');
600
601
            if (is_null($address)) {
602
                // 選択されていなければエラー
603
                log_info('お届け先入力チェックエラー');
604
                return $app->render(
605
                    'Shopping/shipping.twig',
606
                    array(
607
                        'Customer' => $app->user(),
608
                        'shippingId' => $id,
609
                        'error' => true,
610
                    )
611
                );
612
            }
613
614
            // 選択されたお届け先情報を取得
615
            $CustomerAddress = $app['eccube.repository.customer_address']->findOneBy(array(
616
                'Customer' => $app->user(),
617
                'id' => $address,
618
            ));
619
            if (is_null($CustomerAddress)) {
620
                throw new NotFoundHttpException('選択されたお届け先住所が存在しない');
621
            }
622
623
            $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
624
            if (!$Order) {
625
                log_info('購入処理中の受注情報がないため購入エラー');
626
                $app->addError('front.shopping.order.error');
627
628
                return $app->redirect($app->url('shopping_error'));
629
            }
630
631
            $Shipping = $Order->findShipping($id);
632
            if (!$Shipping) {
633
                throw new NotFoundHttpException('お届け先情報が存在しない');
634
            }
635
636
            log_info('お届先情報更新開始', array($Shipping->getId()));
637
638
            // お届け先情報を更新
639
            $Shipping
640
                ->setFromCustomerAddress($CustomerAddress);
641
642
            // 配送料金の設定
643
            $app['eccube.service.shopping']->setShippingDeliveryFee($Shipping);
644
645
            // 合計金額の再計算
646
            $Order = $app['eccube.service.shopping']->getAmount($Order);
647
648
            // 配送先を更新
649
            $app['orm.em']->flush();
650
651
            $event = new EventArgs(
652
                array(
653
                    'Order' => $Order,
654
                    'shippingId' => $id,
655
                ),
656
                $request
657
            );
658
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_COMPLETE, $event);
659
660
            log_info('お届先情報更新完了', array($Shipping->getId()));
661
            return $app->redirect($app->url('shopping'));
662
        }
663
664
        return $app->render(
665
            'Shopping/shipping.twig',
666
            array(
667
                'Customer' => $app->user(),
668
                'shippingId' => $id,
669
                'error' => false,
670
            )
671
        );
672
    }
673
674
    /**
675
     * お届け先の設定(非会員)がクリックされた場合の処理
676
     */
677 View Code Duplication
    public function shippingEditChange(Application $app, Request $request, $id)
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...
678
    {
679
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
680
        if (!$Order) {
681
            $app->addError('front.shopping.order.error');
682
            return $app->redirect($app->url('shopping_error'));
683
        }
684
685
        if ('POST' !== $request->getMethod()) {
686
            return $app->redirect($app->url('shopping'));
687
        }
688
689
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
690
691
        $event = new EventArgs(
692
            array(
693
                'builder' => $builder,
694
                'Order' => $Order,
695
            ),
696
            $request
697
        );
698
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_CHANGE_INITIALIZE, $event);
699
700
        $form = $builder->getForm();
701
702
        $form->handleRequest($request);
703
704
        if ($form->isSubmitted() && $form->isValid()) {
705
            $data = $form->getData();
706
            $message = $data['message'];
707
            $Order->setMessage($message);
708
            // 受注情報を更新
709
            $app['orm.em']->flush();
710
711
            // お届け先設定一覧へリダイレクト
712
            return $app->redirect($app->url('shopping_shipping_edit', array('id' => $id)));
713
        }
714
715
        return $app->render('Shopping/index.twig', array(
716
            'form' => $form->createView(),
717
            'Order' => $Order,
718
        ));
719
    }
720
721
    /**
722
     * お届け先の設定(非会員でも使用する)
723
     */
724
    public function shippingEdit(Application $app, Request $request, $id)
725
    {
726
        // 配送先住所最大値判定
727
        $Customer = $app->user();
728 View Code Duplication
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
729
            $addressCurrNum = count($app->user()->getCustomerAddresses());
730
            $addressMax = $app['config']['deliv_addr_max'];
731
            if ($addressCurrNum >= $addressMax) {
732
                throw new NotFoundHttpException('配送先住所最大数エラー');
733
            }
734
        }
735
736
        // カートチェック
737
        if (!$app['eccube.service.cart']->isLocked()) {
738
            // カートが存在しない、カートがロックされていない時はエラー
739
            log_info('カートが存在しません');
740
            return $app->redirect($app->url('cart'));
741
        }
742
743
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
744
        if (!$Order) {
745
            log_info('購入処理中の受注情報がないため購入エラー');
746
            $app->addError('front.shopping.order.error');
747
            return $app->redirect($app->url('shopping_error'));
748
        }
749
750
        $Shipping = $Order->findShipping($id);
751
        if (!$Shipping) {
752
            throw new NotFoundHttpException('設定されている配送先が存在しない');
753
        }
754
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
755
            $Shipping->clearCustomerAddress();
756
        }
757
758
        $CustomerAddress = new CustomerAddress();
759
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
760
            $CustomerAddress->setCustomer($Customer);
761
        } else {
762
            $CustomerAddress->setFromShipping($Shipping);
763
        }
764
765
        $builder = $app['form.factory']->createBuilder('shopping_shipping', $CustomerAddress);
766
767
        $event = new EventArgs(
768
            array(
769
                'builder' => $builder,
770
                'Order' => $Order,
771
                'Shipping' => $Shipping,
772
                'CustomerAddress' => $CustomerAddress,
773
            ),
774
            $request
775
        );
776
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_INITIALIZE, $event);
777
778
        $form = $builder->getForm();
779
780
        $form->handleRequest($request);
781
782
        if ($form->isSubmitted() && $form->isValid()) {
783
784
            log_info('お届け先追加処理開始', array('id' => $Order->getId(), 'shipping' => $id));
785
786
            // 会員の場合、お届け先情報を新規登録
787
            $Shipping->setFromCustomerAddress($CustomerAddress);
788
789
            if ($Customer instanceof Customer) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\Customer does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
790
                $app['orm.em']->persist($CustomerAddress);
791
                log_info('新規お届け先登録', array(
792
                    'id' => $Order->getId(),
793
                    'shipping' => $id,
794
                    'customer address' => $CustomerAddress->getId()));
795
            }
796
797
            // 配送料金の設定
798
            $app['eccube.service.shopping']->setShippingDeliveryFee($Shipping);
799
800
            // 合計金額の再計算
801
            $app['eccube.service.shopping']->getAmount($Order);
802
803
            // 配送先を更新 
804
            $app['orm.em']->flush();
805
806
            $event = new EventArgs(
807
                array(
808
                    'form' => $form,
809
                    'Shipping' => $Shipping,
810
                    'CustomerAddress' => $CustomerAddress,
811
                ),
812
                $request
813
            );
814
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_EDIT_COMPLETE, $event);
815
816
            log_info('お届け先追加処理完了', array('id' => $Order->getId(), 'shipping' => $id));
817
            return $app->redirect($app->url('shopping'));
818
        }
819
820
        return $app->render('Shopping/shipping_edit.twig', array(
821
            'form' => $form->createView(),
822
            'shippingId' => $id,
823
        ));
824
    }
825
826
    /**
827
     * お客様情報の変更(非会員)
828
     */
829
    public function customer(Application $app, Request $request)
830
    {
831
        if ($request->isXmlHttpRequest()) {
832
            try {
833
834
                log_info('非会員お客様情報変更処理開始');
835
836
                $data = $request->request->all();
837
838
                // 入力チェック
839
                $errors = $this->customerValidation($app, $data);
840
841
                foreach ($errors as $error) {
842 View Code Duplication
                    if ($error->count() != 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
843
                        log_info('非会員お客様情報変更入力チェックエラー');
844
                        $response = new Response(json_encode('NG'), 400);
845
                        $response->headers->set('Content-Type', 'application/json');
846
                        return $response;
847
                    }
848
                }
849
850
                $pref = $app['eccube.repository.master.pref']->findOneBy(array('name' => $data['customer_pref']));
851 View Code Duplication
                if (!$pref) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
852
                    log_info('非会員お客様情報変更入力チェックエラー');
853
                    $response = new Response(json_encode('NG'), 400);
854
                    $response->headers->set('Content-Type', 'application/json');
855
                    return $response;
856
                }
857
858
                $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
859
                if (!$Order) {
860
                    log_info('カートが存在しません');
861
                    $app->addError('front.shopping.order.error');
862
                    return $app->redirect($app->url('shopping_error'));
863
                }
864
865
                $Order
866
                    ->setName01($data['customer_name01'])
867
                    ->setName02($data['customer_name02'])
868
                    ->setCompanyName($data['customer_company_name'])
869
                    ->setTel01($data['customer_tel01'])
870
                    ->setTel02($data['customer_tel02'])
871
                    ->setTel03($data['customer_tel03'])
872
                    ->setZip01($data['customer_zip01'])
873
                    ->setZip02($data['customer_zip02'])
874
                    ->setZipCode($data['customer_zip01'].$data['customer_zip02'])
875
                    ->setPref($pref)
876
                    ->setAddr01($data['customer_addr01'])
877
                    ->setAddr02($data['customer_addr02'])
878
                    ->setEmail($data['customer_email']);
879
880
                // 配送先を更新
881
                $app['orm.em']->flush();
882
883
                // 受注関連情報を最新状態に更新
884
                $app['orm.em']->refresh($Order);
885
886
                $event = new EventArgs(
887
                    array(
888
                        'Order' => $Order,
889
                        'data' => $data,
890
                    ),
891
                    $request
892
                );
893
                $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CUSTOMER_INITIALIZE, $event);
894
895
                log_info('非会員お客様情報変更処理完了', array($Order->getId()));
896
                $response = new Response(json_encode('OK'));
897
                $response->headers->set('Content-Type', 'application/json');
898
            } catch (\Exception $e) {
899
                log_error('予期しないエラー', array($e->getMessage()));
900
                $app['monolog']->error($e);
901
902
                $response = new Response(json_encode('NG'), 500);
903
                $response->headers->set('Content-Type', 'application/json');
904
            }
905
906
            return $response;
907
        }
908
    }
909
910
    /**
911
     * ログイン
912
     */
913
    public function login(Application $app, Request $request)
914
    {
915
        if (!$app['eccube.service.cart']->isLocked()) {
916
            return $app->redirect($app->url('cart'));
917
        }
918
919
        if ($app->isGranted('IS_AUTHENTICATED_FULLY')) {
920
            return $app->redirect($app->url('shopping'));
921
        }
922
923
        /* @var $form \Symfony\Component\Form\FormInterface */
924
        $builder = $app['form.factory']->createNamedBuilder('', 'customer_login');
925
926 View Code Duplication
        if ($app->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
927
            $Customer = $app->user();
928
            if ($Customer) {
929
                $builder->get('login_email')->setData($Customer->getEmail());
930
            }
931
        }
932
933
        $event = new EventArgs(
934
            array(
935
                'builder' => $builder,
936
            ),
937
            $request
938
        );
939
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_LOGIN_INITIALIZE, $event);
940
941
        $form = $builder->getForm();
942
943
        return $app->render('Shopping/login.twig', array(
944
            'error' => $app['security.last_error']($request),
945
            'form' => $form->createView(),
946
        ));
947
    }
948
949
    /**
950
     * 非会員処理
951
     */
952
    public function nonmember(Application $app, Request $request)
953
    {
954
        $cartService = $app['eccube.service.cart'];
955
956
        // カートチェック
957
        if (!$cartService->isLocked()) {
958
            // カートが存在しない、カートがロックされていない時はエラー
959
            log_info('カートが存在しません');
960
            return $app->redirect($app->url('cart'));
961
        }
962
963
        // ログイン済みの場合は, 購入画面へリダイレクト.
964
        if ($app->isGranted('ROLE_USER')) {
965
            return $app->redirect($app->url('shopping'));
966
        }
967
968
        // カートチェック
969 View Code Duplication
        if (count($cartService->getCart()->getCartItems()) <= 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
970
            // カートが存在しない時はエラー
971
            log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
972
            return $app->redirect($app->url('cart'));
973
        }
974
975
        $builder = $app['form.factory']->createBuilder('nonmember');
976
977
        $event = new EventArgs(
978
            array(
979
                'builder' => $builder,
980
            ),
981
            $request
982
        );
983
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_NONMEMBER_INITIALIZE, $event);
984
985
        $form = $builder->getForm();
986
987
        $form->handleRequest($request);
988
989
        if ($form->isSubmitted() && $form->isValid()) {
990
991
            log_info('非会員お客様情報登録開始');
992
993
            $data = $form->getData();
994
            $Customer = new Customer();
995
            $Customer
996
                ->setName01($data['name01'])
997
                ->setName02($data['name02'])
998
                ->setKana01($data['kana01'])
999
                ->setKana02($data['kana02'])
1000
                ->setCompanyName($data['company_name'])
1001
                ->setEmail($data['email'])
1002
                ->setTel01($data['tel01'])
1003
                ->setTel02($data['tel02'])
1004
                ->setTel03($data['tel03'])
1005
                ->setZip01($data['zip01'])
1006
                ->setZip02($data['zip02'])
1007
                ->setZipCode($data['zip01'].$data['zip02'])
1008
                ->setPref($data['pref'])
1009
                ->setAddr01($data['addr01'])
1010
                ->setAddr02($data['addr02']);
1011
1012
            // 非会員複数配送用
1013
            $CustomerAddress = new CustomerAddress();
1014
            $CustomerAddress
1015
                ->setCustomer($Customer)
1016
                ->setName01($data['name01'])
1017
                ->setName02($data['name02'])
1018
                ->setKana01($data['kana01'])
1019
                ->setKana02($data['kana02'])
1020
                ->setCompanyName($data['company_name'])
1021
                ->setTel01($data['tel01'])
1022
                ->setTel02($data['tel02'])
1023
                ->setTel03($data['tel03'])
1024
                ->setZip01($data['zip01'])
1025
                ->setZip02($data['zip02'])
1026
                ->setZipCode($data['zip01'].$data['zip02'])
1027
                ->setPref($data['pref'])
1028
                ->setAddr01($data['addr01'])
1029
                ->setAddr02($data['addr02'])
1030
                ->setDelFlg(Constant::DISABLED);
1031
            $Customer->addCustomerAddress($CustomerAddress);
1032
1033
            // 受注情報を取得
1034
            $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
1035
1036
            // 初回アクセス(受注データがない)の場合は, 受注情報を作成
1037
            if (is_null($Order)) {
1038
                // 受注情報を作成
1039
                try {
1040
                    // 受注情報を作成
1041
                    $Order = $app['eccube.service.shopping']->createOrder($Customer);
1042
                } catch (CartException $e) {
1043
                    $app->addRequestError($e->getMessage());
1044
                    return $app->redirect($app->url('cart'));
1045
                }
1046
            }
1047
1048
            // 非会員用セッションを作成
1049
            $app['eccube.service.shopping']->setNonMember($this->sessionKey, $Customer);
1050
1051
            $CustomerAddressArray = $CustomerAddress->toArray();
1052
            $CustomerAddressArray['Customer'] = $CustomerAddress->getCustomer()->toArray();
1053
            $CustomerAddressArray['Pref'] = $CustomerAddress->getPref()->toArray();
1054
1055
            $CustomerAddressesArray = array();
1056
            $CustomerAddressesArray[] = $CustomerAddressArray;
1057
1058
            $app['session']->set($this->sessionCustomerAddressKey, json_encode($CustomerAddressesArray));
1059
1060
            $event = new EventArgs(
1061
                array(
1062
                    'form' => $form,
1063
                    'Order' => $Order,
1064
                ),
1065
                $request
1066
            );
1067
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_NONMEMBER_COMPLETE, $event);
1068
1069
            if ($event->getResponse() !== null) {
1070
                return $event->getResponse();
1071
            }
1072
1073
            log_info('非会員お客様情報登録完了', array($Order->getId()));
1074
1075
            return $app->redirect($app->url('shopping'));
1076
        }
1077
1078
        return $app->render('Shopping/nonmember.twig', array(
1079
            'form' => $form->createView(),
1080
        ));
1081
    }
1082
1083
    /**
1084
     * 複数配送処理がクリックされた場合の処理
1085
     */
1086 View Code Duplication
    public function shippingMultipleChange(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...
1087
    {
1088
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
1089
        if (!$Order) {
1090
            $app->addError('front.shopping.order.error');
1091
            return $app->redirect($app->url('shopping_error'));
1092
        }
1093
1094
        if ('POST' !== $request->getMethod()) {
1095
            return $app->redirect($app->url('shopping'));
1096
        }
1097
1098
        $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order);
1099
1100
        $event = new EventArgs(
1101
            array(
1102
                'builder' => $builder,
1103
                'Order' => $Order,
1104
            ),
1105
            $request
1106
        );
1107
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_CHANGE_INITIALIZE, $event);
1108
1109
        $form = $builder->getForm();
1110
1111
        $form->handleRequest($request);
1112
1113
        if ($form->isSubmitted() && $form->isValid()) {
1114
            $data = $form->getData();
1115
            $message = $data['message'];
1116
            $Order->setMessage($message);
1117
            // 受注情報を更新
1118
            $app['orm.em']->flush();
1119
1120
            // 複数配送設定へリダイレクト
1121
            return $app->redirect($app->url('shopping_shipping_multiple'));
1122
        }
1123
1124
        return $app->render('Shopping/index.twig', array(
1125
            'form' => $form->createView(),
1126
            'Order' => $Order,
1127
        ));
1128
    }
1129
1130
1131
    /**
1132
     * 複数配送処理
1133
     */
1134
    public function shippingMultiple(Application $app, Request $request)
1135
    {
1136
        $cartService = $app['eccube.service.cart'];
1137
1138
        // カートチェック
1139
        if (!$cartService->isLocked()) {
1140
            // カートが存在しない、カートがロックされていない時はエラー
1141
            log_info('カートが存在しません');
1142
            return $app->redirect($app->url('cart'));
1143
        }
1144
1145
        // カートチェック
1146 View Code Duplication
        if (count($cartService->getCart()->getCartItems()) <= 0) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
1147
            // カートが存在しない時はエラー
1148
            log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト');
1149
            return $app->redirect($app->url('cart'));
1150
        }
1151
1152
        /** @var \Eccube\Entity\Order $Order */
1153
        $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']);
1154
        if (!$Order) {
1155
            log_info('購入処理中の受注情報がないため購入エラー');
1156
            $app->addError('front.shopping.order.error');
1157
            return $app->redirect($app->url('shopping_error'));
1158
        }
1159
1160
        // 処理しやすいようにすべてのShippingItemをまとめる
1161
        $ShipmentItems = array();
1162
        foreach ($Order->getShippings() as $Shipping) {
1163
            foreach ($Shipping->getShipmentItems() as $ShipmentItem) {
1164
                $ShipmentItems[] = $ShipmentItem;
1165
            }
1166
        }
1167
1168
        // Orderに含まれる商品ごとの数量を求める
1169
        $ItemQuantitiesByClassId = array();
1170
        foreach ($ShipmentItems as $item) {
1171
            $itemId = $item->getProductClass()->getId();
1172
            $quantity = $item->getQuantity();
1173
            if (array_key_exists($itemId, $ItemQuantitiesByClassId)) {
1174
                $ItemQuantitiesByClassId[$itemId] += $quantity;
1175
            } else {
1176
                $ItemQuantitiesByClassId[$itemId] = $quantity;
1177
            }
1178
        }
1179
1180
        // FormBuilder用に商品ごとにShippingItemをまとめる
1181
        $ShipmentItemsForFormBuilder = array();
1182
        $tmpAddedClassIds = array();
1183
        foreach ($ShipmentItems as $item) {
1184
            $itemId = $item->getProductClass()->getId();
1185
            if (!in_array($itemId, $tmpAddedClassIds)) {
1186
                $ShipmentItemsForFormBuilder[] = $item;
1187
                $tmpAddedClassIds[] = $itemId;
1188
            }
1189
        }
1190
1191
        // Form生成
1192
        $builder = $app->form();
1193
        $builder
1194
            ->add('shipping_multiple', 'collection', array(
1195
                'type' => 'shipping_multiple',
1196
                'data' => $ShipmentItemsForFormBuilder,
1197
                'allow_add' => true,
1198
                'allow_delete' => true,
1199
            ));
1200
        // Event
1201
        $event = new EventArgs(
1202
            array(
1203
                'builder' => $builder,
1204
                'Order' => $Order,
1205
            ),
1206
            $request
1207
        );
1208
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_INITIALIZE, $event);
1209
1210
        $form = $builder->getForm();
1211
        $form->handleRequest($request);
1212
1213
        $errors = array();
1214
        if ($form->isSubmitted() && $form->isValid()) {
1215
1216
            log_info('複数配送設定処理開始', array($Order->getId()));
1217
1218
            $data = $form['shipping_multiple'];
1219
1220
            // フォームの入力から、送り先ごとに商品の数量を集計する
1221
            $arrShipmentItemTemp = array();
1222
            foreach ($data as $mulitples) {
1223
                $ShipmentItem = $mulitples->getData();
1224
                foreach ($mulitples as $items) {
1225
                    foreach ($items as $item) {
1226
                        $cusAddId = $this->getCustomerAddressId($item['customer_address']->getData());
1227
                        $itemId = $ShipmentItem->getProductClass()->getId();
1228
                        $quantity = $item['quantity']->getData();
1229
1230
                        if (isset($arrShipmentItemTemp[$cusAddId]) && array_key_exists($itemId, $arrShipmentItemTemp[$cusAddId])) {
1231
                            $arrShipmentItemTemp[$cusAddId][$itemId] = $arrShipmentItemTemp[$cusAddId][$itemId] + $quantity;
1232
                        } else {
1233
                            $arrShipmentItemTemp[$cusAddId][$itemId] = $quantity;
1234
                        }
1235
                    }
1236
                }
1237
            }
1238
1239
            // フォームの入力から、商品ごとの数量を集計する
1240
            $itemQuantities = array();
1241
            foreach ($arrShipmentItemTemp as $FormItemByAddress) {
1242
                foreach ($FormItemByAddress as $itemId => $quantity) {
1243
                    if (array_key_exists($itemId, $itemQuantities)) {
1244
                        $itemQuantities[$itemId] = $itemQuantities[$itemId] + $quantity;
1245
                    } else {
1246
                        $itemQuantities[$itemId] = $quantity;
1247
                    }
1248
                }
1249
            }
1250
1251
            // 「Orderに含まれる商品ごとの数量」と「フォームに入力された商品ごとの数量」が一致しているかの確認
1252
            // 数量が異なっているならエラーを表示する
1253
            foreach ($ItemQuantitiesByClassId as $key => $value) {
1254
                if (array_key_exists($key, $itemQuantities)) {
1255
                    if ($itemQuantities[$key] != $value) {
1256
                        $errors[] = array('message' => $app->trans('shopping.multiple.quantity.diff'));
1257
1258
                        // 対象がなければエラー
1259
                        log_info('複数配送設定入力チェックエラー', array($Order->getId()));
1260
                        return $app->render('Shopping/shipping_multiple.twig', array(
1261
                            'form' => $form->createView(),
1262
                            'shipmentItems' => $ShipmentItemsForFormBuilder,
1263
                            'compItemQuantities' => $ItemQuantitiesByClassId,
1264
                            'errors' => $errors,
1265
                        ));
1266
                    }
1267
                }
1268
            }
1269
1270
            // -- ここから先がお届け先を再生成する処理 --
1271
1272
            // お届け先情報をすべて削除
1273
            foreach ($Order->getShippings() as $Shipping) {
1274
                $Order->removeShipping($Shipping);
1275
                $app['orm.em']->remove($Shipping);
1276
            }
1277
1278
            // お届け先のリストを作成する
1279
            $ShippingList = array();
1280
            foreach ($data as $mulitples) {
1281
                $ShipmentItem = $mulitples->getData();
1282
                $ProductClass = $ShipmentItem->getProductClass();
1283
                $Delivery = $ShipmentItem->getShipping()->getDelivery();
1284
                $productTypeId = $ProductClass->getProductType()->getId();
1285
1286
                foreach ($mulitples as $items) {
1287
                    foreach ($items as $item) {
1288
                        $CustomerAddress = $this->getCustomerAddress($app, $item['customer_address']->getData());
1289
                        $cusAddId = $this->getCustomerAddressId($item['customer_address']->getData());
1290
1291
                        $Shipping = new Shipping();
1292
                        $Shipping
1293
                            ->setFromCustomerAddress($CustomerAddress)
1294
                            ->setDelivery($Delivery)
1295
                            ->setDelFlg(Constant::DISABLED)
1296
                            ->setOrder($Order);
1297
1298
                        $ShippingList[$cusAddId][$productTypeId] = $Shipping;
1299
                    }
1300
                }
1301
            }
1302
            // お届け先のリストを保存
1303
            foreach ($ShippingList as $ShippingListByAddress) {
1304
                foreach ($ShippingListByAddress as $Shipping) {
1305
                    $app['orm.em']->persist($Shipping);
1306
                }
1307
            }
1308
1309
            // お届け先に、配送商品の情報(ShipmentItem)を関連付ける
1310
            foreach ($data as $mulitples) {
1311
                $ShipmentItem = $mulitples->getData();
1312
                $ProductClass = $ShipmentItem->getProductClass();
1313
                $Product = $ShipmentItem->getProduct();
1314
                $productTypeId = $ProductClass->getProductType()->getId();
1315
                $productClassId = $ProductClass->getId();
1316
1317
                foreach ($mulitples as $items) {
1318
                    foreach ($items as $item) {
1319
                        $cusAddId = $this->getCustomerAddressId($item['customer_address']->getData());
1320
1321
                        // お届け先から商品の数量を取得
1322
                        $quantity = 0;
0 ignored issues
show
Unused Code introduced by
$quantity is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1323
                        if (isset($arrShipmentItemTemp[$cusAddId]) && array_key_exists($productClassId, $arrShipmentItemTemp[$cusAddId])) {
1324
                            $quantity = $arrShipmentItemTemp[$cusAddId][$productClassId];
1325
                            unset($arrShipmentItemTemp[$cusAddId][$productClassId]);
1326
                        } else {
1327
                            // この配送先には送る商品がないのでスキップ(通常ありえない)
1328
                            continue;
1329
                        }
1330
1331
                        // 関連付けるお届け先のインスタンスを取得
1332
                        $Shipping = $ShippingList[$cusAddId][$productTypeId];
1333
1334
                        // インスタンスを生成して保存
1335
                        $ShipmentItem = new ShipmentItem();
1336
                        $ShipmentItem->setShipping($Shipping)
1337
                            ->setOrder($Order)
1338
                            ->setProductClass($ProductClass)
1339
                            ->setProduct($Product)
1340
                            ->setProductName($Product->getName())
1341
                            ->setProductCode($ProductClass->getCode())
1342
                            ->setPrice($ProductClass->getPrice02())
1343
                            ->setQuantity($quantity);
1344
1345
                        $ClassCategory1 = $ProductClass->getClassCategory1();
1346
                        if (!is_null($ClassCategory1)) {
1347
                            $ShipmentItem->setClasscategoryName1($ClassCategory1->getName());
1348
                            $ShipmentItem->setClassName1($ClassCategory1->getClassName()->getName());
1349
                        }
1350
                        $ClassCategory2 = $ProductClass->getClassCategory2();
1351
                        if (!is_null($ClassCategory2)) {
1352
                            $ShipmentItem->setClasscategoryName2($ClassCategory2->getName());
1353
                            $ShipmentItem->setClassName2($ClassCategory2->getClassName()->getName());
1354
                        }
1355
                        $Shipping->addShipmentItem($ShipmentItem);
1356
                        $app['orm.em']->persist($ShipmentItem);
1357
                    }
1358
                }
1359
            }
1360
1361
            // 送料を計算(お届け先ごと)
1362
            foreach ($ShippingList as $data) {
1363
                // data is product type => shipping
1364
                foreach ($data as $Shipping) {
1365
                    // 配送料金の設定
1366
                    $app['eccube.service.shopping']->setShippingDeliveryFee($Shipping);
1367
                    $Order->addShipping($Shipping);
1368
                }
1369
            }
1370
1371
            // 合計金額の再計算
1372
            $Order = $app['eccube.service.shopping']->getAmount($Order);
1373
1374
            // 配送先を更新
1375
            $app['orm.em']->flush();
1376
1377
            $event = new EventArgs(
1378
                array(
1379
                    'form' => $form,
1380
                    'Order' => $Order,
1381
                ),
1382
                $request
1383
            );
1384
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_COMPLETE, $event);
1385
1386
            log_info('複数配送設定処理完了', array($Order->getId()));
1387
            return $app->redirect($app->url('shopping'));
1388
        }
1389
1390
        return $app->render('Shopping/shipping_multiple.twig', array(
1391
            'form' => $form->createView(),
1392
            'shipmentItems' => $ShipmentItemsForFormBuilder,
1393
            'compItemQuantities' => $ItemQuantitiesByClassId,
1394
            'errors' => $errors,
1395
        ));
1396
    }
1397
1398
    /**
1399
     * フォームの情報からお届け先のインデックスを返す
1400
     *
1401
     * @param Application $app
0 ignored issues
show
Bug introduced by
There is no parameter named $app. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1402
     * @param mixed $CustomerAddressData
1403
     * @return int
1404
     */
1405
    private function getCustomerAddressId($CustomerAddressData)
1406
    {
1407
        if ($CustomerAddressData instanceof CustomerAddress) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\CustomerAddress does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
1408
            return $CustomerAddressData->getId();
1409
        } else {
1410
            return $CustomerAddressData;
1411
        }
1412
    }
1413
1414
    /**
1415
     * フォームの情報からお届け先のインスタンスを返す
1416
     *
1417
     * @param Application $app
1418
     * @param mixed $CustomerAddressData
1419
     * @return CustomerAddress
1420
     */
1421
    private function getCustomerAddress(Application $app, $CustomerAddressData)
1422
    {
1423
        if ($CustomerAddressData instanceof CustomerAddress) {
0 ignored issues
show
Bug introduced by
The class Eccube\Entity\CustomerAddress does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
1424
            return $CustomerAddressData;
1425
        } else {
1426
            $cusAddId = $CustomerAddressData;
1427
1428
            $customerAddresses = $app['session']->get($this->sessionCustomerAddressKey);
1429
            $customerAddresses = json_decode($customerAddresses, true);
1430
1431
            $customerAddressArray = $customerAddresses[$cusAddId];
1432
1433
            $CustomerAddress = new CustomerAddress();
1434
            $CustomerAddress->setPropertiesFromArray($customerAddressArray);
1435
            $CustomerAddress->setPref($app['eccube.repository.master.pref']->find($customerAddressArray['Pref']['id']));
1436
1437
            return $CustomerAddress;
1438
        }
1439
    }
1440
1441
    /**
1442
     * 非会員用複数配送設定時の新規お届け先の設定
1443
     */
1444
    public function shippingMultipleEdit(Application $app, Request $request)
1445
    {
1446
        // カートチェック
1447
        if (!$app['eccube.service.cart']->isLocked()) {
1448
            log_info('カートが存在しません');
1449
            // カートが存在しない、カートがロックされていない時はエラー
1450
            return $app->redirect($app->url('cart'));
1451
        }
1452
1453
        // 非会員用Customerを取得
1454
        $Customer = $app['eccube.service.shopping']->getNonMember($this->sessionKey);
1455
        $CustomerAddress = new CustomerAddress();
1456
        $CustomerAddress->setCustomer($Customer);
1457
        $Customer->addCustomerAddress($CustomerAddress);
1458
1459
        $builder = $app['form.factory']->createBuilder('shopping_shipping', $CustomerAddress);
1460
1461
        $event = new EventArgs(
1462
            array(
1463
                'builder' => $builder,
1464
                'Customer' => $Customer,
1465
            ),
1466
            $request
1467
        );
1468
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_EDIT_INITIALIZE, $event);
1469
1470
        $form = $builder->getForm();
1471
1472
        $form->handleRequest($request);
1473
1474
        if ($form->isSubmitted() && $form->isValid()) {
1475
1476
            log_info('非会員お届け先追加処理開始');
1477
1478
            $customerAddressArray = $CustomerAddress->toArray();
1479
            $customerAddressArray['Customer'] = $CustomerAddress->getCustomer()->toArray();
1480
            $customerAddressArray['Pref'] = $CustomerAddress->getPref()->toArray();
1481
1482
            // 非会員用のセッションに追加
1483
            $customerAddresses = json_decode($app['session']->get($this->sessionCustomerAddressKey), true);
1484
            $customerAddresses[] = $customerAddressArray;
1485
1486
            $app['session']->set($this->sessionCustomerAddressKey, json_encode($customerAddresses));
1487
1488
            $event = new EventArgs(
1489
                array(
1490
                    'form' => $form,
1491
                    'CustomerAddresses' => $customerAddresses,
1492
                ),
1493
                $request
1494
            );
1495
            $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_EDIT_COMPLETE, $event);
1496
1497
            log_info('非会員お届け先追加処理完了');
1498
1499
            return $app->redirect($app->url('shopping_shipping_multiple'));
1500
        }
1501
1502
        return $app->render('Shopping/shipping_multiple_edit.twig', array(
1503
            'form' => $form->createView(),
1504
        ));
1505
    }
1506
1507
    /**
1508
     * 購入エラー画面表示
1509
     */
1510
    public function shoppingError(Application $app, Request $request)
1511
    {
1512
1513
        $event = new EventArgs(
1514
            array(),
1515
            $request
1516
        );
1517
        $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_ERROR_COMPLETE, $event);
1518
1519
        if ($event->getResponse() !== null) {
1520
            return $event->getResponse();
1521
        }
1522
1523
        return $app->render('Shopping/shopping_error.twig');
1524
    }
1525
1526
    /**
1527
     * 非会員でのお客様情報変更時の入力チェック
1528
     *
1529
     * @param Application $app
1530
     * @param array $data リクエストパラメータ
1531
     * @return array
1532
     */
1533
    private function customerValidation(Application $app, array $data)
1534
    {
1535
        // 入力チェック
1536
        $errors = array();
1537
1538
        $errors[] = $app['validator']->validateValue($data['customer_name01'], array(
1539
            new Assert\NotBlank(),
1540
            new Assert\Length(array('max' => $app['config']['name_len'],)),
1541
            new Assert\Regex(array('pattern' => '/^[^\s ]+$/u', 'message' => 'form.type.name.firstname.nothasspace'))
1542
        ));
1543
1544
        $errors[] = $app['validator']->validateValue($data['customer_name02'], array(
1545
            new Assert\NotBlank(),
1546
            new Assert\Length(array('max' => $app['config']['name_len'],)),
1547
            new Assert\Regex(array('pattern' => '/^[^\s ]+$/u', 'message' => 'form.type.name.firstname.nothasspace'))
1548
        ));
1549
1550
        $errors[] = $app['validator']->validateValue($data['customer_company_name'], array(
1551
            new Assert\Length(array('max' => $app['config']['stext_len'])),
1552
        ));
1553
1554
        $errors[] = $app['validator']->validateValue($data['customer_tel01'], array(
1555
            new Assert\NotBlank(),
1556
            new Assert\Type(array('type' => 'numeric', 'message' => 'form.type.numeric.invalid')),
1557
            new Assert\Length(array('max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min'])),
1558
        ));
1559
1560
        $errors[] = $app['validator']->validateValue($data['customer_tel02'], array(
1561
            new Assert\NotBlank(),
1562
            new Assert\Type(array('type' => 'numeric', 'message' => 'form.type.numeric.invalid')),
1563
            new Assert\Length(array('max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min'])),
1564
        ));
1565
1566
        $errors[] = $app['validator']->validateValue($data['customer_tel03'], array(
1567
            new Assert\NotBlank(),
1568
            new Assert\Type(array('type' => 'numeric', 'message' => 'form.type.numeric.invalid')),
1569
            new Assert\Length(array('max' => $app['config']['tel_len'], 'min' => $app['config']['tel_len_min'])),
1570
        ));
1571
1572
        $errors[] = $app['validator']->validateValue($data['customer_zip01'], array(
1573
            new Assert\NotBlank(),
1574
            new Assert\Type(array('type' => 'numeric', 'message' => 'form.type.numeric.invalid')),
1575
            new Assert\Length(array('min' => $app['config']['zip01_len'], 'max' => $app['config']['zip01_len'])),
1576
        ));
1577
1578
        $errors[] = $app['validator']->validateValue($data['customer_zip02'], array(
1579
            new Assert\NotBlank(),
1580
            new Assert\Type(array('type' => 'numeric', 'message' => 'form.type.numeric.invalid')),
1581
            new Assert\Length(array('min' => $app['config']['zip02_len'], 'max' => $app['config']['zip02_len'])),
1582
        ));
1583
1584
        $errors[] = $app['validator']->validateValue($data['customer_addr01'], array(
1585
            new Assert\NotBlank(),
1586
            new Assert\Length(array('max' => $app['config']['address1_len'])),
1587
        ));
1588
1589
        $errors[] = $app['validator']->validateValue($data['customer_addr02'], array(
1590
            new Assert\NotBlank(),
1591
            new Assert\Length(array('max' => $app['config']['address2_len'])),
1592
        ));
1593
1594
        $errors[] = $app['validator']->validateValue($data['customer_email'], array(
1595
            new Assert\NotBlank(),
1596
            new Assert\Email(array('strict' => true)),
1597
        ));
1598
1599
        return $errors;
1600
    }
1601
}
1602