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 ProductController 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 ProductController, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
59 | class ProductController extends AbstractController |
||
60 | { |
||
61 | /** |
||
62 | * @var CsvExportService |
||
63 | */ |
||
64 | protected $csvExportService; |
||
65 | |||
66 | /** |
||
67 | * @var ProductClassRepository |
||
68 | */ |
||
69 | protected $productClassRepository; |
||
70 | |||
71 | /** |
||
72 | * @var ProductImageRepository |
||
73 | */ |
||
74 | protected $productImageRepository; |
||
75 | |||
76 | /** |
||
77 | * @var TaxRuleRepository |
||
78 | */ |
||
79 | protected $taxRuleRepository; |
||
80 | |||
81 | /** |
||
82 | * @var CategoryRepository |
||
83 | */ |
||
84 | protected $categoryRepository; |
||
85 | |||
86 | /** |
||
87 | * @var ProductRepository |
||
88 | */ |
||
89 | protected $productRepository; |
||
90 | |||
91 | /** |
||
92 | * @var BaseInfo |
||
93 | */ |
||
94 | protected $BaseInfo; |
||
95 | |||
96 | /** |
||
97 | * @var PageMaxRepository |
||
98 | */ |
||
99 | protected $pageMaxRepository; |
||
100 | |||
101 | /** |
||
102 | * @var ProductStatusRepository |
||
103 | */ |
||
104 | protected $productStatusRepository; |
||
105 | |||
106 | /** |
||
107 | * @var TagRepository |
||
108 | */ |
||
109 | protected $tagRepository; |
||
110 | |||
111 | /** |
||
112 | * ProductController constructor. |
||
113 | * |
||
114 | * @param CsvExportService $csvExportService |
||
115 | * @param ProductClassRepository $productClassRepository |
||
116 | * @param ProductImageRepository $productImageRepository |
||
117 | * @param TaxRuleRepository $taxRuleRepository |
||
118 | * @param CategoryRepository $categoryRepository |
||
119 | * @param ProductRepository $productRepository |
||
120 | * @param BaseInfoRepository $baseInfoRepository |
||
121 | * @param PageMaxRepository $pageMaxRepository |
||
122 | * @param ProductStatusRepository $productStatusRepository |
||
123 | * @param TagRepository $tagRepository |
||
124 | 26 | */ |
|
125 | View Code Duplication | public function __construct( |
|
|
|||
126 | CsvExportService $csvExportService, |
||
127 | ProductClassRepository $productClassRepository, |
||
128 | ProductImageRepository $productImageRepository, |
||
129 | TaxRuleRepository $taxRuleRepository, |
||
130 | CategoryRepository $categoryRepository, |
||
131 | ProductRepository $productRepository, |
||
132 | BaseInfoRepository $baseInfoRepository, |
||
133 | PageMaxRepository $pageMaxRepository, |
||
134 | ProductStatusRepository $productStatusRepository, |
||
135 | TagRepository $tagRepository |
||
136 | 26 | ) { |
|
137 | 26 | $this->csvExportService = $csvExportService; |
|
138 | 26 | $this->productClassRepository = $productClassRepository; |
|
139 | 26 | $this->productImageRepository = $productImageRepository; |
|
140 | 26 | $this->taxRuleRepository = $taxRuleRepository; |
|
141 | 26 | $this->categoryRepository = $categoryRepository; |
|
142 | 26 | $this->productRepository = $productRepository; |
|
143 | 26 | $this->BaseInfo = $baseInfoRepository->get(); |
|
144 | 26 | $this->pageMaxRepository = $pageMaxRepository; |
|
145 | 26 | $this->productStatusRepository = $productStatusRepository; |
|
146 | $this->tagRepository = $tagRepository; |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @Route("/%eccube_admin_route%/product", name="admin_product") |
||
151 | * @Route("/%eccube_admin_route%/product/page/{page_no}", requirements={"page_no" = "\d+"}, name="admin_product_page") |
||
152 | * @Template("@admin/Product/index.twig") |
||
153 | 4 | */ |
|
154 | public function index(Request $request, $page_no = null, Paginator $paginator) |
||
155 | 4 | { |
|
156 | 4 | $builder = $this->formFactory |
|
157 | ->createBuilder(SearchProductType::class); |
||
158 | 4 | ||
159 | $event = new EventArgs( |
||
160 | 4 | [ |
|
161 | 'builder' => $builder, |
||
162 | 4 | ], |
|
163 | $request |
||
164 | 4 | ); |
|
165 | $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_INITIALIZE, $event); |
||
166 | 4 | ||
167 | $searchForm = $builder->getForm(); |
||
168 | |||
169 | /** |
||
170 | * ページの表示件数は, 以下の順に優先される. |
||
171 | * - リクエストパラメータ |
||
172 | * - セッション |
||
173 | * - デフォルト値 |
||
174 | * また, セッションに保存する際は mtb_page_maxと照合し, 一致した場合のみ保存する. |
||
175 | 4 | **/ |
|
176 | 4 | $page_count = $this->session->get('eccube.admin.order.search.page_count', |
|
177 | $this->eccubeConfig->get('eccube_default_page_count')); |
||
178 | 4 | ||
179 | 4 | $page_count_param = (int) $request->get('page_count'); |
|
180 | $pageMaxis = $this->pageMaxRepository->findAll(); |
||
181 | 4 | ||
182 | View Code Duplication | if ($page_count_param) { |
|
183 | foreach ($pageMaxis as $pageMax) { |
||
184 | if ($page_count_param == $pageMax->getName()) { |
||
185 | $page_count = $pageMax->getName(); |
||
186 | $this->session->set('eccube.admin.order.search.page_count', $page_count); |
||
187 | break; |
||
188 | } |
||
189 | } |
||
190 | } |
||
191 | 4 | ||
192 | 2 | if ('POST' === $request->getMethod()) { |
|
193 | $searchForm->handleRequest($request); |
||
194 | 2 | ||
195 | View Code Duplication | if ($searchForm->isValid()) { |
|
196 | /** |
||
197 | * 検索が実行された場合は, セッションに検索条件を保存する. |
||
198 | * ページ番号は最初のページ番号に初期化する. |
||
199 | 2 | */ |
|
200 | 2 | $page_no = 1; |
|
201 | $searchData = $searchForm->getData(); |
||
202 | |||
203 | 2 | // 検索条件, ページ番号をセッションに保持. |
|
204 | 2 | $this->session->set('eccube.admin.product.search', FormUtil::getViewData($searchForm)); |
|
205 | $this->session->set('eccube.admin.product.search.page_no', $page_no); |
||
206 | } else { |
||
207 | // 検索エラーの際は, 詳細検索枠を開いてエラー表示する. |
||
208 | 2 | return [ |
|
209 | 'searchForm' => $searchForm->createView(), |
||
210 | 'pagination' => [], |
||
211 | 'pageMaxis' => $pageMaxis, |
||
212 | 'page_no' => $page_no, |
||
213 | 'page_count' => $page_count, |
||
214 | 'has_errors' => true, |
||
215 | ]; |
||
216 | } |
||
217 | 2 | View Code Duplication | } else { |
218 | if (null !== $page_no || $request->get('resume')) { |
||
219 | /* |
||
220 | * ページ送りの場合または、他画面から戻ってきた場合は, セッションから検索条件を復旧する. |
||
221 | 1 | */ |
|
222 | if ($page_no) { |
||
223 | 1 | // ページ送りで遷移した場合. |
|
224 | $this->session->set('eccube.admin.product.search.page_no', (int) $page_no); |
||
225 | } else { |
||
226 | // 他画面から遷移した場合. |
||
227 | $page_no = $this->session->get('eccube.admin.product.search.page_no', 1); |
||
228 | 1 | } |
|
229 | 1 | $viewData = $this->session->get('eccube.admin.product.search', []); |
|
230 | $searchData = FormUtil::submitAndGetData($searchForm, $viewData); |
||
231 | } else { |
||
232 | /** |
||
233 | * 初期表示の場合. |
||
234 | 1 | */ |
|
235 | $page_no = 1; |
||
236 | 1 | // submit default value |
|
237 | 1 | $viewData = FormUtil::getViewData($searchForm); |
|
238 | $searchData = FormUtil::submitAndGetData($searchForm, $viewData); |
||
239 | |||
240 | 1 | // セッション中の検索条件, ページ番号を初期化. |
|
241 | 1 | $this->session->set('eccube.admin.product.search', $viewData); |
|
242 | $this->session->set('eccube.admin.product.search.page_no', $page_no); |
||
243 | } |
||
244 | } |
||
245 | 4 | ||
246 | $qb = $this->productRepository->getQueryBuilderBySearchDataForAdmin($searchData); |
||
247 | 4 | ||
248 | $event = new EventArgs( |
||
249 | 4 | [ |
|
250 | 4 | 'qb' => $qb, |
|
251 | 'searchData' => $searchData, |
||
252 | 4 | ], |
|
253 | $request |
||
254 | ); |
||
255 | 4 | ||
256 | $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_INDEX_SEARCH, $event); |
||
257 | 4 | ||
258 | 4 | $pagination = $paginator->paginate( |
|
259 | 4 | $qb, |
|
260 | 4 | $page_no, |
|
261 | $page_count |
||
262 | ); |
||
263 | |||
264 | 4 | return [ |
|
265 | 4 | 'searchForm' => $searchForm->createView(), |
|
266 | 4 | 'pagination' => $pagination, |
|
267 | 4 | 'pageMaxis' => $pageMaxis, |
|
268 | 4 | 'page_no' => $page_no, |
|
269 | 'page_count' => $page_count, |
||
270 | 'has_errors' => false, |
||
271 | ]; |
||
272 | } |
||
273 | |||
274 | /** |
||
275 | * @Route("/%eccube_admin_route%/product/classes/{id}/load", name="admin_product_classes_load", methods={"GET"}, requirements={"id" = "\d+"}) |
||
276 | * @Template("@admin/Product/product_class_popup.twig") |
||
277 | * @ParamConverter("Product") |
||
278 | */ |
||
279 | 1 | public function loadProductClasses(Request $request, Product $Product) |
|
304 | |||
305 | /** |
||
306 | * @Route("/%eccube_admin_route%/product/product/image/add", name="admin_product_image_add", methods={"POST"}) |
||
307 | */ |
||
308 | public function addImage(Request $request) |
||
352 | |||
353 | 18 | /** |
|
354 | * @Route("/%eccube_admin_route%/product/product/new", name="admin_product_product_new") |
||
355 | 18 | * @Route("/%eccube_admin_route%/product/product/{id}/edit", requirements={"id" = "\d+"}, name="admin_product_product_edit") |
|
356 | 18 | * @Template("@admin/Product/product.twig") |
|
357 | 5 | */ |
|
358 | 5 | public function edit(Request $request, $id = null, RouterInterface $router, CacheUtil $cacheUtil) |
|
359 | 5 | { |
|
360 | $has_class = false; |
||
361 | 5 | if (is_null($id)) { |
|
362 | 5 | $Product = new Product(); |
|
363 | $ProductClass = new ProductClass(); |
||
364 | 5 | $ProductStatus = $this->productStatusRepository->find(ProductStatus::DISPLAY_HIDE); |
|
365 | 5 | $Product |
|
366 | 5 | ->addProductClass($ProductClass) |
|
367 | 5 | ->setStatus($ProductStatus); |
|
368 | 5 | $ProductClass |
|
369 | 5 | ->setVisible(true) |
|
370 | ->setStockUnlimited(true) |
||
371 | 13 | ->setProduct($Product); |
|
372 | 13 | $ProductStock = new ProductStock(); |
|
373 | $ProductClass->setProductStock($ProductStock); |
||
374 | $ProductStock->setProductClass($ProductClass); |
||
375 | } else { |
||
376 | 13 | $Product = $this->productRepository->find($id); |
|
377 | 13 | if (!$Product) { |
|
378 | 11 | throw new NotFoundHttpException(); |
|
379 | 11 | } |
|
380 | 11 | // 規格無しの商品の場合は、デフォルト規格を表示用に取得する |
|
381 | $has_class = $Product->hasProductClass(); |
||
382 | if (!$has_class) { |
||
383 | 11 | $ProductClasses = $Product->getProductClasses(); |
|
384 | 11 | foreach ($ProductClasses as $pc) { |
|
385 | 11 | if (!is_null($pc->getClassCategory1())) { |
|
386 | continue; |
||
387 | } |
||
388 | 11 | if ($pc->isVisible()) { |
|
389 | 6 | $ProductClass = $pc; |
|
390 | break; |
||
391 | 11 | } |
|
392 | } |
||
393 | if ($this->BaseInfo->isOptionProductTaxRule() && $ProductClass->getTaxRule()) { |
||
394 | $ProductClass->setTaxRate($ProductClass->getTaxRule()->getTaxRate()); |
||
395 | 18 | } |
|
396 | 18 | $ProductStock = $ProductClass->getProductStock(); |
|
397 | } |
||
398 | } |
||
399 | 18 | ||
400 | 2 | $builder = $this->formFactory |
|
401 | ->createBuilder(ProductType::class, $Product); |
||
402 | |||
403 | 18 | // 規格あり商品の場合、規格関連情報をFormから除外 |
|
404 | if ($has_class) { |
||
405 | 18 | $builder->remove('class'); |
|
406 | 18 | } |
|
407 | |||
408 | 18 | $event = new EventArgs( |
|
409 | [ |
||
410 | 18 | 'builder' => $builder, |
|
411 | 'Product' => $Product, |
||
412 | 18 | ], |
|
413 | $request |
||
414 | 18 | ); |
|
415 | 16 | $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_INITIALIZE, $event); |
|
416 | 16 | ||
417 | $form = $builder->getForm(); |
||
418 | |||
419 | if (!$has_class) { |
||
420 | 18 | $ProductClass->setStockUnlimited($ProductClass->isStockUnlimited()); |
|
421 | 18 | $form['class']->setData($ProductClass); |
|
422 | 18 | } |
|
423 | 13 | ||
424 | // ファイルの登録 |
||
425 | 18 | $images = []; |
|
426 | $ProductImages = $Product->getProductImage(); |
||
427 | 18 | foreach ($ProductImages as $ProductImage) { |
|
428 | 18 | $images[] = $ProductImage->getFileName(); |
|
429 | 18 | } |
|
430 | $form['images']->setData($images); |
||
431 | 13 | ||
432 | $categories = []; |
||
433 | 18 | $ProductCategories = $Product->getProductCategories(); |
|
434 | foreach ($ProductCategories as $ProductCategory) { |
||
435 | 18 | /* @var $ProductCategory \Eccube\Entity\ProductCategory */ |
|
436 | 18 | $categories[] = $ProductCategory->getCategory(); |
|
437 | } |
||
438 | 18 | $form['Category']->setData($categories); |
|
439 | 13 | ||
440 | 13 | $Tags = $Product->getTags(); |
|
441 | 13 | $form['Tag']->setData($Tags); |
|
442 | 13 | ||
443 | if ('POST' === $request->getMethod()) { |
||
444 | 13 | $form->handleRequest($request); |
|
445 | 13 | if ($form->isValid()) { |
|
446 | log_info('商品登録開始', [$id]); |
||
447 | $Product = $form->getData(); |
||
448 | 13 | ||
449 | 12 | if (!$has_class) { |
|
450 | 8 | $ProductClass = $form['class']->getData(); |
|
451 | 4 | ||
452 | // 個別消費税 |
||
453 | 4 | if ($this->BaseInfo->isOptionProductTaxRule()) { |
|
454 | 4 | if ($ProductClass->getTaxRate() !== null) { |
|
455 | 4 | if ($ProductClass->getTaxRule()) { |
|
456 | 4 | $ProductClass->getTaxRule()->setTaxRate($ProductClass->getTaxRate()); |
|
457 | 4 | } else { |
|
458 | 4 | $taxrule = $this->taxRuleRepository->newTaxRule(); |
|
459 | $taxrule->setTaxRate($ProductClass->getTaxRate()); |
||
460 | $taxrule->setApplyDate(new \DateTime()); |
||
461 | 8 | $taxrule->setProduct($Product); |
|
462 | $taxrule->setProductClass($ProductClass); |
||
463 | 4 | $ProductClass->setTaxRule($taxrule); |
|
464 | 2 | } |
|
465 | 2 | ||
466 | $ProductClass->getTaxRule()->setTaxRate($ProductClass->getTaxRate()); |
||
467 | } else { |
||
468 | if ($ProductClass->getTaxRule()) { |
||
469 | 13 | $this->taxRuleRepository->delete($ProductClass->getTaxRule()); |
|
470 | $ProductClass->setTaxRule(null); |
||
471 | } |
||
472 | 13 | } |
|
473 | } |
||
474 | $this->entityManager->persist($ProductClass); |
||
475 | |||
476 | 13 | // 在庫情報を作成 |
|
477 | if (!$ProductClass->isStockUnlimited()) { |
||
478 | 13 | $ProductStock->setStock($ProductClass->getStock()); |
|
479 | } else { |
||
480 | // 在庫無制限時はnullを設定 |
||
481 | $ProductStock->setStock(null); |
||
482 | } |
||
483 | $this->entityManager->persist($ProductStock); |
||
484 | 13 | } |
|
485 | 10 | ||
486 | 10 | // カテゴリの登録 |
|
487 | // 一度クリア |
||
488 | 13 | /* @var $Product \Eccube\Entity\Product */ |
|
489 | 13 | foreach ($Product->getProductCategories() as $ProductCategory) { |
|
490 | $Product->removeProductCategory($ProductCategory); |
||
491 | 13 | $this->entityManager->remove($ProductCategory); |
|
492 | 13 | } |
|
493 | 13 | $this->entityManager->persist($Product); |
|
494 | 13 | $this->entityManager->flush(); |
|
495 | |||
496 | $count = 1; |
||
497 | $Categories = $form->get('Category')->getData(); |
||
498 | $categoriesIdList = []; |
||
499 | foreach ($Categories as $Category) { |
||
500 | View Code Duplication | foreach ($Category->getPath() as $ParentCategory) { |
|
501 | if (!isset($categoriesIdList[$ParentCategory->getId()])) { |
||
502 | $ProductCategory = $this->createProductCategory($Product, $ParentCategory, $count); |
||
503 | $this->entityManager->persist($ProductCategory); |
||
504 | $count++; |
||
505 | /* @var $Product \Eccube\Entity\Product */ |
||
506 | $Product->addProductCategory($ProductCategory); |
||
507 | $categoriesIdList[$ParentCategory->getId()] = true; |
||
508 | } |
||
509 | } |
||
510 | if (!isset($categoriesIdList[$Category->getId()])) { |
||
511 | $ProductCategory = $this->createProductCategory($Product, $Category, $count); |
||
512 | $this->entityManager->persist($ProductCategory); |
||
513 | $count++; |
||
514 | /* @var $Product \Eccube\Entity\Product */ |
||
515 | $Product->addProductCategory($ProductCategory); |
||
516 | 13 | $categoriesIdList[$ParentCategory->getId()] = true; |
|
517 | 13 | } |
|
518 | } |
||
519 | |||
520 | // 画像の登録 |
||
521 | $add_images = $form->get('add_images')->getData(); |
||
522 | foreach ($add_images as $add_image) { |
||
523 | $ProductImage = new \Eccube\Entity\ProductImage(); |
||
524 | $ProductImage |
||
525 | ->setFileName($add_image) |
||
526 | ->setProduct($Product) |
||
527 | ->setSortNo(1); |
||
528 | $Product->addProductImage($ProductImage); |
||
529 | $this->entityManager->persist($ProductImage); |
||
530 | |||
531 | // 移動 |
||
532 | 13 | $file = new File($this->eccubeConfig['eccube_temp_image_dir'].'/'.$add_image); |
|
533 | 13 | $file->move($this->eccubeConfig['eccube_save_image_dir']); |
|
534 | } |
||
535 | |||
536 | // 画像の削除 |
||
537 | $delete_images = $form->get('delete_images')->getData(); |
||
538 | foreach ($delete_images as $delete_image) { |
||
539 | $ProductImage = $this->productImageRepository |
||
540 | ->findOneBy(['file_name' => $delete_image]); |
||
541 | |||
542 | // 追加してすぐに削除した画像は、Entityに追加されない |
||
543 | if ($ProductImage instanceof ProductImage) { |
||
544 | $Product->removeProductImage($ProductImage); |
||
545 | $this->entityManager->remove($ProductImage); |
||
546 | } |
||
547 | $this->entityManager->persist($Product); |
||
548 | 13 | ||
549 | 13 | // 削除 |
|
550 | $fs = new Filesystem(); |
||
551 | 13 | $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$delete_image); |
|
552 | 13 | } |
|
553 | $this->entityManager->persist($Product); |
||
554 | $this->entityManager->flush(); |
||
555 | |||
556 | $sortNos = $request->get('sort_no_images'); |
||
557 | if ($sortNos) { |
||
558 | foreach ($sortNos as $sortNo) { |
||
559 | list($filename, $sortNo_val) = explode('//', $sortNo); |
||
560 | $ProductImage = $this->productImageRepository |
||
561 | ->findOneBy([ |
||
562 | 'file_name' => $filename, |
||
563 | 'Product' => $Product, |
||
564 | 13 | ]); |
|
565 | $ProductImage->setSortNo($sortNo_val); |
||
566 | $this->entityManager->persist($ProductImage); |
||
567 | } |
||
568 | 13 | } |
|
569 | 13 | $this->entityManager->flush(); |
|
570 | 1 | ||
571 | 1 | // 商品タグの登録 |
|
572 | // 商品タグを一度クリア |
||
573 | $ProductTags = $Product->getProductTag(); |
||
574 | foreach ($ProductTags as $ProductTag) { |
||
575 | 13 | $Product->removeProductTag($ProductTag); |
|
576 | 13 | $this->entityManager->remove($ProductTag); |
|
577 | 13 | } |
|
578 | |||
579 | 13 | // 商品タグの登録 |
|
580 | 13 | $Tags = $form->get('Tag')->getData(); |
|
581 | 13 | foreach ($Tags as $Tag) { |
|
582 | 13 | $ProductTag = new ProductTag(); |
|
583 | $ProductTag |
||
584 | ->setProduct($Product) |
||
585 | 13 | ->setTag($Tag); |
|
586 | 13 | $Product->addProductTag($ProductTag); |
|
587 | $this->entityManager->persist($ProductTag); |
||
588 | 13 | } |
|
589 | |||
590 | 13 | $Product->setUpdateDate(new \DateTime()); |
|
591 | $this->entityManager->flush(); |
||
592 | 13 | ||
593 | 13 | log_info('商品登録完了', [$id]); |
|
594 | |||
595 | 13 | $event = new EventArgs( |
|
596 | [ |
||
597 | 13 | 'form' => $form, |
|
598 | 'Product' => $Product, |
||
599 | 13 | ], |
|
600 | $request |
||
601 | 13 | ); |
|
602 | 1 | $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_COMPLETE, $event); |
|
603 | |||
604 | $this->addSuccess('admin.common.save_complete', 'admin'); |
||
605 | 13 | ||
606 | View Code Duplication | if ($returnLink = $form->get('return_link')->getData()) { |
|
607 | try { |
||
608 | // $returnLinkはpathの形式で渡される. pathが存在するかをルータでチェックする. |
||
609 | $pattern = '/^'.preg_quote($request->getBasePath(), '/').'/'; |
||
610 | 5 | $returnLink = preg_replace($pattern, '', $returnLink); |
|
611 | 5 | $result = $router->match($returnLink); |
|
612 | // パラメータのみ抽出 |
||
613 | 5 | $params = array_filter($result, function ($key) { |
|
614 | return 0 !== \strpos($key, '_'); |
||
615 | 5 | }, ARRAY_FILTER_USE_KEY); |
|
616 | 5 | ||
617 | // pathからurlを再構築してリダイレクト. |
||
618 | 5 | return $this->redirectToRoute($result['_route'], $params); |
|
619 | } catch (\Exception $e) { |
||
620 | 5 | // マッチしない場合はログ出力してスキップ. |
|
621 | log_warning('URLの形式が不正です。'); |
||
622 | 5 | } |
|
623 | } |
||
624 | 5 | ||
625 | $cacheUtil->clearDoctrineCache(); |
||
626 | |||
627 | return $this->redirectToRoute('admin_product_product_edit', ['id' => $Product->getId()]); |
||
628 | } |
||
629 | 5 | } |
|
630 | |||
631 | // 検索結果の保持 |
||
632 | 5 | $builder = $this->formFactory |
|
633 | 5 | ->createBuilder(SearchProductType::class); |
|
634 | 3 | ||
635 | 5 | $event = new EventArgs( |
|
636 | [ |
||
637 | 'builder' => $builder, |
||
638 | 5 | 'Product' => $Product, |
|
639 | 5 | ], |
|
640 | 5 | $request |
|
641 | 5 | ); |
|
642 | 5 | $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_EDIT_SEARCH, $event); |
|
643 | 5 | ||
644 | 5 | $searchForm = $builder->getForm(); |
|
645 | 5 | ||
646 | 5 | if ('POST' === $request->getMethod()) { |
|
647 | $searchForm->handleRequest($request); |
||
648 | } |
||
649 | |||
650 | // Get Tags |
||
651 | $TagsList = $this->tagRepository->getList(); |
||
652 | |||
653 | // ツリー表示のため、ルートからのカテゴリを取得 |
||
654 | 1 | $TopCategories = $this->categoryRepository->getList(null); |
|
655 | $ChoicedCategoryIds = array_map(function ($Category) { |
||
656 | 1 | return $Category->getId(); |
|
657 | 1 | }, $form->get('Category')->getData()); |
|
658 | 1 | ||
659 | 1 | return [ |
|
660 | 1 | 'Product' => $Product, |
|
661 | 1 | 'Tags' => $Tags, |
|
662 | 'TagsList' => $TagsList, |
||
663 | 1 | 'form' => $form->createView(), |
|
664 | 'searchForm' => $searchForm->createView(), |
||
665 | 1 | 'has_class' => $has_class, |
|
666 | 1 | 'id' => $id, |
|
667 | 'TopCategories' => $TopCategories, |
||
668 | 'ChoicedCategoryIds' => $ChoicedCategoryIds, |
||
669 | ]; |
||
670 | } |
||
671 | |||
672 | /** |
||
673 | * @Route("/%eccube_admin_route%/product/product/{id}/delete", requirements={"id" = "\d+"}, name="admin_product_product_delete", methods={"DELETE"}) |
||
674 | */ |
||
675 | public function delete(Request $request, $id = null, CacheUtil $cacheUtil) |
||
676 | { |
||
677 | $this->isTokenValid(); |
||
678 | $session = $request->getSession(); |
||
679 | 1 | $page_no = intval($session->get('eccube.admin.product.search.page_no')); |
|
680 | 1 | $page_no = $page_no ? $page_no : Constant::ENABLED; |
|
681 | $message = null; |
||
682 | 1 | $success = false; |
|
683 | 1 | ||
684 | if (!is_null($id)) { |
||
685 | /* @var $Product \Eccube\Entity\Product */ |
||
686 | 1 | $Product = $this->productRepository->find($id); |
|
687 | 1 | View Code Duplication | if (!$Product) { |
688 | if ($request->isXmlHttpRequest()) { |
||
689 | 1 | $message = trans('admin.common.delete_error_already_deleted'); |
|
690 | |||
691 | 1 | return $this->json(['success' => $success, 'message' => $message]); |
|
692 | 1 | } else { |
|
693 | 1 | $this->deleteMessage(); |
|
694 | $rUrl = $this->generateUrl('admin_product_page', ['page_no' => $page_no]).'?resume='.Constant::ENABLED; |
||
695 | 1 | ||
696 | return $this->redirect($rUrl); |
||
697 | 1 | } |
|
698 | 1 | } |
|
699 | |||
700 | if ($Product instanceof Product) { |
||
701 | 1 | log_info('商品削除開始', [$id]); |
|
702 | |||
703 | 1 | $deleteImages = $Product->getProductImage(); |
|
704 | 1 | $ProductClasses = $Product->getProductClasses(); |
|
705 | 1 | ||
706 | try { |
||
707 | $this->productRepository->delete($Product); |
||
708 | $this->entityManager->flush(); |
||
709 | |||
710 | 1 | $event = new EventArgs( |
|
711 | [ |
||
712 | 1 | 'Product' => $Product, |
|
713 | 1 | 'ProductClass' => $ProductClasses, |
|
714 | 'deleteImages' => $deleteImages, |
||
715 | ], |
||
716 | 1 | $request |
|
717 | ); |
||
718 | $this->eventDispatcher->dispatch(EccubeEvents::ADMIN_PRODUCT_DELETE_COMPLETE, $event); |
||
719 | $deleteImages = $event->getArgument('deleteImages'); |
||
720 | 1 | ||
721 | // 画像ファイルの削除(commit後に削除させる) |
||
722 | View Code Duplication | foreach ($deleteImages as $deleteImage) { |
|
723 | try { |
||
724 | $fs = new Filesystem(); |
||
725 | $fs->remove($this->eccubeConfig['eccube_save_image_dir'].'/'.$deleteImage); |
||
726 | } catch (\Exception $e) { |
||
727 | 1 | // エラーが発生しても無視する |
|
728 | } |
||
729 | } |
||
730 | 1 | ||
731 | 1 | log_info('商品削除完了', [$id]); |
|
732 | |||
733 | $success = true; |
||
734 | $message = trans('admin.common.delete_complete'); |
||
735 | |||
736 | 1 | $cacheUtil->clearDoctrineCache(); |
|
737 | } catch (ForeignKeyConstraintViolationException $e) { |
||
738 | 1 | log_info('商品削除エラー', [$id]); |
|
739 | $message = trans('admin.common.delete_error_foreign_key', ['%name%' => $Product->getName()]); |
||
740 | } |
||
741 | } else { |
||
742 | log_info('商品削除エラー', [$id]); |
||
743 | $message = trans('admin.common.delete_error'); |
||
744 | } |
||
745 | } else { |
||
746 | 1 | log_info('商品削除エラー', [$id]); |
|
747 | $message = trans('admin.common.delete_error'); |
||
748 | 1 | } |
|
749 | |||
750 | 1 | View Code Duplication | if ($request->isXmlHttpRequest()) { |
751 | 1 | return $this->json(['success' => $success, 'message' => $message]); |
|
752 | 1 | } else { |
|
753 | 1 | if ($success) { |
|
754 | 1 | $this->addSuccess($message, 'admin'); |
|
755 | 1 | } else { |
|
756 | 1 | $this->addError($message, 'admin'); |
|
757 | } |
||
758 | 1 | ||
759 | 1 | $rUrl = $this->generateUrl('admin_product_page', ['page_no' => $page_no]).'?resume='.Constant::ENABLED; |
|
760 | 1 | ||
761 | return $this->redirect($rUrl); |
||
762 | } |
||
763 | } |
||
764 | 1 | ||
765 | 1 | /** |
|
766 | 1 | * @Route("/%eccube_admin_route%/product/product/{id}/copy", requirements={"id" = "\d+"}, name="admin_product_product_copy", methods={"POST"}) |
|
767 | */ |
||
768 | public function copy(Request $request, $id = null) |
||
864 | |||
865 | /** |
||
866 | * @Route("/%eccube_admin_route%/product/product/{id}/display", requirements={"id" = "\d+"}, name="admin_product_product_display") |
||
867 | */ |
||
868 | public function display(Request $request, $id = null) |
||
882 | |||
883 | /** |
||
884 | * 商品CSVの出力. |
||
885 | * |
||
886 | * @Route("/%eccube_admin_route%/product/export", name="admin_product_export") |
||
887 | * |
||
888 | * @param Request $request |
||
889 | * |
||
890 | * @return StreamedResponse |
||
891 | */ |
||
892 | public function export(Request $request) |
||
993 | |||
994 | /** |
||
995 | * ProductCategory作成 |
||
996 | * |
||
997 | * @param \Eccube\Entity\Product $Product |
||
998 | * @param \Eccube\Entity\Category $Category |
||
999 | * @param integer $count |
||
1000 | * |
||
1001 | * @return \Eccube\Entity\ProductCategory |
||
1002 | */ |
||
1003 | View Code Duplication | private function createProductCategory($Product, $Category, $count) |
|
1004 | 1 | { |
|
1005 | $ProductCategory = new ProductCategory(); |
||
1006 | 1 | $ProductCategory->setProduct($Product); |
|
1007 | $ProductCategory->setProductId($Product->getId()); |
||
1008 | $ProductCategory->setCategory($Category); |
||
1009 | 1 | $ProductCategory->setCategoryId($Category->getId()); |
|
1010 | 1 | ||
1011 | 1 | return $ProductCategory; |
|
1012 | } |
||
1013 | 1 | ||
1014 | 1 | /** |
|
1015 | 1 | * Bulk public action |
|
1016 | * |
||
1017 | 1 | * @Route("/%eccube_admin_route%/product/bulk/product-status/{id}", requirements={"id" = "\d+"}, name="admin_product_bulk_product_status", methods={"POST"}) |
|
1018 | * |
||
1019 | * @param Request $request |
||
1020 | * @param ProductStatus $ProductStatus |
||
1021 | 1 | * |
|
1022 | 1 | * @return RedirectResponse |
|
1023 | 1 | */ |
|
1024 | 1 | public function bulkProductStatus(Request $request, ProductStatus $ProductStatus, CacheUtil $cacheUtil) |
|
1056 | } |
||
1057 |
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.