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

FieldFactory::__construct()   B

Complexity

Conditions 7
Paths 27

Size

Total Lines 31
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 6
c 1
b 0
f 0
nc 27
nop 21
dl 0
loc 31
ccs 7
cts 7
cp 1
crap 7
rs 8.8333

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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 39
    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 39
        if ($labelClass !== null) {
71 2
            $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 39
        if ($hintClass !== null) {
74 2
            $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 39
        if ($errorClass !== null) {
77 2
            $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 1
    public function button(array $config = []): Button
82
    {
83 1
        return $this->field(Button::class, $config);
84
    }
85
86 1
    public function buttonGroup(array $config = []): ButtonGroup
87
    {
88 1
        return $this->field(ButtonGroup::class, $config);
89
    }
90
91 1
    public function checkbox(FormModelInterface $formModel, string $attribute, array $config = []): Checkbox
92
    {
93 1
        return $this->input(Checkbox::class, $formModel, $attribute, $config);
94
    }
95
96 1
    public function checkboxList(FormModelInterface $formModel, string $attribute, array $config = []): CheckboxList
97
    {
98
        return $this
99 1
            ->field(CheckboxList::class, $config)
100 1
            ->formAttribute($formModel, $attribute);
101
    }
102
103 1
    public function date(FormModelInterface $formModel, string $attribute, array $config = []): Date
104
    {
105 1
        return $this->input(Date::class, $formModel, $attribute, $config);
106
    }
107
108 1
    public function dateTime(FormModelInterface $formModel, string $attribute, array $config = []): DateTime
109
    {
110 1
        return $this->input(DateTime::class, $formModel, $attribute, $config);
111
    }
112
113 1
    public function dateTimeLocal(FormModelInterface $formModel, string $attribute, array $config = []): DateTimeLocal
114
    {
115 1
        return $this->input(DateTimeLocal::class, $formModel, $attribute, $config);
116
    }
117
118 1
    public function email(FormModelInterface $formModel, string $attribute, array $config = []): Email
119
    {
120 1
        return $this->input(Email::class, $formModel, $attribute, $config);
121
    }
122
123 3
    public function errorSummary(FormModelInterface $formModel, array $config = []): ErrorSummary
124
    {
125
        return $this
126 3
            ->field(ErrorSummary::class, $config)
127 3
            ->formModel($formModel);
128
    }
129
130 4
    public function fieldset(array $config = []): Fieldset
131
    {
132 4
        return $this->field(Fieldset::class, $config);
133
    }
134
135 1
    public function file(FormModelInterface $formModel, string $attribute, array $config = []): File
136
    {
137 1
        return $this->input(File::class, $formModel, $attribute, $config);
138
    }
139
140 2
    public function hidden(FormModelInterface $formModel, string $attribute, array $config = []): Hidden
141
    {
142 2
        return $this->input(Hidden::class, $formModel, $attribute, $config);
143
    }
144
145 1
    public function image(array $config = []): Image
146
    {
147 1
        return $this->field(Image::class, $config);
148
    }
149
150 1
    public function number(FormModelInterface $formModel, string $attribute, array $config = []): Number
151
    {
152 1
        return $this->input(Number::class, $formModel, $attribute, $config);
153
    }
154
155 1
    public function password(FormModelInterface $formModel, string $attribute, array $config = []): Password
156
    {
157 1
        return $this->input(Password::class, $formModel, $attribute, $config);
158
    }
159
160 1
    public function radioList(FormModelInterface $formModel, string $attribute, array $config = []): RadioList
161
    {
162
        return $this
163 1
            ->field(RadioList::class, $config)
164 1
            ->formAttribute($formModel, $attribute);
165
    }
166
167 1
    public function range(FormModelInterface $formModel, string $attribute, array $config = []): Range
168
    {
169 1
        return $this->input(Range::class, $formModel, $attribute, $config);
170
    }
171
172 1
    public function resetButton(array $config = []): ResetButton
173
    {
174 1
        return $this->field(ResetButton::class, $config);
175
    }
176
177 1
    public function select(FormModelInterface $formModel, string $attribute, array $config = []): Select
178
    {
179 1
        return $this->input(Select::class, $formModel, $attribute, $config);
180
    }
181
182 1
    public function submitButton(array $config = []): SubmitButton
183
    {
184 1
        return $this->field(SubmitButton::class, $config);
185
    }
186
187 1
    public function telephone(FormModelInterface $formModel, string $attribute, array $config = []): Telephone
188
    {
189 1
        return $this->input(Telephone::class, $formModel, $attribute, $config);
190
    }
191
192 19
    public function text(FormModelInterface $formModel, string $attribute, array $config = []): Text
193
    {
194 19
        return $this->input(Text::class, $formModel, $attribute, $config);
195
    }
196
197 1
    public function textarea(FormModelInterface $formModel, string $attribute, array $config = []): Textarea
198
    {
199 1
        return $this->input(Textarea::class, $formModel, $attribute, $config);
200
    }
201
202 1
    public function url(FormModelInterface $formModel, string $attribute, array $config = []): Url
203
    {
204 1
        return $this->input(Url::class, $formModel, $attribute, $config);
205
    }
206
207 7
    public function label(FormModelInterface $formModel, string $attribute, array $config = []): Label
208
    {
209 7
        $widgetConfig = array_merge(
210 7
            $this->labelConfig,
211
            $config,
212
        );
213 7
        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 6
    public function hint(FormModelInterface $formModel, string $attribute, array $config = []): Hint
217
    {
218 6
        $widgetConfig = array_merge(
219 6
            $this->hintConfig,
220
            $config,
221
        );
222 6
        return Hint::widget($widgetConfig)->formAttribute($formModel, $attribute);
223
    }
224
225 6
    public function error(FormModelInterface $formModel, string $attribute, array $config = []): Error
226
    {
227 6
        $widgetConfig = array_merge(
228 6
            $this->errorConfig,
229
            $config,
230
        );
231 6
        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 36
    public function input(string $class, FormModelInterface $formModel, string $attribute, array $config = []): object
240
    {
241 36
        $widget = $this->field($class, $config);
242 36
        if (!$widget instanceof InputField) {
243 1
            throw new InvalidArgumentException(
244 1
                sprintf(
245
                    'Input widget must be instance of "%s".',
246
                    InputField::class
247
                )
248
            );
249
        }
250
251 35
        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 51
    public function field(string $class, array $config = []): object
260
    {
261 51
        $config = array_merge(
262 51
            $this->makeFieldConfig($class),
263 51
            $this->fieldConfigs[$class] ?? [],
264
            $config,
265 51
            ['class' => $class],
266
        );
267
268
        /** @psalm-var T */
269 51
        return WidgetFactory::createWidget($config);
270
    }
271
272
    /**
273
     * @psalm-param class-string $class
274
     */
275 51
    private function makeFieldConfig(string $class): array
276
    {
277 51
        $config = [];
278
279 51
        if ($this->containerTag !== null) {
280 2
            $config['containerTag()'] = [$this->containerTag];
281
        }
282 51
        if ($this->containerAttributes !== []) {
283 4
            $config['containerAttributes()'] = [$this->containerAttributes];
284
        }
285 51
        if ($this->containerClass !== null) {
286 2
            $config['containerClass()'] = is_array($this->containerClass)
287 1
                ? $this->containerClass
288 1
                : [$this->containerClass];
289
        }
290 51
        if ($this->useContainer !== null) {
291 1
            $config['useContainer()'] = [$this->useContainer];
292
        }
293
294 51
        if (is_a($class, PartsField::class, true)) {
295 47
            if ($this->template !== null) {
296 1
                $config['template()'] = [$this->template];
297
            }
298 47
            if ($this->templateBegin !== null) {
299 1
                $config['templateBegin()'] = [$this->templateBegin];
300
            }
301 47
            if ($this->templateEnd !== null) {
302 1
                $config['templateEnd()'] = [$this->templateEnd];
303
            }
304 47
            if ($this->labelConfig !== []) {
305 1
                $config['labelConfig()'] = [$this->labelConfig];
306
            }
307 47
            if ($this->hintConfig !== []) {
308 1
                $config['hintConfig()'] = [$this->hintConfig];
309
            }
310 47
            if ($this->errorConfig !== []) {
311 1
                $config['errorConfig()'] = [$this->errorConfig];
312
            }
313
        }
314
315 51
        if (is_a($class, InputField::class, true)) {
316 35
            if ($this->setInputId !== null) {
317 1
                $config['setInputId()'] = [$this->setInputId];
318 1
                if ($this->setInputId === false) {
319 1
                    $config['labelConfig()'] = [
320 1
                        $this->labelConfig + ['useInputId()' => [false]],
321
                    ];
322
                }
323
            }
324 35
            if ($this->inputAttributes !== []) {
325 2
                $config['inputAttributes()'] = [$this->inputAttributes];
326
            }
327 35
            if ($this->inputClass !== null) {
328 2
                $config['inputClass()'] = is_array($this->inputClass)
329 1
                    ? $this->inputClass
330 1
                    : [$this->inputClass];
331
            }
332
        }
333
334 51
        if (is_a($class, PlaceholderInterface::class, true)) {
335 26
            if ($this->usePlaceholder !== null) {
336 2
                $config['usePlaceholder()'] = [$this->usePlaceholder];
337
            }
338
        }
339
340 51
        if (is_a($class, EnrichmentFromRulesInterface::class, true)) {
341 32
            if ($this->enrichmentFromRules !== null) {
342 1
                $config['enrichmentFromRules()'] = [$this->enrichmentFromRules];
343
            }
344
        }
345
346 51
        if (is_a($class, ValidationClassInterface::class, true)) {
347 35
            if ($this->validClass !== null) {
348 1
                $config['validClass()'] = [$this->validClass];
349
            }
350 35
            if ($this->invalidClass !== null) {
351 1
                $config['invalidClass()'] = [$this->invalidClass];
352
            }
353
        }
354
355 51
        return $config;
356
    }
357
}
358