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