Issues (13)

src/Field/FieldAbstract.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Del\Form\Field;
4
5
use Del\Form\Collection\FilterCollection;
6
use Del\Form\Collection\ValidatorCollection;
7
use Del\Form\Filter\FilterInterface;
8
use Del\Form\FormInterface;
9
use Del\Form\Renderer\Field\FieldRendererInterface;
10
use Del\Form\Renderer\Field\TextRender;
11
use Del\Form\Traits\HasAttributesTrait;
12
use Del\Form\Validator\NotEmpty;
13
use Del\Form\Validator\ValidatorInterface;
14
use Exception;
15
16
abstract class FieldAbstract implements FieldInterface
17
{
18
19
    /**  @var FormInterface[] $dynamicFormCollection */
20
    private $dynamicFormCollection;
21
22
    /**  @var FilterCollection $filterCollection */
23
    private $filterCollection;
24
25
    /**  @var ValidatorCollection $validatorCollection */
26
    private $validatorCollection;
27
28
    /**  @var TransformerInterface $transformer */
29
    private $transformer;
30
31
    /** @var FieldRendererInterface $renderer  */
32
    private $renderer;
33
34
    /** @var array $errorMessages */
35
    private $errorMessages;
36
37
    /** @var string $customErrorMessage */
38
    private $customErrorMessage;
39
40
    /** @var string $label */
41
    private $label;
42
43
    /** @var bool $required */
44
    private $required;
45
46
    use HasAttributesTrait;
47
48
    /**
49
     * @return string
50
     */
51
    abstract public function getTag(): string;
52
53
    abstract public function init();
54
55 67
    public function __construct($name, $value = null)
56
    {
57 67
        $this->required = false;
58 67
        $this->dynamicFormCollection = [];
59 67
        $this->filterCollection = new FilterCollection();
60 67
        $this->validatorCollection = new ValidatorCollection();
61 67
        $this->renderer = new TextRender();
62 67
        $this->setName($name);
63 67
        $value === null ?: $this->setValue($value);
64 67
        $this->init();
65
    }
66
67
    /**
68
     * @return string
69
     */
70 52
    public function getName(): string
71
    {
72 52
        return $this->getAttribute('name');
73
    }
74
75
    /**
76
     * @param string $name
77
     */
78 67
    public function setName(string $name): void
79
    {
80 67
        $this->setAttribute('name', $name);
81
    }
82
83
    /**
84
     * @return string
85
     */
86 37
    public function getId(): ?string
87
    {
88 37
        return $this->getAttribute('id');
89
    }
90
91
    /**
92
     * @param string $id
93
     */
94 8
    public function setId(string $id): void
95
    {
96 8
        $this->setAttribute('id', $id);
97
    }
98
99
    /**
100
     * @return string
101
     */
102 1
    public function getClass(): string
103
    {
104 1
        return $this->getAttribute('class') ?: 'form-control';
105
    }
106
107
    /**
108
     * @param string $class
109
     * @return FieldAbstract
110
     */
111 11
    public function setClass(string $class): void
112
    {
113 11
        $this->setAttribute('class', $class);
114
    }
115
116 50
    public function getValue(): mixed
117
    {
118 50
        return $this->getAttribute('value');
119
    }
120
121
    /**
122
     * @param string $value
123
     */
124 42
    public function setValue($value): void
125
    {
126 42
        $this->setAttribute('value', $value);
127 42
        $this->filterValue();
128
    }
129
130
    /**
131
     * @param ValidatorInterface $validator
132
     */
133 26
    public function addValidator(ValidatorInterface $validator): void
134
    {
135 26
        $this->validatorCollection->append($validator);
136
    }
137
138
    /**
139
     * @return ValidatorCollection
140
     */
141 2
    public function getValidators(): ValidatorCollection
142
    {
143 2
        return $this->validatorCollection;
144
    }
145
146
    /**
147
     * @param FilterInterface $filter
148
     */
149 38
    public function addFilter(FilterInterface $filter): void
150
    {
151 38
        $this->filterCollection->append($filter);
152
    }
153
154
    /**
155
     * @param FilterInterface $transformer
156
     */
157 3
    public function setTransformer(TransformerInterface $transformer): void
158
    {
159 3
        $this->transformer = $transformer;
160
    }
161
162
    /**
163
     * @return TransformerInterface
164
     */
165 2
    public function getTransformer(): TransformerInterface
166
    {
167 2
        return $this->transformer;
168
    }
169
170
    /**
171
     * @return bool
172
     */
173 12
    public function hasTransformer(): bool
174
    {
175 12
        return $this->transformer instanceof TransformerInterface;
176
    }
177
178
    /**
179
     * @return FilterCollection
180
     */
181 1
    public function getFilters(): FilterCollection
182
    {
183 1
        return $this->filterCollection;
184
    }
185
186
    /**
187
     *  Runs the checkForErrors method for each field, which adds to errorMessages if invalid
188
     *
189
     * @return bool
190
     */
191 44
    public function isValid(): bool
192
    {
193 44
        $this->errorMessages = [];
194 44
        $this->validatorCollection->rewind();
195
196 44
        while ($this->validatorCollection->valid()) {
197 23
            $this->checkForErrors($this->validatorCollection->current());
198 23
            $this->validatorCollection->next();
199
        }
200
201 44
        $count = \count($this->errorMessages);
202
203 44
        return $count == 0;
204
    }
205
206
    /**
207
     * @param ValidatorInterface $validator
208
     */
209 23
    private function checkForErrors(ValidatorInterface $validator): void
210
    {
211 23
        $value = $this->getValue();
212
213 23
        if ((!$validator->isValid($value)) && $this->isRequired()) {
214 18
            $this->errorMessages = array_merge($this->errorMessages, $validator->getMessages());
215
        }
216
    }
217
218
    /**
219
     * @throws Exception
220
     */
221 42
    private function filterValue(): void
222
    {
223 42
        $value = $this->getAttribute('value');
224 42
        $this->filterCollection->rewind();
225
226 42
        while ($this->filterCollection->valid()) {
227 16
            $value = $this->filterCollection->current()->filter($value);
228 16
            $this->filterCollection->next();
229
        }
230
231 42
        $this->filterCollection->rewind();
232 42
        $this->setAttribute('value', $value);
233
    }
234
235
    /**
236
     * @return array
237
     */
238 14
    public function getMessages(): array
239
    {
240 14
        return isset($this->customErrorMessage) ? [$this->customErrorMessage] : array_values($this->errorMessages);
241
    }
242
243
    /**
244
     * @return string
245
     */
246 36
    public function getLabel(): ?string
247
    {
248 36
        return $this->label;
249
    }
250
251
    /**
252
     * @param string $label
253
     */
254 21
    public function setLabel(string $label): void
255
    {
256 21
        $this->label = $label;
257
    }
258
259
    /**
260
     * @param string $message
261
     */
262 6
    public function setCustomErrorMessage(string $message): void
263
    {
264 6
        $this->customErrorMessage = $message;
265
    }
266
267
    /**
268
     * @return bool
269
     */
270 4
    public function hasCustomErrorMessage(): bool
271
    {
272 4
        return $this->customErrorMessage != null;
273
    }
274
275
    /**
276
     * @return string
277
     */
278 2
    public function getCustomErrorMessage(): string
279
    {
280 2
        return $this->customErrorMessage;
281
    }
282
283
    /**
284
     * @return FieldRendererInterface
285
     */
286 37
    public function getRenderer(): FieldRendererInterface
287
    {
288 37
        return $this->renderer;
289
    }
290
291
    /**
292
     * @param FieldRendererInterface $renderer
293
     */
294 44
    public function setRenderer(FieldRendererInterface $renderer): void
295
    {
296 44
        $this->renderer = $renderer;
297
    }
298
299
    /**
300
     * If a field is required then it must have a value
301
     * We add a not empty validator
302
     *
303
     * @return boolean
304
     */
305 48
    public function isRequired(): bool
306
    {
307 48
        return $this->required;
308
    }
309
310
    /**
311
     * @param boolean $required
312
     */
313 23
    public function setRequired(bool $required): void
314
    {
315 23
        $required ? $this->addNotEmptyValidator() : $this->removeNotEmptyValidator();
316 23
        $this->required = $required;
317
    }
318
319
    /**
320
     * adds not empty validator
321
     */
322 23
    private function addNotEmptyValidator(): void
323
    {
324 23
        $notEmpty = new NotEmpty();
325 23
        $this->addValidator($notEmpty);
326
    }
327
328
    /**
329
     *  removes not empty validator
330
     */
331 2
    private function removeNotEmptyValidator(): void
332
    {
333 2
        $this->validatorCollection->rewind();
334
335 2
        while ($this->validatorCollection->valid()) {
336 2
            $validator = $this->validatorCollection->current();
337 2
            $validator instanceof NotEmpty
338 2
                ? $this->validatorCollection->offsetUnset($this->validatorCollection->key())
0 ignored issues
show
It seems like $this->validatorCollection->key() can also be of type true; however, parameter $key of ArrayIterator::offsetUnset() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

338
                ? $this->validatorCollection->offsetUnset(/** @scrutinizer ignore-type */ $this->validatorCollection->key())
Loading history...
339 1
                : null;
340 2
            $this->validatorCollection->next();
341
        }
342
    }
343
344
345 3
    public function addDynamicForm(FormInterface $form, string $triggerValue): void
346
    {
347 3
        $this->dynamicFormCollection[$triggerValue] = $form;
348
    }
349
350
    /**
351
     * @return bool
352
     */
353 49
    public function hasDynamicForms(): bool
354
    {
355 49
        return count($this->dynamicFormCollection) > 0;
356
    }
357
358
    /**
359
     * @return FormInterface[]
360
     * @throws Exception
361
     */
362 4
    public function getDynamicForms(): array
363
    {
364 4
        if (!$this->hasDynamicForms()) {
365 1
            throw new Exception('No dynamic form for this value - Did you check hasDynamicForm() ?');
366
        }
367 3
        return $this->dynamicFormCollection;
368
    }
369
}
370