Completed
Push — master ( b4546c...97e2e0 )
by Lars
01:39
created

Validator::filterRulesNamespace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
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\Date;
13
use Respect\Validation\Rules\Email;
14
use Respect\Validation\Rules\HexRgbColor;
15
use Respect\Validation\Rules\Numeric;
16
use Respect\Validation\Rules\Phone;
17
use Respect\Validation\Rules\Url;
18
use Symfony\Component\CssSelector\Exception\SyntaxErrorException;
19
use voku\helper\HtmlDomParser;
20
use voku\helper\SimpleHtmlDom;
21
use voku\helper\UTF8;
22
use voku\HtmlFormValidator\Exceptions\NoValidationRule;
23
use voku\HtmlFormValidator\Exceptions\UnknownFilter;
24
use voku\HtmlFormValidator\Exceptions\UnknownValidationRule;
25
26
class Validator
27
{
28
  /**
29
   * @var HtmlDomParser
30
   */
31
  private $formDocument;
32
33
  /**
34
   * @var string[][]
35
   */
36
  private $rules = [];
37
38
  /**
39
   * @var string[][]
40
   */
41
  private $required_rules = [];
42
43
  /**
44
   * @var string[][]
45
   */
46
  private $rules_namespaces;
47
48
  /**
49
   * @var string[][]
50
   */
51
  private $filters = [];
52
53
  /**
54
   * @var callable[]
55
   */
56
  private $filters_custom = [];
57
58
  /**
59
   * @var callable|null
60
   */
61
  private $translator;
62
63
  /**
64
   * @var ValidatorRulesManager
65
   */
66
  private $validatorRulesManager;
67
68
  /**
69
   * @var string
70
   */
71
  private $selector;
72
73
  /**
74
   * @param string $formHTML
75
   * @param string $selector
76
   */
77 22
  public function __construct($formHTML, $selector = '')
78
  {
79 22
    $this->rules_namespaces['append'] = [];
80 22
    $this->rules_namespaces['prepend'] = [];
81 22
    $this->prependRulesNamespace('voku\\HtmlFormValidator\\Rules');
82
83 22
    $this->validatorRulesManager = new ValidatorRulesManager();
84
85 22
    $this->formDocument = HtmlDomParser::str_get_html($formHTML);
0 ignored issues
show
Unused Code introduced by
The call to HtmlDomParser::str_get_html() has too many arguments starting with $formHTML.

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.

Loading history...
86 22
    $this->selector = $selector;
87
88 22
    $this->parseHtmlDomForRules();
89 22
  }
90
91
  /**
92
   * @param string   $name   <p>A name for the "data-filter"-attribute in the dom.</p>
93
   * @param callable $filter <p>A custom filter.</p>
94
   */
95 1
  public function addCustomFilter(string $name, callable $filter)
96
  {
97 1
    $this->filters_custom[$name] = $filter;
98 1
  }
99
100
  /**
101
   * @param string              $name      <p>A name for the "data-validator"-attribute in the dom.</p>
102
   * @param string|AbstractRule $validator <p>A custom validation class.</p>
103
   */
104 3
  public function addCustomRule(string $name, $validator)
105
  {
106 3
    $this->validatorRulesManager->addCustomRule($name, $validator);
107 3
  }
108
109
  /**
110
   * @param mixed  $currentFieldData
111
   * @param string $fieldFilter
112
   *
113
   * @throws UnknownFilter
114
   *
115
   * @return mixed|string|null
116
   */
117 5
  private function applyFilter($currentFieldData, string $fieldFilter)
118
  {
119 5
    if ($currentFieldData === null) {
120 1
      return null;
121
    }
122
123
    //
124
    // fixed filters
125
    //
126
127
    switch ($fieldFilter) {
128 5
      case 'escape':
129 4
        return \htmlentities($currentFieldData, ENT_QUOTES | ENT_HTML5, 'UTF-8');
130
    }
131
132
    //
133
    // get arguments
134
    //
135
136 5
    list($fieldFilter, $fieldFilterArgs) = ValidatorHelpers::getArgsFromString($fieldFilter);
137
138 5
    $currentFieldData = (array)$currentFieldData;
139 5
    foreach ($fieldFilterArgs as $arg) {
140 1
      $currentFieldData[] = $arg;
141
    }
142
143
    //
144
    // custom filters
145
    //
146
147 5
    if (isset($this->filters_custom[$fieldFilter])) {
148 1
      return \call_user_func_array($this->filters_custom[$fieldFilter], $currentFieldData);
149
    }
150
151
    //
152
    // dynamic filters
153
    //
154
155 4
    if (method_exists(UTF8::class, $fieldFilter)) {
156 4
      $currentFieldData = \call_user_func_array([UTF8::class, $fieldFilter], $currentFieldData);
157
    } else {
158
      throw new UnknownFilter(
159
          'No filter available for "' . $fieldFilter . '"'
160
      );
161
    }
162
163 4
    return $currentFieldData;
164
  }
165
166
  /**
167
   * @param string $type
168
   *
169
   * @return string|null
170
   */
171 3
  public function autoSelectRuleByInputType(string $type)
172
  {
173
    $matchingArray = [
174 3
        'email'  => Email::class,
175
        'url'    => Url::class,
176
        'color'  => HexRgbColor::class,
177
        'number' => Numeric::class,
178
        'date'   => Date::class,
179
        'range'  => Numeric::class,
180
        'tel'    => Phone::class,
181
        // -> this need localisation e.g. for german / us / etc.
182
        //'time'   => Time::class,
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
183
        //'month'  => Month::class,
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
184
        //'week'   => Week::class,
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
185
    ];
186
187 3
    return $matchingArray[$type] ?? null;
188
  }
189
190
  /**
191
   * @param string $phpNamespace
192
   *
193
   * @return string
194
   */
195 22
  private function filterRulesNamespace(string $phpNamespace): string
196
  {
197 22
    $namespaceSeparator = '\\';
198 22
    $rulePrefix = \rtrim($phpNamespace, $namespaceSeparator);
199
200 22
    return $rulePrefix . $namespaceSeparator;
201
  }
202
203
  /**
204
   * Get the filters that will be applied.
205
   *
206
   * @return string[][]
207
   */
208 1
  public function getAllFilters(): array
209
  {
210 1
    return $this->filters;
211
  }
212
213
  /**
214
   * Get the rules that will be applied.
215
   *
216
   * @return string[][]
217
   */
218 15
  public function getAllRules(): array
219
  {
220 15
    return $this->rules;
221
  }
222
223
  /**
224
   * @param array  $formValues
225
   * @param string $field
226
   *
227
   * @return mixed|null
228
   */
229 18
  private function getCurrentFieldValue(array $formValues, string $field)
230
  {
231 18
    $fieldArrayPos = UTF8::strpos($field, '[');
232 18
    if ($fieldArrayPos !== false) {
233 3
      $fieldStart = UTF8::substr($field, 0, $fieldArrayPos);
234 3
      $fieldArray = UTF8::substr($field, $fieldArrayPos);
235 3
      $fieldHelperChar = '';
236 3
      $fieldArrayTmp = preg_replace_callback(
237 3
          '/\[([^\]]+)\]/',
238 3
          function ($match) use ($fieldHelperChar) {
239 3
            return $match[1] . $fieldHelperChar;
240 3
          },
241 3
          $fieldArray
242
      );
243 3
      $fieldArrayTmp = explode($fieldHelperChar, trim($fieldArrayTmp, $fieldHelperChar));
244
245 3
      $i = 0;
246 3
      $fieldHelper = [];
247 3
      foreach ($fieldArrayTmp as $fieldArrayTmpInner) {
248 3
        $fieldHelper[$i] = $fieldArrayTmpInner;
249
250 3
        $i++;
251
      }
252
253 3
      $currentFieldValue = null;
254
255
      switch ($i) {
256 3
        case 4:
257
          if (isset($formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]][$fieldHelper[3]])) {
258
            $currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]][$fieldHelper[3]];
259
          }
