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 Form 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 Form, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Anomaly\Streams\Platform\Ui\Form; |
||
28 | class Form implements PresentableInterface |
||
29 | { |
||
30 | |||
31 | /** |
||
32 | * The form model. |
||
33 | * |
||
34 | * @var null|mixed |
||
35 | */ |
||
36 | protected $model = null; |
||
37 | |||
38 | /** |
||
39 | * The form stream. |
||
40 | * |
||
41 | * @var null|StreamInterface |
||
42 | */ |
||
43 | protected $stream = null; |
||
44 | |||
45 | /** |
||
46 | * The form entry. |
||
47 | * |
||
48 | * @var mixed |
||
49 | */ |
||
50 | protected $entry = null; |
||
51 | |||
52 | /** |
||
53 | * The form content. |
||
54 | * |
||
55 | * @var null|string |
||
56 | */ |
||
57 | protected $content = null; |
||
58 | |||
59 | /** |
||
60 | * The form response. |
||
61 | * |
||
62 | * @var null|Response |
||
63 | */ |
||
64 | protected $response = null; |
||
65 | |||
66 | /** |
||
67 | * The form model. This is set |
||
68 | * to create / edit automatically. |
||
69 | * |
||
70 | * @var null|string |
||
71 | */ |
||
72 | protected $mode = null; |
||
73 | |||
74 | /** |
||
75 | * The form data. |
||
76 | * |
||
77 | * @var Collection |
||
78 | */ |
||
79 | protected $data; |
||
80 | |||
81 | /** |
||
82 | * The form errors. |
||
83 | * |
||
84 | * @var MessageBag |
||
85 | */ |
||
86 | protected $errors; |
||
87 | |||
88 | /** |
||
89 | * The form values. |
||
90 | * |
||
91 | * @var Collection |
||
92 | */ |
||
93 | protected $values; |
||
94 | |||
95 | /** |
||
96 | * The form fields. |
||
97 | * |
||
98 | * @var FieldCollection |
||
99 | */ |
||
100 | protected $fields; |
||
101 | |||
102 | /** |
||
103 | * The form options. |
||
104 | * |
||
105 | * @var Collection |
||
106 | */ |
||
107 | protected $options; |
||
108 | |||
109 | /** |
||
110 | * The form actions. |
||
111 | * |
||
112 | * @var ActionCollection |
||
113 | */ |
||
114 | protected $actions; |
||
115 | |||
116 | /** |
||
117 | * The form buttons. |
||
118 | * |
||
119 | * @var ButtonCollection |
||
120 | */ |
||
121 | protected $buttons; |
||
122 | |||
123 | /** |
||
124 | * The form sections. |
||
125 | * |
||
126 | * @var SectionCollection |
||
127 | */ |
||
128 | protected $sections; |
||
129 | |||
130 | /** |
||
131 | * Create a new Form instance. |
||
132 | * |
||
133 | * @param Collection $data |
||
134 | * @param Collection $values |
||
135 | * @param Collection $options |
||
136 | * @param MessageBag $errors |
||
137 | * @param FieldCollection $fields |
||
138 | * @param ActionCollection $actions |
||
139 | * @param ButtonCollection $buttons |
||
140 | * @param SectionCollection $sections |
||
141 | */ |
||
142 | public function __construct( |
||
161 | |||
162 | /** |
||
163 | * Set the form response. |
||
164 | * |
||
165 | * @param null|false|Response $response |
||
166 | * @return $this |
||
167 | */ |
||
168 | public function setResponse(Response $response) |
||
174 | |||
175 | /** |
||
176 | * Get the form response. |
||
177 | * |
||
178 | * @return null|Response |
||
179 | */ |
||
180 | public function getResponse() |
||
184 | |||
185 | /** |
||
186 | * Get the errors. |
||
187 | * |
||
188 | * @return MessageBag |
||
189 | */ |
||
190 | public function getErrors() |
||
194 | |||
195 | /** |
||
196 | * Set the errors. |
||
197 | * |
||
198 | * @param MessageBag $errors |
||
199 | * @return $this |
||
200 | */ |
||
201 | public function setErrors(MessageBag $errors) |
||
207 | |||
208 | /** |
||
209 | * Return whether the form has errors or not. |
||
210 | * |
||
211 | * @return bool |
||
212 | */ |
||
213 | public function hasErrors() |
||
217 | |||
218 | /** |
||
219 | * Return whether a field has errors or not. |
||
220 | * |
||
221 | * @return bool |
||
222 | */ |
||
223 | public function hasError($fieldName) |
||
227 | |||
228 | /** |
||
229 | * Set the model object. |
||
230 | * |
||
231 | * @param $model |
||
232 | * @return $this |
||
233 | */ |
||
234 | public function setModel($model) |
||
240 | |||
241 | /** |
||
242 | * Get the model object. |
||
243 | * |
||
244 | * @return null|EloquentModel|EntryModel |
||
245 | */ |
||
246 | public function getModel() |
||
250 | |||
251 | /** |
||
252 | * Set the form stream. |
||
253 | * |
||
254 | * @param StreamInterface $stream |
||
255 | * @return $this |
||
256 | */ |
||
257 | public function setStream(StreamInterface $stream) |
||
263 | |||
264 | /** |
||
265 | * Get the form stream. |
||
266 | * |
||
267 | * @return null|StreamInterface |
||
268 | */ |
||
269 | public function getStream() |
||
273 | |||
274 | /** |
||
275 | * Set the entry. |
||
276 | * |
||
277 | * @param mixed $entry |
||
278 | * @return $this |
||
279 | */ |
||
280 | public function setEntry($entry) |
||
286 | |||
287 | /** |
||
288 | * Get the entry. |
||
289 | * |
||
290 | * @return EloquentModel|EntryInterface |
||
291 | */ |
||
292 | public function getEntry() |
||
296 | |||
297 | /** |
||
298 | * Set the form content. |
||
299 | * |
||
300 | * @param string $content |
||
301 | * @return $this |
||
302 | */ |
||
303 | public function setContent($content) |
||
309 | |||
310 | /** |
||
311 | * Get the form content. |
||
312 | * |
||
313 | * @return null|View |
||
314 | */ |
||
315 | public function getContent() |
||
319 | |||
320 | /** |
||
321 | * Add an action to the actions collection. |
||
322 | * |
||
323 | * @param ActionInterface $action |
||
324 | * @return $this |
||
325 | */ |
||
326 | public function addAction(ActionInterface $action) |
||
332 | |||
333 | /** |
||
334 | * Set the form actions. |
||
335 | * |
||
336 | * @param ActionCollection $actions |
||
337 | * @return $this |
||
338 | */ |
||
339 | public function setActions(ActionCollection $actions) |
||
345 | |||
346 | /** |
||
347 | * Get the form actions. |
||
348 | * |
||
349 | * @return ActionCollection |
||
350 | */ |
||
351 | public function getActions() |
||
355 | |||
356 | /** |
||
357 | * Add a button to the buttons collection. |
||
358 | * |
||
359 | * @param ButtonInterface $button |
||
360 | * @return $this |
||
361 | */ |
||
362 | public function addButton(ButtonInterface $button) |
||
368 | |||
369 | /** |
||
370 | * Set the form buttons. |
||
371 | * |
||
372 | * @param ButtonCollection $buttons |
||
373 | * @return $this |
||
374 | */ |
||
375 | public function setButtons(ButtonCollection $buttons) |
||
381 | |||
382 | /** |
||
383 | * Get the form buttons. |
||
384 | * |
||
385 | * @return ButtonCollection |
||
386 | */ |
||
387 | public function getButtons() |
||
391 | |||
392 | /** |
||
393 | * Set the options. |
||
394 | * |
||
395 | * @param Collection $options |
||
396 | * @return $this |
||
397 | */ |
||
398 | public function setOptions(Collection $options) |
||
404 | |||
405 | /** |
||
406 | * Get the options. |
||
407 | * |
||
408 | * @return Collection |
||
409 | */ |
||
410 | public function getOptions() |
||
414 | |||
415 | /** |
||
416 | * Set an option. |
||
417 | * |
||
418 | * @param $key |
||
419 | * @param $value |
||
420 | * @return $this |
||
421 | */ |
||
422 | public function setOption($key, $value) |
||
428 | |||
429 | /** |
||
430 | * Get an option value. |
||
431 | * |
||
432 | * @param $key |
||
433 | * @param null $default |
||
434 | * @return mixed |
||
435 | */ |
||
436 | public function getOption($key, $default = null) |
||
440 | |||
441 | /** |
||
442 | * Get the sections. |
||
443 | * |
||
444 | * @return SectionCollection |
||
445 | */ |
||
446 | public function getSections() |
||
450 | |||
451 | /** |
||
452 | * Set the sections. |
||
453 | * |
||
454 | * @param SectionCollection $sections |
||
455 | * @return $this |
||
456 | */ |
||
457 | public function setSections(SectionCollection $sections) |
||
463 | |||
464 | /** |
||
465 | * Add a section. |
||
466 | * |
||
467 | * @param $slug |
||
468 | * @param $section |
||
469 | * @return $this |
||
470 | */ |
||
471 | public function addSection($slug, $section) |
||
477 | |||
478 | /** |
||
479 | * Add a field to the collection of fields. |
||
480 | * |
||
481 | * @param FieldType $field |
||
482 | * @return $this |
||
483 | */ |
||
484 | public function addField(FieldType $field) |
||
490 | |||
491 | /** |
||
492 | * Remove a field. |
||
493 | * |
||
494 | * @param $field |
||
495 | * @return $this |
||
496 | */ |
||
497 | public function removeField($field) |
||
503 | |||
504 | /** |
||
505 | * Disable a field. |
||
506 | * |
||
507 | * @param $field |
||
508 | * @return $this |
||
509 | */ |
||
510 | public function disableField($field) |
||
518 | |||
519 | /** |
||
520 | * Set the form views. |
||
521 | * |
||
522 | * @param Collection $fields |
||
523 | * @return $this |
||
524 | */ |
||
525 | public function setFields(Collection $fields) |
||
531 | |||
532 | /** |
||
533 | * Get the form fields. |
||
534 | * |
||
535 | * @return FieldCollection |
||
536 | */ |
||
537 | public function getFields() |
||
541 | |||
542 | /** |
||
543 | * Get the enabled fields. |
||
544 | * |
||
545 | * @return FieldCollection |
||
546 | */ |
||
547 | public function getEnabledFields() |
||
551 | |||
552 | /** |
||
553 | * Get a form field. |
||
554 | * |
||
555 | * @param $field |
||
556 | * @return FieldType|mixed |
||
557 | */ |
||
558 | public function getField($field) |
||
562 | |||
563 | /** |
||
564 | * Set a field value. |
||
565 | * |
||
566 | * @param $field |
||
567 | * @param $value |
||
568 | * @return $this |
||
569 | */ |
||
570 | public function setFieldValue($field, $value) |
||
578 | |||
579 | /** |
||
580 | * Add data to the view data collection. |
||
581 | * |
||
582 | * @param $key |
||
583 | * @param $value |
||
584 | * @return $this |
||
585 | */ |
||
586 | public function addData($key, $value) |
||
592 | |||
593 | /** |
||
594 | * Set the form data. |
||
595 | * |
||
596 | * @param Collection $data |
||
597 | * @return $this |
||
598 | */ |
||
599 | public function setData(Collection $data) |
||
605 | |||
606 | /** |
||
607 | * Get the form data. |
||
608 | * |
||
609 | * @return Collection |
||
610 | */ |
||
611 | public function getData() |
||
615 | |||
616 | /** |
||
617 | * Set a value on the value collection. |
||
618 | * |
||
619 | * @param $key |
||
620 | * @param $value |
||
621 | */ |
||
622 | public function setValue($key, $value) |
||
626 | |||
627 | /** |
||
628 | * Get a value from the value collection. |
||
629 | * |
||
630 | * @param $key |
||
631 | * @param null $default |
||
632 | * @return mixed |
||
633 | */ |
||
634 | public function getValue($key, $default = null) |
||
638 | |||
639 | /** |
||
640 | * Set the form values. |
||
641 | * |
||
642 | * @param Collection $values |
||
643 | * @return $this |
||
644 | */ |
||
645 | public function setValues(Collection $values) |
||
651 | |||
652 | /** |
||
653 | * Get the form values. |
||
654 | * |
||
655 | * @return Collection |
||
656 | */ |
||
657 | public function getValues() |
||
661 | |||
662 | /** |
||
663 | * Get the mode. |
||
664 | * |
||
665 | * @return null|string |
||
666 | */ |
||
667 | public function getMode() |
||
671 | |||
672 | /** |
||
673 | * Set the mode. |
||
674 | * |
||
675 | * @param $mode |
||
676 | * @return $this |
||
677 | */ |
||
678 | public function setMode($mode) |
||
684 | |||
685 | /** |
||
686 | * Return whether the form is translatable or not. |
||
687 | * |
||
688 | * @return bool |
||
689 | */ |
||
690 | public function isTranslatable() |
||
696 | |||
697 | /** |
||
698 | * Reset field values. |
||
699 | */ |
||
700 | public function resetFields() |
||
709 | |||
710 | /** |
||
711 | * Return a created presenter. |
||
712 | * |
||
713 | * @return FormPresenter |
||
714 | */ |
||
715 | View Code Duplication | public function getPresenter() |
|
725 | } |
||
726 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.