Failed Conditions
Pull Request — experimental/sf (#3236)
by Kentaro
144:19 queued 116:23
created

Eccube/Controller/ShippingMultipleController.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of EC-CUBE
5
 *
6
 * Copyright(c) LOCKON CO.,LTD. All Rights Reserved.
7
 *
8
 * http://www.lockon.co.jp/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Eccube\Controller;
15
16
use Eccube\Entity\Customer;
17
use Eccube\Entity\CustomerAddress;
18
use Eccube\Entity\Master\OrderItemType;
19
use Eccube\Entity\Master\OrderStatus;
20
use Eccube\Entity\OrderItem;
21
use Eccube\Entity\Shipping;
22
use Eccube\Event\EccubeEvents;
23
use Eccube\Event\EventArgs;
24
use Eccube\Form\Type\Front\ShoppingShippingType;
25
use Eccube\Form\Type\ShippingMultipleType;
26
use Eccube\Repository\Master\OrderItemTypeRepository;
27
use Eccube\Repository\Master\PrefRepository;
28
use Eccube\Repository\OrderRepository;
29
use Eccube\Service\CartService;
30
use Eccube\Service\OrderHelper;
31
use Eccube\Service\PurchaseFlow\PurchaseContext;
32
use Eccube\Service\PurchaseFlow\PurchaseFlow;
33
use Eccube\Service\ShoppingService;
34
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
35
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
36
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
37
use Symfony\Component\HttpFoundation\Request;
38
39
class ShippingMultipleController extends AbstractShoppingController
40
{
41
    /**
42
     * @var PrefRepository
43
     */
44
    protected $prefRepository;
45
46
    /**
47
     * @var OrderItemTypeRepository
48
     */
49
    protected $orderItemTypeRepository;
50
51
    /**
52
     * @var ShoppingService
53
     */
54
    protected $shoppingService;
55
56
    /**
57
     * @var CartService
58
     */
59
    protected $cartService;
60
61
    /**
62
     * @var PurchaseFlow
63
     */
64
    protected $cartPurchaseFlow;
65
66
    /**
67
     * @var OrderRepository
68
     */
69
    protected $orderRepository;
70
71
    /**
72
     * @var OrderHelper
73
     */
74
    protected $orderHelper;
75
76
    /**
77
     * ShippingMultipleController constructor.
78
     *
79
     * @param PrefRepository $prefRepository
80
     * @param OrderItemTypeRepository $orderItemTypeRepository
81
     * @param ShoppingService $shoppingService
82
     * @param CartService $cartService,
83
     * @param OrderHelper $orderHelper
84
     */
85 26
    public function __construct(
86
        PrefRepository $prefRepository,
87
        OrderRepository $orderRepository,
88
        OrderItemTypeRepository $orderItemTypeRepository,
89
        ShoppingService $shoppingService,
90
        CartService $cartService,
91
        OrderHelper $orderHelper,
92
        PurchaseFlow $cartPurchaseFlow
93
    ) {
94 26
        $this->prefRepository = $prefRepository;
95 26
        $this->orderRepository = $orderRepository;
96 26
        $this->orderItemTypeRepository = $orderItemTypeRepository;
97 26
        $this->shoppingService = $shoppingService;
98 26
        $this->cartService = $cartService;
99 26
        $this->orderHelper = $orderHelper;
100 26
        $this->cartPurchaseFlow = $cartPurchaseFlow;
101
    }
102
103
    /**
104
     * 複数配送処理
105
     *
106
     * @Route("/shopping/shipping_multiple", name="shopping_shipping_multiple")
107
     * @Template("Shopping/shipping_multiple.twig")
108
     */
109 26
    public function index(Request $request)
110
    {
111
        // カートチェック
112 26
        $response = $this->forwardToRoute('shopping_check_to_cart');
113 26
        if ($response->isRedirection() || $response->getContent()) {
114
            return $response;
115
        }
116
117
        /** @var \Eccube\Entity\Order $Order */
118 26
        $Order = $this->shoppingService->getOrder(OrderStatus::PROCESSING);
119 26
        if (!$Order) {
120
            log_info('購入処理中の受注情報がないため購入エラー');
121
            $this->addError('front.shopping.order.error');
122
123
            return $this->redirectToRoute('shopping_error');
124
        }
125
126
        // 処理しやすいようにすべてのShippingItemをまとめる
127 26
        $OrderItems = $Order->getProductOrderItems();
128
129
        // Orderに含まれる商品ごとの数量を求める
130 26
        $ItemQuantitiesByClassId = [];
131 26
        foreach ($OrderItems as $item) {
132 26
            $itemId = $item->getProductClass()->getId();
133 26
            $quantity = $item->getQuantity();
134 26
            if (array_key_exists($itemId, $ItemQuantitiesByClassId)) {
135
                $ItemQuantitiesByClassId[$itemId] += $quantity;
136
            } else {
137 26
                $ItemQuantitiesByClassId[$itemId] = $quantity;
138
            }
139
        }
140
141
        // FormBuilder用に商品ごとにShippingItemをまとめる
142 26
        $OrderItemsForFormBuilder = [];
143 26
        $tmpAddedClassIds = [];
144 26
        foreach ($OrderItems as $item) {
145 26
            $itemId = $item->getProductClass()->getId();
146 26
            if (!in_array($itemId, $tmpAddedClassIds)) {
147 26
                $OrderItemsForFormBuilder[] = $item;
148 26
                $tmpAddedClassIds[] = $itemId;
149
            }
150
        }
151
152
        // Form生成
153 26
        $builder = $this->formFactory->createBuilder();
154
        $builder
155 26
            ->add('shipping_multiple', CollectionType::class, [
156 26
                'entry_type' => ShippingMultipleType::class,
157 26
                'data' => $OrderItemsForFormBuilder,
158
                'allow_add' => true,
159
                'allow_delete' => true,
160
            ]);
161
        // Event
162 26
        $event = new EventArgs(
163
            [
164 26
                'builder' => $builder,
165 26
                'Order' => $Order,
166
            ],
167 26
            $request
168
        );
169 26
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_INITIALIZE, $event);
170
171 26
        $form = $builder->getForm();
172 26
        $form->handleRequest($request);
173
174 26
        $errors = [];
175 26
        if ($form->isSubmitted() && $form->isValid()) {
176 25
            log_info('複数配送設定処理開始', [$Order->getId()]);
177
178 25
            $data = $form['shipping_multiple'];
179
180
            // フォームの入力から、送り先ごとに商品の数量を集計する
181 25
            $arrOrderItemTemp = [];
182 25
            foreach ($data as $mulitples) {
183 25
                $OrderItem = $mulitples->getData();
184 25
                foreach ($mulitples as $items) {
185 25
                    foreach ($items as $item) {
186 25
                        $CustomerAddress = $item['customer_address']->getData();
187 25
                        $customerAddressName = $CustomerAddress->getShippingMultipleDefaultName();
188
189 25
                        $itemId = $OrderItem->getProductClass()->getId();
190 25
                        $quantity = $item['quantity']->getData();
191
192 25
                        if (isset($arrOrderItemTemp[$customerAddressName]) && array_key_exists($itemId, $arrOrderItemTemp[$customerAddressName])) {
193 7
                            $arrOrderItemTemp[$customerAddressName][$itemId] = $arrOrderItemTemp[$customerAddressName][$itemId] + $quantity;
194
                        } else {
195 25
                            $arrOrderItemTemp[$customerAddressName][$itemId] = $quantity;
196
                        }
197
                    }
198
                }
199
            }
200
201
            // フォームの入力から、商品ごとの数量を集計する
202 25
            $itemQuantities = [];
203 25
            foreach ($arrOrderItemTemp as $FormItemByAddress) {
204 25
                foreach ($FormItemByAddress as $itemId => $quantity) {
205 25
                    if (array_key_exists($itemId, $itemQuantities)) {
206 14
                        $itemQuantities[$itemId] = $itemQuantities[$itemId] + $quantity;
207
                    } else {
208 25
                        $itemQuantities[$itemId] = $quantity;
209
                    }
210
                }
211
            }
212
213
            // -- ここから先がお届け先を再生成する処理 --
214
215
            // お届け先情報をすべて削除
216
            /** @var Shipping $Shipping */
217 25
            foreach ($Order->getShippings() as $Shipping) {
218 25
                foreach ($Shipping->getOrderItems() as $OrderItem) {
219 25
                    $Shipping->removeOrderItem($OrderItem);
220 25
                    $Order->removeOrderItem($OrderItem);
221 25
                    $this->entityManager->remove($OrderItem);
222
                }
223 25
                $Order->removeShipping($Shipping);
224 25
                $this->entityManager->remove($Shipping);
225
            }
226
227
            // お届け先のリストを作成する
228 25
            $ShippingList = [];
229 25
            foreach ($data as $mulitples) {
230 25
                $OrderItem = $mulitples->getData();
231 25
                $ProductClass = $OrderItem->getProductClass();
232 25
                $Delivery = $OrderItem->getShipping()->getDelivery();
233 25
                $saleTypeId = $ProductClass->getSaleType()->getId();
234
235 25
                foreach ($mulitples as $items) {
236 25
                    foreach ($items as $item) {
237 25
                        $CustomerAddress = $item['customer_address']->getData();
238 25
                        $customerAddressName = $CustomerAddress->getShippingMultipleDefaultName();
239
240 25
                        if (isset($ShippingList[$customerAddressName][$saleTypeId])) {
241 18
                            continue;
242
                        }
243 25
                        $Shipping = new Shipping();
244
                        $Shipping
245 25
                            ->setOrder($Order)
246 25
                            ->setFromCustomerAddress($CustomerAddress)
247 25
                            ->setDelivery($Delivery);
248 25
                        $Order->addShipping($Shipping);
249 25
                        $ShippingList[$customerAddressName][$saleTypeId] = $Shipping;
250
                    }
251
                }
252
            }
253
            // お届け先のリストを保存
254 25
            foreach ($ShippingList as $ShippingListByAddress) {
255 25
                foreach ($ShippingListByAddress as $Shipping) {
256 25
                    $this->entityManager->persist($Shipping);
257
                }
258
            }
259
260 25
            $ProductOrderType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
261
262
            // お届け先に、配送商品の情報(OrderItem)を関連付ける
263 25
            foreach ($data as $mulitples) {
264
                /** @var OrderItem $OrderItem */
265 25
                $OrderItem = $mulitples->getData();
266 25
                $ProductClass = $OrderItem->getProductClass();
267 25
                $Product = $OrderItem->getProduct();
268 25
                $saleTypeId = $ProductClass->getSaleType()->getId();
269 25
                $productClassId = $ProductClass->getId();
270
271 25
                foreach ($mulitples as $items) {
272 25
                    foreach ($items as $item) {
273 25
                        $CustomerAddress = $item['customer_address']->getData();
274 25
                        $customerAddressName = $CustomerAddress->getShippingMultipleDefaultName();
275
276
                        // お届け先から商品の数量を取得
277 25
                        $quantity = 0;
278 25
                        if (isset($arrOrderItemTemp[$customerAddressName]) && array_key_exists($productClassId, $arrOrderItemTemp[$customerAddressName])) {
279 25
                            $quantity = $arrOrderItemTemp[$customerAddressName][$productClassId];
280 25
                            unset($arrOrderItemTemp[$customerAddressName][$productClassId]);
281
                        } else {
282
                            // この配送先には送る商品がないのでスキップ(通常ありえない)
283 7
                            continue;
284
                        }
285
286
                        // 関連付けるお届け先のインスタンスを取得
287 25
                        $Shipping = $ShippingList[$customerAddressName][$saleTypeId];
288
289
                        // インスタンスを生成して保存
290 25
                        $OrderItem = new OrderItem();
291 25
                        $OrderItem->setShipping($Shipping)
292 25
                            ->setOrder($Order)
293 25
                            ->setProductClass($ProductClass)
294 25
                            ->setProduct($Product)
295 25
                            ->setProductName($Product->getName())
296 25
                            ->setProductCode($ProductClass->getCode())
297 25
                            ->setPrice($ProductClass->getPrice02())
298 25
                            ->setQuantity($quantity)
299 25
                            ->setOrderItemType($ProductOrderType);
0 ignored issues
show
It seems like $ProductOrderType defined by $this->orderItemTypeRepo...OrderItemType::PRODUCT) on line 260 can also be of type object; however, Eccube\Entity\OrderItem::setOrderItemType() does only seem to accept null|object<Eccube\Entity\Master\OrderItemType>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
300
301 25
                        $ClassCategory1 = $ProductClass->getClassCategory1();
302 25
                        if (!is_null($ClassCategory1)) {
303 25
                            $OrderItem->setClasscategoryName1($ClassCategory1->getName());
304 25
                            $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
305
                        }
306 25
                        $ClassCategory2 = $ProductClass->getClassCategory2();
307 25
                        if (!is_null($ClassCategory2)) {
308 21
                            $OrderItem->setClasscategoryName2($ClassCategory2->getName());
309 21
                            $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
310
                        }
311 25
                        $Shipping->addOrderItem($OrderItem);
312 25
                        $Order->addOrderItem($OrderItem);
313 25
                        $this->entityManager->persist($OrderItem);
314
                    }
315
                }
316
            }
317
318
            // 合計金額の再計算
319 25
            $flowResult = $this->validatePurchaseFlow($Order);
320 25
            if ($flowResult->hasWarning()) {
321
                return [
322
                    'form' => $form->createView(),
323
                    'OrderItems' => $OrderItemsForFormBuilder,
324
                    'compItemQuantities' => $ItemQuantitiesByClassId,
325
                    'errors' => $errors,
326
                ];
327
            }
328 25
            if ($flowResult->hasError()) {
329
                return $this->redirectToRoute('cart');
330
            }
331
332 25
            $this->entityManager->flush();
333
334 25
            $event = new EventArgs(
335
                [
336 25
                    'form' => $form,
337 25
                    'Order' => $Order,
338
                ],
339 25
                $request
340
            );
341 25
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_COMPLETE, $event);
342
343 25
            log_info('複数配送設定処理完了', [$Order->getId()]);
344
345 25
            $this->entityManager->refresh($Order);
346
347 25
            $quantityByProductClass = [];
348 25
            foreach ($Order->getProductOrderItems() as $Item) {
349 25
                $id = $Item->getProductClass()->getId();
350 25
                if (isset($quantityByProductClass[$id])) {
351 14
                    $quantityByProductClass[$id] += $Item->getQuantity();
352
                } else {
353 25
                    $quantityByProductClass[$id] = $Item->getQuantity();
354
                }
355
            }
356 25
            $Cart = $this->cartService->getCart();
357 25
            foreach ($Cart->getCartItems() as $CartItem) {
358 25
                $id = $CartItem->getProductClass()->getId();
359 25
                if (isset($quantityByProductClass[$id])) {
360 25
                    $CartItem->setQuantity($quantityByProductClass[$id]);
361
                }
362
            }
363
364 25
            $this->cartPurchaseFlow->validate($Cart, new PurchaseContext());
365 25
            $this->cartService->save();
366
367 25
            return $this->redirectToRoute('shopping');
368
        }