260
          break;
261 3
        case 3:
262
          if (isset($formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]])) {
263
            $currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]][$fieldHelper[2]];
264
          }
265
          break;
266 3
        case 2:
267 1
          if (isset($formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]])) {
268 1
            $currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]][$fieldHelper[1]];
269
          }
270 1
          break;
271 2
        case 1:
272 2
          if (isset($formValues[$fieldStart][$fieldHelper[0]])) {
273 2
            $currentFieldValue = $formValues[$fieldStart][$fieldHelper[0]];
274
          }
275 3
          break;
276
      }
277
    } else {
278 15
      $currentFieldValue = $formValues[$field] ?? null;
279
    }
280
281 18
    return $currentFieldValue;
282
  }
283
284
  /**
285
   * @return string
286
   */
287 3
  public function getHtml(): string
288
  {
289 3
    return $this->formDocument->html();
290
  }
291
292
  /**
293
   * Get the required rules that will be applied.
294
   *
295
   * @return string[][]
296
   */
297
  public function getRequiredRules(): array
298
  {
299
    return $this->required_rules;
300
  }
301
302
  /**
303
   * Find the first form on page or via css-selector, and parse <input>-elements.
304
   *
305
   * @return bool
306
   */
307 22
  public function parseHtmlDomForRules(): bool
