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 |
||
| 39 | class ProductController extends AbstractController |
||
| 40 | { |
||
| 41 | /** |
||
| 42 | * @var PurchaseFlow |
||
| 43 | */ |
||
| 44 | protected $purchaseFlow; |
||
| 45 | |||
| 46 | /** |
||
| 47 | * @var CustomerFavoriteProductRepository |
||
| 48 | */ |
||
| 49 | protected $customerFavoriteProductRepository; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * @var CartService |
||
| 53 | */ |
||
| 54 | protected $cartService; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * @var ProductRepository |
||
| 58 | */ |
||
| 59 | protected $productRepository; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * @var BaseInfo |
||
| 63 | */ |
||
| 64 | protected $BaseInfo; |
||
| 65 | |||
| 66 | /** |
||
| 67 | * @var AuthenticationUtils |
||
| 68 | */ |
||
| 69 | protected $helper; |
||
| 70 | |||
| 71 | private $title = ''; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * ProductController constructor. |
||
| 75 | * |
||
| 76 | * @param PurchaseFlow $cartPurchaseFlow |
||
| 77 | * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository |
||
| 78 | * @param CartService $cartService |
||
| 79 | * @param ProductRepository $productRepository |
||
| 80 | * @param BaseInfoRepository $baseInfoRepository |
||
| 81 | * @param AuthenticationUtils $helper |
||
| 82 | */ |
||
| 83 | public function __construct( |
||
| 98 | |||
| 99 | /** |
||
| 100 | * 商品一覧画面. |
||
| 101 | * |
||
| 102 | * @Route("/products/list", name="product_list") |
||
| 103 | * @Template("Product/list.twig") |
||
| 104 | */ |
||
| 105 | public function index(Request $request, Paginator $paginator) |
||
| 106 | 3 | { |
|
| 107 | // Doctrine SQLFilter |
||
| 108 | if ($this->BaseInfo->isOptionNostockHidden()) { |
||
| 109 | $this->entityManager->getFilters()->enable('option_nostock_hidden'); |
||
| 110 | } |
||
| 111 | |||
| 112 | // handleRequestは空のqueryの場合は無視するため |
||
| 113 | if ($request->getMethod() === 'GET') { |
||
| 114 | 3 | $request->query->set('pageno', $request->query->get('pageno', '')); |
|
| 115 | 3 | } |
|
| 116 | |||
| 117 | // searchForm |
||
| 118 | /* @var $builder \Symfony\Component\Form\FormBuilderInterface */ |
||
| 119 | $builder = $this->formFactory->createNamedBuilder('', SearchProductType::class); |
||
| 120 | 3 | ||
| 121 | 3 | if ($request->getMethod() === 'GET') { |
|
| 122 | 3 | $builder->setMethod('GET'); |
|
| 123 | 3 | } |
|
| 124 | 3 | ||
| 125 | $event = new EventArgs( |
||
| 126 | [ |
||
| 127 | 3 | 'builder' => $builder, |
|
| 128 | ], |
||
| 129 | 3 | $request |
|
| 130 | ); |
||
| 131 | 3 | $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE, $event); |
|
| 132 | |||
| 133 | 3 | /* @var $searchForm \Symfony\Component\Form\FormInterface */ |
|
| 134 | $searchForm = $builder->getForm(); |
||
| 135 | |||
| 136 | 3 | $searchForm->handleRequest($request); |
|
| 137 | |||
| 138 | 3 | // paginator |
|
| 139 | $searchData = $searchForm->getData(); |
||
| 140 | $qb = $this->productRepository->getQueryBuilderBySearchData($searchData); |
||
| 141 | 3 | ||
| 142 | 3 | $event = new EventArgs( |
|
| 143 | [ |
||
| 144 | 3 | 'searchData' => $searchData, |
|
| 145 | 'qb' => $qb, |
||
| 146 | 3 | ], |
|
| 147 | 3 | $request |
|
| 148 | ); |
||
| 149 | 3 | $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH, $event); |
|
| 150 | $searchData = $event->getArgument('searchData'); |
||
| 151 | 3 | ||
| 152 | 3 | $pagination = $paginator->paginate( |
|
| 153 | $qb, |
||
| 154 | 3 | !empty($searchData['pageno']) ? $searchData['pageno'] : 1, |
|
| 155 | 3 | $searchData['disp_number']->getId() |
|
| 156 | 3 | ); |
|
| 157 | 3 | ||
| 158 | // addCart form |
||
| 159 | $forms = []; |
||
| 160 | View Code Duplication | foreach ($pagination as $Product) { |
|
|
|
|||
| 161 | 3 | /* @var $builder \Symfony\Component\Form\FormBuilderInterface */ |
|
| 162 | 3 | $builder = $this->formFactory->createNamedBuilder( |
|
| 163 | '', |
||
| 164 | 3 | AddCartType::class, |
|
| 165 | 3 | null, |
|
| 166 | 3 | [ |
|
| 167 | 3 | 'product' => $this->productRepository->findWithSortedClassCategories($Product->getId()), |
|
| 168 | 'allow_extra_fields' => true, |
||
| 169 | 3 | ] |
|
| 170 | ); |
||
| 171 | $addCartForm = $builder->getForm(); |
||
| 172 | |||
| 173 | 3 | $forms[$Product->getId()] = $addCartForm->createView(); |
|
| 174 | } |
||
| 175 | 3 | ||
| 176 | // 表示件数 |
||
| 177 | $builder = $this->formFactory->createNamedBuilder( |
||
| 178 | 'disp_number', |
||
| 179 | 3 | ProductListMaxType::class, |
|
| 180 | 3 | null, |
|
| 181 | 3 | [ |
|
| 182 | 3 | 'required' => false, |
|
| 183 | 'allow_extra_fields' => true, |
||
| 184 | 3 | ] |
|
| 185 | 3 | ); |
|
| 186 | if ($request->getMethod() === 'GET') { |
||
| 187 | $builder->setMethod('GET'); |
||
| 188 | } |
||
| 189 | 3 | ||
| 190 | 3 | $event = new EventArgs( |
|
| 191 | [ |
||
| 192 | 'builder' => $builder, |
||
| 193 | 3 | ], |
|
| 194 | $request |
||
| 195 | 3 | ); |
|
| 196 | $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_DISP, $event); |
||
| 197 | 3 | ||
| 198 | $dispNumberForm = $builder->getForm(); |
||
| 199 | 3 | ||
| 200 | $dispNumberForm->handleRequest($request); |
||
| 201 | 3 | ||
| 202 | // ソート順 |
||
| 203 | 3 | $builder = $this->formFactory->createNamedBuilder( |
|
| 204 | 'orderby', |
||
| 205 | ProductListOrderByType::class, |
||
| 206 | 3 | null, |
|
| 207 | 3 | [ |
|
| 208 | 3 | 'required' => false, |
|
| 209 | 3 | 'allow_extra_fields' => true, |
|
| 210 | ] |
||
| 211 | 3 | ); |
|
| 212 | 3 | if ($request->getMethod() === 'GET') { |
|
| 213 | $builder->setMethod('GET'); |
||
| 214 | } |
||
| 215 | |||
| 216 | 3 | $event = new EventArgs( |
|
| 217 | 3 | [ |
|
| 218 | 'builder' => $builder, |
||
| 219 | ], |
||
| 220 | 3 | $request |
|
| 221 | ); |
||
| 222 | 3 | $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_ORDER, $event); |
|
| 223 | |||
| 224 | 3 | $orderByForm = $builder->getForm(); |
|
| 225 | |||
| 226 | 3 | $orderByForm->handleRequest($request); |
|
| 227 | |||
| 228 | 3 | $Category = $searchForm->get('category_id')->getData(); |
|
| 229 | |||
| 230 | 3 | return [ |
|
| 231 | 'subtitle' => $this->getPageTitle($searchData), |
||
| 232 | 3 | 'pagination' => $pagination, |
|
| 233 | 'search_form' => $searchForm->createView(), |
||
| 234 | 'disp_number_form' => $dispNumberForm->createView(), |
||
| 235 | 3 | 'order_by_form' => $orderByForm->createView(), |
|
| 236 | 3 | 'forms' => $forms, |
|
| 237 | 3 | 'Category' => $Category, |
|
| 238 | 3 | ]; |
|
| 239 | 3 | } |
|
| 240 | 3 | ||
| 241 | 3 | /** |
|
| 242 | * 商品詳細画面. |
||
| 243 | * |
||
| 244 | * @Route("/products/detail/{id}", name="product_detail", methods={"GET"}, requirements={"id" = "\d+"}) |
||
| 245 | * @Template("Product/detail.twig") |
||
| 246 | * @ParamConverter("Product", options={"repository_method" = "findWithSortedClassCategories"}) |
||
| 247 | * |
||
| 248 | * @param Request $request |
||
| 249 | * @param Product $Product |
||
| 250 | * |
||
| 251 | * @return array |
||
| 252 | */ |
||
| 253 | public function detail(Request $request, Product $Product) |
||
| 292 | 11 | ||
| 293 | 11 | /** |
|
| 294 | 11 | * お気に入り追加. |
|
| 295 | * |
||
| 296 | * @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"}) |
||
| 297 | */ |
||
| 298 | public function addFavorite(Request $request, Product $Product) |
||
| 341 | 1 | ||
| 342 | /** |
||
| 343 | 1 | * カートに追加. |
|
| 344 | * |
||
| 345 | * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"}) |
||
| 346 | */ |
||
| 347 | public function addCart(Request $request, Product $Product) |
||
| 463 | 5 | ||
| 464 | /** |
||
| 465 | * ページタイトルの設定 |
||
| 466 | 35 | * |
|
| 467 | * @param null|array $searchData |
||
| 468 | * |
||
| 469 | * @return str |
||
| 470 | */ |
||
| 471 | private function getPageTitle($searchData) |
||
| 481 | 3 | ||
| 482 | 1 | /** |
|
| 483 | * 閲覧可能な商品かどうかを判定 |
||
| 484 | 2 | * |
|
| 485 | * @param Product $Product |
||
| 486 | * |
||
| 487 | * @return boolean 閲覧可能な場合はtrue |
||
| 488 | */ |
||
| 489 | private function checkVisibility(Product $Product) |
||
| 509 | } |
||
| 510 |