Test Failed
Pull Request — master (#192)
by Sergei
02:42
created

FieldFactory::error()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 7
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form;
6
7
use InvalidArgumentException;
8
use Yiisoft\Form\Field\Base\EnrichmentFromRules\EnrichmentFromRulesInterface;
9
use Yiisoft\Form\Field\Base\InputField;
10
use Yiisoft\Form\Field\Base\PartsField;
11
use Yiisoft\Form\Field\Base\Placeholder\PlaceholderInterface;
12
use Yiisoft\Form\Field\Base\ValidationClass\ValidationClassInterface;
13
use Yiisoft\Form\Field\Button;
14
use Yiisoft\Form\Field\ButtonGroup;
15
use Yiisoft\Form\Field\Checkbox;
16
use Yiisoft\Form\Field\CheckboxList;
17
use Yiisoft\Form\Field\Date;
18
use Yiisoft\Form\Field\DateTime;
19
use Yiisoft\Form\Field\DateTimeLocal;
20
use Yiisoft\Form\Field\Email;
21
use Yiisoft\Form\Field\ErrorSummary;
22
use Yiisoft\Form\Field\Fieldset;
23
use Yiisoft\Form\Field\File;
24
use Yiisoft\Form\Field\Hidden;
25
use Yiisoft\Form\Field\Image;
26
use Yiisoft\Form\Field\Number;
27
use Yiisoft\Form\Field\Part\Error;
28
use Yiisoft\Form\Field\Part\Hint;
29
use Yiisoft\Form\Field\Part\Label;
30
use Yiisoft\Form\Field\Password;
31
use Yiisoft\Form\Field\RadioList;
32
use Yiisoft\Form\Field\Range;
33
use Yiisoft\Form\Field\ResetButton;
34
use Yiisoft\Form\Field\Select;
35
use Yiisoft\Form\Field\SubmitButton;
36
use Yiisoft\Form\Field\Telephone;
37
use Yiisoft\Form\Field\Text;
38
use Yiisoft\Form\Field\Textarea;
39
use Yiisoft\Form\Field\Url;
40
use Yiisoft\Widget\WidgetFactory;
41
42
final class FieldFactory
43
{
44
    /**
45
     * @param array[] $fieldConfigs
46
     */
47
    public function __construct(
48
        private ?string $containerTag = null,
49
        private array $containerAttributes = [],
50
        private string|array|null $containerClass = null,
51
        private ?bool $useContainer = null,
52
        private ?string $template = null,
53
        private ?string $templateBegin = null,
54
        private ?string $templateEnd = null,
55
        private ?bool $setInputId = null,
56
        private array $inputAttributes = [],
57
        private string|array|null $inputClass = null,
58
        string|array|null $labelClass = null,
59
        private array $labelConfig = [],
60
        string|array|null $hintClass = null,
61
        private array $hintConfig = [],
62
        string|array|null $errorClass = null,
63
        private array $errorConfig = [],
64
        private ?bool $usePlaceholder = null,
65
        private ?string $validClass = null,
66
        private ?string $invalidClass = null,
67
        private ?bool $enrichmentFromRules = null,
68
        private array $fieldConfigs = [],
69
    ) {
70
        if ($labelClass !== null) {
71
            $this->labelConfig['class()'] = is_array($labelClass) ? $labelClass : [$labelClass];
0 ignored issues
show
introduced by
The condition is_array($labelClass) is always true.
Loading history...
72
        }
73
        if ($hintClass !== null) {
74
            $this->hintConfig['class()'] = is_array($hintClass) ? $hintClass : [$hintClass];
0 ignored issues
show
introduced by
The condition is_array($hintClass) is always true.
Loading history...
75
        }
76
        if ($errorClass !== null) {
77
            $this->errorConfig['class()'] = is_array($errorClass) ? $errorClass : [$errorClass];
0 ignored issues
show
introduced by
The condition is_array($errorClass) is always true.
Loading history...
78
        }
79
    }
80
81
    public function button(array $config = []): Button
82
    {
83
        return $this->field(Button::class, $config);
84
    }
85
86
    public function buttonGroup(array $config = []): ButtonGroup
87
    {
88
        return $this->field(ButtonGroup::class, $config);
89
    }
90
91
    public function checkbox(FormModelInterface $formModel, string $attribute, array $config = []): Checkbox
92
    {
93
        return $this->input(Checkbox::class, $formModel, $attribute, $config);
94
    }
95
96
    public function checkboxList(FormModelInterface $formModel, string $attribute, array $config = []): CheckboxList
97
    {
98
        return $this
99
            ->field(CheckboxList::class, $config)
100
            ->formAttribute($formModel, $attribute);
101
    }
102
103
    public function date(FormModelInterface $formModel, string $attribute, array $config = []): Date
104
    {
105
        return $this->input(Date::class, $formModel, $attribute, $config);
106
    }
107
108
    public function dateTime(FormModelInterface $formModel, string $attribute, array $config = []): DateTime
109
    {
110
        return $this->input(DateTime::class, $formModel, $attribute, $config);
111
    }
112
113
    public function dateTimeLocal(FormModelInterface $formModel, string $attribute, array $config = []): DateTimeLocal
114
    {
115
        return $this->input(DateTimeLocal::class, $formModel, $attribute, $config);
116
    }
117
118
    public function email(FormModelInterface $formModel, string $attribute, array $config = []): Email
119
    {
120
        return $this->input(Email::class, $formModel, $attribute, $config);
121
    }
122
123
    public function errorSummary(FormModelInterface $formModel, array $config = []): ErrorSummary
124
    {
125
        return $this
126
            ->field(ErrorSummary::class, $config)
127
            ->formModel($formModel);
128
    }
129
130
    public function fieldset(array $config = []): Fieldset
131
    {
132
        return $this->field(Fieldset::class, $config);
133
    }
134
135
    public function file(FormModelInterface $formModel, string $attribute, array $config = []): File
136
    {
137
        return $this->input(File::class, $formModel, $attribute, $config);
138
    }
139
140
    public function hidden(FormModelInterface $formModel, string $attribute, array $config = []): Hidden
141
    {
142
        return $this->input(Hidden::class, $formModel, $attribute, $config);
143
    }
144
145
    public function image(array $config = []): Image
146
    {
147
        return $this->field(Image::class, $config);
148
    }
149
150
    public function number(FormModelInterface $formModel, string $attribute, array $config = []): Number
151
    {
152
        return $this->input(Number::class, $formModel, $attribute, $config);
153
    }
154
155
    public function password(FormModelInterface $formModel, string $attribute, array $config = []): Password
156
    {
157
        return $this->input(Password::class, $formModel, $attribute, $config);
158
    }
159
160
    public function radioList(FormModelInterface $formModel, string $attribute, array $config = []): RadioList
161
    {
162
        return $this
163
            ->field(RadioList::class, $config)
164
            ->formAttribute($formModel, $attribute);
165
    }
166
167
    public function range(FormModelInterface $formModel, string $attribute, array $config = []): Range
168
    {
169
        return $this->input(Range::class, $formModel, $attribute, $config);
170
    }
171
172
    public function resetButton(array $config = []): ResetButton
173
    {
174
        return $this->field(ResetButton::class, $config);
175
    }
176
177
    public function select(FormModelInterface $formModel, string $attribute, array $config = []): Select
178
    {
179
        return $this->input(Select::class, $formModel, $attribute, $config);
180
    }
181
182
    public function submitButton(array $config = []): SubmitButton
183
    {
184
        return $this->field(SubmitButton::class, $config);
185
    }
186
187
    public function telephone(FormModelInterface $formModel, string $attribute, array $config = []): Telephone
188
    {
189
        return $this->input(Telephone::class, $formModel, $attribute, $config);
190
    }
191
192
    public function text(FormModelInterface $formModel, string $attribute, array $config = []): Text
193
    {
194
        return $this->input(Text::class, $formModel, $attribute, $config);
195
    }
196
197
    public function textarea(FormModelInterface $formModel, string $attribute, array $config = []): Textarea
198
    {
199
        return $this->input(Textarea::class, $formModel, $attribute, $config);
200
    }
201
202
    public function url(FormModelInterface $formModel, string $attribute, array $config = []): Url
203
    {
204
        return $this->input(Url::class, $formModel, $attribute, $config);
205
    }
206
207
    public function label(FormModelInterface $formModel, string $attribute, array $config = []): Label
208
    {
209
        $widgetConfig = array_merge(
210
            $this->labelConfig,
211
            $config,
212
        );
213
        return Label::widget($widgetConfig)->formAttribute($formModel, $attribute);
0 ignored issues
show
Bug introduced by
The method formAttribute() 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

213
        return Label::widget($widgetConfig)->/** @scrutinizer ignore-call */ formAttribute($formModel, $attribute);
Loading history...
214
    }
215
216
    public function hint(FormModelInterface $formModel, string $attribute, array $config = []): Hint
217
    {
218
        $widgetConfig = array_merge(
219
            $this->hintConfig,
220
            $config,
221
        );
222
        return Hint::widget($widgetConfig)->formAttribute($formModel, $attribute);
223
    }
224
225
    public function error(FormModelInterface $formModel, string $attribute, array $config = []): Error
226
    {
227
        $widgetConfig = array_merge(
228
            $this->errorConfig,
229
            $config,
230
        );
231
        return Error::widget($widgetConfig)->formAttribute($formModel, $attribute);
232
    }
233
234
    /**
235
     * @psalm-template T
236
     * @psalm-param class-string<T> $class
237
     * @psalm-return T
238
     */
239
    public function input(string $class, FormModelInterface $formModel, string $attribute, array $config = []): object
240
    {
241
        $widget = $this->field($class, $config);
242
        if (!$widget instanceof InputField) {
243
            throw new InvalidArgumentException(
244
                sprintf(
245
                    'Input widget must be instance of "%s".',
246
                    InputField::class
247
                )
248
            );
249
        }
250
251
        return $widget->formAttribute($formModel, $attribute);
252
    }
253
254
    /**
255
     * @psalm-template T
256
     * @psalm-param class-string<T> $class
257
     * @psalm-return T
258
     */
259
    public function field(string $class, array $config = []): object
260
    {
261
        $config = array_merge(
262
            $this->makeFieldConfig($class),
263
            $this->fieldConfigs[$class] ?? [],
264
            $config,
265
            ['class' => $class],
266
        );
267
268
        /** @psalm-var T */
269
        return WidgetFactory::createWidget($config);
270
    }
271
272
    /**
273
     * @psalm-param class-string $class
274
     */
275
    private function makeFieldConfig(string $class): array
276
    {
277
        $config = [];
278
279
        if ($this->containerTag !== null) {
280
            $config['containerTag()'] = [$this->containerTag];
281
        }
282
        if ($this->containerAttributes !== []) {
283
            $config['containerAttributes()'] = [$this->containerAttributes];
284
        }
285
        if ($this->containerClass !== null) {
286
            $config['containerClass()'] = is_array($this->containerClass)
287
                ? $this->containerClass
288
                : [$this->containerClass];
289
        }
290
        if ($this->useContainer !== null) {
291
            $config['useContainer()'] = [$this->useContainer];
292
        }
293
294
        if (is_a($class, PartsField::class, true)) {
295
            if ($this->template !== null) {
296
                $config['template()'] = [$this->template];
297
            }
298
            if ($this->templateBegin !== null) {
299
                $config['templateBegin()'] = [$this->templateBegin];
300
            }
301
            if ($this->templateEnd !== null) {
302
                $config['templateEnd()'] = [$this->templateEnd];
303
            }
304
            if ($this->labelConfig !== []) {
305
                $config['labelConfig()'] = [$this->labelConfig];
306
            }
307
            if ($this->hintConfig !== []) {
308
                $config['hintConfig()'] = [$this->hintConfig];
309
            }
310
            if ($this->errorConfig !== []) {
311
                $config['errorConfig()'] = [$this->errorConfig];
312
            }
313
        }
314
315
        if (is_a($class, InputField::class, true)) {
316
            if ($this->setInputId !== null) {
317
                $config['setInputId()'] = [$this->setInputId];
318
                if ($this->setInputId === false) {
319
                    $config['labelConfig()'] = [
320
                        $this->labelConfig + ['useInputId()' => [false]],
321
                    ];
322
                }
323
            }
324
            if ($this->inputAttributes !== []) {
325
                $config['inputAttributes()'] = [$this->inputAttributes];
326
            }
327
            if ($this->inputClass !== null) {
328
                $config['inputClass()'] = is_array($this->inputClass)
329
                    ? $this->inputClass
330
                    : [$this->inputClass];
331
            }
332
        }
333
334
        if (is_a($class, PlaceholderInterface::class, true)) {
335
            if ($this->usePlaceholder !== null) {
336
                $config['usePlaceholder()'] = [$this->usePlaceholder];
337
            }
338
        }
339
340
        if (is_a($class, EnrichmentFromRulesInterface::class, true)) {
341
            if ($this->enrichmentFromRules !== null) {
342
                $config['enrichmentFromRules()'] = [$this->enrichmentFromRules];
343
            }
344
        }
345
346
        if (is_a($class, ValidationClassInterface::class, true)) {
347
            if ($this->validClass !== null) {
348
                $config['validClass()'] = [$this->validClass];
349
            }
350
            if ($this->invalidClass !== null) {
351
                $config['invalidClass()'] = [$this->invalidClass];
352
            }
353
        }
354
355
        return $config;
356
    }
357
}
358