Passed
Push — master ( 79bb78...087da0 )
by Alexander
02:53
created

Url   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 249
Duplicated Lines 0 %

Test Coverage

Coverage 94.32%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 78
c 1
b 0
f 0
dl 0
loc 249
ccs 83
cts 88
cp 0.9432
rs 9.68
wmc 34

16 Methods

Rating   Name   Duplication   Size   Complexity  
A maxlength() 0 5 1
A prepareContainerAttributes() 0 7 2
A ariaLabel() 0 5 1
A generateSchemePattern() 0 9 2
A prepareInputAttributes() 0 8 2
A autofocus() 0 5 1
A minlength() 0 5 1
A readonly() 0 5 1
C beforeRender() 0 33 14
A generateInput() 0 11 3
A pattern() 0 5 1
A size() 0 5 1
A disabled() 0 5 1
A ariaDescribedBy() 0 5 1
A required() 0 5 1
A tabIndex() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field;
6
7
use InvalidArgumentException;
8
use Yiisoft\Form\Field\Base\EnrichmentFromRules\EnrichmentFromRulesInterface;
9
use Yiisoft\Form\Field\Base\EnrichmentFromRules\EnrichmentFromRulesTrait;
10
use Yiisoft\Form\Field\Base\InputField;
11
use Yiisoft\Form\Field\Base\Placeholder\PlaceholderInterface;
12
use Yiisoft\Form\Field\Base\Placeholder\PlaceholderTrait;
13
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassInterface;
14
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassTrait;
15
use Yiisoft\Html\Html;
16
use Yiisoft\Validator\BeforeValidationInterface;
17
use Yiisoft\Validator\Rule\HasLength;
18
use Yiisoft\Validator\Rule\Regex;
19
use Yiisoft\Validator\Rule\Required;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Validator\Rule\Required was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Yiisoft\Validator\Rule\Url as UrlRule;
21
22
use function is_string;
23
24
/**
25
 * @link https://html.spec.whatwg.org/multipage/input.html#url-state-(type=url)
26
 * @link https://developer.mozilla.org/docs/Web/HTML/Element/input/url
27
 */
