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 |