Passed
Push — master ( 4c4f3f...4700f4 )
by Sergei
02:48
created

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