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 Field 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 Field, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
16 | class Field implements Renderable |
||
17 | { |
||
18 | use Macroable; |
||
19 | |||
20 | const FILE_DELETE_FLAG = '_file_del_'; |
||
21 | |||
22 | /** |
||
23 | * Element id. |
||
24 | * |
||
25 | * @var array|string |
||
26 | */ |
||
27 | protected $id; |
||
28 | |||
29 | /** |
||
30 | * Element value. |
||
31 | * |
||
32 | * @var mixed |
||
33 | */ |
||
34 | protected $value; |
||
35 | |||
36 | /** |
||
37 | * Field original value. |
||
38 | * |
||
39 | * @var mixed |
||
40 | */ |
||
41 | protected $original; |
||
42 | |||
43 | /** |
||
44 | * Field default value. |
||
45 | * |
||
46 | * @var mixed |
||
47 | */ |
||
48 | protected $default; |
||
49 | |||
50 | /** |
||
51 | * Element label. |
||
52 | * |
||
53 | * @var string |
||
54 | */ |
||
55 | protected $label = ''; |
||
56 | |||
57 | /** |
||
58 | * Column name. |
||
59 | * |
||
60 | * @var string|array |
||
61 | */ |
||
62 | protected $column = ''; |
||
63 | |||
64 | /** |
||
65 | * Form element name. |
||
66 | * |
||
67 | * @var string |
||
68 | */ |
||
69 | protected $elementName = []; |
||
70 | |||
71 | /** |
||
72 | * Form element classes. |
||
73 | * |
||
74 | * @var array |
||
75 | */ |
||
76 | protected $elementClass = []; |
||
77 | |||
78 | /** |
||
79 | * Variables of elements. |
||
80 | * |
||
81 | * @var array |
||
82 | */ |
||
83 | protected $variables = []; |
||
84 | |||
85 | /** |
||
86 | * Options for specify elements. |
||
87 | * |
||
88 | * @var array |
||
89 | */ |
||
90 | protected $options = []; |
||
91 | |||
92 | /** |
||
93 | * Validation rules. |
||
94 | * |
||
95 | * @var string|\Closure |
||
96 | */ |
||
97 | protected $rules = ''; |
||
98 | |||
99 | /** |
||
100 | * @var callable |
||
101 | */ |
||
102 | protected $validator; |
||
103 | |||
104 | /** |
||
105 | * Validation messages. |
||
106 | * |
||
107 | * @var array |
||
108 | */ |
||
109 | protected $validationMessages = []; |
||
110 | |||
111 | /** |
||
112 | * Css required by this field. |
||
113 | * |
||
114 | * @var array |
||
115 | */ |
||
116 | protected static $css = []; |
||
117 | |||
118 | /** |
||
119 | * Js required by this field. |
||
120 | * |
||
121 | * @var array |
||
122 | */ |
||
123 | protected static $js = []; |
||
124 | |||
125 | /** |
||
126 | * Script for field. |
||
127 | * |
||
128 | * @var string |
||
129 | */ |
||
130 | protected $script = ''; |
||
131 | |||
132 | /** |
||
133 | * Element attributes. |
||
134 | * |
||
135 | * @var array |
||
136 | */ |
||
137 | protected $attributes = []; |
||
138 | |||
139 | /** |
||
140 | * Parent form. |
||
141 | * |
||
142 | * @var Form |
||
143 | */ |
||
144 | protected $form = null; |
||
145 | |||
146 | /** |
||
147 | * View for field to render. |
||
148 | * |
||
149 | * @var string |
||
150 | */ |
||
151 | protected $view = ''; |
||
152 | |||
153 | /** |
||
154 | * Help block. |
||
155 | * |
||
156 | * @var array |
||
157 | */ |
||
158 | protected $help = []; |
||
159 | |||
160 | /** |
||
161 | * Key for errors. |
||
162 | * |
||
163 | * @var mixed |
||
164 | */ |
||
165 | protected $errorKey; |
||
166 | |||
167 | /** |
||
168 | * Placeholder for this field. |
||
169 | * |
||
170 | * @var string|array |
||
171 | */ |
||
172 | protected $placeholder; |
||
173 | |||
174 | /** |
||
175 | * Width for label and field. |
||
176 | * |
||
177 | * @var array |
||
178 | */ |
||
179 | protected $width |
||
180 | = [ |
||
181 | 'label' => 2, |
||
182 | 'field' => 8, |
||
183 | ]; |
||
184 | |||
185 | /** |
||
186 | * If the form horizontal layout. |
||
187 | * |
||
188 | * @var bool |
||
189 | */ |
||
190 | protected $horizontal = true; |
||
191 | |||
192 | /** |
||
193 | * @var bool |
||
194 | */ |
||
195 | protected $display = true; |
||
196 | |||
197 | /** |
||
198 | * @var array |
||
199 | */ |
||
200 | protected $labelClass = []; |
||
201 | |||
202 | /** |
||
203 | * Field constructor. |
||
204 | * |
||
205 | * @param $column |
||
206 | * @param array $arguments |
||
207 | */ |
||
208 | public function __construct($column, $arguments = []) |
||
214 | |||
215 | /** |
||
216 | * Get assets required by this field. |
||
217 | * |
||
218 | * @return array |
||
219 | */ |
||
220 | public static function getAssets() |
||
227 | |||
228 | /** |
||
229 | * Format the field element id. |
||
230 | * |
||
231 | * @param string|array $column |
||
232 | * |
||
233 | * @return string|array |
||
234 | */ |
||
235 | protected function formatId($column) |
||
239 | |||
240 | /** |
||
241 | * Format the label value. |
||
242 | * |
||
243 | * @param array $arguments |
||
244 | * |
||
245 | * @return string |
||
246 | */ |
||
247 | protected function formatLabel($arguments = []) |
||
255 | |||
256 | /** |
||
257 | * Format the name of the field. |
||
258 | * |
||
259 | * @param string $column |
||
260 | * |
||
261 | * @return array|mixed|string |
||
262 | */ |
||
263 | protected function formatName($column) |
||
291 | |||
292 | /** |
||
293 | * Set form element name. |
||
294 | * |
||
295 | * @param string $name |
||
296 | * |
||
297 | * @return $this |
||
298 | * |
||
299 | * @author Edwin Hui |
||
300 | */ |
||
301 | public function setElementName($name) |
||
307 | |||
308 | /** |
||
309 | * Fill data to the field. |
||
310 | * |
||
311 | * @param array $data |
||
312 | * |
||
313 | * @return void |
||
314 | */ |
||
315 | View Code Duplication | public function fill($data) |
|
332 | |||
333 | /** |
||
334 | * Set original value to the field. |
||
335 | * |
||
336 | * @param array $data |
||
337 | * |
||
338 | * @return void |
||
339 | */ |
||
340 | View Code Duplication | public function setOriginal($data) |
|
352 | |||
353 | /** |
||
354 | * @param Form $form |
||
355 | * |
||
356 | * @return $this |
||
357 | */ |
||
358 | public function setForm(Form $form = null) |
||
364 | |||
365 | /** |
||
366 | * Set width for field and label. |
||
367 | * |
||
368 | * @param int $field |
||
369 | * @param int $label |
||
370 | * |
||
371 | * @return $this |
||
372 | */ |
||
373 | public function setWidth($field = 8, $label = 2) |
||
382 | |||
383 | /** |
||
384 | * Set the field options. |
||
385 | * |
||
386 | * @param array $options |
||
387 | * |
||
388 | * @return $this |
||
389 | */ |
||
390 | View Code Duplication | public function options($options = []) |
|
400 | |||
401 | /** |
||
402 | * Get or set rules. |
||
403 | * |
||
404 | * @param null $rules |
||
405 | * @param array $messages |
||
406 | * |
||
407 | * @return $this |
||
408 | */ |
||
409 | public function rules($rules = null, $messages = []) |
||
429 | |||
430 | /** |
||
431 | * Get field validation rules. |
||
432 | * |
||
433 | * @return string |
||
434 | */ |
||
435 | protected function getRules() |
||
443 | |||
444 | /** |
||
445 | * Remove a specific rule. |
||
446 | * |
||
447 | * @param string $rule |
||
448 | * |
||
449 | * @return void |
||
450 | */ |
||
451 | protected function removeRule($rule) |
||
455 | |||
456 | /** |
||
457 | * Set field validator. |
||
458 | * |
||
459 | * @param callable $validator |
||
460 | * |
||
461 | * @return $this |
||
462 | */ |
||
463 | public function validator(callable $validator) |
||
469 | |||
470 | /** |
||
471 | * Get key for error message. |
||
472 | * |
||
473 | * @return string |
||
474 | */ |
||
475 | public function getErrorKey() |
||
479 | |||
480 | /** |
||
481 | * Set key for error message. |
||
482 | * |
||
483 | * @param string $key |
||
484 | * |
||
485 | * @return $this |
||
486 | */ |
||
487 | public function setErrorKey($key) |
||
493 | |||
494 | /** |
||
495 | * Set or get value of the field. |
||
496 | * |
||
497 | * @param null $value |
||
498 | * |
||
499 | * @return mixed |
||
500 | */ |
||
501 | View Code Duplication | public function value($value = null) |
|
511 | |||
512 | /** |
||
513 | * Set default value for field. |
||
514 | * |
||
515 | * @param $default |
||
516 | * |
||
517 | * @return $this |
||
518 | */ |
||
519 | public function default($default) |
||
525 | |||
526 | /** |
||
527 | * Get default value. |
||
528 | * |
||
529 | * @return mixed |
||
530 | */ |
||
531 | public function getDefault() |
||
539 | |||
540 | /** |
||
541 | * Set help block for current field. |
||
542 | * |
||
543 | * @param string $text |
||
544 | * @param string $icon |
||
545 | * |
||
546 | * @return $this |
||
547 | */ |
||
548 | public function help($text = '', $icon = 'fa-info-circle') |
||
554 | |||
555 | /** |
||
556 | * Get column of the field. |
||
557 | * |
||
558 | * @return string|array |
||
559 | */ |
||
560 | public function column() |
||
564 | |||
565 | /** |
||
566 | * Get label of the field. |
||
567 | * |
||
568 | * @return string |
||
569 | */ |
||
570 | public function label() |
||
574 | |||
575 | /** |
||
576 | * Get original value of the field. |
||
577 | * |
||
578 | * @return mixed |
||
579 | */ |
||
580 | public function original() |
||
584 | |||
585 | /** |
||
586 | * Get validator for this field. |
||
587 | * |
||
588 | * @param array $input |
||
589 | * |
||
590 | * @return bool|Validator |
||
591 | */ |
||
592 | public function getValidator(array $input) |
||
628 | |||
629 | /** |
||
630 | * Sanitize input data. |
||
631 | * |
||
632 | * @param array $input |
||
633 | * @param string $column |
||
634 | * |
||
635 | * @return array |
||
636 | */ |
||
637 | protected function sanitizeInput($input, $column) |
||
646 | |||
647 | /** |
||
648 | * Add html attributes to elements. |
||
649 | * |
||
650 | * @param array|string $attribute |
||
651 | * @param mixed $value |
||
652 | * |
||
653 | * @return $this |
||
654 | */ |
||
655 | public function attribute($attribute, $value = null) |
||
665 | |||
666 | /** |
||
667 | * Set the field as readonly mode. |
||
668 | * |
||
669 | * @return Field |
||
670 | */ |
||
671 | public function readOnly() |
||
675 | |||
676 | /** |
||
677 | * Set field placeholder. |
||
678 | * |
||
679 | * @param string $placeholder |
||
680 | * |
||
681 | * @return Field |
||
682 | */ |
||
683 | public function placeholder($placeholder = '') |
||
689 | |||
690 | /** |
||
691 | * Get placeholder. |
||
692 | * |
||
693 | * @return string |
||
694 | */ |
||
695 | public function getPlaceholder() |
||
699 | |||
700 | /** |
||
701 | * Prepare for a field value before update or insert. |
||
702 | * |
||
703 | * @param $value |
||
704 | * |
||
705 | * @return mixed |
||
706 | */ |
||
707 | public function prepare($value) |
||
711 | |||
712 | /** |
||
713 | * Format the field attributes. |
||
714 | * |
||
715 | * @return string |
||
716 | */ |
||
717 | protected function formatAttributes() |
||
727 | |||
728 | /** |
||
729 | * @return $this |
||
730 | */ |
||
731 | public function disableHorizontal() |
||
737 | |||
738 | /** |
||
739 | * @return array |
||
740 | */ |
||
741 | public function getViewElementClasses() |
||
753 | |||
754 | /** |
||
755 | * Set form element class. |
||
756 | * |
||
757 | * @param string|array $class |
||
758 | * |
||
759 | * @return $this |
||
760 | */ |
||
761 | public function setElementClass($class) |
||
767 | |||
768 | /** |
||
769 | * Get element class. |
||
770 | * |
||
771 | * @return array |
||
772 | */ |
||
773 | protected function getElementClass() |
||
783 | |||
784 | /** |
||
785 | * Get element class string. |
||
786 | * |
||
787 | * @return mixed |
||
788 | */ |
||
789 | View Code Duplication | protected function getElementClassString() |
|
805 | |||
806 | /** |
||
807 | * Get element class selector. |
||
808 | * |
||
809 | * @return string |
||
810 | */ |
||
811 | View Code Duplication | protected function getElementClassSelector() |
|
827 | |||
828 | /** |
||
829 | * Add the element class. |
||
830 | * |
||
831 | * @param $class |
||
832 | * |
||
833 | * @return $this |
||
834 | */ |
||
835 | public function addElementClass($class) |
||
847 | |||
848 | /** |
||
849 | * Remove element class. |
||
850 | * |
||
851 | * @param $class |
||
852 | * |
||
853 | * @return $this |
||
854 | */ |
||
855 | public function removeElementClass($class) |
||
871 | |||
872 | /** |
||
873 | * Add variables to field view. |
||
874 | * |
||
875 | * @param array $variables |
||
876 | * |
||
877 | * @return $this |
||
878 | */ |
||
879 | protected function addVariables(array $variables = []) |
||
885 | |||
886 | /** |
||
887 | * @return string |
||
888 | */ |
||
889 | public function getLabelClass() |
||
894 | |||
895 | /** |
||
896 | * @param array $labelClass |
||
897 | * |
||
898 | * @return self |
||
899 | */ |
||
900 | public function setLabelClass(array $labelClass) |
||
907 | |||
908 | /** |
||
909 | * Get the view variables of this field. |
||
910 | * |
||
911 | * @return array |
||
912 | */ |
||
913 | protected function variables() |
||
929 | |||
930 | /** |
||
931 | * Get view of this field. |
||
932 | * |
||
933 | * @return string |
||
934 | */ |
||
935 | public function getView() |
||
945 | |||
946 | /** |
||
947 | * Get script of current field. |
||
948 | * |
||
949 | * @return string |
||
950 | */ |
||
951 | public function getScript() |
||
955 | |||
956 | /** |
||
957 | * Render this filed. |
||
958 | * |
||
959 | * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View |
||
960 | */ |
||
961 | public function render() |
||
971 | |||
972 | /** |
||
973 | * @return string |
||
974 | */ |
||
975 | public function __toString() |
||
979 | } |
||
980 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.