Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ShoppingController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ShoppingController, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 42 | class ShoppingController extends AbstractController |
||
|
|
|||
| 43 | { |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @var string 非会員用セッションキー |
||
| 47 | */ |
||
| 48 | private $sessionKey = 'eccube.front.shopping.nonmember'; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var string 非会員用セッションキー |
||
| 52 | */ |
||
| 53 | private $sessionCustomerAddressKey = 'eccube.front.shopping.nonmember.customeraddress'; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @var string 複数配送警告メッセージ |
||
| 57 | */ |
||
| 58 | private $sessionMultipleKey = 'eccube.front.shopping.multiple'; |
||
| 59 | |||
| 60 | /** |
||
| 61 | * @var string 受注IDキー |
||
| 62 | */ |
||
| 63 | private $sessionOrderKey = 'eccube.front.shopping.order.id'; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * 購入画面表示 |
||
| 67 | * |
||
| 68 | * @param Application $app |
||
| 69 | * @param Request $request |
||
| 70 | * @return \Symfony\Component\HttpFoundation\RedirectResponse|Response |
||
| 71 | */ |
||
| 72 | 94 | public function index(Application $app, Request $request) |
|
| 73 | { |
||
| 74 | 94 | $cartService = $app['eccube.service.cart']; |
|
| 75 | |||
| 76 | // カートチェック |
||
| 77 | 94 | if (!$cartService->isLocked()) { |
|
| 78 | 4 | log_info('カートが存在しません'); |
|
| 79 | // カートが存在しない、カートがロックされていない時はエラー |
||
| 80 | 4 | return $app->redirect($app->url('cart')); |
|
| 81 | } |
||
| 82 | |||
| 83 | // カートチェック |
||
| 84 | 90 | View Code Duplication | if (count($cartService->getCart()->getCartItems()) <= 0) { |
| 85 | 7 | log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト'); |
|
| 86 | // カートが存在しない時はエラー |
||
| 87 | 7 | return $app->redirect($app->url('cart')); |
|
| 88 | } |
||
| 89 | |||
| 90 | // 登録済みの受注情報を取得 |
||
| 91 | 86 | $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']); |
|
| 92 | |||
| 93 | // 初回アクセス(受注情報がない)の場合は, 受注情報を作成 |
||
| 94 | 86 | if (is_null($Order)) { |
|
| 95 | // 未ログインの場合, ログイン画面へリダイレクト. |
||
| 96 | 86 | if (!$app->isGranted('IS_AUTHENTICATED_FULLY')) { |
|
| 97 | // 非会員でも一度会員登録されていればショッピング画面へ遷移 |
||
| 98 | 30 | $Customer = $app['eccube.service.shopping']->getNonMember($this->sessionKey); |
|
| 99 | |||
| 100 | 30 | if (is_null($Customer)) { |
|
| 101 | log_info('未ログインのためログイン画面にリダイレクト'); |
||
| 102 | 30 | return $app->redirect($app->url('shopping_login')); |
|
| 103 | } |
||
| 104 | } else { |
||
| 105 | 56 | $Customer = $app->user(); |
|
| 106 | } |
||
| 107 | |||
| 108 | try { |
||
| 109 | // 受注情報を作成 |
||
| 110 | 86 | $Order = $app['eccube.service.shopping']->createOrder($Customer); |
|
| 111 | 1 | } catch (CartException $e) { |
|
| 112 | 1 | log_error('初回受注情報作成エラー', array($e->getMessage())); |
|
| 113 | 1 | $app->addRequestError($e->getMessage()); |
|
| 114 | 1 | return $app->redirect($app->url('cart')); |
|
| 115 | } |
||
| 116 | |||
| 117 | // セッション情報を削除 |
||
| 118 | 85 | $app['session']->remove($this->sessionOrderKey); |
|
| 119 | 85 | $app['session']->remove($this->sessionMultipleKey); |
|
| 120 | } |
||
| 121 | |||
| 122 | // 受注関連情報を最新状態に更新 |
||
| 123 | 85 | $app['orm.em']->refresh($Order); |
|
| 124 | |||
| 125 | // form作成 |
||
| 126 | 85 | $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order); |
|
| 127 | |||
| 128 | 85 | $event = new EventArgs( |
|
| 129 | array( |
||
| 130 | 85 | 'builder' => $builder, |
|
| 131 | 85 | 'Order' => $Order, |
|
| 132 | ), |
||
| 133 | $request |
||
| 134 | ); |
||
| 135 | 85 | $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_INDEX_INITIALIZE, $event); |
|
| 136 | |||
| 137 | 85 | $form = $builder->getForm(); |
|
| 138 | |||
| 139 | 85 | if ($Order->getTotalPrice() < 0) { |
|
| 140 | // 合計金額がマイナスの場合、エラー |
||
| 141 | log_info('受注金額マイナスエラー', array($Order->getId())); |
||
| 142 | $message = $app->trans('shopping.total.price', array('totalPrice' => number_format($Order->getTotalPrice()))); |
||
| 143 | $app->addError($message); |
||
| 144 | |||
| 145 | return $app->redirect($app->url('shopping_error')); |
||
| 146 | } |
||
| 147 | |||
| 148 | // 複数配送の場合、エラーメッセージを一度だけ表示 |
||
| 149 | 85 | if (!$app['session']->has($this->sessionMultipleKey)) { |
|
| 150 | 85 | if (count($Order->getShippings()) > 1) { |
|
| 151 | |||
| 152 | 5 | $BaseInfo = $app['eccube.repository.base_info']->get(); |
|
| 153 | |||
| 154 | 5 | if (!$BaseInfo->getOptionMultipleShipping()) { |
|
| 155 | // 複数配送に設定されていないのに複数配送先ができればエラー |
||
| 156 | $app->addRequestError('cart.product.type.kind'); |
||
| 157 | return $app->redirect($app->url('cart')); |
||
| 158 | } |
||
| 159 | |||
| 160 | 5 | $app->addError('shopping.multiple.delivery'); |
|
| 161 | } |
||
| 162 | 85 | $app['session']->set($this->sessionMultipleKey, 'multiple'); |
|
| 163 | } |
||
| 164 | |||
| 165 | 85 | return $app->render('Shopping/index.twig', array( |
|
| 166 | 85 | 'form' => $form->createView(), |
|
| 167 | 85 | 'Order' => $Order, |
|
| 168 | )); |
||
| 169 | } |
||
| 170 | |||
| 171 | /** |
||
| 172 | * 購入処理 |
||
| 173 | */ |
||
| 174 | 23 | public function confirm(Application $app, Request $request) |
|
| 175 | { |
||
| 176 | 23 | $cartService = $app['eccube.service.cart']; |
|
| 177 | |||
| 178 | // カートチェック |
||
| 179 | 23 | if (!$cartService->isLocked()) { |
|
| 180 | // カートが存在しない、カートがロックされていない時はエラー |
||
| 181 | log_info('カートが存在しません'); |
||
| 182 | return $app->redirect($app->url('cart')); |
||
| 183 | } |
||
| 184 | |||
| 185 | 23 | $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']); |
|
| 186 | 23 | if (!$Order) { |
|
| 187 | log_info('購入処理中の受注情報がないため購入エラー'); |
||
| 188 | $app->addError('front.shopping.order.error'); |
||
| 189 | return $app->redirect($app->url('shopping_error')); |
||
| 190 | } |
||
| 191 | |||
| 192 | 23 | if ('POST' !== $request->getMethod()) { |
|
| 193 | return $app->redirect($app->url('cart')); |
||
| 194 | } |
||
| 195 | |||
| 196 | // form作成 |
||
| 197 | 23 | $builder = $app['eccube.service.shopping']->getShippingFormBuilder($Order); |
|
| 198 | |||
| 199 | 23 | $event = new EventArgs( |
|
| 200 | array( |
||
| 201 | 23 | 'builder' => $builder, |
|
| 202 | 23 | 'Order' => $Order, |
|
| 203 | ), |
||
| 204 | $request |
||
| 205 | ); |
||
| 206 | 23 | $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_INITIALIZE, $event); |
|
| 207 | |||
| 208 | 23 | $form = $builder->getForm(); |
|
| 209 | |||
| 210 | 23 | $form->handleRequest($request); |
|
| 211 | |||
| 212 | 23 | if ($form->isSubmitted() && $form->isValid()) { |
|
| 213 | 23 | $data = $form->getData(); |
|
| 214 | |||
| 215 | 23 | log_info('購入処理開始', array($Order->getId())); |
|
| 216 | |||
| 217 | // トランザクション制御 |
||
| 218 | 23 | $em = $app['orm.em']; |
|
| 219 | 23 | $em->getConnection()->beginTransaction(); |
|
| 220 | try { |
||
| 221 | |||
| 222 | // お問い合わせ、配送時間などのフォーム項目をセット |
||
| 223 | 23 | $app['eccube.service.shopping']->setFormData($Order, $data); |
|
| 224 | // 購入処理 |
||
| 225 | 23 | $app['eccube.service.shopping']->processPurchase($Order); |
|
| 226 | |||
| 227 | 22 | $em->flush(); |
|
| 228 | 22 | $em->getConnection()->commit(); |
|
| 229 | |||
| 230 | 22 | log_info('購入処理完了', array($Order->getId())); |
|
| 231 | |||
| 232 | 1 | } catch (ShoppingException $e) { |
|
| 233 | |||
| 234 | 1 | log_error('購入エラー', array($e->getMessage())); |
|
| 235 | |||
| 236 | 1 | $em->getConnection()->rollback(); |
|
| 237 | |||
| 238 | 1 | $app->log($e); |
|
| 239 | 1 | $app->addError($e->getMessage()); |
|
| 240 | |||
| 241 | 1 | return $app->redirect($app->url('shopping_error')); |
|
| 242 | } catch (\Exception $e) { |
||
| 243 | |||
| 244 | log_error('予期しないエラー', array($e->getMessage())); |
||
| 245 | |||
| 246 | $em->getConnection()->rollback(); |
||
| 247 | |||
| 248 | $app->log($e); |
||
| 249 | |||
| 250 | $app->addError('front.shopping.system.error'); |
||
| 251 | return $app->redirect($app->url('shopping_error')); |
||
| 252 | } |
||
| 253 | |||
| 254 | // カート削除 |
||
| 255 | 22 | $app['eccube.service.cart']->clear()->save(); |
|
| 256 | |||
| 257 | 22 | $event = new EventArgs( |
|
| 258 | array( |
||
| 259 | 22 | 'form' => $form, |
|
| 260 | 22 | 'Order' => $Order, |
|
| 261 | ), |
||
| 262 | $request |
||
| 263 | ); |
||
| 264 | 22 | $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_PROCESSING, $event); |
|
| 265 | |||
| 266 | 22 | View Code Duplication | if ($event->getResponse() !== null) { |
| 267 | log_info('イベントレスポンス返却', array($Order->getId())); |
||
| 268 | return $event->getResponse(); |
||
| 269 | } |
||
| 270 | |||
| 271 | // 受注IDをセッションにセット |
||
| 272 | 22 | $app['session']->set($this->sessionOrderKey, $Order->getId()); |
|
| 273 | |||
| 274 | // メール送信 |
||
| 275 | 22 | $MailHistory = $app['eccube.service.shopping']->sendOrderMail($Order); |
|
| 276 | |||
| 277 | 22 | $event = new EventArgs( |
|
| 278 | array( |
||
| 279 | 22 | 'form' => $form, |
|
| 280 | 22 | 'Order' => $Order, |
|
| 281 | 22 | 'MailHistory' => $MailHistory, |
|
| 282 | ), |
||
| 283 | $request |
||
| 284 | ); |
||
| 285 | 22 | $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_CONFIRM_COMPLETE, $event); |
|
| 286 | |||
| 287 | 22 | View Code Duplication | if ($event->getResponse() !== null) { |
| 288 | log_info('イベントレスポンス返却', array($Order->getId())); |
||
| 289 | return $event->getResponse(); |
||
| 290 | } |
||
| 291 | |||
| 292 | // 完了画面表示 |
||
| 293 | 22 | return $app->redirect($app->url('shopping_complete')); |
|
| 294 | } |
||
| 295 | |||
| 296 | log_info('購入チェックエラー', array($Order->getId())); |
||
| 297 | |||
| 298 | return $app->render('Shopping/index.twig', array( |
||
| 299 | 'form' => $form->createView(), |
||
| 300 | 'Order' => $Order, |
||
| 301 | )); |
||
| 302 | } |
||
| 303 | |||
| 304 | |||
| 305 | /** |
||
| 306 | * 購入完了画面表示 |
||
| 307 | */ |
||
| 308 | 9 | public function complete(Application $app, Request $request) |
|
| 334 | |||
| 335 | |||
| 336 | /** |
||
| 337 | * 配送業者選択処理 |
||
| 338 | */ |
||
| 339 | 6 | public function delivery(Application $app, Request $request) |
|
| 440 | |||
| 441 | /** |
||
| 442 | * 支払い方法選択処理 |
||
| 443 | */ |
||
| 444 | 9 | public function payment(Application $app, Request $request) |
|
| 511 | |||
| 512 | /** |
||
| 513 | * お届け先変更がクリックされた場合の処理 |
||
| 514 | */ |
||
| 515 | 18 | View Code Duplication | public function shippingChange(Application $app, Request $request, $id) |
| 558 | |||
| 559 | /** |
||
| 560 | * お届け先の設定一覧からの選択 |
||
| 561 | */ |
||
| 562 | 4 | public function shipping(Application $app, Request $request, $id) |
|
| 646 | |||
| 647 | /** |
||
| 648 | * お届け先の設定(非会員)がクリックされた場合の処理 |
||
| 649 | */ |
||
| 650 | 19 | View Code Duplication | public function shippingEditChange(Application $app, Request $request, $id) |
| 693 | |||
| 694 | /** |
||
| 695 | * お届け先の設定(非会員でも使用する) |
||
| 696 | */ |
||
| 697 | 4 | public function shippingEdit(Application $app, Request $request, $id) |
|
| 798 | |||
| 799 | /** |
||
| 800 | * お客様情報の変更(非会員) |
||
| 801 | */ |
||
| 802 | public function customer(Application $app, Request $request) |
||
| 882 | |||
| 883 | /** |
||
| 884 | * ログイン |
||
| 885 | */ |
||
| 886 | 4 | public function login(Application $app, Request $request) |
|
| 921 | |||
| 922 | /** |
||
| 923 | * 非会員処理 |
||
| 924 | */ |
||
| 925 | 35 | public function nonmember(Application $app, Request $request) |
|
| 1053 | |||
| 1054 | /** |
||
| 1055 | * 複数配送処理がクリックされた場合の処理 |
||
| 1056 | */ |
||
| 1057 | View Code Duplication | public function shippingMultipleChange(Application $app, Request $request) |
|
| 1100 | |||
| 1101 | |||
| 1102 | /** |
||
| 1103 | * 複数配送処理 |
||
| 1104 | */ |
||
| 1105 | 37 | public function shippingMultiple(Application $app, Request $request) |
|
| 1106 | { |
||
| 1107 | 37 | $cartService = $app['eccube.service.cart']; |
|
| 1108 | |||
| 1109 | // カートチェック |
||
| 1110 | 37 | if (!$cartService->isLocked()) { |
|
| 1111 | // カートが存在しない、カートがロックされていない時はエラー |
||
| 1112 | 4 | log_info('カートが存在しません'); |
|
| 1113 | 4 | return $app->redirect($app->url('cart')); |
|
| 1114 | } |
||
| 1115 | |||
| 1116 | // カートチェック |
||
| 1117 | 33 | if (count($cartService->getCart()->getCartItems()) <= 0) { |
|
| 1118 | // カートが存在しない時はエラー |
||
| 1119 | log_info('カートに商品が入っていないためショッピングカート画面にリダイレクト'); |
||
| 1120 | return $app->redirect($app->url('cart')); |
||
| 1121 | } |
||
| 1122 | |||
| 1123 | /** @var \Eccube\Entity\Order $Order */ |
||
| 1124 | 33 | $Order = $app['eccube.service.shopping']->getOrder($app['config']['order_processing']); |
|
| 1125 | 33 | if (!$Order) { |
|
| 1126 | log_info('購入処理中の受注情報がないため購入エラー'); |
||
| 1127 | $app->addError('front.shopping.order.error'); |
||
| 1128 | return $app->redirect($app->url('shopping_error')); |
||
| 1129 | } |
||
| 1130 | |||
| 1131 | // 処理しやすいようにすべてのShippingItemをまとめる |
||
| 1132 | 33 | $ShipmentItems = array(); |
|
| 1133 | 33 | foreach ($Order->getShippings() as $Shipping) { |
|
| 1134 | 33 | foreach ($Shipping->getShipmentItems() as $ShipmentItem) { |
|
| 1135 | 33 | $ShipmentItems[] = $ShipmentItem; |
|
| 1136 | } |
||
| 1137 | } |
||
| 1138 | |||
| 1139 | // Orderに含まれる商品ごとの数量を求める |
||
| 1140 | 33 | $ItemQuantitiesByClassId = array(); |
|
| 1141 | 33 | foreach ($ShipmentItems as $item) { |
|
| 1142 | 33 | $itemId = $item->getProductClass()->getId(); |
|
| 1143 | 33 | $quantity = $item->getQuantity(); |
|
| 1144 | 33 | if (array_key_exists($itemId, $ItemQuantitiesByClassId)) { |
|
| 1145 | $ItemQuantitiesByClassId[$itemId] += $quantity; |
||
| 1146 | } else { |
||
| 1147 | 33 | $ItemQuantitiesByClassId[$itemId] = $quantity; |
|
| 1148 | } |
||
| 1149 | } |
||
| 1150 | |||
| 1151 | // FormBuilder用に商品ごとにShippingItemをまとめる |
||
| 1152 | 33 | $ShipmentItemsForFormBuilder = array(); |
|
| 1153 | 33 | $tmpAddedClassIds = array(); |
|
| 1154 | 33 | foreach ($ShipmentItems as $item) { |
|
| 1155 | 33 | $itemId = $item->getProductClass()->getId(); |
|
| 1156 | 33 | if (!in_array($itemId, $tmpAddedClassIds)) { |
|
| 1157 | 33 | $ShipmentItemsForFormBuilder[] = $item; |
|
| 1158 | 33 | $tmpAddedClassIds[] = $itemId; |
|
| 1159 | } |
||
| 1160 | } |
||
| 1161 | |||
| 1162 | // Form生成 |
||
| 1163 | 33 | $builder = $app->form(); |
|
| 1164 | $builder |
||
| 1165 | 33 | ->add('shipping_multiple', 'collection', array( |
|
| 1166 | 33 | 'type' => 'shipping_multiple', |
|
| 1167 | 33 | 'data' => $ShipmentItemsForFormBuilder, |
|
| 1168 | 'allow_add' => true, |
||
| 1169 | 'allow_delete' => true, |
||
| 1170 | )); |
||
| 1171 | // Event |
||
| 1172 | 33 | $event = new EventArgs( |
|
| 1173 | array( |
||
| 1174 | 33 | 'builder' => $builder, |
|
| 1175 | 33 | 'Order' => $Order, |
|
| 1176 | ), |
||
| 1177 | $request |
||
| 1178 | ); |
||
| 1179 | 33 | $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_INITIALIZE, $event); |
|
| 1180 | |||
| 1181 | 33 | $form = $builder->getForm(); |
|
| 1182 | 33 | $form->handleRequest($request); |
|
| 1183 | |||
| 1184 | 33 | $errors = array(); |
|
| 1185 | 33 | if ($form->isSubmitted() && $form->isValid()) { |
|
| 1186 | |||
| 1187 | 32 | log_info('複数配送設定処理開始', array($Order->getId())); |
|
| 1188 | |||
| 1189 | 32 | $data = $form['shipping_multiple']; |
|
| 1190 | |||
| 1191 | // フォームの入力から、送り先ごとに商品の数量を集計する |
||
| 1192 | 32 | $arrShipmentItemTemp = array(); |
|
| 1193 | 32 | foreach ($data as $mulitples) { |
|
| 1194 | 32 | $ShipmentItem = $mulitples->getData(); |
|
| 1195 | 32 | foreach ($mulitples as $items) { |
|
| 1196 | 32 | foreach ($items as $item) { |
|
| 1197 | 32 | $cusAddId = $this->getCustomerAddressId($item['customer_address']->getData()); |
|
| 1198 | 32 | $itemId = $ShipmentItem->getProductClass()->getId(); |
|
| 1199 | 32 | $quantity = $item['quantity']->getData(); |
|
| 1200 | |||
| 1201 | 32 | if (isset($arrShipmentItemTemp[$cusAddId]) && array_key_exists($itemId, $arrShipmentItemTemp[$cusAddId])) { |
|
| 1202 | 10 | $arrShipmentItemTemp[$cusAddId][$itemId] = $arrShipmentItemTemp[$cusAddId][$itemId] + $quantity; |
|
| 1203 | } else { |
||
| 1204 | 32 | $arrShipmentItemTemp[$cusAddId][$itemId] = $quantity; |
|
| 1205 | } |
||
| 1206 | } |
||
| 1207 | } |
||
| 1208 | } |
||
| 1209 | |||
| 1210 | // フォームの入力から、商品ごとの数量を集計する |
||
| 1211 | 32 | $itemQuantities = array(); |
|
| 1212 | 32 | foreach ($arrShipmentItemTemp as $FormItemByAddress) { |
|
| 1213 | 32 | foreach ($FormItemByAddress as $itemId => $quantity) { |
|
| 1214 | 32 | if (array_key_exists($itemId, $itemQuantities)) { |
|
| 1215 | 17 | $itemQuantities[$itemId] = $itemQuantities[$itemId] + $quantity; |
|
| 1216 | } else { |
||
| 1217 | 32 | $itemQuantities[$itemId] = $quantity; |
|
| 1218 | } |
||
| 1219 | } |
||
| 1220 | } |
||
| 1221 | |||
| 1222 | // 「Orderに含まれる商品ごとの数量」と「フォームに入力された商品ごとの数量」が一致しているかの確認 |
||
| 1223 | // 数量が異なっているならエラーを表示する |
||
| 1224 | 32 | foreach ($ItemQuantitiesByClassId as $key => $value) { |
|
| 1225 | 32 | if (array_key_exists($key, $itemQuantities)) { |
|
| 1226 | 32 | if ($itemQuantities[$key] != $value) { |
|
| 1227 | 2 | $errors[] = array('message' => $app->trans('shopping.multiple.quantity.diff')); |
|
| 1228 | |||
| 1229 | // 対象がなければエラー |
||
| 1230 | 2 | log_info('複数配送設定入力チェックエラー', array($Order->getId())); |
|
| 1231 | 2 | return $app->render('Shopping/shipping_multiple.twig', array( |
|
| 1232 | 2 | 'form' => $form->createView(), |
|
| 1233 | 2 | 'shipmentItems' => $ShipmentItemsForFormBuilder, |
|
| 1234 | 2 | 'compItemQuantities' => $ItemQuantitiesByClassId, |
|
| 1235 | 32 | 'errors' => $errors, |
|
| 1236 | )); |
||
| 1237 | } |
||
| 1238 | } |
||
| 1239 | } |
||
| 1240 | |||
| 1241 | // -- ここから先がお届け先を再生成する処理 -- |
||
| 1242 | |||
| 1243 | // お届け先情報をすべて削除 |
||
| 1244 | 30 | foreach ($Order->getShippings() as $Shipping) { |
|
| 1245 | 30 | $Order->removeShipping($Shipping); |
|
| 1246 | 30 | $app['orm.em']->remove($Shipping); |
|
| 1247 | } |
||
| 1248 | |||
| 1249 | // お届け先のリストを作成する |
||
| 1250 | 30 | $ShippingList = array(); |
|
| 1251 | 30 | foreach ($data as $mulitples) { |
|
| 1252 | 30 | $ShipmentItem = $mulitples->getData(); |
|
| 1253 | 30 | $ProductClass = $ShipmentItem->getProductClass(); |
|
| 1254 | 30 | $Delivery = $ShipmentItem->getShipping()->getDelivery(); |
|
| 1255 | 30 | $productTypeId = $ProductClass->getProductType()->getId(); |
|
| 1256 | |||
| 1257 | 30 | foreach ($mulitples as $items) { |
|
| 1258 | 30 | foreach ($items as $item) { |
|
| 1259 | 30 | $CustomerAddress = $this->getCustomerAddress($app, $item['customer_address']->getData()); |
|
| 1260 | 30 | $cusAddId = $this->getCustomerAddressId($item['customer_address']->getData()); |
|
| 1261 | |||
| 1262 | 30 | $Shipping = new Shipping(); |
|
| 1263 | $Shipping |
||
| 1264 | 30 | ->setFromCustomerAddress($CustomerAddress) |
|
| 1265 | 30 | ->setDelivery($Delivery) |
|
| 1266 | 30 | ->setDelFlg(Constant::DISABLED) |
|
| 1267 | 30 | ->setOrder($Order); |
|
| 1268 | |||
| 1269 | 30 | $ShippingList[$cusAddId][$productTypeId] = $Shipping; |
|
| 1270 | } |
||
| 1271 | } |
||
| 1272 | } |
||
| 1273 | // お届け先のリストを保存 |
||
| 1274 | 30 | foreach ($ShippingList as $ShippingListByAddress) { |
|
| 1275 | 30 | foreach ($ShippingListByAddress as $Shipping) { |
|
| 1276 | 30 | $app['orm.em']->persist($Shipping); |
|
| 1277 | } |
||
| 1278 | } |
||
| 1279 | |||
| 1280 | // お届け先に、配送商品の情報(ShipmentItem)を関連付ける |
||
| 1281 | 30 | foreach ($data as $mulitples) { |
|
| 1282 | 30 | $ShipmentItem = $mulitples->getData(); |
|
| 1283 | 30 | $ProductClass = $ShipmentItem->getProductClass(); |
|
| 1284 | 30 | $Product = $ShipmentItem->getProduct(); |
|
| 1285 | 30 | $productTypeId = $ProductClass->getProductType()->getId(); |
|
| 1286 | 30 | $productClassId = $ProductClass->getId(); |
|
| 1287 | |||
| 1288 | 30 | foreach ($mulitples as $items) { |
|
| 1289 | 30 | foreach ($items as $item) { |
|
| 1290 | 30 | $cusAddId = $this->getCustomerAddressId($item['customer_address']->getData()); |
|
| 1291 | |||
| 1292 | // お届け先から商品の数量を取得 |
||
| 1293 | 30 | $quantity = 0; |
|
| 1294 | 30 | if (isset($arrShipmentItemTemp[$cusAddId]) && array_key_exists($productClassId, $arrShipmentItemTemp[$cusAddId])) { |
|
| 1295 | 30 | $quantity = $arrShipmentItemTemp[$cusAddId][$productClassId]; |
|
| 1296 | 30 | unset($arrShipmentItemTemp[$cusAddId][$productClassId]); |
|
| 1297 | } else { |
||
| 1298 | // この配送先には送る商品がないのでスキップ(通常ありえない) |
||
| 1299 | 10 | continue; |
|
| 1300 | } |
||
| 1301 | |||
| 1302 | // 関連付けるお届け先のインスタンスを取得 |
||
| 1303 | 30 | $Shipping = $ShippingList[$cusAddId][$productTypeId]; |
|
| 1304 | |||
| 1305 | // インスタンスを生成して保存 |
||
| 1306 | 30 | $ShipmentItem = new ShipmentItem(); |
|
| 1307 | 30 | $ShipmentItem->setShipping($Shipping) |
|
| 1308 | 30 | ->setOrder($Order) |
|
| 1309 | 30 | ->setProductClass($ProductClass) |
|
| 1310 | 30 | ->setProduct($Product) |
|
| 1311 | 30 | ->setProductName($Product->getName()) |
|
| 1312 | 30 | ->setProductCode($ProductClass->getCode()) |
|
| 1313 | 30 | ->setPrice($ProductClass->getPrice02()) |
|
| 1314 | 30 | ->setQuantity($quantity); |
|
| 1315 | |||
| 1316 | 30 | $ClassCategory1 = $ProductClass->getClassCategory1(); |
|
| 1317 | 30 | if (!is_null($ClassCategory1)) { |
|
| 1318 | 30 | $ShipmentItem->setClasscategoryName1($ClassCategory1->getName()); |
|
| 1319 | 30 | $ShipmentItem->setClassName1($ClassCategory1->getClassName()->getName()); |
|
| 1320 | } |
||
| 1321 | 30 | $ClassCategory2 = $ProductClass->getClassCategory2(); |
|
| 1322 | 30 | if (!is_null($ClassCategory2)) { |
|
| 1323 | 27 | $ShipmentItem->setClasscategoryName2($ClassCategory2->getName()); |
|
| 1324 | 27 | $ShipmentItem->setClassName2($ClassCategory2->getClassName()->getName()); |
|
| 1325 | } |
||
| 1326 | 30 | $Shipping->addShipmentItem($ShipmentItem); |
|
| 1327 | 30 | $app['orm.em']->persist($ShipmentItem); |
|
| 1328 | } |
||
| 1329 | } |
||
| 1330 | } |
||
| 1331 | |||
| 1332 | // 送料を計算(お届け先ごと) |
||
| 1333 | 30 | foreach ($ShippingList as $data) { |
|
| 1334 | // data is product type => shipping |
||
| 1335 | 30 | foreach ($data as $Shipping) { |
|
| 1336 | // 配送料金の設定 |
||
| 1337 | 30 | $app['eccube.service.shopping']->setShippingDeliveryFee($Shipping); |
|
| 1338 | 30 | $Order->addShipping($Shipping); |
|
| 1339 | } |
||
| 1340 | } |
||
| 1341 | |||
| 1342 | // 合計金額の再計算 |
||
| 1343 | 30 | $Order = $app['eccube.service.shopping']->getAmount($Order); |
|
| 1344 | |||
| 1345 | // 配送先を更新 |
||
| 1346 | 30 | $app['orm.em']->flush(); |
|
| 1347 | |||
| 1348 | 30 | $event = new EventArgs( |
|
| 1349 | array( |
||
| 1350 | 30 | 'form' => $form, |
|
| 1351 | 30 | 'Order' => $Order, |
|
| 1352 | ), |
||
| 1353 | $request |
||
| 1354 | ); |
||
| 1355 | 30 | $app['eccube.event.dispatcher']->dispatch(EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_COMPLETE, $event); |
|
| 1356 | |||
| 1357 | 30 | log_info('複数配送設定処理完了', array($Order->getId())); |
|
| 1358 | 30 | return $app->redirect($app->url('shopping')); |
|
| 1359 | } |
||
| 1360 | |||
| 1361 | 5 | return $app->render('Shopping/shipping_multiple.twig', array( |
|
| 1362 | 5 | 'form' => $form->createView(), |
|
| 1363 | 5 | 'shipmentItems' => $ShipmentItemsForFormBuilder, |
|
| 1364 | 5 | 'compItemQuantities' => $ItemQuantitiesByClassId, |
|
| 1365 | 5 | 'errors' => $errors, |
|
| 1366 | )); |
||
| 1367 | } |
||
| 1368 | |||
| 1369 | /** |
||
| 1370 | * フォームの情報からお届け先のインデックスを返す |
||
| 1371 | * |
||
| 1372 | * @param Application $app |
||
| 1373 | * @param mixed $CustomerAddressData |
||
| 1374 | * @return int |
||
| 1375 | */ |
||
| 1376 | 32 | private function getCustomerAddressId($CustomerAddressData) |
|
| 1384 | |||
| 1385 | /** |
||
| 1386 | * フォームの情報からお届け先のインスタンスを返す |
||
| 1387 | * |
||
| 1388 | * @param Application $app |
||
| 1389 | * @param mixed $CustomerAddressData |
||
| 1390 | * @return CustomerAddress |
||
| 1391 | */ |
||
| 1392 | 30 | private function getCustomerAddress(Application $app, $CustomerAddressData) |
|
| 1408 | |||
| 1409 | /** |
||
| 1410 | * 非会員用複数配送設定時の新規お届け先の設定 |
||
| 1411 | */ |
||
| 1412 | 10 | public function shippingMultipleEdit(Application $app, Request $request) |
|
| 1470 | |||
| 1471 | /** |
||
| 1472 | * 購入エラー画面表示 |
||
| 1473 | */ |
||
| 1474 | 2 | public function shoppingError(Application $app, Request $request) |
|
| 1489 | |||
| 1490 | /** |
||
| 1491 | * 非会員でのお客様情報変更時の入力チェック |
||
| 1492 | * |
||
| 1493 | * @param Application $app |
||
| 1494 | * @param array $data リクエストパラメータ |
||
| 1495 | * @return array |
||
| 1496 | */ |
||
| 1497 | private function customerValidation(Application $app, array $data) |
||
| 1565 | } |
||
| 1566 |