Test Failed
Pull Request — master (#238)
by
unknown
02:27
created

FieldFactory::time()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 3
ccs 1
cts 1
cp 1
crap 1
rs 10
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\Time;
40
use Yiisoft\Form\Field\Url;
41
use Yiisoft\Widget\WidgetFactory;
42
43
final class FieldFactory
44
{
45
    /**
46
     * @param array[] $fieldConfigs
47 44
     */
48
    public function __construct(
49
        private ?string $containerTag = null,
50
        private array $containerAttributes = [],
51
        private string|array|null $containerClass = null,
52
        private ?bool $useContainer = null,
53
        private ?string $template = null,
54
        private ?string $templateBegin = null,
55
        private ?string $templateEnd = null,
56
        private ?bool $setInputId = null,
57
        private array $inputAttributes = [],
58
        private string|array|null $inputClass = null,
59
        private ?string $inputContainerTag = null,
60
        private array $inputContainerAttributes = [],
61
        private string|array|null $inputContainerClass = null,
62
        string|array|null $labelClass = null,
63
        private array $labelConfig = [],
64
        string|array|null $hintClass = null,
65
        private array $hintConfig = [],
66
        string|array|null $errorClass = null,
67
        private array $errorConfig = [],
68
        private ?bool $usePlaceholder = null,
69
        private ?string $validClass = null,
70
        private ?string $invalidClass = null,
71
        private ?string $inputValidClass = null,
72
        private ?string $inputInvalidClass = null,
73
        private ?bool $enrichmentFromRules = null,
74
        private array $fieldConfigs = [],
75 44
    ) {
76 2
        if ($labelClass !== null) {
77
            $this->labelConfig['class()'] = is_array($labelClass) ? $labelClass : [$labelClass];
0 ignored issues
show
introduced by
The condition is_array($labelClass) is always true.
Loading history...
78 44
        }
79 2
        if ($hintClass !== null) {
80
            $this->hintConfig['class()'] = is_array($hintClass) ? $hintClass : [$hintClass];
0 ignored issues
show
introduced by
The condition is_array($hintClass) is always true.
Loading history...
81 44
        }
82 2
        if ($errorClass !== null) {
83
            $this->errorConfig['class()'] = is_array($errorClass) ? $errorClass : [$errorClass];
0 ignored issues
show
introduced by
The condition is_array($errorClass) is always true.
Loading history...
84
        }
85
    }
86 1
87
    public function button(?string $content = null, array $config = []): Button
88 1
    {
89
        $field = $this->field(Button::class, $config);
90 1
91 1
        if ($content !== null) {
92
            $field = $field->content($content);
93
        }
94 1
95
        return $field;
96
    }
97 1
98
    public function buttonGroup(array $config = []): ButtonGroup
99 1
    {
100
        return $this->field(ButtonGroup::class, $config);
101
    }
102 1
103
    public function checkbox(FormModelInterface $formModel, string $attribute, array $config = []): Checkbox
104 1
    {
105
        return $this->input(Checkbox::class, $formModel, $attribute, $config);
106
    }
107 1
108
    public function checkboxList(FormModelInterface $formModel, string $attribute, array $config = []): CheckboxList
109 1
    {
110 1
        return $this
111 1
            ->field(CheckboxList::class, $config)
112
            ->formAttribute($formModel, $attribute);
113
    }
114 1
115
    public function date(FormModelInterface $formModel, string $attribute, array $config = []): Date
116 1
    {
117
        return $this->input(Date::class, $formModel, $attribute, $config);
118
    }
119 1
120
    public function dateTime(FormModelInterface $formModel, string $attribute, array $config = []): DateTime
121 1
    {
122
        return $this->input(DateTime::class, $formModel, $attribute, $config);
123
    }
124 1
125
    public function dateTimeLocal(FormModelInterface $formModel, string $attribute, array $config = []): DateTimeLocal
126 1
    {
127
        return $this->input(DateTimeLocal::class, $formModel, $attribute, $config);
128
    }
129 1
130
    public function email(FormModelInterface $formModel, string $attribute, array $config = []): Email
131 1
    {
132
        return $this->input(Email::class, $formModel, $attribute, $config);
133
    }
134 3
135
    public function errorSummary(FormModelInterface $formModel, array $config = []): ErrorSummary
136 3
    {
137 3
        return $this
138 3
            ->field(ErrorSummary::class, $config)
139
            ->formModel($formModel);
140
    }
141 4
142
    public function fieldset(array $config = []): Fieldset
143 4
    {
144
        return $this->field(Fieldset::class, $config);
145
    }
146 1
147
    public function file(FormModelInterface $formModel, string $attribute, array $config = []): File
148 1
    {
149
        return $this->input(File::class, $formModel, $attribute, $config);
150
    }
151 2
152
    public function hidden(FormModelInterface $formModel, string $attribute, array $config = []): Hidden
153 2
    {
154
        return $this->input(Hidden::class, $formModel, $attribute, $config);
155
    }
156 1
157
    public function image(array $config = []): Image
158 1
    {
159
        return $this->field(Image::class, $config);
160
    }
161 1
162
    public function number(FormModelInterface $formModel, string $attribute, array $config = []): Number
163 1
    {
164
        return $this->input(Number::class, $formModel, $attribute, $config);
165
    }
166 1
167
    public function password(FormModelInterface $formModel, string $attribute, array $config = []): Password
168 1
    {
169
        return $this->input(Password::class, $formModel, $attribute, $config);
170
    }
171 1
172
    public function radioList(FormModelInterface $formModel, string $attribute, array $config = []): RadioList
173 1
    {
174 1
        return $this
175 1
            ->field(RadioList::class, $config)
176
            ->formAttribute($formModel, $attribute);
177
    }
178 1
179
    public function range(FormModelInterface $formModel, string $attribute, array $config = []): Range
180 1
    {
181
        return $this->input(Range::class, $formModel, $attribute, $config);
182
    }
183 1
184
    public function resetButton(?string $content = null, array $config = []): ResetButton
185 1
    {
186
        $field = $this->field(ResetButton::class, $config);
187 1
188 1
        if ($content !== null) {
189
            $field = $field->content($content);
190
        }
191 1
192
        return $field;
193
    }
194 1
195
    public function select(FormModelInterface $formModel, string $attribute, array $config = []): Select
196 1
    {
197
        return $this->input(Select::class, $formModel, $attribute, $config);
198
    }
199 1
200
    public function submitButton(?string $content = null, array $config = []): SubmitButton
201 1
    {
202
        $field = $this->field(SubmitButton::class, $config);
203 1
204 1
        if ($content !== null) {
205
            $field = $field->content($content);
206
        }
207 1
208
        return $field;
209
    }
210 1
211
    public function telephone(FormModelInterface $formModel, string $attribute, array $config = []): Telephone
212 1
    {
213
        return $this->input(Telephone::class, $formModel, $attribute, $config);
214
    }
215 24
216
    public function text(FormModelInterface $formModel, string $attribute, array $config = []): Text
217 24
    {
218
        return $this->input(Text::class, $formModel, $attribute, $config);
219
    }
220 1
221
    public function textarea(FormModelInterface $formModel, string $attribute, array $config = []): Textarea
222 1
    {
223
        return $this->input(Textarea::class, $formModel, $attribute, $config);
224
    }
225 1
226
    public function time(FormModelInterface $formModel, string $attribute, array $config = []): Time
227 1
    {
228
        return $this->input(Time::class, $formModel, $attribute, $config);
229
    }
230 7
231
    public function url(FormModelInterface $formModel, string $attribute, array $config = []): Url
232 7
    {
233 7
        return $this->input(Url::class, $formModel, $attribute, $config);
234 7
    }
235 7
236 7
    public function label(FormModelInterface $formModel, string $attribute, array $config = []): Label
237
    {
238
        $widgetConfig = array_merge(
239 6
            $this->labelConfig,
240
            $config,
241 6
        );
242 6
        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

242
        return Label::widget($widgetConfig)->/** @scrutinizer ignore-call */ formAttribute($formModel, $attribute);
Loading history...
243 6
    }
244 6
245 6
    public function hint(FormModelInterface $formModel, string $attribute, array $config = []): Hint
246
    {
247
        $widgetConfig = array_merge(
248 6
            $this->hintConfig,
249
            $config,
250 6
        );
251 6
        return Hint::widget($widgetConfig)->formAttribute($formModel, $attribute);
252 6
    }
253 6
254 6
    public function error(FormModelInterface $formModel, string $attribute, array $config = []): Error
255
    {
256
        $widgetConfig = array_merge(
257
            $this->errorConfig,
258
            $config,
259
        );
260
        return Error::widget($widgetConfig)->formAttribute($formModel, $attribute);
261
    }
262 41
263
    /**
264 41
     * @psalm-template T
265 41
     * @psalm-param class-string<T> $class
266 1
     * @psalm-return T
267 1
     */
268 1
    public function input(string $class, FormModelInterface $formModel, string $attribute, array $config = []): object
269 1
    {
270 1
        $widget = $this->field($class, $config);
271 1
        if (!$widget instanceof InputField) {
272
            throw new InvalidArgumentException(
273
                sprintf(
274 40
                    'Input widget must be instance of "%s".',
275
                    InputField::class
276
                )
277
            );
278
        }
279
280
        return $widget->formAttribute($formModel, $attribute);
281
    }
282 56
283
    /**
284 56
     * @psalm-template T
285 56
     * @psalm-param class-string<T> $class
286 56
     * @psalm-return T
287 56
     */
288 56
    public function field(string $class, array $config = []): object
289 56
    {
290
        $config = array_merge(
291
            $this->makeFieldConfig($class),
292 56
            $this->fieldConfigs[$class] ?? [],
293
            $config,
294
            ['class' => $class],
295
        );
296
297
        /** @psalm-var T */
298 56
        return WidgetFactory::createWidget($config);
299
    }
300 56
301
    /**
302 56
     * @psalm-param class-string $class
303 2
     */
304
    private function makeFieldConfig(string $class): array
305 56
    {
306 6
        $config = [];
307
308 56
        if ($this->containerTag !== null) {
309 2
            $config['containerTag()'] = [$this->containerTag];
310 1
        }
311 1
        if ($this->containerAttributes !== []) {
312
            $config['containerAttributes()'] = [$this->containerAttributes];
313 56
        }
314 1
        if ($this->containerClass !== null) {
315
            $config['containerClass()'] = is_array($this->containerClass)
316
                ? $this->containerClass
317 56
                : [$this->containerClass];
318 52
        }
319 1
        if ($this->useContainer !== null) {
320
            $config['useContainer()'] = [$this->useContainer];
321 52
        }
322 1
323
        if (is_a($class, PartsField::class, true)) {
324 52
            if ($this->template !== null) {
325 1
                $config['template()'] = [$this->template];
326
            }
327 52
            if ($this->templateBegin !== null) {
328 3
                $config['templateBegin()'] = [$this->templateBegin];
329
            }
330 52
            if ($this->templateEnd !== null) {
331 1
                $config['templateEnd()'] = [$this->templateEnd];
332
            }
333 52
            if ($this->inputContainerTag !== null) {
334 2
                $config['inputContainerTag()'] = [$this->inputContainerTag];
335 1
            }
336 1
            if ($this->inputContainerAttributes !== []) {
337
                $config['inputContainerAttributes()'] = [$this->inputContainerAttributes];
338 52
            }
339 1
            if ($this->inputContainerClass !== null) {
340
                $config['inputContainerClass()'] = is_array($this->inputContainerClass)
341 52
                    ? $this->inputContainerClass
342 1
                    : [$this->inputContainerClass];
343
            }
344 52
            if ($this->labelConfig !== []) {
345 1
                $config['labelConfig()'] = [$this->labelConfig];
346
            }
347
            if ($this->hintConfig !== []) {
348
                $config['hintConfig()'] = [$this->hintConfig];
349 56
            }
350 40
            if ($this->errorConfig !== []) {
351 1
                $config['errorConfig()'] = [$this->errorConfig];
352 1
            }
353 1
        }
354 1
355 1
        if (is_a($class, InputField::class, true)) {
356
            if ($this->setInputId !== null) {
357
                $config['setInputId()'] = [$this->setInputId];
358 40
                if ($this->setInputId === false) {
359 2
                    $config['labelConfig()'] = [
360
                        $this->labelConfig + ['useInputId()' => [false]],
361 40
                    ];
362 2
                }
363 1
            }
364 1
            if ($this->inputAttributes !== []) {
365
                $config['inputAttributes()'] = [$this->inputAttributes];
366
            }
367
            if ($this->inputClass !== null) {
368 56
                $config['inputClass()'] = is_array($this->inputClass)
369 31
                    ? $this->inputClass
370 2
                    : [$this->inputClass];
371
            }
372
        }
373
374 56
        if (is_a($class, PlaceholderInterface::class, true)) {
375 37
            if ($this->usePlaceholder !== null) {
376 1
                $config['usePlaceholder()'] = [$this->usePlaceholder];
377
            }
378
        }
379
380 56
        if (is_a($class, EnrichmentFromRulesInterface::class, true)) {
381 40
            if ($this->enrichmentFromRules !== null) {
382 1
                $config['enrichmentFromRules()'] = [$this->enrichmentFromRules];
383
            }
384 40
        }
385 1
386
        if (is_a($class, ValidationClassInterface::class, true)) {
387 40
            if ($this->validClass !== null) {
388 1
                $config['validClass()'] = [$this->validClass];
389
            }
390 40
            if ($this->invalidClass !== null) {
391 1
                $config['invalidClass()'] = [$this->invalidClass];
392
            }
393
            if ($this->inputValidClass !== null) {
394
                $config['inputValidClass()'] = [$this->inputValidClass];
395 56
            }
396
            if ($this->inputInvalidClass !== null) {
397
                $config['inputInvalidClass()'] = [$this->inputInvalidClass];
398
            }
399
        }
400
401
        return $config;
402
    }
403
}
404