308
  {
309
    // init
310 22
    $this->rules = [];
311 22
    $inputForm = [];
312
313 22
    if ($this->selector) {
314 2
      $forms = $this->formDocument->find($this->selector);
315
    } else {
316 20
      $forms = $this->formDocument->find('form');
317
    }
318
319 22
    if (\count($forms) === 0) {
320 1
      return false;
321
    }
322
323
    // get the first form
324 21
    $form = $forms[0];
325
326
    // get the from-id
327 21
    if ($form->id) {
328 14
      $formHelperId = $form->id;
329
    } else {
330 7
      $formHelperId = \uniqid('html-form-validator-tmp', true);
331
    }
332
333 21
    $formTagSelector = 'input, textarea, select';
334
335
    // get the <input>-elements from the form
336 21
    $inputFromFields = $form->find($formTagSelector);
337 21
    foreach ($inputFromFields as $inputFormField) {
338 21
      $this->parseInputForRules($inputFormField, $formHelperId, $form);
339 21
      $this->parseInputForFilter($inputFormField, $formHelperId);
340
    }
341
342
    // get the <input>-elements with a matching form="id"
343 21
    if (\strpos($formHelperId, 'html-form-validator-tmp') !== 0) {
344 14
      $inputFromFieldsTmpAll = $this->formDocument->find($formTagSelector);
345 14
      foreach ($inputFromFieldsTmpAll as $inputFromFieldTmp) {
0 ignored issues
show
Bug introduced by
The expression $inputFromFieldsTmpAll of type array<integer,object<vok...leHtmlDomNodeInterface> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
346 14
        if ($inputFromFieldTmp->form == $formHelperId) {
347 1
          $this->parseInputForRules($inputFromFieldTmp, $formHelperId);
348 14
          $this->parseInputForFilter($inputFromFieldTmp, $formHelperId);
349
        }
350
      }
351
    }
352
353 21
    return (\count($inputForm) >= 0);
354
  }
355
356
  /**
357
   * Determine if element has filter attributes, and save the given filter.
358
   *
359
   * @param SimpleHtmlDom $inputField
360
   * @param string        $formHelperId
361
   */
362 21
  private function parseInputForFilter(SimpleHtmlDom $inputField, string $formHelperId)
363
  {
364 21
    if (!$inputField->hasAttribute('data-filter')) {
365 21
      return;
366
    }
367
368 6
    $inputName = $inputField->getAttribute('name');
369 6
    $inputFilter = $inputField->getAttribute('data-filter');
370
371 6
    if (!$inputFilter) {
372 1
      $inputFilter = 'htmlentities';
373
    }
374
375 6
    $this->filters[$formHelperId][$inputName] = $inputFilter;
376 6
  }
377
378
  /**
379
   * Determine if element has validator attributes, and save the given rule.
380
   *
381
   * @param SimpleHtmlDom      $formField
382
   * @param string             $formHelperId
383
   * @param SimpleHtmlDom|null $form
384
   */
385 21
  private function parseInputForRules(SimpleHtmlDom $formField, string $formHelperId, SimpleHtmlDom $form = null)
