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 PluginController 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 PluginController, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 61 | class PluginController extends AbstractController |
||
| 62 | { |
||
| 63 | /** |
||
| 64 | * @Inject("orm.em") |
||
| 65 | * @var EntityManager |
||
| 66 | */ |
||
| 67 | protected $entityManager; |
||
| 68 | |||
| 69 | /** |
||
| 70 | * @Inject("monolog") |
||
| 71 | * @var Logger |
||
| 72 | */ |
||
| 73 | protected $logger; |
||
| 74 | |||
| 75 | /** |
||
| 76 | * @Inject(PluginEventHandlerRepository::class) |
||
| 77 | * @var PluginEventHandlerRepository |
||
| 78 | */ |
||
| 79 | protected $pluginEventHandlerRepository; |
||
| 80 | |||
| 81 | /** |
||
| 82 | * @Inject(PluginService::class) |
||
| 83 | * @var PluginService |
||
| 84 | */ |
||
| 85 | protected $pluginService; |
||
| 86 | |||
| 87 | /** |
||
| 88 | * @Inject("config") |
||
| 89 | * @var array |
||
| 90 | */ |
||
| 91 | protected $appConfig; |
||
| 92 | |||
| 93 | /** |
||
| 94 | * @Inject(BaseInfo::class) |
||
| 95 | * @var BaseInfo |
||
| 96 | */ |
||
| 97 | protected $BaseInfo; |
||
| 98 | |||
| 99 | /** |
||
| 100 | * @Inject("form.factory") |
||
| 101 | * @var FormFactory |
||
| 102 | */ |
||
| 103 | protected $formFactory; |
||
| 104 | |||
| 105 | /** |
||
| 106 | * @Inject(PluginRepository::class) |
||
| 107 | * @var PluginRepository |
||
| 108 | */ |
||
| 109 | protected $pluginRepository; |
||
| 110 | |||
| 111 | |||
| 112 | /** |
||
| 113 | * インストール済プラグイン画面 |
||
| 114 | * |
||
| 115 | * @Route("/{_admin}/store/plugin", name="admin_store_plugin") |
||
| 116 | * @Template("Store/plugin.twig") |
||
| 117 | */ |
||
| 118 | public function index(Application $app, Request $request) |
||
| 210 | |||
| 211 | /** |
||
| 212 | * インストール済プラグインからのアップデート |
||
| 213 | * |
||
| 214 | * @Method("POST") |
||
| 215 | * @Route("/{_admin}/store/plugin/{id}/update", requirements={"id" = "\d+"}, name="admin_store_plugin_update") |
||
| 216 | */ |
||
| 217 | public function update(Application $app, Request $request, Plugin $Plugin) |
||
| 276 | |||
| 277 | |||
| 278 | /** |
||
| 279 | * 対象のプラグインを有効にします。 |
||
| 280 | * |
||
| 281 | * @Method("PUT") |
||
| 282 | * @Route("/{_admin}/store/plugin/{id}/enable", requirements={"id" = "\d+"}, name="admin_store_plugin_enable") |
||
| 283 | */ |
||
| 284 | View Code Duplication | public function enable(Application $app, Plugin $Plugin) |
|
| 297 | |||
| 298 | /** |
||
| 299 | * 対象のプラグインを無効にします。 |
||
| 300 | * |
||
| 301 | * @Method("PUT") |
||
| 302 | * @Route("/{_admin}/store/plugin/{id}/disable", requirements={"id" = "\d+"}, name="admin_store_plugin_disable") |
||
| 303 | */ |
||
| 304 | View Code Duplication | public function disable(Application $app, Plugin $Plugin) |
|
| 317 | |||
| 318 | |||
| 319 | /** |
||
| 320 | * 対象のプラグインを削除します。 |
||
| 321 | * Update new ways to remove plugin: using composer command |
||
| 322 | * |
||
| 323 | * @Method("DELETE") |
||
| 324 | * @Route("/{_admin}/store/plugin/{id}/uninstall", requirements={"id" = "\d+"}, name="admin_store_plugin_uninstall") |
||
| 325 | * @param Application $app |
||
| 326 | * @param Plugin $Plugin |
||
| 327 | * @return RedirectResponse |
||
| 328 | */ |
||
| 329 | public function uninstall(Application $app, Plugin $Plugin) |
||
| 360 | |||
| 361 | /** |
||
| 362 | * @Route("/{_admin}/store/plugin/handler", name="admin_store_plugin_handler") |
||
| 363 | * @Template("Store/plugin_handler.twig") |
||
| 364 | */ |
||
| 365 | public function handler(Application $app) |
||
| 379 | |||
| 380 | /** |
||
| 381 | * @Route("/{_admin}/store/plugin/handler_up/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_up") |
||
| 382 | */ |
||
| 383 | View Code Duplication | public function handler_up(Application $app, PluginEventHandler $Handler) |
|
| 390 | |||
| 391 | /** |
||
| 392 | * @Route("/{_admin}/store/plugin/handler_down/{id}", requirements={"id" = "\d+"}, name="admin_store_plugin_handler_down") |
||
| 393 | */ |
||
| 394 | View Code Duplication | public function handler_down(Application $app, PluginEventHandler $Handler) |
|
| 401 | |||
| 402 | /** |
||
| 403 | * プラグインファイルアップロード画面 |
||
| 404 | * |
||
| 405 | * @Route("/{_admin}/store/plugin/install", name="admin_store_plugin_install") |
||
| 406 | * @Template("Store/plugin_install.twig") |
||
| 407 | */ |
||
| 408 | public function install(Application $app, Request $request) |
||
| 468 | |||
| 469 | /** |
||
| 470 | * オーナーズストアプラグインインストール画面 |
||
| 471 | * |
||
| 472 | * @Route("/{_admin}/store/plugin/owners_install", name="admin_store_plugin_owners_install") |
||
| 473 | * @Template("Store/plugin_owners_install.twig") |
||
| 474 | */ |
||
| 475 | public function ownersInstall(Application $app, Request $request) |
||
| 476 | { |
||
| 477 | // オーナーズストアからダウンロード可能プラグイン情報を取得 |
||
| 478 | $authKey = $this->BaseInfo->getAuthenticationKey(); |
||
| 479 | $authResult = true; |
||
| 480 | $success = 0; |
||
| 481 | $items = array(); |
||
| 482 | $promotionItems = array(); |
||
| 483 | $message = ''; |
||
| 484 | if (!is_null($authKey)) { |
||
| 485 | |||
| 486 | // オーナーズストア通信 |
||
| 487 | $url = $this->appConfig['owners_store_url'].'?method=list'; |
||
| 488 | list($json, $info) = $this->getRequestApi($request, $authKey, $url, $app); |
||
| 489 | |||
| 490 | if ($json === false) { |
||
| 491 | // 接続失敗時 |
||
| 492 | $success = 0; |
||
| 493 | |||
| 494 | $message = $this->getResponseErrorMessage($info); |
||
| 495 | |||
| 496 | } else { |
||
| 497 | // 接続成功時 |
||
| 498 | |||
| 499 | $data = json_decode($json, true); |
||
| 500 | |||
| 501 | if (isset($data['success'])) { |
||
| 502 | $success = $data['success']; |
||
| 503 | if ($success == '1') { |
||
| 504 | $items = array(); |
||
| 505 | |||
| 506 | // 既にインストールされているかどうか確認 |
||
| 507 | $Plugins = $this->pluginRepository->findAll(); |
||
| 508 | $status = false; |
||
| 509 | // update_status 1 : 未インストール、2 : インストール済、 3 : 更新あり、4 : 有料購入 |
||
| 510 | foreach ($data['item'] as $item) { |
||
| 511 | foreach ($Plugins as $plugin) { |
||
| 512 | if ($plugin->getSource() == $item['product_id']) { |
||
| 513 | if ($plugin->getVersion() == $item['version']) { |
||
| 514 | // バージョンが同じ |
||
| 515 | $item['update_status'] = 2; |
||
| 516 | } else { |
||
| 517 | // バージョンが異なる |
||
| 518 | $item['update_status'] = 3; |
||
| 519 | } |
||
| 520 | $items[] = $item; |
||
| 521 | $status = true; |
||
| 522 | break; |
||
| 523 | } |
||
| 524 | } |
||
| 525 | if (!$status) { |
||
| 526 | // 未インストール |
||
| 527 | $item['update_status'] = 1; |
||
| 528 | $items[] = $item; |
||
| 529 | } |
||
| 530 | $status = false; |
||
| 531 | } |
||
| 532 | |||
| 533 | // EC-CUBEのバージョンチェック |
||
| 534 | // 参照渡しをして値を追加 |
||
| 535 | foreach ($items as &$item) { |
||
| 536 | if (in_array(Constant::VERSION, $item['eccube_version'])) { |
||
| 537 | // 対象バージョン |
||
| 538 | $item['version_check'] = 1; |
||
| 539 | } else { |
||
| 540 | // 未対象バージョン |
||
| 541 | $item['version_check'] = 0; |
||
| 542 | } |
||
| 543 | if ($item['price'] != '0' && $item['purchased'] == '0') { |
||
| 544 | // 有料商品で未購入 |
||
| 545 | $item['update_status'] = 4; |
||
| 546 | } |
||
| 547 | } |
||
| 548 | unset($item); |
||
| 549 | |||
| 550 | // promotionアイテム |
||
| 551 | $i = 0; |
||
| 552 | View Code Duplication | foreach ($items as $item) { |
|
| 553 | if ($item['promotion'] == 1) { |
||
| 554 | $promotionItems[] = $item; |
||
| 555 | unset($items[$i]); |
||
| 556 | } |
||
| 557 | $i++; |
||
| 558 | } |
||
| 559 | |||
| 560 | } else { |
||
| 561 | $message = $data['error_code'].' : '.$data['error_message']; |
||
| 562 | } |
||
| 563 | } else { |
||
| 564 | $success = 0; |
||
| 565 | $message = "EC-CUBEオーナーズストアにエラーが発生しています。"; |
||
| 566 | } |
||
| 567 | } |
||
| 568 | |||
| 569 | } else { |
||
| 570 | $authResult = false; |
||
| 571 | } |
||
| 572 | |||
| 573 | return [ |
||
| 574 | 'authResult' => $authResult, |
||
| 575 | 'success' => $success, |
||
| 576 | 'items' => $items, |
||
| 577 | 'promotionItems' => $promotionItems, |
||
| 578 | 'message' => $message, |
||
| 579 | ]; |
||
| 580 | } |
||
| 581 | |||
| 582 | /** |
||
| 583 | * オーナーズブラグインインストール、アップデート |
||
| 584 | * |
||
| 585 | * @Route("/{_admin}/store/plugin/upgrade/{action}/{id}/{version}", requirements={"id" = "\d+"}, name="admin_store_plugin_upgrade") |
||
| 586 | */ |
||
| 587 | public function upgrade(Application $app, Request $request, $action, $id, $version) |
||
| 679 | |||
| 680 | /** |
||
| 681 | * 認証キー設定画面 |
||
| 682 | * |
||
| 683 | * @Route("/{_admin}/store/plugin/authentication_setting", name="admin_store_authentication_setting") |
||
| 684 | * @Template("Store/authentication_setting.twig") |
||
| 685 | */ |
||
| 686 | public function authenticationSetting(Application $app, Request $request) |
||
| 716 | |||
| 717 | |||
| 718 | /** |
||
| 719 | * APIリクエスト処理 |
||
| 720 | * |
||
| 721 | * @param Request $request |
||
| 722 | * @param $authKey |
||
| 723 | * @param string $url |
||
| 724 | * @param Application $app |
||
| 725 | * @return array |
||
| 726 | */ |
||
| 727 | private function getRequestApi(Request $request, $authKey, $url, $app) |
||
| 757 | |||
| 758 | /** |
||
| 759 | * レスポンスのチェック |
||
| 760 | * |
||
| 761 | * @param $info |
||
| 762 | * @return string |
||
| 763 | */ |
||
| 764 | View Code Duplication | private function getResponseErrorMessage($info) |
|
| 778 | |||
| 779 | |||
| 780 | /** |
||
| 781 | * フォルダ設置のみのプラグインを取得する. |
||
| 782 | * |
||
| 783 | * @param array $plugins |
||
| 784 | * @param Application $app |
||
| 785 | * @return array |
||
| 786 | */ |
||
| 787 | protected function getUnregisteredPlugins(array $plugins, \Eccube\Application $app) |
||
| 823 | } |
||
| 824 |