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 OwnerStoreController extends AbstractController |
||
42 | { |
||
43 | /** |
||
44 | * @var PluginRepository |
||
45 | */ |
||
46 | protected $pluginRepository; |
||
47 | |||
48 | /** |
||
49 | * @var PluginService |
||
50 | */ |
||
51 | protected $pluginService; |
||
52 | |||
53 | /** |
||
54 | * @var ComposerServiceInterface |
||
55 | */ |
||
56 | protected $composerService; |
||
57 | |||
58 | /** |
||
59 | * @var SystemService |
||
60 | */ |
||
61 | protected $systemService; |
||
62 | |||
63 | /** |
||
64 | * @var PluginApiService |
||
65 | */ |
||
66 | protected $pluginApiService; |
||
67 | |||
68 | private static $vendorName = 'ec-cube'; |
||
69 | |||
70 | /** @var BaseInfo */ |
||
71 | private $BaseInfo; |
||
72 | |||
73 | /** |
||
74 | * OwnerStoreController constructor. |
||
75 | * |
||
76 | * @param PluginRepository $pluginRepository |
||
77 | * @param PluginService $pluginService |
||
78 | * @param ComposerProcessService $composerProcessService |
||
79 | * @param ComposerApiService $composerApiService |
||
80 | * @param SystemService $systemService |
||
81 | * @param PluginApiService $pluginApiService |
||
82 | * @param BaseInfoRepository $baseInfoRepository |
||
83 | * |
||
84 | * @throws \Doctrine\ORM\NoResultException |
||
85 | * @throws \Doctrine\ORM\NonUniqueResultException |
||
86 | */ |
||
87 | public function __construct( |
||
110 | |||
111 | /** |
||
112 | * Owner's Store Plugin Installation Screen - Search function |
||
113 | * |
||
114 | * @Route("/search", name="admin_store_plugin_owners_search") |
||
115 | * @Route("/search/page/{page_no}", name="admin_store_plugin_owners_search_page", requirements={"page_no" = "\d+"}) |
||
116 | * @Template("@admin/Store/plugin_search.twig") |
||
117 | * |
||
118 | * @param Request $request |
||
119 | * @param int $page_no |
||
120 | * @param Paginator $paginator |
||
121 | * |
||
122 | * @return array |
||
123 | */ |
||
124 | public function search(Request $request, $page_no = null, Paginator $paginator) |
||
125 | { |
||
126 | if (empty($this->BaseInfo->getAuthenticationKey())) { |
||
127 | $this->addWarning('認証キーを設定してください。', 'admin'); |
||
128 | |||
129 | return $this->redirectToRoute('admin_store_authentication_setting'); |
||
130 | } |
||
131 | |||
132 | // Acquire downloadable plug-in information from owners store |
||
133 | $category = []; |
||
134 | |||
135 | $json = $this->pluginApiService->getCategory(); |
||
136 | if (!empty($json)) { |
||
137 | $data = json_decode($json, true); |
||
138 | $category = array_column($data, 'name', 'id'); |
||
139 | } |
||
140 | |||
141 | // build form with master data |
||
142 | $builder = $this->formFactory |
||
143 | ->createBuilder(SearchPluginApiType::class, null, ['category' => $category]); |
||
144 | $searchForm = $builder->getForm(); |
||
145 | |||
146 | $searchForm->handleRequest($request); |
||
147 | $searchData = $searchForm->getData(); |
||
148 | if ($searchForm->isSubmitted()) { |
||
149 | if ($searchForm->isValid()) { |
||
150 | $page_no = 1; |
||
151 | $searchData = $searchForm->getData(); |
||
152 | $this->session->set('eccube.admin.plugin_api.search', FormUtil::getViewData($searchForm)); |
||
153 | $this->session->set('eccube.admin.plugin_api.search.page_no', $page_no); |
||
154 | } |
||
155 | } else { |
||
156 | // quick search |
||
157 | if (is_numeric($categoryId = $request->get('category_id')) && array_key_exists($categoryId, $category)) { |
||
158 | $searchForm['category_id']->setData($categoryId); |
||
159 | } |
||
160 | // reset page count |
||
161 | $this->session->set('eccube.admin.plugin_api.search.page_count', $this->eccubeConfig->get('eccube_default_page_count')); |
||
162 | View Code Duplication | if (null !== $page_no || $request->get('resume')) { |
|
|
|||
163 | if ($page_no) { |
||
164 | $this->session->set('eccube.admin.plugin_api.search.page_no', (int) $page_no); |
||
165 | } else { |
||
166 | $page_no = $this->session->get('eccube.admin.plugin_api.search.page_no', 1); |
||
167 | } |
||
168 | $viewData = $this->session->get('eccube.admin.plugin_api.search', []); |
||
169 | $searchData = FormUtil::submitAndGetData($searchForm, $viewData); |
||
170 | } else { |
||
171 | $page_no = 1; |
||
172 | // submit default value |
||
173 | $viewData = FormUtil::getViewData($searchForm); |
||
174 | $searchData = FormUtil::submitAndGetData($searchForm, $viewData); |
||
175 | $this->session->set('eccube.admin.plugin_api.search', $searchData); |
||
176 | $this->session->set('eccube.admin.plugin_api.search.page_no', $page_no); |
||
177 | } |
||
178 | } |
||
179 | |||
180 | // set page count |
||
181 | $pageCount = $this->session->get('eccube.admin.plugin_api.search.page_count', $this->eccubeConfig->get('eccube_default_page_count')); |
||
182 | if (($PageMax = $searchForm['page_count']->getData()) instanceof PageMax) { |
||
183 | $pageCount = $PageMax->getId(); |
||
184 | $this->session->set('eccube.admin.plugin_api.search.page_count', $pageCount); |
||
185 | } |
||
186 | |||
187 | // Owner's store communication |
||
188 | $searchData['page_no'] = $page_no; |
||
189 | $searchData['page_count'] = $pageCount; |
||
190 | |||
191 | $total = 0; |
||
192 | $items = []; |
||
193 | |||
194 | try { |
||
195 | $data = $this->pluginApiService->getPlugins($searchData); |
||
196 | $total = $data['total']; |
||
197 | $items = $data['plugins']; |
||
198 | } catch (PluginApiException $e) { |
||
199 | $this->addError($e->getMessage(), 'admin'); |
||
200 | } |
||
201 | |||
202 | // The usage is set because `$items` are already paged. |
||
203 | // virtual paging |
||
204 | $pagination = $paginator->paginate($items, 1, $pageCount); |
||
205 | $pagination->setTotalItemCount($total); |
||
206 | $pagination->setCurrentPageNumber($page_no); |
||
207 | $pagination->setItemNumberPerPage($pageCount); |
||
208 | |||
209 | return [ |
||
210 | 'pagination' => $pagination, |
||
211 | 'total' => $total, |
||
212 | 'searchForm' => $searchForm->createView(), |
||
213 | 'page_no' => $page_no, |
||
214 | 'Categories' => $category, |
||
215 | ]; |
||
216 | } |
||
217 | |||
218 | /** |
||
219 | * Do confirm page |
||
220 | * |
||
221 | * @Route("/install/{id}/confirm", requirements={"id" = "\d+"}, name="admin_store_plugin_install_confirm") |
||
222 | * @Template("@admin/Store/plugin_confirm.twig") |
||
223 | * |
||
224 | * @param Request $request |
||
225 | * |
||
226 | * @return array |
||
227 | * |
||
228 | * @throws \Eccube\Exception\PluginException |
||
229 | */ |
||
230 | public function doConfirm(Request $request, $id) |
||
231 | { |
||
232 | try { |
||
233 | $item = $this->pluginApiService->getPlugin($id); |
||
234 | // Todo: need define item's dependency mechanism |
||
235 | $requires = $this->pluginService->getPluginRequired($item); |
||
236 | |||
237 | return [ |
||
238 | 'item' => $item, |
||
239 | 'requires' => $requires, |
||
240 | 'is_update' => $request->get('is_update', false), |
||
241 | ]; |
||
242 | } catch (PluginApiException $e) { |
||
243 | $this->addError($e->getMessage(), 'admin'); |
||
244 | |||
245 | return $this->redirectToRoute('admin_store_authentication_setting'); |
||
246 | } |
||
247 | } |
||
248 | |||
249 | /** |
||
250 | * Api Install plugin by composer connect with package repo |
||
251 | * |
||
252 | * @Route("/install", name="admin_store_plugin_api_install", methods={"POST"}) |
||
253 | * |
||
254 | * @param Request $request |
||
255 | * |
||
256 | * @return \Symfony\Component\HttpFoundation\JsonResponse |
||
257 | */ |
||
258 | public function apiInstall(Request $request) |
||
276 | |||
277 | /** |
||
278 | * New ways to remove plugin: using composer command |
||
279 | * |
||
280 | * @Route("/delete/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_api_uninstall", methods={"DELETE"}) |
||
281 | * |
||
282 | * @param Plugin $Plugin |
||
283 | * |
||
284 | * @return \Symfony\Component\HttpFoundation\JsonResponse |
||
285 | */ |
||
286 | public function apiUninstall(Plugin $Plugin) |
||
320 | |||
321 | /** |
||
322 | * オーナーズブラグインインストール、アップデート |
||
323 | * |
||
324 | * @Route("/upgrade", name="admin_store_plugin_api_upgrade", methods={"POST"}) |
||
325 | * |
||
326 | * @param Request $request |
||
327 | * |
||
328 | * @return \Symfony\Component\HttpFoundation\JsonResponse |
||
329 | */ |
||
330 | public function apiUpgrade(Request $request) |
||
349 | |||
350 | /** |
||
351 | * オーナーズブラグインインストール、スキーマ更新 |
||
352 | * |
||
353 | * @Route("/schema_update", name="admin_store_plugin_api_schema_update", methods={"POST"}) |
||
354 | * |
||
355 | * @param Request $request |
||
356 | * |
||
357 | * @return \Symfony\Component\HttpFoundation\JsonResponse |
||
358 | */ |
||
359 | View Code Duplication | public function apiSchemaUpdate(Request $request) |
|
387 | |||
388 | /** |
||
389 | * オーナーズブラグインインストール、更新処理 |
||
390 | * |
||
391 | * @Route("/update", name="admin_store_plugin_api_update", methods={"POST"}) |
||
392 | * |
||
393 | * @param Request $request |
||
394 | * |
||
395 | * @return \Symfony\Component\HttpFoundation\JsonResponse |
||
396 | */ |
||
397 | View Code Duplication | public function apiUpdate(Request $request) |
|
424 | |||
425 | /** |
||
426 | * Do confirm update page |
||
427 | * |
||
428 | * @Route("/upgrade/{id}/confirm", requirements={"id" = "\d+"}, name="admin_store_plugin_update_confirm") |
||
429 | * @Template("@admin/Store/plugin_confirm.twig") |
||
430 | * |
||
431 | * @param Plugin $Plugin |
||
432 | * |
||
433 | * @return array |
||
434 | */ |
||
435 | public function doUpdateConfirm(Plugin $Plugin) |
||
452 | |||
453 | /** |
||
454 | * API request processing |
||
455 | * |
||
456 | * @param string $url |
||
457 | * |
||
458 | * @return array |
||
459 | * |
||
460 | * @deprecated since release, please preference PluginApiService |
||
461 | */ |
||
462 | private function getRequestApi($url) |
||
488 | } |
||
489 |
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.