1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace voku\HtmlFormValidator; |
6
|
|
|
|
7
|
|
|
use Respect\Validation\Exceptions\ComponentException; |
8
|
|
|
use Respect\Validation\Exceptions\NestedValidationException; |
9
|
|
|
use Respect\Validation\Exceptions\ValidationException; |
10
|
|
|
use Respect\Validation\Factory; |
11
|
|
|
use Respect\Validation\Rules\AbstractRule; |
12
|
|
|
use Respect\Validation\Rules\Email; |
13
|
|
|
use Respect\Validation\Rules\HexRgbColor; |
14
|
|
|
use Respect\Validation\Rules\Url; |
15
|
|
|
use voku\helper\HtmlDomParser; |
16
|
|
|
use voku\helper\SimpleHtmlDom; |
17
|
|
|
use voku\helper\UTF8; |
18
|
|
|
use voku\HtmlFormValidator\Exceptions\NoValidationRule; |
19
|
|
|
use voku\HtmlFormValidator\Exceptions\UnknownFilter; |
20
|
|
|
use voku\HtmlFormValidator\Exceptions\UnknownValidationRule; |
21
|
|
|
|
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
|
19 |
|
public function __construct($formHTML, $selector = '') |
69
|
|
|
{ |
70
|
19 |
|
$this->validatorRulesManager = new ValidatorRulesManager(); |
71
|
|
|
|
72
|
19 |
|
$this->formDocument = HtmlDomParser::str_get_html($formHTML); |
|
|
|
|
73
|
19 |
|
$this->selector = $selector; |
74
|
|
|
|
75
|
19 |
|
$this->parseHtmlDomForRules(); |
76
|
19 |
|
} |
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) |
83
|
|
|
{ |
84
|
1 |
|
$this->filters_custom[$name] = $filter; |
85
|
1 |
|
} |
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
|
3 |
|
public function addCustomRule(string $name, $validator) |
92
|
|
|
{ |
93
|
3 |
|
$this->validatorRulesManager->addCustomRule($name, $validator); |
94
|
3 |
|
} |
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
|
4 |
|
public function autoSelectRuleByInputType(string $type) |
138
|
|
|
{ |
139
|
|
|
$matchingArray = [ |
140
|
4 |
|
'email' => Email::class, |
141
|
|
|
'url' => Url::class, |
142
|
|
|
'color' => HexRgbColor::class, |
143
|
|
|
|
144
|
|
|
// |
145
|
|
|
// TODO@me -> take a look here |
146
|
|
|
// -> https://github.com/xtreamwayz/html-form-validator/blob/master/src/FormElement/Number.php |
147
|
|
|
// |
148
|
|
|
]; |
149
|
|
|
|
150
|
4 |
|
return $matchingArray[$type] ?? null; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Get the filters that will be applied. |
155
|
|
|
* |
156
|
|
|
* @return string[][] |
157
|
|
|
*/ |
158
|
1 |
|
public function getAllFilters(): array |
159
|
|
|
{ |
160
|
1 |
|
return $this->filters; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Get the rules that will be applied. |
165
|
|
|
* |
166
|
|
|
* @return string[][] |
167
|
|
|
*/ |
168
|
12 |
|
public function getAllRules(): array |
169
|
|
|
{ |
170
|
12 |
|
return $this->rules; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @param array $formValues |
175
|
|
|
* @param string $field |
176
|
|
|
* |
177
|
|
|
* @return mixed|null |
178
|
|
|
*/ |
179
|
15 |
|
private function getCurrentFieldValue(array $formValues, string $field) |
180
|
|
|
{ |
181
|
15 |
|
$fieldArrayPos = UTF8::strpos($field, '['); |
182
|
15 |
|
if ($fieldArrayPos !== false) { |
183
|
3 |
|
$fieldStart = UTF8::substr($field, 0, $fieldArrayPos); |
184
|
3 |
|
$fieldArray = UTF8::substr($field, $fieldArrayPos); |
185
|
3 |
|
$fieldHelperChar = ''; |
186
|
3 |
|
$fieldArrayTmp = preg_replace_callback( |
187
|
3 |
|
'/\[([^\]]+)\]/', |
188
|
3 |
|
function ($match) use ($fieldHelperChar) { |
189
|
3 |
|
return $match[1] . $fieldHelperChar; |
190
|
3 |
|
}, |
191
|
3 |
|
$fieldArray |
192
|
|
|
); |
193
|
3 |
|
$fieldArrayTmp = explode($fieldHelperChar, trim($fieldArrayTmp, $fieldHelperChar)); |
194
|
|
|
|
195
|
3 |
|
$i = 0; |
196
|
3 |
|
$fieldHelper = []; |
197
|
3 |
|
foreach ($fieldArrayTmp as $fieldArrayTmpInner) { |
198
|
3 |
|
$fieldHelper[$i] = $fieldArrayTmpInner; |
199
|
|
|
|
200
|
3 |
|
$i++; |
201
|
|
|
} |
202
|
|
|
|
203
|
3 |
|
$currentFieldValue = null; |
204
|
|
|
|
205
|
|
|
switch ($i) { |
206
|
3 |
|
case 4: |
207
|
|
|
if (isset($formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]][$fieldHelper[3]])) { |
208
|
|
|
$currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]][$fieldHelper[3]]; |
209
|
|
|
} |
210
|
|
|
break; |
211
|
3 |
|
case 3: |
212
|
|
|
if (isset($formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]])) { |
213
|
|
|
$currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]]; |
214
|
|
|
} |
215
|
|
|
break; |
216
|
3 |
|
case 2: |
217
|
1 |
|
if (isset($formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]])) { |
218
|
1 |
|
$currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]]; |
219
|
|
|
} |
220
|
1 |
|
break; |
221
|
2 |
|
case 1: |
222
|
2 |
|
if (isset($formValues[$fieldStart][$fieldHelper[0]])) { |
223
|
2 |
|
$currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]]; |
224
|
|
|
} |
225
|
3 |
|
break; |
226
|
|
|
} |
227
|
|
|
} else { |
228
|
12 |
|
$currentFieldValue = $formValues[$field] ?? null; |
229
|
|
|
} |
230
|
|
|
|
231
|
15 |
|
return $currentFieldValue; |
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* @return string |
236
|
|
|
*/ |
237
|
3 |
|
public function getHtml(): string |
238
|
|
|
{ |
239
|
3 |
|
return $this->formDocument->html(); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* Get the required rules that will be applied. |
244
|
|
|
* |
245
|
|
|
* @return string[][] |
246
|
|
|
*/ |
247
|
|
|
public function getRequiredRules(): array |
248
|
|
|
{ |
249
|
|
|
return $this->required_rules; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* @return callable|null |
254
|
|
|
*/ |
255
|
14 |
|
public function getTranslator() |
256
|
|
|
{ |
257
|
14 |
|
return $this->translator; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* Find the first form on page or via css-selector, and parse <input>-elements. |
262
|
|
|
* |
263
|
|
|
* @return bool |
264
|
|
|
*/ |
265
|
19 |
|
public function parseHtmlDomForRules(): bool |
266
|
|
|
{ |
267
|
|
|
// init |
268
|
19 |
|
$this->rules = []; |
269
|
19 |
|
$inputForm = []; |
270
|
|
|
|
271
|
19 |
|
if ($this->selector) { |
272
|
2 |
|
$forms = $this->formDocument->find($this->selector); |
273
|
|
|
} else { |
274
|
17 |
|
$forms = $this->formDocument->find('form'); |
275
|
|
|
} |
276
|
|
|
|
277
|
19 |
|
if (\count($forms) === 0) { |
278
|
1 |
|
return false; |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
// get the first form |
282
|
18 |
|
$form = $forms[0]; |
283
|
|
|
|
284
|
|
|
// get the from-id |
285
|
18 |
|
if ($form->id) { |
286
|
11 |
|
$formHelperId = $form->id; |
287
|
|
|
} else { |
288
|
7 |
|
$formHelperId = \uniqid('html-form-validator-tmp', true); |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
// get the <input>-elements from the form |
292
|
18 |
|
$inputFromFields = $form->getElementsByTagName('input'); |
293
|
18 |
|
foreach ($inputFromFields as $inputFormField) { |
294
|
18 |
|
$this->parseInputForRules($inputFormField, $formHelperId); |
295
|
18 |
|
$this->parseInputForFilter($inputFormField, $formHelperId); |
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
// get the <input>-elements with a matching form="id" |
299
|
18 |
|
if (\strpos($formHelperId, 'html-form-validator-tmp') !== 0) { |
300
|
11 |
|
$inputFromFieldsTmpAll = $this->formDocument->find('input'); |
301
|
11 |
|
foreach ($inputFromFieldsTmpAll as $inputFromFieldTmp) { |
|
|
|
|
302
|
11 |
|
if ($inputFromFieldTmp->form == $formHelperId) { |
303
|
1 |
|
$this->parseInputForRules($inputFromFieldTmp, $formHelperId); |
304
|
11 |
|
$this->parseInputForFilter($inputFromFieldTmp, $formHelperId); |
305
|
|
|
} |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
|
309
|
18 |
|
return (\count($inputForm) >= 0); |
310
|
|
|
} |
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
|
18 |
|
private function parseInputForFilter(SimpleHtmlDom $inputField, string $formHelperId) |
319
|
|
|
{ |
320
|
18 |
|
if (!$inputField->hasAttribute('data-filter')) { |
321
|
18 |
|
return; |
322
|
|
|
} |
323
|
|
|
|
324
|
6 |
|
$inputName = $inputField->getAttribute('name'); |
325
|
6 |
|
$inputFilter = $inputField->getAttribute('data-filter'); |
326
|
|
|
|
327
|
6 |
|
if (!$inputFilter) { |
328
|
1 |
|
$inputFilter = 'htmlentities'; |
329
|
|
|
} |
330
|
|
|
|
331
|
6 |
|
$this->filters[$formHelperId][$inputName] = $inputFilter; |
332
|
6 |
|
} |
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
|
18 |
|
private function parseInputForRules(SimpleHtmlDom $inputField, string $formHelperId) |
342
|
|
|
{ |
343
|
18 |
|
if (!$inputField->hasAttribute('data-validator')) { |
344
|
14 |
|
return; |
345
|
|
|
} |
346
|
|
|
|
347
|
17 |
|
$inputName = $inputField->getAttribute('name'); |
348
|
17 |
|
$inputPattern = $inputField->getAttribute('pattern'); |
349
|
17 |
|
$inputRule = $inputField->getAttribute('data-validator'); |
350
|
|
|
|
351
|
17 |
|
if (strpos($inputRule, 'auto') !== false) { |
352
|
4 |
|
$inputType = $inputField->getAttribute('type'); |
353
|
|
|
|
354
|
4 |
|
$inputRule = str_replace( |
355
|
4 |
|
'auto', |
356
|
4 |
|
$this->autoSelectRuleByInputType($inputType), |
357
|
4 |
|
$inputRule |
358
|
|
|
); |
359
|
|
|
} |
360
|
|
|
|
361
|
17 |
|
if ($inputPattern) { |
362
|
1 |
|
$inputRule .= '|regex(/' . $inputPattern . '/)'; |
363
|
|
|
} |
364
|
|
|
|
365
|
17 |
|
if ($inputField->hasAttribute('required')) { |
366
|
17 |
|
$this->required_rules[$formHelperId][$inputName] = $inputRule; |
367
|
|
|
} |
368
|
|
|
|
369
|
17 |
|
$this->rules[$formHelperId][$inputName] = $inputRule; |
370
|
17 |
|
} |
371
|
|
|
|
372
|
|
|
/** |
373
|
|
|
* @param callable $translator |
374
|
|
|
* |
375
|
|
|
* @return Validator |
376
|
|
|
*/ |
377
|
1 |
|
public function setTranslator(callable $translator): Validator |
378
|
|
|
{ |
379
|
1 |
|
$this->translator = $translator; |
380
|
|
|
|
381
|
1 |
|
return $this; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* Loop the form data through form rules. |
386
|
|
|
* |
387
|
|
|
* @param array $formValues |
388
|
|
|
* @param bool $useNoValidationRuleException |
389
|
|
|
* |
390
|
|
|
* @throws UnknownValidationRule |
391
|
|
|
* |
392
|
|
|
* @return ValidatorResult |
393
|
|
|
*/ |
394
|
17 |
|
public function validate(array $formValues, $useNoValidationRuleException = false): ValidatorResult |
395
|
|
|
{ |
396
|
|
|
if ( |
397
|
17 |
|
$useNoValidationRuleException === true |
398
|
|
|
&& |
399
|
17 |
|
\count($this->rules) === 0 |
400
|
|
|
) { |
401
|
1 |
|
throw new NoValidationRule( |
402
|
1 |
|
'No rules defined in the html.' |
403
|
|
|
); |
404
|
|
|
} |
405
|
|
|
|
406
|
|
|
// init |
407
|
16 |
|
$validatorResult = new ValidatorResult($this->formDocument); |
408
|
|
|
|
409
|
16 |
|
foreach ($this->rules as $formHelperId => $formFields) { |
410
|
15 |
|
foreach ($formFields as $field => $fieldRuleOuter) { |
411
|
|
|
|
412
|
15 |
|
$currentFieldValue = $this->getCurrentFieldValue($formValues, $field); |
413
|
|
|
|
414
|
|
|
// |
415
|
|
|
// use the filter |
416
|
|
|
// |
417
|
|
|
|
418
|
15 |
|
if (isset($this->filters[$formHelperId][$field])) { |
419
|
5 |
|
$filtersOuter = $this->filters[$formHelperId][$field]; |
420
|
5 |
|
$fieldFilters = preg_split("/\|+(?![^\(]*\))/", $filtersOuter); |
421
|
|
|
|
422
|
5 |
|
foreach ($fieldFilters as $fieldFilter) { |
423
|
|
|
|
424
|
5 |
|
if (!$fieldFilter) { |
425
|
|
|
continue; |
426
|
|
|
} |
427
|
|
|
|
428
|
5 |
|
$currentFieldValue = $this->applyFilter($currentFieldValue, $fieldFilter); |
429
|
|
|
} |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
// |
433
|
|
|
// save the new values into the result-object |
434
|
|
|
// |
435
|
|
|
|
436
|
15 |
|
$validatorResult->setValues($field, $currentFieldValue); |
437
|
|
|
|
438
|
|
|
// |
439
|
|
|
// skip validation, if there was no value and validation is not required |
440
|
|
|
// |
441
|
|
|
|
442
|
|
|
if ( |
443
|
15 |
|
$currentFieldValue === null |
444
|
|
|
&& |
445
|
15 |
|
!isset($this->required_rules[$formHelperId][$field]) |
446
|
|
|
) { |
447
|
3 |
|
continue; |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
// |
451
|
|
|
// use the validation rules from the dom |
452
|
|
|
// |
453
|
|
|
|
454
|
15 |
|
$fieldRules = preg_split("/\|+(?![^\(?:]*\))/", $fieldRuleOuter); |
455
|
|
|
|
456
|
15 |
|
foreach ($fieldRules as $fieldRule) { |
457
|
|
|
|
458
|
15 |
|
if (!$fieldRule) { |
459
|
1 |
|
continue; |
460
|
|
|
} |
461
|
|
|
|
462
|
15 |
|
$validationClassArray = $this->validatorRulesManager->getClassViaAlias($fieldRule); |
463
|
|
|
|
464
|
15 |
|
if ($validationClassArray['object']) { |
465
|
1 |
|
$validationClass = $validationClassArray['object']; |
466
|
15 |
|
} else if ($validationClassArray['class']) { |
467
|
15 |
|
$validationClass = $validationClassArray['class']; |
468
|
|
|
} else { |
469
|
|
|
$validationClass = null; |
470
|
|
|
} |
471
|
|
|
|
472
|
15 |
|
$validationClassArgs = $validationClassArray['classArgs'] ?? null; |
473
|
|
|
|
474
|
15 |
|
if ($validationClass instanceof AbstractRule) { |
475
|
|
|
|
476
|
1 |
|
$respectValidator = $validationClass; |
477
|
|
|
|
478
|
|
|
} else { |
479
|
|
|
|
480
|
|
|
try { |
481
|
15 |
|
$respectValidatorFactory = new Factory(); |
482
|
15 |
|
$respectValidatorFactory->prependRulePrefix('voku\\HtmlFormValidator\\Rules'); |
483
|
|
|
|
484
|
15 |
|
if ($validationClassArgs !== null) { |
485
|
6 |
|
$respectValidator = $respectValidatorFactory->rule($validationClass, $validationClassArgs); |
486
|
|
|
} else { |
487
|
15 |
|
$respectValidator = $respectValidatorFactory->rule($validationClass); |
488
|
|
|
} |
489
|
|
|
|
490
|
1 |
|
} catch (ComponentException $componentException) { |
491
|
1 |
|
throw new UnknownValidationRule( |
492
|
1 |
|
'No rule defined for: ' . $field . ' (rule: ' . $fieldRule . ' | class: ' . $validationClass . ')', |
493
|
1 |
|
500, |
494
|
1 |
|
$componentException |
495
|
|
|
); |
496
|
|
|
} |
497
|
|
|
|
498
|
|
|
} |
499
|
|
|
|
500
|
14 |
|
$hasPassed = false; |
501
|
14 |
|
$translator = $this->getTranslator(); |
|
|
|
|
502
|
|
|
|
503
|
|
|
try { |
504
|
14 |
|
$hasPassed = $respectValidator->assert($currentFieldValue); |
505
|
9 |
|
} catch (NestedValidationException $nestedValidationException) { |
506
|
|
|
|
507
|
1 |
|
if ($translator) { |
508
|
|
|
$nestedValidationException->setParam('translator', $translator); |
509
|
|
|
} |
510
|
|
|
|
511
|
1 |
|
$validatorResult->setError($field, $nestedValidationException->getFullMessage()); |
512
|
8 |
|
} catch (ValidationException $validationException) { |
513
|
|
|
|
514
|
8 |
|
if ($translator) { |
515
|
1 |
|
$validationException->setParam('translator', $translator); |
516
|
|
|
} |
517
|
|
|
|
518
|
8 |
|
$validatorResult->setError($field, $validationException->getMainMessage()); |
519
|
|
|
} |
520
|
|
|
|
521
|
14 |
|
if ($hasPassed === true) { |
522
|
14 |
|
continue; |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
} |
526
|
|
|
} |
527
|
|
|
} |
528
|
|
|
|
529
|
15 |
|
return $validatorResult; |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
} |
533
|
|
|
|
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.