Complex classes like Validator 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 Validator, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
22 | class Validator |
||
23 | { |
||
24 | /** |
||
25 | * @var HtmlDomParser |
||
26 | */ |
||
27 | private $formDocument; |
||
28 | |||
29 | /** |
||
30 | * @var string[][] |
||
31 | */ |
||
32 | private $rules = []; |
||
33 | |||
34 | /** |
||
35 | * @var string[][] |
||
36 | */ |
||
37 | private $required_rules = []; |
||
38 | |||
39 | /** |
||
40 | * @var string[][] |
||
41 | */ |
||
42 | private $filters = []; |
||
43 | |||
44 | /** |
||
45 | * @var callable[] |
||
46 | */ |
||
47 | private $filters_custom = []; |
||
48 | |||
49 | /** |
||
50 | * @var callable|null |
||
51 | */ |
||
52 | private $translator; |
||
53 | |||
54 | /** |
||
55 | * @var ValidatorRulesManager |
||
56 | */ |
||
57 | private $validatorRulesManager; |
||
58 | |||
59 | /** |
||
60 | * @var string |
||
61 | */ |
||
62 | private $selector; |
||
63 | |||
64 | /** |
||
65 | * @param string $formHTML |
||
66 | * @param string $selector |
||
67 | */ |
||
68 | 18 | public function __construct($formHTML, $selector = '') |
|
77 | |||
78 | /** |
||
79 | * @param string $name <p>A name for the "data-filter"-attribute in the dom.</p> |
||
80 | * @param callable $filter <p>A custom filter.</p> |
||
81 | */ |
||
82 | 1 | public function addCustomFilter(string $name, callable $filter) |
|
86 | |||
87 | /** |
||
88 | * @param string $name <p>A name for the "data-validator"-attribute in the dom.</p> |
||
89 | * @param string|AbstractRule $validator <p>A custom validation class.</p> |
||
90 | */ |
||
91 | 2 | public function addCustomRule(string $name, $validator) |
|
95 | |||
96 | /** |
||
97 | * @param mixed $currentFieldData |
||
98 | * @param string $fieldFilter |
||
99 | * |
||
100 | * @throws UnknownFilter |
||
101 | * |
||
102 | * @return mixed|string|null |
||
103 | */ |
||
104 | 5 | private function applyFilter($currentFieldData, string $fieldFilter) |
|
105 | { |
||
106 | 5 | if ($currentFieldData === null) { |
|
107 | 1 | return null; |
|
108 | } |
||
109 | |||
110 | 5 | if (isset($this->filters_custom[$fieldFilter])) { |
|
111 | 1 | return \call_user_func($this->filters_custom[$fieldFilter], $currentFieldData); |
|
112 | } |
||
113 | |||
114 | switch ($fieldFilter) { |
||
115 | 4 | case 'trim': |
|
116 | 4 | return \trim($currentFieldData); |
|
117 | 4 | case 'escape': |
|
118 | 4 | return \htmlentities($currentFieldData, ENT_QUOTES | ENT_HTML5, 'UTF-8'); |
|
119 | } |
||
120 | |||
121 | 4 | if (method_exists(UTF8::class, $fieldFilter)) { |
|
122 | 4 | $currentFieldData = \call_user_func([UTF8::class, $fieldFilter], $currentFieldData); |
|
123 | } else { |
||
124 | throw new UnknownFilter( |
||
125 | 'No filter available for "' . $fieldFilter . '"' |
||
126 | ); |
||
127 | } |
||
128 | |||
129 | 4 | return $currentFieldData; |
|
130 | } |
||
131 | |||
132 | /** |
||
133 | * @param string $type |
||
134 | * |
||
135 | * @return string|null |
||
136 | */ |
||
137 | 3 | public function autoSelectRuleByInputType(string $type) |
|
152 | |||
153 | /** |
||
154 | * Get the filters that will be applied. |
||
155 | * |
||
156 | * @return string[][] |
||
157 | */ |
||
158 | 1 | public function getAllFilters(): array |
|
162 | |||
163 | /** |
||
164 | * Get the rules that will be applied. |
||
165 | * |
||
166 | * @return string[][] |
||
167 | */ |
||
168 | 11 | public function getAllRules(): array |
|
172 | |||
173 | /** |
||
174 | * @param array $formValues |
||
175 | * @param string $field |
||
176 | * |
||
177 | * @return mixed|null |
||
178 | */ |
||
179 | 14 | private function getCurrentFieldValue(array $formValues, string $field) |
|
233 | |||
234 | /** |
||
235 | * @return string |
||
236 | */ |
||
237 | 3 | public function getHtml(): string |
|
241 | |||
242 | /** |
||
243 | * Get the required rules that will be applied. |
||
244 | * |
||
245 | * @return string[][] |
||
246 | */ |
||
247 | public function getRequiredRules(): array |
||
251 | |||
252 | /** |
||
253 | * @return callable|null |
||
254 | */ |
||
255 | 13 | public function getTranslator() |
|
259 | |||
260 | /** |
||
261 | * Find the first form on page or via css-selector, and parse <input>-elements. |
||
262 | * |
||
263 | * @return bool |
||
264 | */ |
||
265 | 18 | public function parseHtmlDomForRules(): bool |
|
311 | |||
312 | /** |
||
313 | * Determine if element has filter attributes, and save the given filter. |
||
314 | * |
||
315 | * @param SimpleHtmlDom $inputField |
||
316 | * @param string $formHelperId |
||
317 | */ |
||
318 | 17 | private function parseInputForFilter(SimpleHtmlDom $inputField, string $formHelperId) |
|
333 | |||
334 | |||
335 | /** |
||
336 | * Determine if element has validator attributes, and save the given rule. |
||
337 | * |
||
338 | * @param SimpleHtmlDom $inputField |
||
339 | * @param string $formHelperId |
||
340 | */ |
||
341 | 17 | private function parseInputForRules(SimpleHtmlDom $inputField, string $formHelperId) |
|
366 | |||
367 | /** |
||
368 | * @param callable $translator |
||
369 | * |
||
370 | * @return Validator |
||
371 | */ |
||
372 | 1 | public function setTranslator(callable $translator): Validator |
|
378 | |||
379 | /** |
||
380 | * Loop the form data through form rules. |
||
381 | * |
||
382 | * @param array $formValues |
||
383 | * @param bool $useNoValidationRuleException |
||
384 | * |
||
385 | * @throws UnknownValidationRule |
||
386 | * |
||
387 | * @return ValidatorResult |
||
388 | */ |
||
389 | 16 | public function validate(array $formValues, $useNoValidationRuleException = false): ValidatorResult |
|
534 | |||
535 | } |
||
536 |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.