Passed
Push — master ( 5e485e...857d21 )
by Sergei
02:50
created

File::value()   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
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
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 Stringable;
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\ValidationClass\ValidationClassInterface;
12
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassTrait;
13
use Yiisoft\Html\Html;
14
use Yiisoft\Validator\Rule\Required;
15
use Yiisoft\Validator\WhenInterface;
16
17
/**
18
 * Represents `<input>` element of type "file" are ley the user choose one or more files from their device storage.
19
 *
20
 * @link https://html.spec.whatwg.org/multipage/input.html#file-upload-state-(type=file)
21
 * @link https://developer.mozilla.org/docs/Web/HTML/Element/input/file
22
 */
23
final class File extends InputField implements EnrichmentFromRulesInterface, ValidationClassInterface
24
{
25
    use EnrichmentFromRulesTrait;
26
    use ValidationClassTrait;
27
28
    private bool|float|int|string|Stringable|null $uncheckValue = null;
29
    private array $uncheckInputAttributes = [];
30
31
    /**
32
     * The accept attribute value is a string that defines the file types the file input should accept. This string is
33
     * a comma-separated list of unique file type specifiers. Because a given file type may be identified in more than
34
     * one manner, it's useful to provide a thorough set of type specifiers when you need files of a given format.
35
     *
36
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-accept
37
     */
38 2
    public function accept(?string $value): self
39
    {
40 2
        $new = clone $this;
41 2
        $new->inputAttributes['accept'] = $value;
42 2
        return $new;
43
    }
44
45
    /**
46
     * @param bool $multiple Whether to allow selecting multiple files.
47
     *
48
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-multiple
49
     */
50 2
    public function multiple(bool $multiple = true): self
51
    {
52 2
        $new = clone $this;
53 2
        $new->inputAttributes['multiple'] = $multiple;
54 2
        return $new;
55
    }
56
57
    /**
58
     * A boolean attribute. When specified, the element is required.
59
     *
60
     * @param bool $value Whether the control is required for form submission.
61
     *
62
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-required
63
     */
64 2
    public function required(bool $value = true): self
65
    {
66 2
        $new = clone $this;
67 2
        $new->inputAttributes['required'] = $value;
68 2
        return $new;
69
    }
70
71
    /**
72
     * @param bool $disabled Whether select input is disabled.
73
     *
74
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
75
     */
76 3
    public function disabled(bool $disabled = true): self
77
    {
78 3
        $new = clone $this;
79 3
        $new->inputAttributes['disabled'] = $disabled;
80 3
        return $new;
81
    }
82
83
    /**
84
     * Identifies the element (or elements) that describes the object.
85
     *
86
     * @link https://w3c.github.io/aria/#aria-describedby
87
     */
88 2
    public function ariaDescribedBy(?string $value): self
89
    {
90 2
        $new = clone $this;
91 2
        $new->inputAttributes['aria-describedby'] = $value;
92 2
        return $new;
93
    }
94
95
    /**
96
     * Defines a string value that labels the current element.
97
     *
98
     * @link https://w3c.github.io/aria/#aria-label
99
     */
100 2
    public function ariaLabel(?string $value): self
101
    {
102 2
        $new = clone $this;
103 2
        $new->inputAttributes['aria-label'] = $value;
104 2
        return $new;
105
    }
106
107
    /**
108
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
109
     * keyboard navigation (usually with the Tab key, hence the name).
110
     *
111
     * It accepts an integer as a value, with different results depending on the integer's value:
112
     *
113
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
114
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
115
     *   with JavaScript.
116
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
117
     *   defined by the document's source order.
118
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
119
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
120
     *   `tabindex="3"`.
121
     *
122
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
123
     */
124 2
    public function tabIndex(?int $value): self
125
    {
126 2
        $new = clone $this;
127 2
        $new->inputAttributes['tabindex'] = $value;
128 2
        return $new;
129
    }
130
131
    /**
132
     * @param bool|float|int|string|Stringable|null $value Value that corresponds to "unchecked" state of the input.
133
     */
134 6
    public function uncheckValue(bool|float|int|string|Stringable|null $value): self
135
    {
136 6
        $new = clone $this;
137 6
        $new->uncheckValue = $value;
138 6
        return $new;
139
    }
140
141 2
    public function uncheckInputAttributes(array $attributes): self
142
    {
143 2
        $new = clone $this;
144 2
        $new->uncheckInputAttributes = $attributes;
145 2
        return $new;
146
    }
147
148 2
    public function addUncheckInputAttributes(array $attributes): self
149
    {
150 2
        $new = clone $this;
151 2
        $new->uncheckInputAttributes = array_merge($new->uncheckInputAttributes, $attributes);
152 2
        return $new;
153
    }
154
155
    /**
156
     * @psalm-suppress MixedAssignment,MixedArgument
157
     */
158 16
    protected function beforeRender(): void
159
    {
160 16
        parent::beforeRender();
161 16
        if ($this->enrichmentFromRules) {
162 2
            foreach ($this->getInputData()->getValidationRules() as $rule) {
163 2
                if ($rule instanceof WhenInterface && $rule->getWhen() !== null) {
164 1
                    continue;
165
                }
166
167 1
                if ($rule instanceof Required) {
168 1
                    $this->inputAttributes['required'] = true;
169
                }
170
            }
171
        }
172
    }
173
174 16
    protected function generateInput(): string
175
    {
176 16
        $inputAttributes = $this->getInputAttributes();
177
178 16
        $tag = Html::file($this->getName(), attributes: $inputAttributes);
179 16
        if ($this->uncheckValue !== null) {
180 5
            $tag = $tag->uncheckValue($this->uncheckValue);
181 5
            if (!empty($this->uncheckInputAttributes)) {
182 2
                $tag = $tag->addUncheckInputAttributes($this->uncheckInputAttributes);
183
            }
184
        }
185
186 16
        return $tag->render();
187
    }
188
189 9
    protected function prepareContainerAttributes(array &$attributes): void
190
    {
191 9
        $this->addValidationClassToAttributes($attributes, $this->getInputData());
192
    }
193
194 16
    protected function prepareInputAttributes(array &$attributes): void
195
    {
196 16
        $this->addInputValidationClassToAttributes($attributes, $this->getInputData());
197
    }
198
}
199