Passed
Push — master ( 6b3bd5...b249fa )
by Sergei
05:31 queued 02:48
created

File   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Test Coverage

Coverage 98.31%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 49
c 1
b 0
f 0
dl 0
loc 167
ccs 58
cts 59
cp 0.9831
rs 10
wmc 17

14 Methods

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