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 FieldsBuilder 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 FieldsBuilder, and based on these observations, apply Extract Interface, too.
| 1 | <?php | ||
| 5 | class FieldsBuilder extends Builder | ||
| 6 | { | ||
| 7 | protected $config = []; | ||
| 8 | protected $fields = []; | ||
| 9 | protected $location = null; | ||
| 10 | protected $name; | ||
| 11 | |||
| 12 | public function __construct($name, $groupConfig = []) | ||
| 20 | |||
| 21 | public function setGroupConfig($key, $value) | ||
| 27 | |||
| 28 | public function getName() | ||
| 32 | |||
| 33 | /** | ||
| 34 | * Build the final config array. Build any other builders that may exist | ||
| 35 | * in the config. | ||
| 36 | * @return array final field config | ||
| 37 | */ | ||
| 38 | public function build() | ||
| 64 | |||
| 65 | private function buildFields($fields) | ||
| 79 | |||
| 80 | /** | ||
| 81 | * Replace field values with the field's respective key | ||
| 82 | * @param array $config | ||
| 83 | * @return array | ||
| 84 | */ | ||
| 85 | protected function transformConditionalConfig($config) | ||
| 102 | |||
| 103 | /** | ||
| 104 | * Add multiple fields either via an array or from another builder | ||
| 105 | * @param mixed $fields array of fields or a FieldBuilder | ||
| 106 | */ | ||
| 107 | public function addFields($fields) | ||
| 122 | |||
| 123 | public function addField($name, $args = []) | ||
| 135 | |||
| 136 | protected function addFieldType($name, $type, $args = []) | ||
| 142 | |||
| 143 | public function addText($name, $args = []) | ||
| 147 | |||
| 148 | public function addTextarea($name, $args = []) | ||
| 152 | |||
| 153 | public function addNumber($name, $args = []) | ||
| 157 | |||
| 158 | public function addEmail($name, $args = []) | ||
| 162 | |||
| 163 | public function addUrl($name, $args = []) | ||
| 167 | |||
| 168 | public function addPassword($name, $args = []) | ||
| 172 | |||
| 173 | public function addWysiwyg($name, $args = []) | ||
| 177 | |||
| 178 | public function addOembed($name, $args = []) | ||
| 182 | |||
| 183 | public function addImage($name, $args = []) | ||
| 187 | |||
| 188 | public function addFile($name, $args = []) | ||
| 192 | |||
| 193 | public function addGallery($name, $args = []) | ||
| 197 | |||
| 198 | public function addTrueFalse($name, $args = []) | ||
| 202 | |||
| 203 | public function addSelect($name, $args = []) | ||
| 207 | |||
| 208 | public function addRadio($name, $args = []) | ||
| 212 | |||
| 213 | public function addCheckbox($name, $args = []) | ||
| 217 | |||
| 218 | public function addPostObject($name, $args = []) | ||
| 222 | |||
| 223 | public function addPostLink($name, $args = []) | ||
| 227 | |||
| 228 | public function addRelationship($name, $args = []) | ||
| 232 | |||
| 233 | public function addTaxonomy($name, $args = []) | ||
| 237 | |||
| 238 | public function addUser($name, $args = []) | ||
| 242 | |||
| 243 | public function addDatePicker($name, $args = []) | ||
| 247 | |||
| 248 | public function addTimePicker($name, $args = []) | ||
| 252 | |||
| 253 | public function addDateTimePicker($name, $args = []) | ||
| 257 | |||
| 258 | public function addColorPicker($name, $args = []) | ||
| 262 | |||
| 263 | View Code Duplication | public function addTab($label, $args = []) | |
| 272 | |||
| 273 | public function endpoint($value = 1) | ||
| 277 | |||
| 278 | View Code Duplication | public function addMessage($label, $message, $args = []) | |
| 288 | |||
| 289 | public function addRepeater($name, $args = []) | ||
| 297 | |||
| 298 | public function addFlexibleContent($name, $args = []) | ||
| 306 | |||
| 307 | public function addChoice($choice, $label = null) | ||
| 319 | |||
| 320 | public function addChoices() | ||
| 333 | |||
| 334 | public function conditional($name, $operator, $value) | ||
| 345 | |||
| 346 | public function getFields() | ||
| 350 | |||
| 351 | /** | ||
| 352 | * Return the index in the $this->fields array looked up by the field's name | ||
| 353 | * @param string $name Field Name | ||
| 354 | * | ||
| 355 | * @throws FieldNotFoundException if the field name doesn't exist | ||
| 356 | * | ||
| 357 | * @return integer Field Index | ||
| 358 | */ | ||
| 359 | protected function getFieldIndexByName($name) | ||
| 369 | |||
| 370 | protected function getFieldByName($name) | ||
| 374 | |||
| 375 | /** | ||
| 376 | * Modify an already defined field | ||
| 377 | * @param string $name Name of the field | ||
| 378 | * @param mixed $modify Array of field configs or a closure that accepts | ||
| 379 | * a FieldsBuilder and returns a FieldsBuilder. | ||
| 380 | * | ||
| 381 | * @throws ModifyFieldReturnTypeException if $modify is a closure and doesn't | ||
| 382 | * return a FieldsBuilder. | ||
| 383 | * | ||
| 384 | * @return FieldsBuilder $this | ||
| 385 | */ | ||
| 386 | public function modifyField($name, $modify) | ||
| 414 | |||
| 415 | /** | ||
| 416 | * Remove a field by name | ||
| 417 | * @param string $name Field to remove | ||
| 418 | * | ||
| 419 | * @return FieldsBuilder $this | ||
| 420 | */ | ||
| 421 | public function removeField($name) | ||
| 428 | |||
| 429 | public function defaultValue($value) | ||
| 433 | |||
| 434 | public function required($value = true) | ||
| 438 | |||
| 439 | public function instructions($value) | ||
| 443 | |||
| 444 | public function setConfig($key, $value) | ||
| 452 | |||
| 453 | public function setLocation($param, $operator, $value) | ||
| 464 | |||
| 465 | public function getLocation() | ||
| 469 | |||
| 470 | protected function popLastField() | ||
| 474 | |||
| 475 | protected function pushField($field) | ||
| 479 | |||
| 480 | protected function generateLabel($name) | ||
| 484 | |||
| 485 | protected function generateName($name) | ||
| 489 | } | ||
| 490 |