Test Failed
Pull Request — master (#159)
by Sergei
02:19
created

AbstractField::getFormModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 0
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Field\Base;
6
7
use InvalidArgumentException;
8
use Stringable;
9
use Yiisoft\Form\FormModelInterface;
10
use Yiisoft\Form\Helper\HtmlForm;
11
use Yiisoft\Html\Tag\Base\Tag;
12
use Yiisoft\Html\Tag\Base\TagContentInterface;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Html\Tag\Base\TagContentInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Yiisoft\Html\Tag\Div;
14
use Yiisoft\Html\Tag\Label;
15
use Yiisoft\Widget\Widget;
16
17
abstract class AbstractField extends Widget
18
{
19
    private ?FormModelInterface $formModel = null;
20
    private string $attribute = '';
21
22
    private ?TagContentInterface $containerTag = null;
23
    private bool $withoutContainer = false;
24
25
    private string $template = "{label}\n{input}\n{hint}\n{error}";
26
27
    private ?string $inputId = null;
28
    private bool $setInputIdAttribute = true;
29
30
    private ?Label $labelTag = null;
31
    private ?string $labelContent = null;
32
    private bool $setLabelForAttribute = true;
33
34
    private ?TagContentInterface $hintTag = null;
35
    private ?string $hintContent = null;
36
37
    /**
38
     * @return static
39
     */
40
    final public function attribute(FormModelInterface $formModel, string $attribute): self
41
    {
42
        $new = clone $this;
43
        $new->formModel = $formModel;
44
        $new->attribute = $attribute;
45
        return $new;
46
    }
47
48
    final public function containerTag(?TagContentInterface $tag): self
49
    {
50
        $new = clone $this;
51
        $new->containerTag = $tag;
52
        return $new;
53
    }
54
55
    final public function withoutContainer(): self
56
    {
57
        $new = clone $this;
58
        $new->withoutContainer = true;
59
        return $new;
60
    }
61
62
    /**
63
     * Set layout template for render a field.
64
     *
65
     * @param string $template
66
     *
67
     * @return static
68
     */
69
    final public function template(string $template): self
70
    {
71
        $new = clone $this;
72
        $new->template = $template;
73
        return $new;
74
    }
75
76
    final public function id(?string $id): self
77
    {
78
        $new = clone $this;
79
        $new->inputId = $id;
80
        return $new;
81
    }
82
83
    final public function doNotSetInputIdAttribute(): self
84
    {
85
        $new = clone $this;
86
        $new->setInputIdAttribute = false;
87
        return $new;
88
    }
89
90
    final public function labelTag(?Label $tag): self
91
    {
92
        $new = clone $this;
93
        $new->labelTag = $tag;
94
        return $new;
95
    }
96
97
    final public function label(?string $content): self
98
    {
99
        $new = clone $this;
100
        $new->labelContent = $content;
101
        return $new;
102
    }
103
104
    final public function doNotSetLabelForAttribute(): self
105
    {
106
        $new = clone $this;
107
        $new->setLabelForAttribute = false;
108
        return $new;
109
    }
110
111
    final public function hintTag(?TagContentInterface $tag): self
112
    {
113
        $new = clone $this;
114
        $new->hintTag = $tag;
115
        return $new;
116
    }
117
118
    final public function hint(?string $content): self
119
    {
120
        $new = clone $this;
121
        $new->hintContent = $content;
122
        return $new;
123
    }
124
125
    final protected function getFormModel(): FormModelInterface
126
    {
127
        if ($this->formModel === null) {
128
            throw new InvalidArgumentException('Form model is not set.');
129
        }
130
131
        return $this->formModel;
132
    }
133
134
    final protected function getInputName(): string
135
    {
136
        return HtmlForm::getInputName($this->getFormModel(), $this->attribute);
137
    }
138
139
    final protected function getInputId(): ?string
140
    {
141
        if (!$this->setInputIdAttribute) {
142
            return null;
143
        }
144
145
        return $this->inputId ?? HtmlForm::getInputId($this->getFormModel(), $this->attribute);
146
    }
147
148
    /**
149
     * @return bool|float|int|iterable|object|string|Stringable|null
150
     */
151
    final protected function getAttributeValue()
152
    {
153
        return HtmlForm::getAttributeValue($this->getFormModel(), $this->attribute);
154
    }
155
156
    final protected function getAttributeLabel(): string
157
    {
158
        return HtmlForm::getAttributeLabel($this->getFormModel(), $this->attribute);
159
    }
160
161
    final protected function getAttributeHint(): string
162
    {
163
        return HtmlForm::getAttributeHint($this->getFormModel(), $this->attribute);
164
    }
165
166
    final protected function getAttributePlaceholder(): ?string
167
    {
168
        return $this->getFormModel()->getAttributePlaceholder($this->attribute);
169
    }
170
171
    final protected function prepareIdInInputTag(Tag $tag): Tag
172
    {
173
        if (
174
            $this->setInputIdAttribute
175
            && $tag->getAttribute('id') === null
0 ignored issues
show
Bug introduced by
The method getAttribute() does not exist on Yiisoft\Html\Tag\Base\Tag. ( Ignorable by Annotation )

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

175
            && $tag->/** @scrutinizer ignore-call */ getAttribute('id') === null

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
176
        ) {
177
            $id = $this->getInputId();
178
            if ($id !== null) {
179
                $tag = $tag->id($id);
180
            }
181
        }
182
183
        return $tag;
184
    }
185
186
    final protected function run(): string
187
    {
188
        if ($this->withoutContainer) {
189
            return $this->generateContent();
190
        }
191
192
        $containerTag = $this->containerTag ?? Div::tag();
193
194
        return $containerTag->open()
195
            . PHP_EOL
196
            . $this->generateContent()
197
            . PHP_EOL
198
            . $containerTag->close();
199
    }
200
201
    abstract protected function generateInput(): string;
202
203
    private function generateContent(): string
204
    {
205
        $parts = [
206
            '{label}' => $this->generateLabel(),
207
            '{input}' => $this->generateInput(),
208
            '{hint}' => $this->generateHint(),
209
            '{error}' => $this->generateError(),
210
        ];
211
212
        return preg_replace('/^\h*\v+/m', '', trim(strtr($this->template, $parts)));
213
    }
214
215
    private function generateLabel(): string
216
    {
217
        $tag = $this->labelTag ?? Label::tag();
218
219
        if ($this->labelContent !== null) {
220
            $tag = $tag->content($this->labelContent);
221
        } elseif ($tag->getContent() === '') {
0 ignored issues
show
Bug introduced by
The method getContent() does not exist on Yiisoft\Html\Tag\Label. ( Ignorable by Annotation )

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

221
        } elseif ($tag->/** @scrutinizer ignore-call */ getContent() === '') {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
222
            $tag = $tag->content($this->getAttributeLabel());
223
        }
224
225
        if (
226
            $this->setLabelForAttribute
227
            && $tag->getAttribute('for') === null
0 ignored issues
show
Bug introduced by
The method getAttribute() does not exist on Yiisoft\Html\Tag\Label. ( Ignorable by Annotation )

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

227
            && $tag->/** @scrutinizer ignore-call */ getAttribute('for') === null

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
228
        ) {
229
            $id = $this->getInputId();
230
            if ($id !== null) {
231
                $tag = $tag->forId($id);
232
            }
233
        }
234
235
        return $tag->render();
236
    }
237
238
    private function generateHint(): string
239
    {
240
        $tag = $this->hintTag ?? Div::tag();
241
242
        if ($this->hintContent !== null) {
243
            $tag = $tag->content($this->hintContent);
244
        } elseif ($tag->getContent() === '') {
0 ignored issues
show
Bug introduced by
The method getContent() does not exist on Yiisoft\Html\Tag\Div. ( Ignorable by Annotation )

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

244
        } elseif ($tag->/** @scrutinizer ignore-call */ getContent() === '') {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
245
            $tag = $tag->content($this->getAttributeHint());
246
        }
247
248
        return $tag->render();
249
    }
250
251
    private function generateError(): string
252
    {
253
        return '';
254
    }
255
}
256