386
  {
387 21
    if (!$formField->hasAttribute('data-validator')) {
388 14
      return;
389
    }
390
391 20
    $inputName = $formField->getAttribute('name');
392 20
    $inputType = $formField->getAttribute('type');
393 20
    $inputPattern = $formField->getAttribute('pattern');
394 20
    $inputRule = $formField->getAttribute('data-validator');
395
396 20
    $inputMinLength = $formField->getAttribute('minlength');
397 20
    $inputMaxLength = $formField->getAttribute('maxlength');
398
399 20
    $inputMin = $formField->getAttribute('min');
400 20
    $inputMax = $formField->getAttribute('max');
401
402 20
    if (strpos($inputRule, 'auto') !== false) {
403
404
      //
405
      // select default rule by input-type
406
      //
407
408 4
      if ($inputType) {
409 3
        $selectedRule = $this->autoSelectRuleByInputType($inputType);
410 3
        if ($selectedRule) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $selectedRule of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
411 3
          $inputRule .= '|' . $selectedRule;
412
        }
413
      }
414
415
      //
416
      // html5 pattern to regex
417
      //
418
419 4
      if ($inputPattern) {
420 1
        $inputRule .= '|regex(/' . $inputPattern . '/)';
421
      }
422
423
      //
424
      // min- / max values
425
      //
426
427 4
      if ($inputMinLength) {
428
        $inputRule .= '|minLength(' . serialize($inputMinLength) . ')';
429
      }
430
431 4
      if ($inputMaxLength) {
432
        $inputRule .= '|maxLength(' . serialize($inputMaxLength) . ')';
433
      }
434
435 4
      if ($inputMin) {
436
        $inputRule .= '|min(' . serialize($inputMin) . ')';
437
      }
438
439 4
      if ($inputMax) {
440
        $inputRule .= '|max(' . serialize($inputMax) . ')';
441
      }
442
443
    }
444
445 20
    if (strpos($inputRule, 'strict') !== false) {
446
447 3
      if ($formField->tag === 'select') {
448
449 1
        $selectableValues = [];
450 1
        foreach ($formField->getElementsByTagName('option') as $option) {
451 1
          $selectableValues[] = $option->getNode()->nodeValue;
452
        }
453 1
        $inputRule .= '|in(' . serialize($selectableValues) . ')';
454
455
      } elseif (
456
          (
457 2
              $inputType == 'checkbox'
458
              ||
459 2
              $inputType == 'radio'
460
          )
461
          &&
462 2
          $form) {
463
464 2
        $selectableValues = [];
465
466
        try {
467 2
          $formFieldNames = $form->find('[name=' . $formField->name . ']');
468
        } catch (SyntaxErrorException $syntaxErrorException) {
469
          $formFieldNames = null;
470
          // TODO@me -> can the symfony CssSelectorConverter use array-name-attributes?
471
        }
472
473 2
        if ($formFieldNames) {
474 2
          foreach ($formFieldNames as $formFieldName) {
0 ignored issues
show
Bug introduced by
The expression $formFieldNames of type array<integer,object<vok...leHtmlDomNodeInterface> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
475 2
            $selectableValues[] = $formFieldName->value;
476
          }
477
        }
478
479 2
        $inputRule .= '|in(' . serialize($selectableValues) . ')';
480
481
      }
482
    }
483
484 20
    if ($formField->hasAttribute('required')) {
485 18
      $this->required_rules[$formHelperId][$inputName] = $inputRule;
486
    }
487
488 20
    $this->rules[$formHelperId][$inputName] = $inputRule;
489 20
  }
490
491
  /**
492
   * @param string $phpNamespace <p>e.g.: "voku\\HtmlFormValidator\\Rules"</p>
493
   *
494
   * @return $this
495
   */
496
  public function appendRulesNamespace(string $phpNamespace): self
497
  {
498
    \array_push($this->rules_namespaces['append'], $this->filterRulesNamespace($phpNamespace));
499
500
    return $this;
501
  }
502
503
  /**
504
   * @param string $phpNamespace <p>e.g.: "voku\\HtmlFormValidator\\Rules"</p>
505
   *
506
   * @return $this
507
   */
508 22
  public function prependRulesNamespace(string $phpNamespace): self
509
  {
510 22
    \array_unshift($this->rules_namespaces['prepend'], $this->filterRulesNamespace($phpNamespace));
511
512 22
    return $this;
513
  }
514
515
  /**
516
   * @return callable|null
517
   */
518 17
  public function getTranslator()
519
  {
520 17
    return $this->translator;
521
  }
522
523
  /**
524
   * @param callable $translator
525
   *
526
   * @return Validator
527
   */
528 1
  public function setTranslator(callable $translator): self
529
  {
530 1
    $this->translator = $translator;
531
532 1
    return $this;
533
  }
534
535
  /**
536
   * Loop the form data through form rules.
537
   *
538
   * @param array $formValues
539
   * @param bool  $useNoValidationRuleException
540
   *
541
   * @throws UnknownValidationRule
542
   *
543
   * @return ValidatorResult
544
   */
545 20
  public function validate(array $formValues, $useNoValidationRuleException = false): ValidatorResult