369
370
        return [
371 4
            'form' => $form->createView(),
372 4
            'OrderItems' => $OrderItemsForFormBuilder,
373 4
            'compItemQuantities' => $ItemQuantitiesByClassId,
374 4
            'errors' => $errors,
375
        ];
376
    }
377
378
    /**
379
     * 複数配送設定時の新規お届け先の設定
380
     *
381
     * @Route("/shopping/shipping_multiple_edit", name="shopping_shipping_multiple_edit")
382
     * @Template("Shopping/shipping_multiple_edit.twig")
383
     */
384 8
    public function shippingMultipleEdit(Request $request)
385
    {
386
        // カートチェック
387 8
        $response = $this->forwardToRoute('shopping_check_to_cart');
388 8
        if ($response->isRedirection() || $response->getContent()) {
389
            return $response;
390
        }
391
392
        /** @var Customer $Customer */
393 8
        $Customer = $this->getUser();
394 8
        $CustomerAddress = new CustomerAddress();
395 8
        $builder = $this->formFactory->createBuilder(ShoppingShippingType::class, $CustomerAddress);
396
397 8
        $event = new EventArgs(
398
            [
399 8
                'builder' => $builder,
400 8
                'Customer' => $Customer,
401
            ],
402 8
            $request
403
        );
404 8
        $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_EDIT_INITIALIZE, $event);
