Complex classes like SugarController 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 SugarController, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 46 | class SugarController{ |
||
| 47 | /** |
||
| 48 | * remap actions in here |
||
| 49 | * e.g. make all detail views go to edit views |
||
| 50 | * $action_remap = array('detailview'=>'editview'); |
||
| 51 | */ |
||
| 52 | protected $action_remap = array('index'=>'listview'); |
||
| 53 | /** |
||
| 54 | * The name of the current module. |
||
| 55 | */ |
||
| 56 | public $module = 'Home'; |
||
| 57 | /** |
||
| 58 | * The name of the target module. |
||
| 59 | */ |
||
| 60 | public $target_module = null; |
||
| 61 | /** |
||
| 62 | * The name of the current action. |
||
| 63 | */ |
||
| 64 | public $action = 'index'; |
||
| 65 | /** |
||
| 66 | * The id of the current record. |
||
| 67 | */ |
||
| 68 | public $record = ''; |
||
| 69 | /** |
||
| 70 | * The name of the return module. |
||
| 71 | */ |
||
| 72 | public $return_module = null; |
||
| 73 | /** |
||
| 74 | * The name of the return action. |
||
| 75 | */ |
||
| 76 | public $return_action = null; |
||
| 77 | /** |
||
| 78 | * The id of the return record. |
||
| 79 | */ |
||
| 80 | public $return_id = null; |
||
| 81 | /** |
||
| 82 | * If the action was remapped it will be set to do_action and then we will just |
||
| 83 | * use do_action for the actual action to perform. |
||
| 84 | */ |
||
| 85 | protected $do_action = 'index'; |
||
| 86 | /** |
||
| 87 | * If a bean is present that set it. |
||
| 88 | */ |
||
| 89 | public $bean = null; |
||
| 90 | /** |
||
| 91 | * url to redirect to |
||
| 92 | */ |
||
| 93 | public $redirect_url = ''; |
||
| 94 | /** |
||
| 95 | * any subcontroller can modify this to change the view |
||
| 96 | */ |
||
| 97 | public $view = 'classic'; |
||
| 98 | /** |
||
| 99 | * this array will hold the mappings between a key and an object for use within the view. |
||
| 100 | */ |
||
| 101 | public $view_object_map = array(); |
||
| 102 | |||
| 103 | /** |
||
| 104 | * This array holds the methods that handleAction() will invoke, in sequence. |
||
| 105 | */ |
||
| 106 | protected $tasks = array( |
||
| 107 | 'pre_action', |
||
| 108 | 'do_action', |
||
| 109 | 'post_action' |
||
| 110 | ); |
||
| 111 | /** |
||
| 112 | * List of options to run through within the process() method. |
||
| 113 | * This list is meant to easily allow additions for new functionality as well as |
||
| 114 | * the ability to add a controller's own handling. |
||
| 115 | */ |
||
| 116 | public $process_tasks = array( |
||
| 117 | 'blockFileAccess', |
||
| 118 | 'handleEntryPoint', |
||
| 119 | 'callLegacyCode', |
||
| 120 | 'remapAction', |
||
| 121 | 'handle_action', |
||
| 122 | 'handleActionMaps', |
||
| 123 | ); |
||
| 124 | /** |
||
| 125 | * Whether or not the action has been handled by $process_tasks |
||
| 126 | * |
||
| 127 | * @var bool |
||
| 128 | */ |
||
| 129 | protected $_processed = false; |
||
| 130 | /** |
||
| 131 | * Map an action directly to a file |
||
| 132 | */ |
||
| 133 | /** |
||
| 134 | * Map an action directly to a file. This will be loaded from action_file_map.php |
||
| 135 | */ |
||
| 136 | protected $action_file_map = array(); |
||
| 137 | /** |
||
| 138 | * Map an action directly to a view |
||
| 139 | */ |
||
| 140 | /** |
||
| 141 | * Map an action directly to a view. This will be loaded from action_view_map.php |
||
| 142 | */ |
||
| 143 | protected $action_view_map = array(); |
||
| 144 | |||
| 145 | /** |
||
| 146 | * This can be set from the application to tell us whether we have authorization to |
||
| 147 | * process the action. If this is set we will default to the noaccess view. |
||
| 148 | */ |
||
| 149 | public $hasAccess = true; |
||
| 150 | |||
| 151 | /** |
||
| 152 | * Map case sensitive filenames to action. This is used for linux/unix systems |
||
| 153 | * where filenames are case sensitive |
||
| 154 | */ |
||
| 155 | public static $action_case_file = array( |
||
| 156 | 'editview'=>'EditView', |
||
| 157 | 'detailview'=>'DetailView', |
||
| 158 | 'listview'=>'ListView' |
||
| 159 | ); |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Constructor. This ie meant tot load up the module, action, record as well |
||
| 163 | * as the mapping arrays. |
||
| 164 | */ |
||
| 165 | 16 | public function __construct(){ |
|
| 167 | |||
| 168 | /** |
||
| 169 | * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead |
||
| 170 | */ |
||
| 171 | public function SugarController(){ |
||
| 181 | |||
| 182 | |||
| 183 | /** |
||
| 184 | * Called from SugarApplication and is meant to perform the setup operations |
||
| 185 | * on the controller. |
||
| 186 | * |
||
| 187 | */ |
||
| 188 | 2 | public function setup($module = ''){ |
|
| 203 | /** |
||
| 204 | * Set the module on the Controller |
||
| 205 | * |
||
| 206 | * @param object $module |
||
| 207 | */ |
||
| 208 | 6 | public function setModule($module){ |
|
| 211 | |||
| 212 | /** |
||
| 213 | * Set properties on the Controller from the $_REQUEST |
||
| 214 | * |
||
| 215 | */ |
||
| 216 | 2 | private function loadPropertiesFromRequest(){ |
|
| 230 | |||
| 231 | /** |
||
| 232 | * Load map files for use within the Controller |
||
| 233 | * |
||
| 234 | */ |
||
| 235 | 2 | private function loadMappings(){ |
|
| 240 | |||
| 241 | /** |
||
| 242 | * Given a record id load the bean. This bean is accessible from any sub controllers. |
||
| 243 | */ |
||
| 244 | 5 | public function loadBean() |
|
| 259 | |||
| 260 | /** |
||
| 261 | * Generic load method to load mapping arrays. |
||
| 262 | */ |
||
| 263 | 3 | private function loadMapping($var, $merge = false){ |
|
| 298 | |||
| 299 | /** |
||
| 300 | * This method is called from SugarApplication->execute and it will bootstrap the entire controller process |
||
| 301 | */ |
||
| 302 | 1 | final public function execute() |
|
| 325 | |||
| 326 | /** |
||
| 327 | * Handle exception |
||
| 328 | * @param Exception $e |
||
| 329 | */ |
||
| 330 | 1 | protected function handleException(Exception $e) |
|
| 345 | |||
| 346 | /** |
||
| 347 | * Display the appropriate view. |
||
| 348 | */ |
||
| 349 | 1 | private function processView(){ |
|
| 365 | |||
| 366 | /** |
||
| 367 | * Meant to be overridden by a subclass and allows for specific functionality to be |
||
| 368 | * injected prior to the process() method being called. |
||
| 369 | */ |
||
| 370 | public function preProcess() |
||
| 372 | |||
| 373 | /** |
||
| 374 | * if we have a function to support the action use it otherwise use the default action |
||
| 375 | * |
||
| 376 | * 1) check for file |
||
| 377 | * 2) check for action |
||
| 378 | */ |
||
| 379 | 2 | public function process(){ |
|
| 406 | |||
| 407 | /** |
||
| 408 | * This method is called from the process method. I could also be called within an action_* method. |
||
| 409 | * It allows a developer to override any one of these methods contained within, |
||
| 410 | * or if the developer so chooses they can override the entire action_* method. |
||
| 411 | * |
||
| 412 | * @return true if any one of the pre_, do_, or post_ methods have been defined, |
||
| 413 | * false otherwise. This is important b/c if none of these methods exists, then we will run the |
||
| 414 | * action_default() method. |
||
| 415 | */ |
||
| 416 | 2 | protected function handle_action(){ |
|
| 423 | |||
| 424 | /** |
||
| 425 | * Perform an action prior to the specified action. |
||
| 426 | * This can be overridde in a sub-class |
||
| 427 | */ |
||
| 428 | 2 | private function pre_action(){ |
|
| 437 | |||
| 438 | /** |
||
| 439 | * Perform the specified action. |
||
| 440 | * This can be overridde in a sub-class |
||
| 441 | */ |
||
| 442 | 2 | private function do_action(){ |
|
| 451 | |||
| 452 | /** |
||
| 453 | * Perform an action after to the specified action has occurred. |
||
| 454 | * This can be overridde in a sub-class |
||
| 455 | */ |
||
| 456 | 2 | private function post_action(){ |
|
| 465 | |||
| 466 | /** |
||
| 467 | * If there is no action found then display an error to the user. |
||
| 468 | */ |
||
| 469 | protected function no_action(){ |
||
| 472 | |||
| 473 | /** |
||
| 474 | * The default action handler for instances where we do not have access to process. |
||
| 475 | */ |
||
| 476 | protected function no_access(){ |
||
| 479 | |||
| 480 | /////////////////////////////////////////////// |
||
| 481 | /////// HELPER FUNCTIONS |
||
| 482 | /////////////////////////////////////////////// |
||
| 483 | |||
| 484 | /** |
||
| 485 | * Determine if a given function exists on the objects |
||
| 486 | * @param function - the function to check |
||
| 487 | * @return true if the method exists on the object, false otherwise |
||
| 488 | */ |
||
| 489 | 2 | protected function hasFunction($function){ |
|
| 492 | |||
| 493 | |||
| 494 | /** |
||
| 495 | * Set the url to which we will want to redirect |
||
| 496 | * |
||
| 497 | * @param string url - the url to which we will want to redirect |
||
| 498 | */ |
||
| 499 | protected function set_redirect($url){ |
||
| 502 | |||
| 503 | /** |
||
| 504 | * Perform redirection based on the redirect_url |
||
| 505 | * |
||
| 506 | */ |
||
| 507 | 2 | protected function redirect(){ |
|
| 512 | |||
| 513 | //////////////////////////////////////////////////////// |
||
| 514 | ////// DEFAULT ACTIONS |
||
| 515 | /////////////////////////////////////////////////////// |
||
| 516 | |||
| 517 | /* |
||
| 518 | * Save a bean |
||
| 519 | */ |
||
| 520 | |||
| 521 | /** |
||
| 522 | * Do some processing before saving the bean to the database. |
||
| 523 | */ |
||
| 524 | 1 | public function pre_save(){ |
|
| 560 | |||
| 561 | /** |
||
| 562 | * Perform the actual save |
||
| 563 | */ |
||
| 564 | 1 | public function action_save(){ |
|
| 567 | |||
| 568 | |||
| 569 | 1 | public function action_spot() |
|
| 573 | |||
| 574 | |||
| 575 | /** |
||
| 576 | * Specify what happens after the save has occurred. |
||
| 577 | */ |
||
| 578 | protected function post_save(){ |
||
| 586 | |||
| 587 | /* |
||
| 588 | * Delete a bean |
||
| 589 | */ |
||
| 590 | |||
| 591 | /** |
||
| 592 | * Perform the actual deletion. |
||
| 593 | */ |
||
| 594 | protected function action_delete(){ |
||
| 607 | |||
| 608 | /** |
||
| 609 | * Specify what happens after the deletion has occurred. |
||
| 610 | */ |
||
| 611 | protected function post_delete(){ |
||
| 634 | /** |
||
| 635 | * Perform the actual massupdate. |
||
| 636 | */ |
||
| 637 | protected function action_massupdate(){ |
||
| 673 | /** |
||
| 674 | * Specify what happens after the massupdate has occurred. |
||
| 675 | */ |
||
| 676 | protected function post_massupdate(){ |
||
| 691 | /** |
||
| 692 | * Perform the listview action |
||
| 693 | */ |
||
| 694 | 2 | protected function action_listview(){ |
|
| 698 | |||
| 699 | /* |
||
| 700 | |||
| 701 | //THIS IS HANDLED IN ACTION_REMAP WHERE INDEX IS SET TO LISTVIEW |
||
| 702 | function action_index(){ |
||
| 703 | } |
||
| 704 | */ |
||
| 705 | |||
| 706 | /** |
||
| 707 | * Action to handle when using a file as was done in previous versions of Sugar. |
||
| 708 | */ |
||
| 709 | protected function action_default(){ |
||
| 712 | |||
| 713 | /** |
||
| 714 | * this method id used within a Dashlet when performing an ajax call |
||
| 715 | */ |
||
| 716 | protected function action_callmethoddashlet(){ |
||
| 735 | |||
| 736 | /** |
||
| 737 | * this method is used within a Dashlet when the options configuration is posted |
||
| 738 | */ |
||
| 739 | protected function action_configuredashlet(){ |
||
| 763 | |||
| 764 | /** |
||
| 765 | * Global method to delete an attachment |
||
| 766 | * |
||
| 767 | * If the bean does not have a deleteAttachment method it will return 'false' as a string |
||
| 768 | * |
||
| 769 | * @return void |
||
| 770 | */ |
||
| 771 | protected function action_deleteattachment() |
||
| 791 | |||
| 792 | /** |
||
| 793 | * getActionFilename |
||
| 794 | */ |
||
| 795 | 4 | public static function getActionFilename($action) { |
|
| 801 | |||
| 802 | /********************************************************************/ |
||
| 803 | // PROCESS TASKS |
||
| 804 | /********************************************************************/ |
||
| 805 | |||
| 806 | /** |
||
| 807 | * Given the module and action, determine whether the super/admin has prevented access |
||
| 808 | * to this url. In addition if any links specified for this module, load the links into |
||
| 809 | * GLOBALS |
||
| 810 | * |
||
| 811 | * @return true if we want to stop processing, false if processing should continue |
||
| 812 | */ |
||
| 813 | 2 | private function blockFileAccess(){ |
|
| 849 | |||
| 850 | /** |
||
| 851 | * This code is part of the entry points reworking. We have consolidated all |
||
| 852 | * entry points to go through index.php. Now in order to bring up an entry point |
||
| 853 | * it will follow the format: |
||
| 854 | * 'index.php?entryPoint=download' |
||
| 855 | * the download entry point is mapped in the following file: entry_point_registry.php |
||
| 856 | * |
||
| 857 | */ |
||
| 858 | 2 | private function handleEntryPoint(){ |
|
| 870 | |||
| 871 | /** |
||
| 872 | * Checks to see if the requested entry point requires auth |
||
| 873 | * |
||
| 874 | * @param $entrypoint string name of the entrypoint |
||
| 875 | * @return bool true if auth is required, false if not |
||
| 876 | */ |
||
| 877 | 1 | public function checkEntryPointRequiresAuth($entryPoint) |
|
| 886 | |||
| 887 | /** |
||
| 888 | * Meant to handle old views e.g. DetailView.php. |
||
| 889 | * |
||
| 890 | */ |
||
| 891 | 2 | protected function callLegacyCode() |
|
| 918 | |||
| 919 | /** |
||
| 920 | * If the action has been remapped to a different action as defined in |
||
| 921 | * action_file_map.php or action_view_map.php load those maps here. |
||
| 922 | * |
||
| 923 | */ |
||
| 924 | private function handleActionMaps(){ |
||
| 937 | |||
| 938 | /** |
||
| 939 | * Actually remap the action if required. |
||
| 940 | * |
||
| 941 | */ |
||
| 942 | 2 | protected function remapAction(){ |
|
| 948 | |||
| 949 | } |
||
| 950 | ?> |
||
| 951 |
This function has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.