Completed
Push — master ( fcb641...65474d )
by Derek Stephen
04:39
created

AbstractForm::setFormRenderer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
222
        }
223
224 14
        if ($field->hasDynamicForms()) {
225 2
            $forms = $field->getDynamicForms();
226 2
            $this->populateDynamicForms($forms, $data);
227
        }
228 14
    }
229
230
    /**
231
     * @param string $name
232
     * @return FieldInterface|null
233
     */
234 2
    public function getField(string $name): ?FieldInterface
235
    {
236 2
        return $this->fieldCollection->findByName($name);
237
    }
238
239
    /**
240
     * @return FieldCollection
241
     */
242 36
    public function getFields(): FieldCollection
243
    {
244 36
        return $this->fieldCollection;
245
    }
246
247
    /**
248
     * @param FieldInterface $field
249
     */
250 51
    public function addField(FieldInterface $field): void
251
    {
252 51
        $this->fieldCollection->append($field);
253 51
    }
254
255
    /**
256
     * @return string
257
     */
258 32
    public function render(): string
259
    {
260 32
        return $this->formRenderer->render($this, $this->isDisplayErrors());
261
    }
262
263
    /**
264
     * @param $url
265
     */
266 2
    public function setAction(string $url): void
267
    {
268 2
        $this->setAttribute('action', $url);
269 2
    }
270
271
    /**
272
     * @return string
273
     */
274 2
    public function getAction(): string
275
    {
276 2
        return $this->getAttribute('action');
277
    }
278
279
    /**
280
     * @return string
281
     */
282 33
    public function getId(): ?string
283
    {
284 33
        return $this->getAttribute('id');
285
    }
286
287
    /**
288
     * @param string $id
289
     */
290 2
    public function setId(string $id): void
291
    {
292 2
        $this->setAttribute('id', $id);
293 2
    }
294
295
    /**
296
     * @param $encType
297
     */
298 2
    public function setEncType(string $encType): void
299
    {
300 2
        $this->setAttribute('enctype', $encType);
301 2
    }
302
303
    /**
304
     * @return string
305
     */
306 1
    public function getEncType(): string
307
    {
308 1
        return $this->getAttribute('enctype');
309
    }
310
311
    /**
312
     * @param string $method
313
     * @return FormInterface
314
     */
315 2
    public function setMethod(string $method): void
316
    {
317 2
        $this->setAttribute('method', $method);
318 2
    }
319
320
    /**
321
     * @return string
322
     */
323 33
    public function getMethod(): string
324
    {
325 33
        return $this->getAttribute('method');
326
    }
327
328
    /**
329
     * @param $class
330
     */
331 2
    public function setClass(string $class): void
332
    {
333 2
        $this->setAttribute('class', $class);
334 2
    }
335
336
    /**
337
     * @return string
338
     */
339 2
    public function getClass(): string
340
    {
341 2
        return $this->getAttribute('class');
342
    }
343
344
    /**
345
     * @return boolean
346
     */
347 33
    public function isDisplayErrors(): bool
348
    {
349 33
        return $this->displayErrors;
350
    }
351
352
    /**
353
     * @param boolean $displayError
0 ignored issues
show
Documentation introduced by
There is no parameter named $displayError. Did you maybe mean $displayErrors?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
354
     */
355 3
    public function setDisplayErrors(bool $displayErrors): void
356
    {
357 3
        $this->displayErrors = $displayErrors;
358 3
    }
359
360
    /**
361
     * @param FormRendererInterface $renderer
362
     * @return AbstractForm
363
     */
364 5
    public function setFormRenderer(FormRendererInterface $renderer): AbstractForm
365
    {
366 5
        $this->formRenderer = $renderer;
367
368 5
        return $this;
369
    }
370
371 8
    public function moveUploadedFiles(): void
372
    {
373 8
        $this->fieldCollection->rewind();
374 8
        while ($this->fieldCollection->valid()) {
375 8
            $current = $this->fieldCollection->current();
376 8
            $this->moveFileIfUploadField($current);
377 7
            $this->fieldCollection->next();
378
        }
379 7
    }
380
381
    /**
382
     * @param FieldInterface $field
383
     * @return bool
384
     */
385 8
    public function moveFileIfUploadField(FieldInterface $field): bool
386
    {
387 8
        if ($field instanceof FileUpload) {
388 2
            $field->moveUploadToDestination();
389 1
            return true;
390
        }
391 6
        return false;
392
    }
393
}