405
406 8
        $form = $builder->getForm();
407
408 8
        $form->handleRequest($request);
409
410 8
        if ($form->isSubmitted() && $form->isValid()) {
411 8
            log_info('複数配送のお届け先追加処理開始');
412
413 8
            if ($this->isGranted('ROLE_USER')) {
414
                $CustomerAddresses = $Customer->getCustomerAddresses();
415
416
                $count = count($CustomerAddresses);
417
                if ($count >= $this->eccubeConfig['eccube_deliv_addr_max']) {
418
                    return [
419
                        'error' => trans('delivery.text.error.max_delivery_address'),
420
                        'form' => $form->createView(),
421
                    ];
422
                }
423
424
                $CustomerAddress->setCustomer($Customer);
425
                $this->entityManager->persist($CustomerAddress);
426
                $this->entityManager->flush($CustomerAddress);
427
            } else {
428
                // 非会員用のセッションに追加
429 8
                $CustomerAddresses = $this->session->get($this->sessionCustomerAddressKey);
430 8
                $CustomerAddresses = unserialize($CustomerAddresses);
431 8
                $CustomerAddresses[] = $CustomerAddress;
432 8
                $this->session->set($this->sessionCustomerAddressKey, serialize($CustomerAddresses));
433
            }
434
435 8
            $event = new EventArgs(
436
                [
437 8
                    'form' => $form,
438 8
                    'CustomerAddresses' => $CustomerAddresses,
439
                ],
440 8
                $request
441
            );
442 8
            $this->eventDispatcher->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_EDIT_COMPLETE, $event);
443
444 8
            log_info('複数配送のお届け先追加処理完了');
445
446 8
            return $this->redirectToRoute('shopping_shipping_multiple');
447
        }
448
449
        return [
450 1
            'form' => $form->createView(),
451
        ];
452
    }
453
}
454