AbstractForm::getClass()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Del\Form;
6
7
use Del\Form\Collection\FieldCollection;
8
use Del\Form\Field\CheckBox;
9
use Del\Form\Field\FieldInterface;
10
use Del\Form\Field\FileUpload;
11
use Del\Form\Renderer\FormRenderer;
12
use Del\Form\Renderer\FormRendererInterface;
13
use Del\Form\Traits\HasAttributesTrait;
14
15
abstract class AbstractForm implements FormInterface
16
{
17
    const ENC_TYPE_MULTIPART_FORM_DATA = 'multipart/form-data';
18
    const ENC_TYPE_URL_ENCODED = 'application/x-www-form-urlencoded';
19
    const ENC_TYPE_TEXT_PLAIN = 'text/plain';
20
21
    const METHOD_POST = 'post';
22
    const METHOD_GET = 'get';
23
24
    private FieldCollection $fieldCollection;
25
    private FormRendererInterface $formRenderer;
26
    private array $errorMessages;
27
    private bool $displayErrors;
28
29
    use HasAttributesTrait;
30
31 67
    public function __construct(string $name)
32
    {
33 67
        $this->fieldCollection = new FieldCollection();
34 67
        $this->formRenderer = new FormRenderer();
35 67
        $this->attributes = [
36 67
            'name' => $name,
37 67
            'method' => self::METHOD_POST,
38 67
        ];
39 67
        $this->displayErrors = false;
40 67
        $this->init();
41
    }
42
43
    abstract public function init();
44
45 16
    public function isValid(): bool
46
    {
47 16
        $this->errorMessages = [];
48 16
        $fields = $this->fieldCollection;
49 16
        $this->validateFields($fields);
50 16
        $count = count($this->errorMessages);
51 16
        $valid = ($count == 0);
52
53 16
        if ($valid) {
54 10
            $this->moveUploadedFiles();
55
        }
56
57 15
        return $valid;
58
    }
59
60 3
    public function getErrorMessages(): array
61
    {
62 3
        return $this->errorMessages;
63
    }
64
65 16
    private function validateFields(FieldCollection $fields): void
66
    {
67 16
        $fields->rewind();
68
69 16
        while ($fields->valid()) {
70 16
            $this->checkFieldForErrors($fields->current());
71 16
            $this->checkDynamicFormsForErrors($fields->current());
72 16
            $fields->next();
73
        }
74
75 16
        $fields->rewind();
76
    }
77
78 16
    private function checkFieldForErrors(FieldInterface $field): void
79
    {
80 16
        if (!$field->isValid()) {
81 12
            $this->errorMessages[$field->getName()] = $field->getMessages();
82
        }
83
    }
84
85 16
    public function checkDynamicFormsForErrors(FieldInterface $field): void
86
    {
87 16
        if ($field->hasDynamicForms()) {
88 1
            $forms = $field->getDynamicForms();
89 1
            $value = $field->getValue();
90
91 1
            if (isset($forms[$value])) {
92 1
                $form = $forms[$value];
93 1
                $fields = $form->getFields();
94 1
                $this->validateFields($fields);
95
            }
96
        }
97
    }
98
99 8
    public function getValues(bool $transform = false): array
100
    {
101 8
        $values = [];
102 8
        $fields = $this->fieldCollection;
103 8
        $values = $this->getFieldValues($fields, $values, $transform);
104
105 8
        return $values;
106
    }
107
108 8
    private function getFieldValues(FieldCollection $fields, array $values, bool $transform): array
109
    {
110 8
        $fields->rewind();
111
112 8
        while ($fields->valid()) {
113
            /** @var FieldInterface $field */
114 8
            $field = $fields->current();
115 8
            $value = $field->getValue();
116
117 8
            if ($transform && $field->hasTransformer()) {
118 2
                $value = $field->getTransformer()->output($value);
119
            }
120
121 8
            $values[$field->getName()] = $value;
122
123 8
            if ($field->hasDynamicForms()) {
124 1
                $forms = $field->getDynamicForms();
125 1
                if (isset($forms[$value])) {
126 1
                    $form = $forms[$value];
127 1
                    $dynamicFormFields = $form->getFields();
128 1
                    $values = $this->getFieldValues($dynamicFormFields, $values, $transform);
129
                }
130
            }
131
132 8
            $fields->next();
133
        }
134
135 8
        $fields->rewind();
136
137 8
        return $values;
138
    }
139
140 16
    public function populate(array $values): void
141
    {
142 16
        $fields = $this->fieldCollection;
143 16
        $this->populateFields($fields, $values);
144 16
        $this->displayErrors = true;
145
    }
146
147 2
    private function populateDynamicForms(array $dynamicForms, array $data): void
148
    {
149
        /** @var FormInterface $form **/
150 2
        foreach ($dynamicForms as $form) {
151 2
            $fields = $form->getFields();
152 2
            $this->populateFields($fields, $data);
153
        }
154
    }
155
156 16
    private function populateFields(FieldCollection $fields, array $data): void
157
    {
158 16
        $fields->rewind();
159
160 16
        while ($fields->valid()) {
161 16
            $field = $fields->current();
162 16
            $this->populateField($field, $data);
163 16
            $fields->next();
164
        }
165
166 16
        $fields->rewind();
167
    }
168
169 16
    private function populateField(FieldInterface $field, array $data): void
170
    {
171 16
        $name = $field->getName();
172
173 16
        if (isset($data[$name]) && $field->hasTransformer()) {
174 2
            $value = $field->getTransformer()->input($data[$name]);
175 2
            $field->setValue($value);
176 14
        } elseif (isset($data[$name])) {
177 10
            $field->setValue($data[$name]);
178 9
        } elseif ($field instanceof CheckBox) {
179 1
            $field->setValue(false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $value of Del\Form\Field\FieldAbstract::setValue(). ( Ignorable by Annotation )

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

179
            $field->setValue(/** @scrutinizer ignore-type */ false);
Loading history...
180
        }
181
182 16
        if ($field->hasDynamicForms()) {
183 2
            $forms = $field->getDynamicForms();
184 2
            $this->populateDynamicForms($forms, $data);
185
        }
186
    }
187
188 3
    public function getField(string $name): ?FieldInterface
189
    {
190 3
        return $this->fieldCollection->findByName($name);
191
    }
192
193 42
    public function getFields(): FieldCollection
194
    {
195 42
        return $this->fieldCollection;
196
    }
197
198 58
    public function addField(FieldInterface $field): void
199
    {
200 58
        $this->fieldCollection->append($field);
201
    }
202
203 36
    public function render(): string
204
    {
205 36
        return $this->formRenderer->render($this, $this->isDisplayErrors());
206
    }
207
208 2
    public function setAction(string $url): void
209
    {
210 2
        $this->setAttribute('action', $url);
211
    }
212
213 2
    public function getAction(): string
214
    {
215 2
        return $this->getAttribute('action');
216
    }
217
218 37
    public function getId(): ?string
219
    {
220 37
        return $this->getAttribute('id');
221
    }
222
223 2
    public function setId(string $id): void
224
    {
225 2
        $this->setAttribute('id', $id);
226
    }
227
228 3
    public function setEncType(string $encType): void
229
    {
230 3
        $this->setAttribute('enctype', $encType);
231
    }
232
233 1
    public function getEncType(): string
234
    {
235 1
        return $this->getAttribute('enctype');
236
    }
237
238 2
    public function setMethod(string $method): void
239
    {
240 2
        $this->setAttribute('method', $method);
241
    }
242
243 37
    public function getMethod(): string
244
    {
245 37
        return $this->getAttribute('method');
246
    }
247
248 2
    public function setClass(string $class): void
249
    {
250 2
        $this->setAttribute('class', $class);
251
    }
252
253 2
    public function getClass(): string
254
    {
255 2
        return $this->getAttribute('class');
256
    }
257
258 37
    public function isDisplayErrors(): bool
259
    {
260 37
        return $this->displayErrors;
261
    }
262
263 3
    public function setDisplayErrors(bool $displayErrors): void
264
    {
265 3
        $this->displayErrors = $displayErrors;
266
    }
267
268 5
    public function setFormRenderer(FormRendererInterface $renderer): AbstractForm
269
    {
270 5
        $this->formRenderer = $renderer;
271
272 5
        return $this;
273
    }
274
275 10
    public function moveUploadedFiles(): void
276
    {
277 10
        $this->fieldCollection->rewind();
278
279 10
        while ($this->fieldCollection->valid()) {
280 10
            $current = $this->fieldCollection->current();
281 10
            $this->moveFileIfUploadField($current);
282 9
            $this->fieldCollection->next();
283
        }
284
    }
285
286 10
    public function moveFileIfUploadField(FieldInterface $field): bool
287
    {
288 10
        if ($field instanceof FileUpload) {
289 2
            $field->moveUploadToDestination();
290 1
            return true;
291
        }
292 8
        return false;
293
    }
294
295
296
}
297