Passed
Pull Request — master (#249)
by Sergei
03:22
created

Url::autofocus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
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\Rule\Length;
17
use Yiisoft\Validator\Rule\Regex;
18
use Yiisoft\Validator\Rule\Required;
19
use Yiisoft\Validator\Rule\Url as UrlRule;
20
use Yiisoft\Validator\WhenInterface;
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
193
     */
194 21
    protected function beforeRender(): void
195
    {
196 21
        parent::beforeRender();
197 21
        if ($this->enrichmentFromRules && $this->hasFormModelAndAttribute()) {
198 8
            foreach ($this->getFormAttributeValidationRules() as $rule) {
199 8
                if ($rule instanceof WhenInterface && $rule->getWhen() !== null) {
200 1
                    continue;
201
                }
202
203 7
                if ($rule instanceof Required) {
204 1
                    $this->inputAttributes['required'] = true;
205
                }
206
207 7
                if ($rule instanceof Length) {
208 1
                    if (null !== $min = $rule->getMin()) {
209 1
                        $this->inputAttributes['minlength'] = $min;
210
                    }
211 1
                    if (null !== $max = $rule->getMax()) {
212 1
                        $this->inputAttributes['maxlength'] = $max;
213
                    }
214
                }
215
216 7
                $pattern = null;
217 7
                if ($rule instanceof UrlRule) {
218 3
                    $pattern = $rule->getPattern();
219 6
                } elseif ($rule instanceof Regex) {
220 4
                    if (!($rule->isNot())) {
221 3
                        $pattern = $rule->getPattern();
222
                    }
223
                }
224 7
                if ($pattern !== null) {
225 4
                    $this->inputAttributes['pattern'] = Html::normalizeRegexpPattern($pattern);
226
                }
227
            }
228
        }
229
    }
230
231 21
    protected function generateInput(): string
232
    {
233 21
        $value = $this->getFormAttributeValue();
234
235 21
        if (!is_string($value) && $value !== null) {
236 1
            throw new InvalidArgumentException('URL field requires a string or null value.');
237
        }
238
239 20
        $inputAttributes = $this->getInputAttributes();
240
241 20
        return Html::input('url', $this->getInputName(), $value, $inputAttributes)->render();
242
    }
243
244 12
    protected function prepareContainerAttributes(array &$attributes): void
245
    {
246 12
        if ($this->hasFormModelAndAttribute()) {
247 12
            $this->addValidationClassToAttributes(
248 12
                $attributes,
249 12
                $this->getFormModel(),
250 12
                $this->getFormAttributeName(),
251 12
            );
252
        }
253
    }
254
255 20
    protected function prepareInputAttributes(array &$attributes): void
256
    {
257 20
        $this->preparePlaceholderInInputAttributes($attributes);
258 20
        if ($this->hasFormModelAndAttribute()) {
259 20
            $this->addInputValidationClassToAttributes(
260 20
                $attributes,
261 20
                $this->getFormModel(),
262 20
                $this->getFormAttributeName(),
263 20
            );
264
        }
265
    }
266
267
    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...
268
    {
269
        $result = '';
270
271
        for ($i = 0, $length = strlen($scheme); $i < $length; $i++) {
272
            $result .= '[' . strtolower($scheme[$i]) . strtoupper($scheme[$i]) . ']';
273
        }
274
275
        return $result;
276
    }
277
}
278