Passed
Pull Request — master (#202)
by Alexander
19:04 queued 16:27
created

Url::minlength()   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\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
199 8
                    ->getFormModel()
200 8
                    ->getRules()[$this->getFormAttributeName()] ?? [];
201 8
            foreach ($rules as $rule) {
202 8
                if ($rule instanceof BeforeValidationInterface && $rule->getWhen() !== null) {
203 1
                    continue;
204
                }
205
206 7
                if ($rule instanceof Required) {
207 1
                    $this->inputAttributes['required'] = true;
208
                }
209
210 7
                if ($rule instanceof HasLength) {
211 1
                    if (null !== $min = $rule->getOptions()['min']) {
212 1
                        $this->inputAttributes['minlength'] = $min;
213
                    }
214 1
                    if (null !== $max = $rule->getOptions()['max']) {
215 1
                        $this->inputAttributes['maxlength'] = $max;
216
                    }
217
                }
218
219 7
                $pattern = null;
220 7
                if ($rule instanceof UrlRule) {
221 3
                    $pattern = $rule->getOptions()['pattern'];
222 6
                } elseif ($rule instanceof Regex) {
223 4
                    if (!($rule->getOptions()['not'])) {
224 3
                        $pattern = $rule->getOptions()['pattern'];
225
                    }
226
                }
227 7
                if ($pattern !== null) {
228 4
                    $this->inputAttributes['pattern'] = Html::normalizeRegexpPattern($pattern);
229
                }
230
            }
231
        }
232
    }
233
234 21
    protected function generateInput(): string
235
    {
236 21
        $value = $this->getFormAttributeValue();
237
238 21
        if (!is_string($value) && $value !== null) {
239 1
            throw new InvalidArgumentException('URL field requires a string or null value.');
240
        }
241
242 20
        $inputAttributes = $this->getInputAttributes();
243
244 20
        return Html::input('url', $this->getInputName(), $value, $inputAttributes)->render();
245
    }
246
247 12
    protected function prepareContainerAttributes(array &$attributes): void
248
    {
249 12
        if ($this->hasFormModelAndAttribute()) {
250 12
            $this->addValidationClassToAttributes(
251
                $attributes,
252 12
                $this->getFormModel(),
253 12
                $this->getFormAttributeName(),
254
            );
255
        }
256
    }
257
258 20
    protected function prepareInputAttributes(array &$attributes): void
259
    {
260 20
        $this->preparePlaceholderInInputAttributes($attributes);
261 20
        if ($this->hasFormModelAndAttribute()) {
262 20
            $this->addInputValidationClassToAttributes(
263
                $attributes,
264 20
                $this->getFormModel(),
265 20
                $this->getFormAttributeName(),
266
            );
267
        }
268
    }
269
270
    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...
271
    {
272
        $result = '';
273
274
        for ($i = 0, $length = strlen($scheme); $i < $length; $i++) {
275
            $result .= '[' . strtolower($scheme[$i]) . strtoupper($scheme[$i]) . ']';
276
        }
277
278
        return $result;
279
    }
280
}
281