Completed
Pull Request — experimental/sf (#3420)
by chihiro
244:13 queued 235:15
created

OrderHelper::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 11
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
ccs 12
cts 12
cp 1
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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\Service;
15
16
use Doctrine\Common\Collections\ArrayCollection;
17
use Doctrine\ORM\EntityManager;
18
use Doctrine\ORM\EntityManagerInterface;
19
use Eccube\Common\EccubeConfig;
20
use Eccube\Entity\Cart;
21
use Eccube\Entity\CartItem;
22
use Eccube\Entity\Customer;
23
use Eccube\Entity\Master\DeviceType;
24
use Eccube\Entity\Master\OrderItemType;
25
use Eccube\Entity\Master\OrderStatus;
26
use Eccube\Entity\Order;
27
use Eccube\Entity\OrderItem;
28
use Eccube\Entity\Shipping;
29
use Eccube\Repository\DeliveryFeeRepository;
30
use Eccube\Repository\DeliveryRepository;
31
use Eccube\Repository\Master\OrderItemTypeRepository;
32
use Eccube\Repository\Master\OrderStatusRepository;
33
use Eccube\Repository\OrderRepository;
34
use Eccube\Repository\PaymentRepository;
35
use Eccube\Repository\TaxRuleRepository;
36
use Eccube\Util\StringUtil;
37
use Eccube\Repository\Master\DeviceTypeRepository;
38
39
/**
40
 * OrderやOrderに関連するエンティティを構築するクラス
41
 * namespaceやクラス名は要検討
42
 */
43
class OrderHelper
44
{
45
    /**
46
     * @var OrderItemTypeRepository
47
     */
48
    protected $orderItemTypeRepository;
49
50
    /**
51
     * @var OrderStatusRepository
52
     */
53
    protected $orderStatusRepository;
54
55
    /**
56
     * @var TaxRuleRepository
57
     */
58
    protected $taxRuleRepository;
59
60
    /**
61
     * @var DeliveryFeeRepository
62
     */
63
    protected $deliveryFeeRepository;
64
65
    /**
66
     * @var DeliveryRepository
67
     */
68
    protected $deliveryRepository;
69
70
    /**
71
     * @var PaymentRepository
72
     */
73
    protected $paymentRepository;
74
75
    /**
76
     * @var OrderRepository
77
     */
78
    protected $orderRepository;
79
80
    /**
81
     * @var EntityManager
82
     */
83
    protected $entityManager;
84
85
    /**
86
     * @var EccubeConfig
87
     */
88
    protected $eccubeConfig;
89
90
    /**
91
     * @var \Mobile_Detect
92
     */
93
    protected $mobileDetect;
94
95
    /**
96
     * @var DeviceTypeRepository
97
     */
98
    protected $deviceTypeRepository;
99
100
    /**
101
     * OrderHelper constructor.
102
     *
103
     * @param OrderItemTypeRepository $orderItemTypeRepository
104
     * @param OrderStatusRepository $orderStatusRepository
0 ignored issues
show
introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
105
     * @param TaxRuleRepository $taxRuleRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
106
     * @param DeliveryFeeRepository $deliveryFeeRepository
0 ignored issues
show
introduced by
Expected 3 spaces after parameter type; 1 found
Loading history...
107
     * @param DeliveryRepository $deliveryRepository
0 ignored issues
show
introduced by
Expected 6 spaces after parameter type; 1 found
Loading history...
108
     * @param PaymentRepository $paymentRepository
0 ignored issues
show
introduced by
Expected 7 spaces after parameter type; 1 found
Loading history...
109
     * @param OrderRepository $orderRepository
0 ignored issues
show
introduced by
Expected 9 spaces after parameter type; 1 found
Loading history...
110
     * @param EntityManager $entityManager
0 ignored issues
show
introduced by
Expected 11 spaces after parameter type; 1 found
Loading history...
111
     * @param EccubeConfig $eccubeConfig
0 ignored issues
show
introduced by
Expected 12 spaces after parameter type; 1 found
Loading history...
112
     * @param \Mobile_Detect $mobileDetect
0 ignored issues
show
introduced by
Expected 10 spaces after parameter type; 1 found
Loading history...
113
     * @param DeviceTypeRepository $deviceTypeRepository
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
114
     */
115 175
    public function __construct(
116
        OrderItemTypeRepository $orderItemTypeRepository,
117
        OrderStatusRepository $orderStatusRepository,
118
        TaxRuleRepository $taxRuleRepository,
119
        DeliveryFeeRepository $deliveryFeeRepository,
120
        DeliveryRepository $deliveryRepository,
121
        PaymentRepository $paymentRepository,
122
        OrderRepository $orderRepository,
123
        EntityManagerInterface $entityManager,
124
        EccubeConfig $eccubeConfig,
125
        \Mobile_Detect $mobileDetect,
126
        DeviceTypeRepository $deviceTypeRepository
127
    ) {
128 175
        $this->orderItemTypeRepository = $orderItemTypeRepository;
129 175
        $this->orderStatusRepository = $orderStatusRepository;
130 175
        $this->taxRuleRepository = $taxRuleRepository;
131 175
        $this->deliveryFeeRepository = $deliveryFeeRepository;
132 175
        $this->deliveryRepository = $deliveryRepository;
133 175
        $this->paymentRepository = $paymentRepository;
134 175
        $this->orderRepository = $orderRepository;
135 175
        $this->entityManager = $entityManager;
0 ignored issues
show
Documentation Bug introduced by
$entityManager is of type object<Doctrine\ORM\EntityManagerInterface>, but the property $entityManager was declared to be of type object<Doctrine\ORM\EntityManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
136 175
        $this->eccubeConfig = $eccubeConfig;
137 175
        $this->mobileDetect = $mobileDetect;
138 175
        $this->deviceTypeRepository = $deviceTypeRepository;
139
    }
140
141
    /**
0 ignored issues
show
introduced by
Doc comment for parameter "$preOrderId" missing
Loading history...
142
     * 購入処理中の受注データを生成する.
143
     *
144
     * @param Customer $Customer
145
     * @param array $CartItems
0 ignored issues
show
introduced by
Expected 4 spaces after parameter type; 1 found
Loading history...
146
     *
147
     * @return Order
148
     */
149 51
    public function createProcessingOrder(Customer $Customer, $CartItems, $preOrderId = null)
150
    {
151 51
        $OrderStatus = $this->orderStatusRepository->find(OrderStatus::PROCESSING);
152 51
        $Order = new Order($OrderStatus);
153
154 51
        if (!$preOrderId) {
155
            // pre_order_idを生成
156 51
            $Order->setPreOrderId($this->createPreOrderId());
157
        }
158
159
        // 顧客情報の設定
160 51
        $this->setCustomer($Order, $Customer);
161
162 51
        $DeviceType = $this->deviceTypeRepository->find($this->mobileDetect->isMobile() ? DeviceType::DEVICE_TYPE_SP : DeviceType::DEVICE_TYPE_PC);
163 51
        $Order->setDeviceType($DeviceType);
164
165
        // 明細情報の設定
166 51
        $OrderItems = $this->createOrderItemsFromCartItems($CartItems);
0 ignored issues
show
Documentation introduced by
$CartItems is of type array, but the function expects a object<Doctrine\Common\C...ctions\ArrayCollection>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
167 51
        $OrderItemsGroupBySaleType = array_reduce($OrderItems, function ($result, $item) {
168
            /* @var OrderItem $item */
169 51
            $saleTypeId = $item->getProductClass()->getSaleType()->getId();
170 51
            $result[$saleTypeId][] = $item;
171
172 51
            return $result;
173 51
        }, []);
174
175 51
        foreach ($OrderItemsGroupBySaleType as $OrderItems) {
176 51
            $Shipping = $this->createShippingFromCustomer($Customer);
177 51
            $Shipping->setOrder($Order);
178 51
            $this->addOrderItems($Order, $Shipping, $OrderItems);
179 51
            $this->setDefaultDelivery($Shipping);
180 51
            $this->entityManager->persist($Shipping);
181 51
            $Order->addShipping($Shipping);
182
        }
183
184 51
        $this->setDefaultPayment($Order);
185
186 51
        $this->entityManager->persist($Order);
187
        //$this->entityManager->flush();
188
189 51
        return $Order;
190
    }
191
192
    /**
193
     * OrderをCartに変換します.
194
     *
195
     * @param Order $Order
196
     *
197
     * @return Cart
198
     */
199 2
    public function convertToCart(Order $Order)
200
    {
201 2
        $Cart = new Cart();
202 2
        $Cart->setPreOrderId($Order->getPreOrderId());
203
        /** @var OrderItem $OrderItem */
204 2
        foreach ($Order->getProductOrderItems() as $OrderItem) {
205 1
            $CartItem = new CartItem();
206 1
            $ProductClass = $OrderItem->getProductClass();
207 1
            $this->entityManager->refresh($ProductClass);
208 1
            $CartItem->setProductClass($ProductClass);
209 1
            $CartItem->setPrice($OrderItem->getPriceIncTax());
210 1
            $CartItem->setQuantity($OrderItem->getQuantity());
211 1
            $Cart->addCartItem($CartItem);
212
        }
213
214 2
        return $Cart;
215
    }
216
217 51
    private function createPreOrderId()
218
    {
219
        // ランダムなpre_order_idを作成
220 View Code Duplication
        do {
221 51
            $preOrderId = sha1(StringUtil::random(32));
222
223 51
            $Order = $this->orderRepository->findOneBy(
224
                [
225 51
                    'pre_order_id' => $preOrderId,
226
                    'OrderStatus' => OrderStatus::PROCESSING,
227
                ]
228
            );
229 51
        } while ($Order);
230
231 51
        return $preOrderId;
232
    }
233
234 51
    private function setCustomer(Order $Order, Customer $Customer)
235
    {
236 51
        if ($Customer->getId()) {
237 34
            $Order->setCustomer($Customer);
238
        }
239
240 51
        $Order->copyProperties(
241 51
            $Customer,
242
            [
243 51
                'id',
244
                'create_date',
245
                'update_date',
246
                'del_flg',
247
            ]
248
        );
249
    }
250
251
    /**
252
     * @param ArrayCollection $CartItems
253
     *
254
     * @return OrderItem[]
255
     */
256 51
    private function createOrderItemsFromCartItems($CartItems)
257
    {
258 51
        $ProductItemType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
259
260 51
        return array_map(function ($item) use ($ProductItemType) {
261
            /* @var $item CartItem */
262
            /* @var $ProductClass \Eccube\Entity\ProductClass */
263 51
            $ProductClass = $item->getProductClass();
264
            /* @var $Product \Eccube\Entity\Product */
265 51
            $Product = $ProductClass->getProduct();
266
267 51
            $OrderItem = new OrderItem();
268
            $OrderItem
269 51
                ->setProduct($Product)
270 51
                ->setProductClass($ProductClass)
271 51
                ->setProductName($Product->getName())
272 51
                ->setProductCode($ProductClass->getCode())
273 51
                ->setPrice($ProductClass->getPrice02())
274 51
                ->setQuantity($item->getQuantity())
275 51
                ->setOrderItemType($ProductItemType);
276
277 51
            $ClassCategory1 = $ProductClass->getClassCategory1();
278 51
            if (!is_null($ClassCategory1)) {
279 51
                $OrderItem->setClasscategoryName1($ClassCategory1->getName());
280 51
                $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
281
            }
282 51
            $ClassCategory2 = $ProductClass->getClassCategory2();
283 51
            if (!is_null($ClassCategory2)) {
284 43
                $OrderItem->setClasscategoryName2($ClassCategory2->getName());
285 43
                $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
286
            }
287
288 51
            return $OrderItem;
289 51
        }, $CartItems->toArray());
290
    }
291
292 51
    private function createShippingFromCustomer(Customer $Customer)
293
    {
294 51
        $Shipping = new Shipping();
295
        $Shipping
296 51
            ->setName01($Customer->getName01())
297 51
            ->setName02($Customer->getName02())
298 51
            ->setKana01($Customer->getKana01())
299 51
            ->setKana02($Customer->getKana02())
300 51
            ->setCompanyName($Customer->getCompanyName())
301 51
            ->setPhoneNumber($Customer->getPhoneNumber())
302 51
            ->setPostalCode($Customer->getPostalCode())
303 51
            ->setPref($Customer->getPref())
304 51
            ->setAddr01($Customer->getAddr01())
305 51
            ->setAddr02($Customer->getAddr02());
306
307 51
        return $Shipping;
308
    }
309
310 51
    private function setDefaultDelivery(Shipping $Shipping)
311
    {
312
        // 配送商品に含まれる販売種別を抽出.
313 51
        $OrderItems = $Shipping->getOrderItems();
314 51
        $SaleTypes = [];
315
        /** @var OrderItem $OrderItem */
316 51 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
317 51
            $ProductClass = $OrderItem->getProductClass();
318 51
            $SaleType = $ProductClass->getSaleType();
319 51
            $SaleTypes[$SaleType->getId()] = $SaleType;
320
        }
321
322
        // 販売種別に紐づく配送業者を取得.
323 51
        $Deliveries = $this->deliveryRepository->getDeliveries($SaleTypes);
324
325
        // 初期の配送業者を設定
326 51
        $Delivery = current($Deliveries);
327 51
        $Shipping->setDelivery($Delivery);
328 51
        $Shipping->setShippingDeliveryName($Delivery->getName());
329
    }
330
331 51
    private function setDefaultPayment(Order $Order)
332
    {
333 51
        $OrderItems = $Order->getOrderItems();
334
335
        // 受注明細に含まれる販売種別を抽出.
336 51
        $SaleTypes = [];
337
        /** @var OrderItem $OrderItem */
338 51 View Code Duplication
        foreach ($OrderItems as $OrderItem) {
339 51
            $ProductClass = $OrderItem->getProductClass();
340 51
            if (is_null($ProductClass)) {
341
                // 商品明細のみ対象とする. 送料明細等はスキップする.
342
                continue;
343
            }
344 51
            $SaleType = $ProductClass->getSaleType();
345 51
            $SaleTypes[$SaleType->getId()] = $SaleType;
346
        }
347
348
        // 販売種別に紐づく配送業者を抽出
349 51
        $Deliveries = $this->deliveryRepository->getDeliveries($SaleTypes);
350
351
        // 利用可能な支払い方法を抽出.
352 51
        $Payments = $this->paymentRepository->findAllowedPayments($Deliveries, true);
353
354
        // 初期の支払い方法を設定.
355 51
        $Payment = current($Payments);
356 51
        if ($Payment) {
357 51
            $Order->setPayment($Payment);
358 51
            $Order->setPaymentMethod($Payment->getMethod());
359
        }
360
    }
361
362 51
    private function addOrderItems(Order $Order, Shipping $Shipping, array $OrderItems)
363
    {
364 51
        foreach ($OrderItems as $OrderItem) {
365 51
            $Shipping->addOrderItem($OrderItem);
366 51
            $Order->addOrderItem($OrderItem);
367 51
            $OrderItem->setOrder($Order);
368 51
            $OrderItem->setShipping($Shipping);
369
        }
370
    }
371
}
372