Passed
Pull Request — master (#192)
by Alexander
03:40
created

FieldFactory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

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

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