Test Failed
Pull Request — master (#192)
by Sergei
02:42
created

Range::autofocus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field;
6
7
use InvalidArgumentException;
8
use Stringable;
9
use Yiisoft\Form\Field\Base\EnrichmentFromRules\EnrichmentFromRulesInterface;
10
use Yiisoft\Form\Field\Base\EnrichmentFromRules\EnrichmentFromRulesTrait;
11
use Yiisoft\Form\Field\Base\InputField;
12
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassInterface;
13
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassTrait;
14
use Yiisoft\Html\Html;
15
use Yiisoft\Validator\Rule\Number as NumberRule;
16
use Yiisoft\Validator\Rule\Required;
17
18
use function is_string;
19
20
/**
21
 * Represents `<input>` element of type "range" are let the user specify a numeric value which must be no less than
22
 * a given value, and no more than another given value.
23
 *
24
 * @link https://html.spec.whatwg.org/multipage/input.html#range-state-(type=range)
25
 * @link https://developer.mozilla.org/docs/Web/HTML/Element/input/range
26
 */
27
final class Range extends InputField implements EnrichmentFromRulesInterface, ValidationClassInterface
28
{
29
    use EnrichmentFromRulesTrait;
30
    use ValidationClassTrait;
31
32
    private bool $showOutput = false;
33
34
    /**
35
     * @psalm-var non-empty-string
36
     */
37
    private string $outputTag = 'span';
38
    private array $outputAttributes = [];
39
40
    /**
41
     * Maximum value.
42
     *
43
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-max
44
     */
45
    public function max(float|int|string|Stringable|null $value): self
46
    {
47
        $new = clone $this;
48
        $new->inputAttributes['max'] = $value;
49
        return $new;
50
    }
51
52
    /**
53
     * Minimum value.
54
     *
55
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-min
56
     */
57
    public function min(float|int|string|Stringable|null $value): self
58
    {
59
        $new = clone $this;
60
        $new->inputAttributes['min'] = $value;
61
        return $new;
62
    }
63
64
    /**
65
     * Granularity to be matched by the form control's value.
66
     *
67
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-step
68
     */
69
    public function step(float|int|string|Stringable|null $value): self
70
    {
71
        $new = clone $this;
72
        $new->inputAttributes['step'] = $value;
73
        return $new;
74
    }
75
76
    /**
77
     * ID of element that lists predefined options suggested to the user.
78
     *
79
     * @link https://html.spec.whatwg.org/multipage/input.html#the-list-attribute
80
     */
81
    public function list(?string $id): self
82
    {
83
        $new = clone $this;
84
        $new->inputAttributes['list'] = $id;
85
        return $new;
86
    }
87
88
    /**
89
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
90
     */
91
    public function disabled(bool $disabled = true): self
92
    {
93
        $new = clone $this;
94
        $new->inputAttributes['disabled'] = $disabled;
95
        return $new;
96
    }
97
98
    /**
99
     * Identifies the element (or elements) that describes the object.
100
     *
101
     * @link https://w3c.github.io/aria/#aria-describedby
102
     */
103
    public function ariaDescribedBy(?string $value): self
104
    {
105
        $new = clone $this;
106
        $new->inputAttributes['aria-describedby'] = $value;
107
        return $new;
108
    }
109
110
    /**
111
     * Defines a string value that labels the current element.
112
     *
113
     * @link https://w3c.github.io/aria/#aria-label
114
     */
115
    public function ariaLabel(?string $value): self
116
    {
117
        $new = clone $this;
118
        $new->inputAttributes['aria-label'] = $value;
119
        return $new;
120
    }
121
122
    /**
123
     * Focus on the control (put cursor into it) when the page loads. Only one form element could be in focus
124
     * at the same time.
125
     *
126
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus
127
     */
128
    public function autofocus(bool $value = true): self
129
    {
130
        $new = clone $this;
131
        $new->inputAttributes['autofocus'] = $value;
132
        return $new;
133
    }
134
135
    /**
136
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
137
     * keyboard navigation (usually with the Tab key, hence the name).
138
     *
139
     * It accepts an integer as a value, with different results depending on the integer's value:
140
     *
141
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
142
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
143
     *   with JavaScript.
144
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
145
     *   defined by the document's source order.
146
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
147
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
148
     *   `tabindex="3"`.
149
     *
150
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
151
     */
152
    public function tabIndex(?int $value): self
153
    {
154
        $new = clone $this;
155
        $new->inputAttributes['tabindex'] = $value;
156
        return $new;
157
    }
158
159
    public function showOutput(bool $show = true): self
160
    {
161
        $new = clone $this;
162
        $new->showOutput = $show;
163
        return $new;
164
    }
165
166
    public function outputTag(string $tagName): self
167
    {
168
        if ($tagName === '') {
169
            throw new InvalidArgumentException('The output tag name it cannot be empty value.');
170
        }
171
172
        $new = clone $this;
173
        $new->outputTag = $tagName;
174
        return $new;
175
    }
176
177
    public function outputAttributes(array $attributes): self
178
    {
179
        $new = clone $this;
180
        $new->outputAttributes = array_merge($new->outputAttributes, $attributes);
181
        return $new;
182
    }
183
184
    public function replaceOutputAttributes(array $attributes): self
185
    {
186
        $new = clone $this;
187
        $new->outputAttributes = $attributes;
188
        return $new;
189
    }
190
191
    /**
192
     * @psalm-suppress MixedAssignment,MixedArgument Remove after fix https://github.com/yiisoft/validator/issues/225
193
     */
194
    protected function beforeRender(): void
195
    {
196
        parent::beforeRender();
197
        if ($this->enrichmentFromRules && $this->hasFormModelAndAttribute()) {
198
            $rules = $this->getFormModel()->getRules()[$this->getFormAttributeName()] ?? [];
199
            foreach ($rules as $rule) {
200
                if ($rule instanceof Required) {
201
                    $this->inputAttributes['required'] = true;
202
                }
203
204
                if ($rule instanceof NumberRule) {
205
                    if (null !== $min = $rule->getOptions()['min']) {
206
                        $this->inputAttributes['min'] = $min;
207
                    }
208
                    if (null !== $max = $rule->getOptions()['max']) {
209
                        $this->inputAttributes['max'] = $max;
210
                    }
211
                }
212
            }
213
        }
214
    }
215
216
    protected function generateInput(): string
217
    {
218
        $value = $this->getFormAttributeValue();
219
220
        if (!is_string($value) && !is_numeric($value) && $value !== null) {
221
            throw new InvalidArgumentException('Range field requires a string, numeric or null value.');
222
        }
223
224
        $tag = Html::range($this->getInputName(), $value, $this->getInputAttributes());
225
        if ($this->showOutput) {
226
            $tag = $tag
227
                ->showOutput()
228
                ->outputTag($this->outputTag)
0 ignored issues
show
Bug introduced by
The method outputTag() does not exist on Yiisoft\Html\Tag\Input\Range. Did you maybe mean outputTagName()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

228
                ->/** @scrutinizer ignore-call */ outputTag($this->outputTag)

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
229
                ->outputAttributes($this->outputAttributes);
230
        }
231
232
        return $tag->render();
233
    }
234
235
    protected function prepareContainerAttributes(array &$attributes): void
236
    {
237
        if ($this->hasFormModelAndAttribute()) {
238
            $this->addValidationClassToAttributes(
239
                $attributes,
240
                $this->getFormModel(),
241
                $this->getFormAttributeName(),
242
            );
243
        }
244
    }
245
}
246