Completed
Push — master ( 84f9de...ae5555 )
by Lars
04:51
created

ValidatorResult::setError()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7.0099

Importance

Changes 0
Metric Value
dl 0
loc 34
c 0
b 0
f 0
ccs 16
cts 17
cp 0.9412
rs 8.4426
cc 7
nc 24
nop 4
crap 7.0099
1
<?php
2
3
declare(strict_types=1);
4
5
namespace voku\HtmlFormValidator;
6
7
use voku\helper\HtmlDomParser;
8
9
class ValidatorResult
10
{
11
    /**
12
     * List of errors from validation
13
     *
14
     * @var string[][]
15
     */
16
    private $errors = [];
17
18
    /**
19
     * @var array
20
     */
21
    private $values = [];
22
23
    /**
24
     * @var HtmlDomParser
25
     */
26
    private $formDocument;
27
28
    /**
29
     * ValidatorResult constructor.
30
     *
31
     * @param HtmlDomParser $formDocument
32
     */
33 24
    public function __construct($formDocument)
34
    {
35 24
        $this->formDocument = clone $formDocument;
36 24
    }
37
38
    /**
39
     * @return int
40
     */
41 9
    public function countErrors(): int
42
    {
43 9
        return \count($this->errors);
44
    }
45
46
    /**
47
     * @return array
48
     */
49 17
    public function getErrorMessages(): array
50
    {
51 17
        return $this->errors;
52
    }
53
54
    /**
55
     * @return string
56
     */
57 3
    public function getHtml(): string
58
    {
59 3
        return $this->formDocument->html();
60
    }
61
62
    /**
63
     * @return array
64
     */
65 2
    public function getValues(): array
66
    {
67 2
        return $this->values;
68
    }
69
70
    /**
71
     * @return bool
72
     */
73 9
    public function isSuccess(): bool
74
    {
75 9
        return $this->countErrors() === 0;
76
    }
77
78
    /**
79
     * @param string          $field
80
     * @param string          $fieldRule
81
     * @param string|string[] $errorMsg
82
     * @param mixed           $currentFieldValue
83
     *
84
     * @return self
85
     */
86 17
    public function setError(string $field, string $fieldRule, $errorMsg, $currentFieldValue): self
87
    {
88 17
        $inputTag = $this->formDocument->find('[name=\'' . $field . '\']', 0);
89 17
        if ($inputTag) {
90
            /** @noinspection UnusedFunctionResultInspection */
91 17
            $inputTag->setAttribute('aria-invalid', 'true');
0 ignored issues
show
Bug introduced by
The method setAttribute does only exist in voku\helper\SimpleHtmlDom, but not in voku\helper\SimpleHtmlDomNodeInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
92
        }
93
94
        // overwrite the error message if needed
95 17
        $fieldRule = (new ValidatorRulesManager)->getClassViaAlias($fieldRule)['class'];
96 17
        $errorMsgFromHtml = $inputTag->getAttribute('data-error-message--' . \strtolower($fieldRule));
0 ignored issues
show
Bug introduced by
The method getAttribute does only exist in voku\helper\SimpleHtmlDom, but not in voku\helper\SimpleHtmlDomNodeInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
97 17
        if ($errorMsgFromHtml) {
98 1
            $errorMsg = \sprintf($errorMsgFromHtml, \htmlspecialchars((string) $currentFieldValue, \ENT_COMPAT));
99
        }
100
101
        // save the error message per field into this object
102 17
        if (\is_array($errorMsg) === false) {
103 17
            $errorMsg = [$errorMsg];
104
        }
105 17
        foreach ($errorMsg as &$errorMsgSingle) {
106
            if (
107 17
                isset($this->errors[$field])
108
                &&
109 17
                \in_array($errorMsgSingle, $this->errors[$field], true)
110
            ) {
111
                continue;
112
            }
113
114 17
            $this->errors[$field][] = $errorMsgSingle;
115
        }
116 17
        unset($errorMsgSingle);
117
118 17
        return $this;
119
    }
120
121
    /**
122
     * @param string $field
123
     * @param mixed  $value
124
     *
125
     * @return self
126
     */
127 19
    public function setValue(string $field, $value): self
128
    {
129 19
        $inputTag = $this->formDocument->find('[name=\'' . $field . '\']', 0);
130 19
        if ($inputTag) {
131
            /** @noinspection UnusedFunctionResultInspection */
132 19
            $inputTag->setAttribute('aria-invalid', 'false');
0 ignored issues
show
Bug introduced by
The method setAttribute does only exist in voku\helper\SimpleHtmlDom, but not in voku\helper\SimpleHtmlDomNodeInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
133
134
            /** @noinspection UnusedFunctionResultInspection */
135 19
            $inputTag->val($value);
0 ignored issues
show
Bug introduced by
The method val does only exist in voku\helper\SimpleHtmlDom, but not in voku\helper\SimpleHtmlDomNodeInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
136
        }
137
138 19
        return $this;
139
    }
140
141
    /**
142
     * Write the error messages into the dom, if needed.
143
     *
144
     * @return self
145
     */
146 23
    public function writeErrorsIntoTheDom(): self
147
    {
148 23
        foreach ($this->errors as $field => $errors) {
149 17
            $inputTag = $this->formDocument->find('[name=\'' . $field . '\']', 0);
150 17
            if ($inputTag) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $inputTag of type voku\helper\SimpleHtmlDom[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
151 17
                $errorMsgTemplateSelector = $inputTag->getAttribute('data-error-template-selector');
0 ignored issues
show
Bug introduced by
The method getAttribute cannot be called on $inputTag (of type array<integer,object<voku\helper\SimpleHtmlDom>>).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
152 17
                if ($errorMsgTemplateSelector) {
153 1
                    $errorMsgTemplate = $this->formDocument->find($errorMsgTemplateSelector, 0);
154 1
                    if ($errorMsgTemplate) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $errorMsgTemplate of type voku\helper\SimpleHtmlDom[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
155 1
                        foreach ($errors as $error) {
156 17
                            $errorMsgTemplate->innerText .= ' ' . $error;
157
                        }
158
                    }
159
                }
160
            }
161
        }
162
163 23
        return $this;
164
    }
165
166
    /**
167
     * @param string $field
168
     * @param mixed  $value
169
     *
170
     * @return self
171
     */
172 23
    public function saveValue(string $field, $value): self
173
    {
174 23
        $this->values[$field] = $value;
175
176 23
        return $this;
177
    }
178
}
179