Passed
Pull Request — master (#192)
by Sergei
03:07
created

Textarea::ariaDescribedBy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
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\Rule\HasLength;
17
use Yiisoft\Validator\Rule\Required;
18
19
use function is_string;
20
21
final class Textarea
22
    extends InputField
23
    implements EnrichmentFromRulesInterface, PlaceholderInterface, ValidationClassInterface
24
{
25
    use EnrichmentFromRulesTrait;
26
    use PlaceholderTrait;
27
    use ValidationClassTrait;
28
29
    /**
30
     * Maximum length of value.
31
     *
32
     * @param int $value A limit on the number of characters a user can input.
33
     *
34
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-maxlength
35
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-maxlength
36
     */
37
    public function maxlength(int $value): self
38
    {
39
        $new = clone $this;
40
        $new->inputTagAttributes['maxlength'] = $value;
41
        return $new;
42
    }
43
44
    /**
45
     * Minimum length of value.
46
     *
47
     * @param int $value A lower bound on the number of characters a user can input.
48
     *
49
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-minlength
50
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-minlength
51
     */
52
    public function minlength(int $value): self
53
    {
54
        $new = clone $this;
55
        $new->inputTagAttributes['minlength'] = $value;
56
        return $new;
57
    }
58
59
    /**
60
     * Name of form control to use for sending the element's directionality in form submission
61
     *
62
     * @param string|null $value Any string that is not empty.
63
     *
64
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-dirname
65
     */
66
    public function dirname(?string $value): self
67
    {
68
        $new = clone $this;
69
        $new->inputTagAttributes['dirname'] = $value;
70
        return $new;
71
    }
72
73
    /**
74
     * A boolean attribute that controls whether or not the user can edit the form control.
75
     *
76
     * @param bool $value Whether to allow the value to be edited by the user.
77
     *
78
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-readonly
79
     */
80
    public function readonly(bool $value = true): self
81
    {
82
        $new = clone $this;
83
        $new->inputTagAttributes['readonly'] = $value;
84
        return $new;
85
    }
86
87
    /**
88
     * A boolean attribute. When specified, the element is required.
89
     *
90
     * @param bool $value Whether the control is required for form submission.
91
     *
92
     * @link https://html.spec.whatwg.org/multipage/input.html#attr-input-required
93
     */
94
    public function required(bool $value = true): self
95
    {
96
        $new = clone $this;
97
        $new->inputTagAttributes['required'] = $value;
98
        return $new;
99
    }
100
101
    /**
102
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
103
     */
104
    public function disabled(bool $disabled = true): self
105
    {
106
        $new = clone $this;
107
        $new->inputTagAttributes['disabled'] = $disabled;
108
        return $new;
109
    }
110
111
    /**
112
     * Identifies the element (or elements) that describes the object.
113
     *
114
     * @link https://w3c.github.io/aria/#aria-describedby
115
     */
116
    public function ariaDescribedBy(string $value): self
117
    {
118
        $new = clone $this;
119
        $new->inputTagAttributes['aria-describedby'] = $value;
120
        return $new;
121
    }
122
123
    /**
124
     * Defines a string value that labels the current element.
125
     *
126
     * @link https://w3c.github.io/aria/#aria-label
127
     */
128
    public function ariaLabel(string $value): self
129
    {
130
        $new = clone $this;
131
        $new->inputTagAttributes['aria-label'] = $value;
132
        return $new;
133
    }
134
135
    /**
136
     * Focus on the control (put cursor into it) when the page loads. Only one form element could be in focus
137
     * at the same time.
138
     *
139
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus
140
     */
141
    public function autofocus(bool $value = true): self
142
    {
143
        $new = clone $this;
144
        $new->inputTagAttributes['autofocus'] = $value;
145
        return $new;
146
    }
147
148
    /**
149
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
150
     * keyboard navigation (usually with the Tab key, hence the name).
151
     *
152
     * It accepts an integer as a value, with different results depending on the integer's value:
153
     *
154
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
155
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
156
     *   with JavaScript.
157
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
158
     *   defined by the document's source order.
159
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
160
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
161
     *   `tabindex="3"`.
162
     *
163
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
164
     */
165
    public function tabIndex(?int $value): self
166
    {
167
        $new = clone $this;
168
        $new->inputTagAttributes['tabindex'] = $value;
169
        return $new;
170
    }
171
172
    /**
173
     * The expected maximum number of characters per line of text to show.
174
     *
175
     * @link https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-cols
176
     */
177
    public function cols(?int $value): self
178
    {
179
        $new = clone $this;
180
        $new->inputTagAttributes['cols'] = $value;
181
        return $new;
182
    }
183
184
    /**
185
     * The number of lines of text to show.
186
     *
187
     * @link https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-rows
188
     */
189
    public function rows(?int $value): self
190
    {
191
        $new = clone $this;
192
        $new->inputTagAttributes['rows'] = $value;
193
        return $new;
194
    }
195
196
    /**
197
     * Define how the value of the form control is to be wrapped for form submission:
198
     *  - `hard` indicates that the text in the `textarea` is to have newlines added by the user agent so that the text
199
     *    is wrapped when it is submitted.
200
     *  - `soft` indicates that the text in the `textarea` is not to be wrapped when it is submitted (though it can
201
     *    still be wrapped in the rendering).
202
     *
203
     * @link https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-wrap
204
     */
205
    public function wrap(?string $value): self
206
    {
207
        $new = clone $this;
208
        $new->inputTagAttributes['wrap'] = $value;
209
        return $new;
210
    }
211
212
    /**
213
     * @psalm-suppress MixedAssignment,MixedArgument Remove after fix https://github.com/yiisoft/validator/issues/225
214
     */
215 1
    protected function beforeRender(): void
216
    {
217 1
        parent::beforeRender();
218 1
        if ($this->enrichmentFromRules && $this->hasFormModelAndAttribute()) {
219
            $rules = $this->getFormModel()->getRules()[$this->getAttributeName()] ?? [];
220
            foreach ($rules as $rule) {
221
                if ($rule instanceof Required) {
222
                    $this->inputTagAttributes['required'] = true;
223
                }
224
225
                if ($rule instanceof HasLength) {
226
                    if (null !== $min = $rule->getOptions()['min']) {
227
                        $this->inputTagAttributes['minlength'] = $min;
228
                    }
229
                    if (null !== $max = $rule->getOptions()['max']) {
230
                        $this->inputTagAttributes['maxlength'] = $max;
231
                    }
232
                }
233
            }
234
        }
235
    }
236
237 1
    protected function generateInput(): string
238
    {
239 1
        $value = $this->getAttributeValue();
240
241 1
        if (!is_string($value) && $value !== null) {
242
            throw new InvalidArgumentException('Textarea widget must be a string or null value.');
243
        }
244
245 1
        $tagAttributes = $this->getInputTagAttributes();
246
247 1
        return Html::textarea($this->getInputName(), $value, $tagAttributes)->render();
248
    }
249
250 1
    protected function prepareContainerTagAttributes(array &$attributes): void
251
    {
252 1
        if ($this->hasFormModelAndAttribute()) {
253 1
            $this->addValidationClassToTagAttributes(
254
                $attributes,
255 1
                $this->getFormModel(),
256 1
                $this->getAttributeName(),
257
            );
258
        }
259
    }
260
261 1
    protected function prepareInputTagAttributes(array &$attributes): void
262
    {
263 1
        $this->preparePlaceholderInInputTagAttributes($attributes);
264
    }
265
}
266