Passed
Pull Request — master (#192)
by Alexander
28:18 queued 25:44
created

FieldFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 1
eloc 0
c 3
b 1
f 0
nc 1
nop 18
dl 0
loc 20
ccs 1
cts 1
cp 1
crap 1
rs 10

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 26
    public function __construct(
48
        private ?string $containerTag = null,
49
        private array $containerTagAttributes = [],
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 $setInputIdAttribute = null,
56
        private array $inputTagAttributes = [],
57
        private string|array|null $inputClass = null,
58
        private array $labelConfig = [],
59
        private array $hintConfig = [],
60
        private array $errorConfig = [],
61
        private ?bool $usePlaceholder = null,
62
        private ?string $validClass = null,
63
        private ?string $invalidClass = null,
64
        private ?bool $enrichmentFromRules = null,
65
        private array $fieldConfigs = [],
66
    ) {
67
    }
68
69 1
    public function button(array $config = []): Button
70
    {
71 1
        return $this->field(Button::class, $config);
72
    }
73
74 1
    public function buttonGroup(array $config = []): ButtonGroup
75
    {
76 1
        return $this->field(ButtonGroup::class, $config);
77
    }
78
79 1
    public function checkbox(FormModelInterface $formModel, string $attribute, array $config = []): Checkbox
80
    {
81 1
        return $this->input(Checkbox::class, $formModel, $attribute, $config);
82
    }
83
84 1
    public function checkboxList(FormModelInterface $formModel, string $attribute, array $config = []): CheckboxList
85
    {
86
        return $this
87 1
            ->field(CheckboxList::class, $config)
88 1
            ->attribute($formModel, $attribute);
89
    }
90
91 1
    public function date(FormModelInterface $formModel, string $attribute, array $config = []): Date
92
    {
93 1
        return $this->input(Date::class, $formModel, $attribute, $config);
94
    }
95
96 1
    public function dateTime(FormModelInterface $formModel, string $attribute, array $config = []): DateTime
97
    {
98 1
        return $this->input(DateTime::class, $formModel, $attribute, $config);
99
    }
100
101 1
    public function dateTimeLocal(FormModelInterface $formModel, string $attribute, array $config = []): DateTimeLocal
102
    {
103 1
        return $this->input(DateTimeLocal::class, $formModel, $attribute, $config);
104
    }
105
106 1
    public function email(FormModelInterface $formModel, string $attribute, array $config = []): Email
107
    {
108 1
        return $this->input(Email::class, $formModel, $attribute, $config);
109
    }
110
111 3
    public function errorSummary(FormModelInterface $formModel, array $config = []): ErrorSummary
112
    {
113
        return $this
114 3
            ->field(ErrorSummary::class, $config)
115 3
            ->formModel($formModel);
116
    }
117
118 4
    public function fieldset(array $config = []): Fieldset
119
    {
120 4
        return $this->field(Fieldset::class, $config);
121
    }
122
123 1
    public function file(FormModelInterface $formModel, string $attribute, array $config = []): File
124
    {
125 1
        return $this->input(File::class, $formModel, $attribute, $config);
126
    }
127
128 2
    public function hidden(FormModelInterface $formModel, string $attribute, array $config = []): Hidden
129
    {
130 2
        return $this->input(Hidden::class, $formModel, $attribute, $config);
131
    }
132
133 1
    public function image(array $config = []): Image
134
    {
135 1
        return $this->field(Image::class, $config);
136
    }
137
138 1
    public function number(FormModelInterface $formModel, string $attribute, array $config = []): Number
139
    {
140 1
        return $this->input(Number::class, $formModel, $attribute, $config);
141
    }
142
143 1
    public function password(FormModelInterface $formModel, string $attribute, array $config = []): Password
144
    {
145 1
        return $this->input(Password::class, $formModel, $attribute, $config);
146
    }
147
148 1
    public function radioList(FormModelInterface $formModel, string $attribute, array $config = []): RadioList
149
    {
150
        return $this
151 1
            ->field(RadioList::class, $config)
152 1
            ->attribute($formModel, $attribute);
153
    }
154
155 1
    public function range(FormModelInterface $formModel, string $attribute, array $config = []): Range
156
    {
157 1
        return $this->input(Range::class, $formModel, $attribute, $config);
158
    }
159
160 1
    public function resetButton(array $config = []): ResetButton
161
    {
162 1
        return $this->field(ResetButton::class, $config);
163
    }
164
165 1
    public function select(FormModelInterface $formModel, string $attribute, array $config = []): Select
166
    {
167 1
        return $this->input(Select::class, $formModel, $attribute, $config);
168
    }
169
170 1
    public function submitButton(array $config = []): SubmitButton
171
    {
172 1
        return $this->field(SubmitButton::class, $config);
173
    }
174
175 1
    public function telephone(FormModelInterface $formModel, string $attribute, array $config = []): Telephone
176
    {
177 1
        return $this->input(Telephone::class, $formModel, $attribute, $config);
178
    }
179
180 15
    public function text(FormModelInterface $formModel, string $attribute, array $config = []): Text
181
    {
182 15
        return $this->input(Text::class, $formModel, $attribute, $config);
183
    }
184
185 1
    public function textarea(FormModelInterface $formModel, string $attribute, array $config = []): Textarea
186
    {
187 1
        return $this->input(Textarea::class, $formModel, $attribute, $config);
188
    }
189
190 1
    public function url(FormModelInterface $formModel, string $attribute, array $config = []): Url
191
    {
192 1
        return $this->input(Url::class, $formModel, $attribute, $config);
193
    }
194
195 4
    public function label(FormModelInterface $formModel, string $attribute, array $config = []): Label
196
    {
197 4
        $widgetConfig = array_merge(
198 4
            $this->labelConfig,
199
            $config,
200
        );
201 4
        return Label::widget($widgetConfig)->attribute($formModel, $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

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