Complex classes like MyObject 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 MyObject, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 33 | class MyObject extends CommonObject |
||
| 34 | { |
||
| 35 | /** |
||
| 36 | * @var string ID to identify managed object |
||
| 37 | */ |
||
| 38 | public $element = 'myobject'; |
||
| 39 | |||
| 40 | /** |
||
| 41 | * @var string Name of table without prefix where object is stored |
||
| 42 | */ |
||
| 43 | public $table_element = 'mymodule_myobject'; |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @var string Name of subtable if this object has sub lines |
||
| 47 | */ |
||
| 48 | //public $table_element_line = 'mymodule_myobjectline'; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var int Does myobject support multicompany module ? 0=No test on entity, 1=Test with field entity, 2=Test with link by societe |
||
| 52 | */ |
||
| 53 | public $ismultientitymanaged = 0; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @var int Does myobject support extrafields ? 0=No, 1=Yes |
||
| 57 | */ |
||
| 58 | public $isextrafieldmanaged = 1; |
||
| 59 | |||
| 60 | /** |
||
| 61 | * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png |
||
| 62 | */ |
||
| 63 | public $picto = 'myobject@mymodule'; |
||
| 64 | |||
| 65 | |||
| 66 | const STATUS_DRAFT = 0; |
||
| 67 | const STATUS_VALIDATED = 1; |
||
| 68 | const STATUS_DISABLED = 9; |
||
| 69 | |||
| 70 | |||
| 71 | /** |
||
| 72 | * 'type' if the field format ('integer', 'integer:Class:pathtoclass', 'varchar(x)', 'double(24,8)', 'text', 'html', 'datetime', 'timestamp', 'float') |
||
| 73 | * 'label' the translation key. |
||
| 74 | * 'enabled' is a condition when the field must be managed. |
||
| 75 | * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). Using a negative value means field is not shown by default on list but can be selected for viewing) |
||
| 76 | * 'noteditable' says if field is not editable (1 or 0) |
||
| 77 | * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). |
||
| 78 | * 'default' is a default value for creation (can still be replaced by the global setup of default values) |
||
| 79 | * 'index' if we want an index in database. |
||
| 80 | * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). |
||
| 81 | * 'position' is the sort order of field. |
||
| 82 | * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. |
||
| 83 | * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). |
||
| 84 | * 'css' is the CSS style to use on field. For example: 'maxwidth200' |
||
| 85 | * 'help' is a string visible as a tooltip on field |
||
| 86 | * 'comment' is not used. You can store here any text of your choice. It is not used by application. |
||
| 87 | * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record |
||
| 88 | * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") |
||
| 89 | */ |
||
| 90 | |||
| 91 | // BEGIN MODULEBUILDER PROPERTIES |
||
| 92 | /** |
||
| 93 | * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. |
||
| 94 | */ |
||
| 95 | public $fields=array( |
||
| 96 | 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'noteditable'=>1, 'notnull'=> 1, 'index'=>1, 'position'=>1, 'comment'=>'Id'), |
||
| 97 | 'ref' =>array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'noteditable'=>0, 'notnull'=> 1, 'default'=>'(PROV)', 'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'), |
||
| 98 | 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=> 1, 'default'=>1, 'index'=>1, 'position'=>20), |
||
| 99 | 'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth200', 'help'=>'Help text', 'showoncombobox'=>1), |
||
| 100 | 'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount'), |
||
| 101 | 'qty' =>array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp'), |
||
| 102 | 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'LinkToThirparty'), |
||
| 103 | 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>0, 'position'=>60), |
||
| 104 | 'note_public' =>array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61), |
||
| 105 | 'note_private' =>array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62), |
||
| 106 | 'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>500), |
||
| 107 | 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 0, 'position'=>501), |
||
| 108 | //'date_validation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>502), |
||
| 109 | 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'notnull'=> 1, 'position'=>510, 'foreignkey'=>'user.rowid'), |
||
| 110 | 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511), |
||
| 111 | //'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>512), |
||
| 112 | 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>0, 'position'=>1000), |
||
| 113 | 'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=> 1, 'default'=>0, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', 9=>'Canceled')), |
||
| 114 | ); |
||
| 115 | |||
| 116 | /** |
||
| 117 | * @var int ID |
||
| 118 | */ |
||
| 119 | public $rowid; |
||
| 120 | |||
| 121 | /** |
||
| 122 | * @var string Ref |
||
| 123 | */ |
||
| 124 | public $ref; |
||
| 125 | |||
| 126 | /** |
||
| 127 | * @var int Entity |
||
| 128 | */ |
||
| 129 | public $entity; |
||
| 130 | |||
| 131 | /** |
||
| 132 | * @var string label |
||
| 133 | */ |
||
| 134 | public $label; |
||
| 135 | |||
| 136 | /** |
||
| 137 | * @var string amount |
||
| 138 | */ |
||
| 139 | public $amount; |
||
| 140 | |||
| 141 | /** |
||
| 142 | * @var int Status |
||
| 143 | */ |
||
| 144 | public $status; |
||
| 145 | |||
| 146 | /** |
||
| 147 | * @var integer|string date_creation |
||
| 148 | */ |
||
| 149 | public $date_creation; |
||
| 150 | |||
| 151 | /** |
||
| 152 | * @var integer tms |
||
| 153 | */ |
||
| 154 | public $tms; |
||
| 155 | |||
| 156 | /** |
||
| 157 | * @var int ID |
||
| 158 | */ |
||
| 159 | public $fk_user_creat; |
||
| 160 | |||
| 161 | /** |
||
| 162 | * @var int ID |
||
| 163 | */ |
||
| 164 | public $fk_user_modif; |
||
| 165 | |||
| 166 | /** |
||
| 167 | * @var string import_key |
||
| 168 | */ |
||
| 169 | public $import_key; |
||
| 170 | // END MODULEBUILDER PROPERTIES |
||
| 171 | |||
| 172 | |||
| 173 | |||
| 174 | // If this object has a subtable with lines |
||
| 175 | |||
| 176 | /** |
||
| 177 | * @var int Name of subtable line |
||
| 178 | */ |
||
| 179 | //public $table_element_line = 'myobjectdet'; |
||
| 180 | |||
| 181 | /** |
||
| 182 | * @var int Field with ID of parent key if this field has a parent |
||
| 183 | */ |
||
| 184 | //public $fk_element = 'fk_myobject'; |
||
| 185 | |||
| 186 | /** |
||
| 187 | * @var int Name of subtable class that manage subtable lines |
||
| 188 | */ |
||
| 189 | //public $class_element_line = 'MyObjectline'; |
||
| 190 | |||
| 191 | /** |
||
| 192 | * @var array Array of child tables (child tables to delete before deleting a record) |
||
| 193 | */ |
||
| 194 | //protected $childtables=array('myobjectdet'); |
||
| 195 | |||
| 196 | /** |
||
| 197 | * @var MyObjectLine[] Array of subtable lines |
||
| 198 | */ |
||
| 199 | //public $lines = array(); |
||
| 200 | |||
| 201 | |||
| 202 | |||
| 203 | /** |
||
| 204 | * Constructor |
||
| 205 | * |
||
| 206 | * @param DoliDb $db Database handler |
||
| 207 | */ |
||
| 208 | public function __construct(DoliDB $db) |
||
| 238 | |||
| 239 | /** |
||
| 240 | * Create object into database |
||
| 241 | * |
||
| 242 | * @param User $user User that creates |
||
| 243 | * @param bool $notrigger false=launch triggers after, true=disable triggers |
||
| 244 | * @return int <0 if KO, Id of created object if OK |
||
| 245 | */ |
||
| 246 | public function create(User $user, $notrigger = false) |
||
| 250 | |||
| 251 | /** |
||
| 252 | * Clone an object into another one |
||
| 253 | * |
||
| 254 | * @param User $user User that creates |
||
| 255 | * @param int $fromid Id of object to clone |
||
| 256 | * @return mixed New object created, <0 if KO |
||
| 257 | */ |
||
| 258 | public function createFromClone(User $user, $fromid) |
||
| 315 | |||
| 316 | /** |
||
| 317 | * Load object in memory from the database |
||
| 318 | * |
||
| 319 | * @param int $id Id object |
||
| 320 | * @param string $ref Ref |
||
| 321 | * @return int <0 if KO, 0 if not found, >0 if OK |
||
| 322 | */ |
||
| 323 | public function fetch($id, $ref = null) |
||
| 329 | |||
| 330 | /** |
||
| 331 | * Load object lines in memory from the database |
||
| 332 | * |
||
| 333 | * @return int <0 if KO, 0 if not found, >0 if OK |
||
| 334 | */ |
||
| 335 | public function fetchLines() |
||
| 342 | |||
| 343 | |||
| 344 | /** |
||
| 345 | * Load list of objects in memory from the database. |
||
| 346 | * |
||
| 347 | * @param string $sortorder Sort Order |
||
| 348 | * @param string $sortfield Sort field |
||
| 349 | * @param int $limit limit |
||
| 350 | * @param int $offset Offset |
||
| 351 | * @param array $filter Filter array. Example array('field'=>'valueforlike', 'customurl'=>...) |
||
| 352 | * @param string $filtermode Filter mode (AND or OR) |
||
| 353 | * @return array|int int <0 if KO, array of pages if OK |
||
| 354 | */ |
||
| 355 | public function fetchAll($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, array $filter = array(), $filtermode = 'AND') |
||
| 422 | |||
| 423 | /** |
||
| 424 | * Update object into database |
||
| 425 | * |
||
| 426 | * @param User $user User that modifies |
||
| 427 | * @param bool $notrigger false=launch triggers after, true=disable triggers |
||
| 428 | * @return int <0 if KO, >0 if OK |
||
| 429 | */ |
||
| 430 | public function update(User $user, $notrigger = false) |
||
| 434 | |||
| 435 | /** |
||
| 436 | * Delete object in database |
||
| 437 | * |
||
| 438 | * @param User $user User that deletes |
||
| 439 | * @param bool $notrigger false=launch triggers after, true=disable triggers |
||
| 440 | * @return int <0 if KO, >0 if OK |
||
| 441 | */ |
||
| 442 | public function delete(User $user, $notrigger = false) |
||
| 447 | |||
| 448 | /** |
||
| 449 | * Delete a line of object in database |
||
| 450 | * |
||
| 451 | * @param User $user User that delete |
||
| 452 | * @param int $idline Id of line to delete |
||
| 453 | * @param bool $notrigger false=launch triggers after, true=disable triggers |
||
| 454 | * @return int >0 if OK, <0 if KO |
||
| 455 | */ |
||
| 456 | public function deleteLine(User $user, $idline, $notrigger = false) |
||
| 466 | |||
| 467 | /** |
||
| 468 | * Return a link to the object card (with optionaly the picto) |
||
| 469 | * |
||
| 470 | * @param int $withpicto Include picto in link (0=No picto, 1=Include picto into link, 2=Only picto) |
||
| 471 | * @param string $option On what the link point to ('nolink', ...) |
||
| 472 | * @param int $notooltip 1=Disable tooltip |
||
| 473 | * @param string $morecss Add more css on link |
||
| 474 | * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking |
||
| 475 | * @return string String with URL |
||
| 476 | */ |
||
| 477 | public function getNomUrl($withpicto = 0, $option = '', $notooltip = 0, $morecss = '', $save_lastsearch_value = -1) |
||
| 538 | |||
| 539 | /** |
||
| 540 | * Return label of the status |
||
| 541 | * |
||
| 542 | * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto |
||
| 543 | * @return string Label of status |
||
| 544 | */ |
||
| 545 | public function getLibStatut($mode = 0) |
||
| 549 | |||
| 550 | // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps |
||
| 551 | /** |
||
| 552 | * Return the status |
||
| 553 | * |
||
| 554 | * @param int $status Id status |
||
| 555 | * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto, 6=Long label + Picto |
||
| 556 | * @return string Label of status |
||
| 557 | */ |
||
| 558 | public function LibStatut($status, $mode = 0) |
||
| 599 | |||
| 600 | /** |
||
| 601 | * Load the info information in the object |
||
| 602 | * |
||
| 603 | * @param int $id Id of object |
||
| 604 | * @return void |
||
| 605 | */ |
||
| 606 | public function info($id) |
||
| 652 | |||
| 653 | /** |
||
| 654 | * Initialise object with example values |
||
| 655 | * Id must be 0 if object instance is a specimen |
||
| 656 | * |
||
| 657 | * @return void |
||
| 658 | */ |
||
| 659 | public function initAsSpecimen() |
||
| 663 | |||
| 664 | /** |
||
| 665 | * Create an array of lines |
||
| 666 | * |
||
| 667 | * @return array|int array of lines if OK, <0 if KO |
||
| 668 | */ |
||
| 669 | public function getLinesArray() |
||
| 688 | |||
| 689 | /** |
||
| 690 | * Create a document onto disk according to template module. |
||
| 691 | * |
||
| 692 | * @param string $modele Force template to use ('' to not force) |
||
| 693 | * @param Translate $outputlangs objet lang a utiliser pour traduction |
||
| 694 | * @param int $hidedetails Hide details of lines |
||
| 695 | * @param int $hidedesc Hide description |
||
| 696 | * @param int $hideref Hide ref |
||
| 697 | * @param null|array $moreparams Array to provide more information |
||
| 698 | * @return int 0 if KO, 1 if OK |
||
| 699 | */ |
||
| 700 | public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null) |
||
| 721 | |||
| 722 | /** |
||
| 723 | * Action executed by scheduler |
||
| 724 | * CAN BE A CRON TASK. In such a case, parameters come from the schedule job setup field 'Parameters' |
||
| 725 | * |
||
| 726 | * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) |
||
| 727 | */ |
||
| 728 | //public function doScheduledJob($param1, $param2, ...) |
||
| 729 | public function doScheduledJob() |
||
| 751 | } |
||
| 752 | |||
| 760 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.