Passed
Pull Request — master (#192)
by Alexander
05:43 queued 02:47
created

Number::max()   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 0
Metric Value
cc 1
eloc 3
c 0
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 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\Placeholder\PlaceholderInterface;
13
use Yiisoft\Form\Field\Base\Placeholder\PlaceholderTrait;
14
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassInterface;
15
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassTrait;
16
use Yiisoft\Html\Html;
17
use Yiisoft\Validator\Rule\Number as NumberRule;
18
use Yiisoft\Validator\Rule\Required;
19
20
/**
21
 * A control for setting the element's value to a string representing a number.
22
 *
23
 * @link https://html.spec.whatwg.org/multipage/input.html#number-state-(type=number)
24
 */
25
final class Number extends InputField implements EnrichmentFromRulesInterface, PlaceholderInterface, ValidationClassInterface
26
{
27
    use EnrichmentFromRulesTrait;
28
    use PlaceholderTrait;
29
    use ValidationClassTrait;
30
31
    /**
32
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-max
33
     */
34 6
    public function max(int|float|string|Stringable|null $value): self
35
    {
36 6
        $new = clone $this;
37 6
        $new->inputTagAttributes['max'] = $value;
38 6
        return $new;
39
    }
40
41
    /**
42
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-min
43
     */
44 6
    public function min(int|float|string|Stringable|null $value): self
45
    {
46 6
        $new = clone $this;
47 6
        $new->inputTagAttributes['min'] = $value;
48 6
        return $new;
49
    }
50
51
    /**
52
     * Granularity to be matched by the form control's value.
53
     *
54
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-step
55
     */
56 6
    public function step(float|int|string|Stringable|null $value): self
57
    {
58 6
        $new = clone $this;
59 6
        $new->inputTagAttributes['step'] = $value;
60 6
        return $new;
61
    }
62
63
    /**
64
     * A boolean attribute that controls whether or not the user can edit the form control.
65
     *
66
     * @param bool $value Whether to allow the value to be edited by the user.
67
     *
68
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
69
     */
70 2
    public function readonly(bool $value = true): self
71
    {
72 2
        $new = clone $this;
73 2
        $new->inputTagAttributes['readonly'] = $value;
74 2
        return $new;
75
    }
76
77
    /**
78
     * A boolean attribute. When specified, the element is required.
79
     *
80
     * @param bool $value Whether the control is required for form submission.
81
     *
82
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-required
83
     */
84 2
    public function required(bool $value = true): self
85
    {
86 2
        $new = clone $this;
87 2
        $new->inputTagAttributes['required'] = $value;
88 2
        return $new;
89
    }
90
91
    /**
92
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
93
     */
94 2
    public function disabled(bool $disabled = true): self
95
    {
96 2
        $new = clone $this;
97 2
        $new->inputTagAttributes['disabled'] = $disabled;
98 2
        return $new;
99
    }
100
101
    /**
102
     * Identifies the element (or elements) that describes the object.
103
     *
104
     * @link https://w3c.github.io/aria/#aria-describedby
105
     */
106 2
    public function ariaDescribedBy(?string $value): self
107
    {
108 2
        $new = clone $this;
109 2
        $new->inputTagAttributes['aria-describedby'] = $value;
110 2
        return $new;
111
    }
112
113
    /**
114
     * Defines a string value that labels the current element.
115
     *
116
     * @link https://w3c.github.io/aria/#aria-label
117
     */
118 2
    public function ariaLabel(?string $value): self
119
    {
120 2
        $new = clone $this;
121 2
        $new->inputTagAttributes['aria-label'] = $value;
122 2
        return $new;
123
    }
124
125
    /**
126
     * Focus on the control (put cursor into it) when the page loads. Only one form element could be in focus
127
     * at the same time.
128
     *
129
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus
130
     */
131 2
    public function autofocus(bool $value = true): self
132
    {
133 2
        $new = clone $this;
134 2
        $new->inputTagAttributes['autofocus'] = $value;
135 2
        return $new;
136
    }
137
138
    /**
139
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
140
     * keyboard navigation (usually with the Tab key, hence the name).
141
     *
142
     * It accepts an integer as a value, with different results depending on the integer's value:
143
     *
144
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
145
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
146
     *   with JavaScript.
147
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
148
     *   defined by the document's source order.
149
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
150
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
151
     *   `tabindex="3"`.
152
     *
153
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
154
     */
155 2
    public function tabIndex(?int $value): self
156
    {
157 2
        $new = clone $this;
158 2
        $new->inputTagAttributes['tabindex'] = $value;
159 2
        return $new;
160
    }
161
162
    /**
163
     * @psalm-suppress MixedAssignment,MixedArgument Remove after fix https://github.com/yiisoft/validator/issues/225
164
     */
165 27
    protected function beforeRender(): void
166
    {
167 27
        parent::beforeRender();
168 27
        if ($this->enrichmentFromRules && $this->hasFormModelAndAttribute()) {
169 2
            $rules = $this->getFormModel()->getRules()[$this->getAttributeName()] ?? [];
170 2
            foreach ($rules as $rule) {
171 2
                if ($rule instanceof Required) {
172 1
                    $this->inputTagAttributes['required'] = true;
173
                }
174
175 2
                if ($rule instanceof NumberRule) {
176 1
                    if (null !== $min = $rule->getOptions()['min']) {
177 1
                        $this->inputTagAttributes['min'] = $min;
178
                    }
179 1
                    if (null !== $max = $rule->getOptions()['max']) {
180 1
                        $this->inputTagAttributes['max'] = $max;
181
                    }
182
                }
183
            }
184
        }
185
    }
186
187 27
    protected function generateInput(): string
188
    {
189 27
        $value = $this->getAttributeValue();
190
191 27
        if (!is_numeric($value) && $value !== null) {
192 1
            throw new InvalidArgumentException('Number field requires a numeric or null value.');
193
        }
194
195 26
        $tagAttributes = $this->getInputTagAttributes();
196
197 26
        return Html::input('number', $this->getInputName(), $value, $tagAttributes)->render();
198
    }
199
200 9
    protected function prepareContainerTagAttributes(array &$attributes): void
201
    {
202 9
        if ($this->hasFormModelAndAttribute()) {
203 9
            $this->addValidationClassToTagAttributes(
204
                $attributes,
205 9
                $this->getFormModel(),
206 9
                $this->getAttributeName(),
207
            );
208
        }
209
    }
210
211 26
    protected function prepareInputTagAttributes(array &$attributes): void
212
    {
213 26
        $this->preparePlaceholderInInputTagAttributes($attributes);
214
    }
215
}
216