Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 41 | class OrderHelper |
||
| 42 | { |
||
| 43 | // FIXME 必要なメソッドのみ移植する |
||
| 44 | use ControllerTrait; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var ContainerInterface |
||
| 48 | */ |
||
| 49 | protected $container; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * @var string 非会員情報を保持するセッションのキー |
||
| 53 | */ |
||
| 54 | const SESSION_NON_MEMBER = 'eccube.front.shopping.nonmember'; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * @var string 非会員の住所情報を保持するセッションのキー |
||
| 58 | */ |
||
| 59 | const SESSION_NON_MEMBER_ADDRESSES = 'eccube.front.shopping.nonmember.customeraddress'; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * @var string 受注IDを保持するセッションのキー |
||
| 63 | */ |
||
| 64 | const SESSION_ORDER_ID = 'eccube.front.shopping.order.id'; |
||
| 65 | |||
| 66 | /** |
||
| 67 | * @var string カートが分割されているかどうかのフラグ. 購入フローからのログイン時にカートが分割された場合にtrueがセットされる. |
||
| 68 | * |
||
| 69 | * @see SecurityListener |
||
| 70 | */ |
||
| 71 | const SESSION_CART_DEVIDE_FLAG = 'eccube.front.cart.divide'; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * @var SessionInterface |
||
| 75 | */ |
||
| 76 | protected $session; |
||
| 77 | |||
| 78 | /** |
||
| 79 | * @var PrefRepository |
||
| 80 | */ |
||
| 81 | protected $prefRepository; |
||
| 82 | |||
| 83 | /** |
||
| 84 | * @var OrderRepository |
||
| 85 | */ |
||
| 86 | protected $orderRepository; |
||
| 87 | |||
| 88 | /** |
||
| 89 | * @var OrderItemTypeRepository |
||
| 90 | */ |
||
| 91 | protected $orderItemTypeRepository; |
||
| 92 | |||
| 93 | public function __construct( |
||
| 94 | ContainerInterface $container, |
||
| 95 | EntityManagerInterface $entityManager, |
||
| 96 | OrderRepository $orderRepository, |
||
| 97 | OrderItemTypeRepository $orderItemTypeRepository, |
||
| 98 | OrderStatusRepository $orderStatusRepository, |
||
| 99 | DeliveryRepository $deliveryRepository, |
||
| 100 | PaymentRepository $paymentRepository, |
||
| 101 | DeviceTypeRepository $deviceTypeRepository, |
||
| 102 | PrefRepository $prefRepository, |
||
| 103 | MobileDetector $mobileDetector, |
||
| 104 | SessionInterface $session |
||
| 105 | ) { |
||
| 106 | $this->container = $container; |
||
| 107 | $this->orderRepository = $orderRepository; |
||
| 108 | $this->orderStatusRepository = $orderStatusRepository; |
||
| 109 | $this->orderItemTypeRepository = $orderItemTypeRepository; |
||
| 110 | $this->deliveryRepository = $deliveryRepository; |
||
| 111 | $this->paymentRepository = $paymentRepository; |
||
| 112 | $this->deviceTypeRepository = $deviceTypeRepository; |
||
| 113 | $this->entityManager = $entityManager; |
||
| 114 | $this->prefRepository = $prefRepository; |
||
| 115 | 175 | $this->mobileDetector = $mobileDetector; |
|
| 116 | $this->session = $session; |
||
| 117 | } |
||
| 118 | |||
| 119 | /** |
||
| 120 | * 購入処理中の受注を生成する. |
||
| 121 | * |
||
| 122 | * @param Customer $Customer |
||
| 123 | * @param $CartItems |
||
| 124 | * |
||
| 125 | * @return Order |
||
| 126 | */ |
||
| 127 | public function createPurchaseProcessingOrder(Cart $Cart, Customer $Customer) |
||
| 128 | 175 | { |
|
| 129 | 175 | $OrderStatus = $this->orderStatusRepository->find(OrderStatus::PROCESSING); |
|
| 130 | 175 | $Order = new Order($OrderStatus); |
|
| 131 | 175 | ||
| 132 | 175 | $preOrderId = $this->createPreOrderId(); |
|
| 133 | 175 | $Order->setPreOrderId($preOrderId); |
|
| 134 | 175 | ||
| 135 | 175 | // 顧客情報の設定 |
|
| 136 | 175 | $this->setCustomer($Order, $Customer); |
|
| 137 | 175 | ||
| 138 | 175 | $DeviceType = $this->deviceTypeRepository->find($this->mobileDetector->isMobile() ? DeviceType::DEVICE_TYPE_MB : DeviceType::DEVICE_TYPE_PC); |
|
| 139 | $Order->setDeviceType($DeviceType); |
||
| 140 | |||
| 141 | // 明細情報の設定 |
||
| 142 | $OrderItems = $this->createOrderItemsFromCartItems($Cart->getCartItems()); |
||
|
|
|||
| 143 | $OrderItemsGroupBySaleType = array_reduce($OrderItems, function ($result, $item) { |
||
| 144 | /* @var OrderItem $item */ |
||
| 145 | $saleTypeId = $item->getProductClass()->getSaleType()->getId(); |
||
| 146 | $result[$saleTypeId][] = $item; |
||
| 147 | |||
| 148 | return $result; |
||
| 149 | 51 | }, []); |
|
| 150 | |||
| 151 | 51 | foreach ($OrderItemsGroupBySaleType as $OrderItems) { |
|
| 152 | 51 | $Shipping = $this->createShippingFromCustomer($Customer); |
|
| 153 | $Shipping->setOrder($Order); |
||
| 154 | 51 | $this->addOrderItems($Order, $Shipping, $OrderItems); |
|
| 155 | $this->setDefaultDelivery($Shipping); |
||
| 156 | 51 | $this->entityManager->persist($Shipping); |
|
| 157 | $Order->addShipping($Shipping); |
||
| 158 | } |
||
| 159 | |||
| 160 | 51 | $this->setDefaultPayment($Order); |
|
| 161 | |||
| 162 | 51 | $this->entityManager->persist($Order); |
|
| 163 | 51 | ||
| 164 | return $Order; |
||
| 165 | } |
||
| 166 | 51 | ||
| 167 | 51 | /** |
|
| 168 | * @param Cart $Cart |
||
| 169 | 51 | * |
|
| 170 | 51 | * @return bool |
|
| 171 | */ |
||
| 172 | 51 | public function verifyCart(Cart $Cart) |
|
| 173 | 51 | { |
|
| 174 | if (count($Cart->getCartItems()) > 0) { |
||
| 175 | 51 | $divide = $this->session->get(self::SESSION_CART_DEVIDE_FLAG); |
|
| 176 | 51 | if ($divide) { |
|
| 177 | 51 | log_info('ログイン時に販売種別が異なる商品がカートと結合されました。'); |
|
| 178 | 51 | ||
| 179 | 51 | return false; |
|
| 180 | 51 | } |
|
| 181 | 51 | ||
| 182 | return true; |
||
| 183 | } |
||
| 184 | 51 | ||
| 185 | log_info('カートに商品が入っていません。'); |
||
| 186 | 51 | ||
| 187 | return false; |
||
| 188 | } |
||
| 189 | 51 | ||
| 190 | /** |
||
| 191 | * 注文手続き画面でログインが必要かどうかの判定 |
||
| 192 | * |
||
| 193 | * @return bool |
||
| 194 | */ |
||
| 195 | public function isLoginRequired() |
||
| 214 | 2 | ||
| 215 | /** |
||
| 216 | * 購入処理中の受注を取得する. |
||
| 217 | 51 | * |
|
| 218 | * @param null|string $preOrderId |
||
| 219 | * |
||
| 220 | * @return null|Order |
||
| 221 | 51 | */ |
|
| 222 | public function getPurchaseProcessingOrder($preOrderId = null) |
||
| 233 | |||
| 234 | 51 | /** |
|
| 235 | * セッションに保持されている非会員情報を取得する. |
||
| 236 | 51 | * 非会員購入時に入力されたお客様情報を返す. |
|
| 237 | 34 | * |
|
| 238 | * @return Customer |
||
| 239 | */ |
||
| 240 | 51 | public function getNonMember() |
|
| 241 | 51 | { |
|
| 242 | $NonMember = $this->session->get(self::SESSION_NON_MEMBER); |
||
| 243 | 51 | if ($NonMember && $NonMember->getPref()) { |
|
| 244 | $Pref = $this->prefRepository->find($NonMember->getPref()->getId()); |
||
| 245 | $NonMember->setPref($Pref); |
||
| 246 | } |
||
| 247 | |||
| 248 | return $NonMember; |
||
| 249 | } |
||
| 250 | |||
| 251 | /** |
||
| 252 | * @param Cart $Cart |
||
| 253 | * @param Customer $Customer |
||
| 254 | * |
||
| 255 | * @return Order|null |
||
| 256 | 51 | */ |
|
| 257 | public function initializeOrder(Cart $Cart, Customer $Customer) |
||
| 270 | 51 | ||
| 271 | 51 | public function removeSession() |
|
| 278 | 51 | ||
| 279 | 51 | private function createPreOrderId() |
|
| 295 | |||
| 296 | 51 | private function setCustomer(Order $Order, Customer $Customer) |
|
| 312 | |||
| 313 | 51 | /** |
|
| 314 | 51 | * @param ArrayCollection|CartItem[] $CartItems |
|
| 315 | * |
||
| 316 | 51 | * @return OrderItem[] |
|
| 317 | 51 | */ |
|
| 318 | 51 | private function createOrderItemsFromCartItems($CartItems) |
|
| 353 | |||
| 354 | /** |
||
| 355 | 51 | * @param Customer $Customer |
|
| 356 | 51 | * |
|
| 357 | 51 | * @return Shipping |
|
| 358 | 51 | */ |
|
| 359 | private function createShippingFromCustomer(Customer $Customer) |
||
| 376 | |||
| 377 | /** |
||
| 378 | * @param Shipping $Shipping |
||
| 379 | */ |
||
| 380 | private function setDefaultDelivery(Shipping $Shipping) |
||
| 400 | |||
| 401 | /** |
||
| 402 | * @param Order $Order |
||
| 403 | */ |
||
| 404 | private function setDefaultPayment(Order $Order) |
||
| 434 | |||
| 435 | /** |
||
| 436 | * @param Order $Order |
||
| 437 | * @param Shipping $Shipping |
||
| 438 | * @param array $OrderItems |
||
| 439 | */ |
||
| 440 | private function addOrderItems(Order $Order, Shipping $Shipping, array $OrderItems) |
||
| 449 | } |
||
| 450 |
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.