Complex classes like FieldWrapper 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 FieldWrapper, and based on these observations, apply Extract Interface, too.
1 | <?php namespace Mascame\Artificer\Fields; |
||
7 | class FieldWrapper |
||
8 | { |
||
9 | use Filterable; |
||
10 | |||
11 | protected $widgets = []; |
||
12 | |||
13 | /** |
||
14 | * Sometimes ajax limits output, setting this to true will return all |
||
15 | * |
||
16 | * @var bool |
||
17 | */ |
||
18 | public $showFullField = false; |
||
19 | |||
20 | /** |
||
21 | * @var bool |
||
22 | */ |
||
23 | protected $withWidgets = false; |
||
24 | |||
25 | /** |
||
26 | * @var FieldInterface|TypeInterface |
||
27 | */ |
||
28 | public $field; |
||
29 | |||
30 | /** |
||
31 | * Field constructor. |
||
32 | * @param FieldInterface|TypeInterface $field |
||
33 | * @param null $relation |
||
|
|||
34 | */ |
||
35 | public function __construct(FieldInterface $field) |
||
41 | |||
42 | /** |
||
43 | * Only get widgets that are installed |
||
44 | * |
||
45 | * @return array |
||
46 | */ |
||
47 | protected function getInstalledWidgets() |
||
61 | |||
62 | /** |
||
63 | * @param null $value |
||
64 | * @return null |
||
65 | */ |
||
66 | public function show($value = null) |
||
78 | |||
79 | /** |
||
80 | * @return bool|mixed|null|string |
||
81 | */ |
||
82 | public function output() |
||
94 | |||
95 | public function protectGuarded() { |
||
104 | |||
105 | public function withWidgets() { |
||
110 | |||
111 | protected function applyWidgets() { |
||
123 | |||
124 | /** |
||
125 | * @param $array |
||
126 | * @return bool |
||
127 | */ |
||
128 | protected function isAll($array) |
||
132 | |||
133 | /** |
||
134 | * @param string $visibility [visible|hidden] |
||
135 | * @return bool |
||
136 | */ |
||
137 | protected function isListedAs($visibility, $action = null) |
||
151 | |||
152 | /** |
||
153 | * Hidden fields have preference. |
||
154 | * |
||
155 | * @return bool |
||
156 | */ |
||
157 | public function isVisible() |
||
163 | |||
164 | /** |
||
165 | * @param $value |
||
166 | * @param $array |
||
167 | * @return bool |
||
168 | */ |
||
169 | public function isInArray($value, $array) |
||
173 | |||
174 | /** |
||
175 | * @return bool |
||
176 | */ |
||
177 | public function isHidden() |
||
181 | |||
182 | public static function get($name) |
||
186 | |||
187 | public function __get($name) { |
||
188 | $accessor = 'get' . studly_case($name); |
||
189 | |||
190 | return $this->useFieldMethod($accessor); |
||
191 | } |
||
192 | |||
193 | protected function useFieldMethod($method, $args = []) { |
||
194 | if (! method_exists($this->field, $method)) { |
||
195 | return null; |
||
196 | } |
||
197 | |||
198 | return (empty($args)) ? $this->field->$method() : $this->field->$method($args); |
||
199 | } |
||
200 | |||
201 | public function __call($method, $args) { |
||
202 | return $this->useFieldMethod($method, $args); |
||
203 | } |
||
204 | |||
205 | public function isFillable() { |
||
210 | |||
211 | /** |
||
212 | * @param array|string $classes |
||
213 | */ |
||
214 | protected function mergeClassAttribute($class) { |
||
222 | |||
223 | /** |
||
224 | * @param string $attribute |
||
225 | * @param array|string $value |
||
226 | */ |
||
227 | public function addAttribute($attribute, $value) { |
||
234 | } |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italy
is not defined by the methodfinale(...)
.The most likely cause is that the parameter was removed, but the annotation was not.