546
  {
547
    if (
548 20
        $useNoValidationRuleException === true
549
        &&
550 20
        \count($this->rules) === 0
551
    ) {
552 1
      throw new NoValidationRule(
553 1
          'No rules defined in the html.'
554
      );
555
    }
556
557
    // init
558 19
    $validatorResult = new ValidatorResult($this->formDocument);
559
560 19
    foreach ($this->rules as $formHelperId => $formFields) {
561 18
      foreach ($formFields as $field => $fieldRuleOuter) {
562
563 18
        $currentFieldValue = $this->getCurrentFieldValue($formValues, $field);
564
565
        //
566
        // use the filter
567
        //
568
569 18
        if (isset($this->filters[$formHelperId][$field])) {
570 5
          $filtersOuter = $this->filters[$formHelperId][$field];
571 5
          $fieldFilters = preg_split("/\|+(?![^\(]*\))/", $filtersOuter);
572
573 5
          foreach ($fieldFilters as $fieldFilter) {
574
575 5
            if (!$fieldFilter) {
576
              continue;
577
            }
578
579 5
            $currentFieldValue = $this->applyFilter($currentFieldValue, $fieldFilter);
580
          }
581
        }
582
583
        //
584
        // save the new values into the result-object
585
        //
586
587 18
        $validatorResult->setValues($field, $currentFieldValue);
588
589
        //
590
        // skip validation, if there was no value and validation is not required
591
        //
592
593
        if (
594 18
            $currentFieldValue === null
595
            &&
596 18
            !isset($this->required_rules[$formHelperId][$field])
597
        ) {
598 3
          continue;
599
        }
600
601
        //
602
        // use the validation rules from the dom
603
        //
604
605 18
        $fieldRules = preg_split("/\|+(?![^\(?:]*\))/", $fieldRuleOuter);
606
607 18
        foreach ($fieldRules as $fieldRule) {
608
609 18
          if (!$fieldRule) {
610
            continue;
611
          }
612
613 18
          $validationClassArray = $this->validatorRulesManager->getClassViaAlias($fieldRule);
614
615 18
          if ($validationClassArray['object']) {
616 1
            $validationClass = $validationClassArray['object'];
617 18
          } elseif ($validationClassArray['class']) {
618 18
            $validationClass = $validationClassArray['class'];
619
          } else {
620
            $validationClass = null;
621
          }
622
623 18
          $validationClassArgs = $validationClassArray['classArgs'] ?? null;
624
625 18
          if ($validationClass instanceof AbstractRule) {
626
627 1
            $respectValidator = $validationClass;
628
629
          } else {
630
631 18
            $respectValidatorFactory = new Factory();
632 18
            foreach ($this->rules_namespaces['prepend'] as $rules_namespace) {
633 18
              $respectValidatorFactory->prependRulePrefix($rules_namespace);
634
            }
635 18
            foreach ($this->rules_namespaces['append'] as $rules_namespace) {
636
              $respectValidatorFactory->appendRulePrefix($rules_namespace);
637
            }
638
639
            try {
640
641 18
              if ($validationClassArgs !== null) {
642 9
                $respectValidator = $respectValidatorFactory->rule($validationClass, $validationClassArgs);
643
              } else {
644 18
                $respectValidator = $respectValidatorFactory->rule($validationClass);
645
              }
646
647 1
            } catch (ComponentException $componentException) {
648 1
              throw new UnknownValidationRule(
649 1
                  'No rule defined for: ' . $field . ' (rule: ' . $fieldRule . ' | class: ' . $validationClass . ')',
650 1
                  500,
651 1
                  $componentException
652
              );
653
            }
654
655
          }
656
657 17
          $hasPassed = false;
658 17
          $translator = $this->getTranslator();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $translator is correct as $this->getTranslator() (which targets voku\HtmlFormValidator\Validator::getTranslator()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
659
660
          try {
661 17
            $hasPassed = $respectValidator->assert($currentFieldValue);
662 12
          } catch (NestedValidationException $nestedValidationException) {
663
664 1
            if ($translator) {
665
              $nestedValidationException->setParam('translator', $translator);
666
            }
667
668 1
            $validatorResult->setError($field, $nestedValidationException->getFullMessage());
669 11
          } catch (ValidationException $validationException) {
670
671 11
            if ($translator) {
672 1
              $validationException->setParam('translator', $translator);
673
            }
674
675 11
            $validatorResult->setError($field, $validationException->getMainMessage());
676
          }
677
678 17
          if ($hasPassed === true) {
679 17
            continue;
680
          }
681
682
        }
683
      }
684
    }
685
686 18
    return $validatorResult;
687
  }
688
689
}
690