Passed
Pull Request — master (#192)
by Sergei
19:23 queued 16:27
created

InputField::inputId()   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\Base;
6
7
use Yiisoft\Form\Field\Part\Error;
8
use Yiisoft\Form\Field\Part\Hint;
9
use Yiisoft\Form\Field\Part\Label;
10
use Yiisoft\Form\Helper\HtmlForm;
11
12
use function in_array;
13
14
abstract class InputField extends PartsField
15
{
16
    use FormAttributeTrait;
17
18
    protected ?string $inputId = null;
19
    protected ?string $inputIdFromTag = null;
20
    protected bool $setInputIdAttribute = true;
21
22
    protected array $inputTagAttributes = [];
23
24
    /**
25
     * Identifies the element (or elements) that describes the object.
26
     *
27
     * @link https://w3c.github.io/aria/#aria-describedby
28
     */
29
    final public function ariaDescribedBy(string $value): static
30
    {
31
        $new = clone $this;
32
        $new->inputTagAttributes['aria-describedby'] = $value;
33
        return $new;
34
    }
35
36
    /**
37
     * Defines a string value that labels the current element.
38
     *
39
     * @link https://w3c.github.io/aria/#aria-label
40
     */
41
    final public function ariaLabel(string $value): static
42
    {
43
        $new = clone $this;
44
        $new->inputTagAttributes['aria-label'] = $value;
45
        return $new;
46
    }
47
48
    /**
49
     * Specifies the form element the tag input element belongs to. The value of this attribute must be the ID
50
     * attribute of a form element in the same document.
51
     *
52
     * @link https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form
53
     */
54
    final public function form(string $value): static
55
    {
56
        $new = clone $this;
57
        $new->inputTagAttributes['form'] = $value;
58
        return $new;
59
    }
60
61
    /**
62
     * The `tabindex` attribute indicates that its element can be focused, and where it participates in sequential
63
     * keyboard navigation (usually with the Tab key, hence the name).
64
     *
65
     * It accepts an integer as a value, with different results depending on the integer's value:
66
     *
67
     * - A negative value (usually `tabindex="-1"`) means that the element is not reachable via sequential keyboard
68
     *   navigation, but could be focused with Javascript or visually. It's mostly useful to create accessible widgets
69
     *   with JavaScript.
70
     * - `tabindex="0"` means that the element should be focusable in sequential keyboard navigation, but its order is
71
     *   defined by the document's source order.
72
     * - A positive value means the element should be focusable in sequential keyboard navigation, with its order
73
     *   defined by the value of the number. That is, `tabindex="4"` is focused before `tabindex="5"`, but after
74
     *   `tabindex="3"`.
75
     *
76
     * @link https://html.spec.whatwg.org/multipage/interaction.html#attr-tabindex
77
     */
78
    final public function tabIndex(?int $value): static
79
    {
80
        $new = clone $this;
81
        $new->inputTagAttributes['tabindex'] = $value;
82
        return $new;
83
    }
84
85 2
    final public function inputId(?string $inputId): static
86
    {
87 2
        $new = clone $this;
88 2
        $new->inputId = $inputId;
89 2
        return $new;
90
    }
91
92 2
    final public function setInputIdAttribute(bool $value): static
93
    {
94 2
        $new = clone $this;
95 2
        $new->setInputIdAttribute = $value;
96 2
        return $new;
97
    }
98
99 6
    final public function inputTagAttributes(array $attributes): static
100
    {
101 6
        $new = clone $this;
102 6
        $new->inputTagAttributes = $attributes;
103 6
        return $new;
104
    }
105
106 74
    final protected function getInputName(): string
107
    {
108 74
        return HtmlForm::getInputName($this->getFormModel(), $this->attribute);
109
    }
110
111 70
    final protected function getInputTagAttributes(): array
112
    {
113 70
        $attributes = $this->inputTagAttributes;
114
115 70
        $this->prepareIdInInputTagAttributes($attributes);
116
117 70
        if ($this->isUsePlaceholder()) {
118
            /** @psalm-suppress UndefinedMethod */
119 42
            $this->preparePlaceholderInInputTagAttributes($attributes);
0 ignored issues
show
Bug introduced by
The method preparePlaceholderInInputTagAttributes() does not exist on Yiisoft\Form\Field\Base\InputField. It seems like you code against a sub-type of Yiisoft\Form\Field\Base\InputField such as Yiisoft\Form\Field\Email or Yiisoft\Form\Field\Url or Yiisoft\Form\Field\Text or Yiisoft\Form\Field\Number or Yiisoft\Form\Field\Telephone or Yiisoft\Form\Field\Password or Yiisoft\Form\Field\Textarea. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

119
            $this->/** @scrutinizer ignore-call */ 
120
                   preparePlaceholderInInputTagAttributes($attributes);
Loading history...
120
        }
121
122 70
        return $attributes;
123
    }
124
125 70
    final protected function prepareIdInInputTagAttributes(array &$attributes): void
126
    {
127
        /** @var mixed $idFromTag */
128 70
        $idFromTag = $attributes['id'] ?? null;
129 70
        if ($idFromTag !== null) {
130 2
            $this->inputIdFromTag = (string) $idFromTag;
131
        }
132
133 70
        if ($this->setInputIdAttribute) {
134 68
            if ($this->inputId !== null) {
135 2
                $attributes['id'] = $this->inputId;
136 66
            } elseif ($idFromTag === null) {
137 65
                $attributes['id'] = $this->getInputId();
138
            }
139
        }
140
    }
141
142 59
    final protected function generateLabel(): string
143
    {
144 59
        $label = Label::widget($this->labelConfig)
145 59
            ->attribute($this->getFormModel(), $this->attribute);
0 ignored issues
show
Bug introduced by
The method attribute() does not exist on Yiisoft\Widget\Widget. It seems like you code against a sub-type of Yiisoft\Widget\Widget such as Yiisoft\Form\Field\Part\Label or Yiisoft\Form\Field\Part\Error or Yiisoft\Form\Field\Part\Hint or Yiisoft\Form\Field\RadioList or Yiisoft\Form\Field\Base\InputField or Yiisoft\Form\Field\CheckboxList. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

145
            ->/** @scrutinizer ignore-call */ attribute($this->getFormModel(), $this->attribute);
Loading history...
146
147 59
        if ($this->setInputIdAttribute === false) {
148 2
            $label = $label->useInputIdAttribute(false);
149
        }
150
151 59
        if ($this->inputId !== null) {
152 2
            $label = $label->forId($this->inputId);
153 57
        } elseif ($this->inputIdFromTag !== null) {
154 1
            $label = $label->forId($this->inputIdFromTag);
155
        }
156
157 59
        return $label->render();
158
    }
159
160 74
    final protected function generateHint(): string
161
    {
162 74
        return Hint::widget($this->hintConfig)
163 74
            ->attribute($this->getFormModel(), $this->attribute)
164 74
            ->render();
165
    }
166
167 74
    final protected function generateError(): string
168
    {
169 74
        return Error::widget($this->errorConfig)
170 74
            ->attribute($this->getFormModel(), $this->attribute)
171 74
            ->render();
172
    }
173
174 70
    private function isUsePlaceholder(): bool
175
    {
176 70
        $traits = class_uses($this);
177 70
        return in_array(PlaceholderTrait::class, $traits, true);
178
    }
179
}
180