28
final class Url extends InputField implements PlaceholderInterface, ValidationClassInterface, EnrichmentFromRulesInterface
29
{
30
    use EnrichmentFromRulesTrait;
31
    use PlaceholderTrait;
32
    use ValidationClassTrait;
33
34
    /**
35
     * Maximum length of value.
36
     *
37
     * @param int|null $value A limit on the number of characters a user can input.
38
     *
39
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-maxlength
40
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-maxlength
41
     */
42 2
    public function maxlength(?int $value): self
43
    {
44 2
        $new = clone $this;
45 2
        $new->inputAttributes['maxlength'] = $value;
46 2
        return $new;
47
    }
48
49
    /**
50
     * Minimum length of value.
51
     *
52
     * @param int|null $value A lower bound on the number of characters a user can input.
53
     *
54
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-minlength
55
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-minlength
56
     */
57 2
    public function minlength(?int $value): self
58
    {
59 2
        $new = clone $this;
60 2
        $new->inputAttributes['minlength'] = $value;
61 2
        return $new;
62
    }
63
64
    /**
65
     * Pattern to be matched by the form control's value.
66
     *
67
     * @param string|null $value A regular expression against which the control's value.
68
     *
69
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-pattern
70
     */
71 2
    public function pattern(?string $value): self
72
    {
73 2
        $new = clone $this;
74 2
        $new->inputAttributes['pattern'] = $value;
75 2
        return $new;
76
    }
77
78
    /**
79
     * A boolean attribute that controls whether or not the user can edit the form control.
80
     *
81
     * @param bool $value Whether to allow the value to be edited by the user.
82
     *
83
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
84
     */
85 2
    public function readonly(bool $value = true): self
86
    {
87 2
        $new = clone $this;
88 2
        $new->inputAttributes['readonly'] = $value;
89 2
        return $new;
90
    }
91
92
    /**
93
     * A boolean attribute. When specified, the element is required.
94
     *
95
     * @param bool $value Whether the control is required for form submission.
96
     *
97
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-required
98
     */
99 2
    public function required(bool $value = true): self
100
    {
101 2
        $new = clone $this;
102 2
        $new->inputAttributes['required'] = $value;
103 2
        return $new;
104
    }
105
106
    /**
107
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
108
     */
109 2
    public function disabled(bool $disabled = true): self
110
    {
111 2
        $new = clone $this;
112 2
        $new->inputAttributes['disabled'] = $disabled;
113 2
        return $new;
114
    }
115
116
    /**
117
     * Identifies the element (or elements) that describes the object.
118
     *
119
     * @link https://w3c.github.io/aria/#aria-describedby
120
     */
121 2
    public function ariaDescribedBy(?string $value): self
122
    {
123 2
        $new = clone $this;
124 2
        $new->inputAttributes['aria-describedby'] = $value;
125 2
        return $new;
126
    }
127
128
    /**
129
     * Defines a string value that labels the current element.
130
     *
131
     * @link https://w3c.github.io/aria/#aria-label
132
     */
133 2
    public function ariaLabel(?string $value): self
134
    {
135 2
        $new = clone $this;
136 2
        $new->inputAttributes['aria-label'] = $value;
137 2
        return $new;
138
    }
139
140
    /**
141
     * Focus on the control (put cursor into it) when the page loads. Only one form element could be in focus
142
     * at the same time.
143
     *
144
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus
145
     */
146 2
    public function autofocus(bool $value = true): self
147
    {
148 2
        $new = clone $this;
149 2
        $new->inputAttributes['autofocus'] = $value;
150 2
        return $new;
151
    }
152
153
    /**
154
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
155
     * keyboard navigation (usually with the Tab key, hence the name).
156
     *
157
     * It accepts an integer as a value, with different results depending on the integer's value:
158
     *
159
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
160
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
161
     *   with JavaScript.
162
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
163
     *   defined by the document's source order.
164
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
165
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
166
     *   `tabindex="3"`.
167
     *
168
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
169
     */
170 2
    public function tabIndex(?int $value): self
171
    {
172 2
        $new = clone $this;
173 2
        $new->inputAttributes['tabindex'] = $value;
174 2
        return $new;
175
    }
176
177
    /**
178
     * The size of the control.
179
     *
180
     * @param int|null $value The number of characters that allow the user to see while editing the element's value.
181
     *
182
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-size
183
     */
184 2
    public function size(?int $value): self
185
    {
186 2
        $new = clone $this;
187 2
        $new->inputAttributes['size'] = $value;
188 2
        return $new;
189
    }
190
191
    /**
192
     * @psalm-suppress MixedAssignment,MixedArgument Remove after fix https://github.com/yiisoft/validator/issues/225
193
     */
194 21
    protected function beforeRender(): void
195
    {
196 21
        parent::beforeRender();
197 21
        if ($this->enrichmentFromRules && $this->hasFormModelAndAttribute()) {
198 8
            $rules = $this->getFormModel()->getRules()[$this->getFormAttributeName()] ?? [];
199 8
            foreach ($rules as $rule) {
200 8
                if ($rule instanceof BeforeValidationInterface && $rule->getWhen() !== null) {
201 1
                    continue;
202
                }
203
204 7
                if ($rule instanceof Required) {
205 1
                    $this->inputAttributes['required'] = true;
206
                }
207
208 7
                if ($rule instanceof HasLength) {
209 1
                    if (null !== $min = $rule->getOptions()['min']) {
210 1
                        $this->inputAttributes['minlength'] = $min;
211
                    }
212 1
                    if (null !== $max = $rule->getOptions()['max']) {
213 1
                        $this->inputAttributes['maxlength'] = $max;
214
                    }
215
                }
216
217 7
                $pattern = null;
218 7
                if ($rule instanceof UrlRule) {
219 3
                    $pattern = $rule->getOptions()['pattern'];
220 6
                } elseif ($rule instanceof Regex) {
221 4
                    if (!($rule->getOptions()['not'])) {
222 3
                        $pattern = $rule->getOptions()['pattern'];
223
                    }
224
                }
225 7
                if ($pattern !== null) {
226 4
                    $this->inputAttributes['pattern'] = Html::normalizeRegexpPattern($pattern);
227
                }
228
            }
229
        }
230
    }
231
232 21
    protected function generateInput(): string
233
    {
234 21
        $value = $this->getFormAttributeValue();
235
236 21
        if (!is_string($value) && $value !== null) {
237 1
            throw new InvalidArgumentException('URL field requires a string or null value.');
238
        }
239
240 20
        $inputAttributes = $this->getInputAttributes();
241
242 20
        return Html::input('url', $this->getInputName(), $value, $inputAttributes)->render();
243
    }
244
245 12
    protected function prepareContainerAttributes(array &$attributes): void
246
    {
247 12
        if ($this->hasFormModelAndAttribute()) {
248 12
            $this->addValidationClassToAttributes(
249
                $attributes,
250 12
                $this->getFormModel(),
251 12
                $this->getFormAttributeName(),
252
            );
253
        }
254
    }
255
256 20
    protected function prepareInputAttributes(array &$attributes): void
257
    {
258 20
        $this->preparePlaceholderInInputAttributes($attributes);
259 20
        if ($this->hasFormModelAndAttribute()) {
260 20
            $this->addInputValidationClassToAttributes(
261
                $attributes,
262 20
                $this->getFormModel(),
263 20
                $this->getFormAttributeName(),
264
            );
265
        }
266
    }
267
268
    private function generateSchemePattern(string $scheme): string
0 ignored issues
show
Unused Code introduced by
The method generateSchemePattern() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
269
    {
270
        $result = '';
271
272
        for ($i = 0, $length = strlen($scheme); $i < $length; $i++) {
273
            $result .= '[' . strtolower($scheme[$i]) . strtoupper($scheme[$i]) . ']';
274
        }
275
276
        return $result;
277
    }
278
}
279