Completed
Branch dynamicfields (c98305)
by Derek Stephen
02:33
created

AbstractForm::checkDynamicFormsForErrors()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 12
Ratio 100 %

Code Coverage

Tests 3
CRAP Score 5.667

Importance

Changes 0
Metric Value
dl 12
loc 12
ccs 3
cts 9
cp 0.3333
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 1
crap 5.667
1
<?php
2
/**
3
 * User: delboy1978uk
4
 * Date: 19/11/2016
5
 * Time: 12:13
6
 */
7
8
namespace Del\Form;
9
10
use Del\Form\Collection\FieldCollection;
11
use Del\Form\Field\FieldInterface;
12
use Del\Form\Field\FileUpload;
13
use Del\Form\Renderer\FormRenderer;
14
use Del\Form\Renderer\FormRendererInterface;
15
use Del\Form\Traits\HasAttributesTrait;
16
17
abstract class AbstractForm implements FormInterface
18
{
19
    const ENC_TYPE_MULTIPART_FORM_DATA = 'multipart/form-data';
20
    const ENC_TYPE_URL_ENCODED = 'application/x-www-form-urlencoded';
21
    const ENC_TYPE_TEXT_PLAIN = 'text/plain';
22
23
    const METHOD_POST = 'post';
24
    const METHOD_GET = 'get';
25
26
    /** @var FieldCollection $fieldCollection */
27
    private $fieldCollection;
28
29
    /** @var FormRendererInterface  */
30
    private $formRenderer;
31
32
    /** @var array $errorMessages */
33
    private $errorMessages;
34
35
    /** @var bool $displayErrors */
36
    private $displayErrors;
37
38
    use HasAttributesTrait;
39
40
    /**
41
     * AbstractForm constructor.
42
     * @param $name
43
     */
44 47
    public function __construct($name)
45
    {
46 47
        $this->fieldCollection = new FieldCollection();
47 47
        $this->formRenderer = new FormRenderer();
48 47
        $this->attributes = [
49 47
            'name' => $name,
50 47
            'method' => self::METHOD_POST,
51
        ];
52 47
        $this->displayErrors = false;
53 47
        $this->init();
54 47
    }
55
56
    abstract public function init();
57
58
    /**
59
     * @return bool
60
     */
61 8
    public function isValid()
62
    {
63 8
        $this->errorMessages = [];
64 8
        $fields = $this->fieldCollection;
65 8
        $this->validateFields($fields);
66 8
        $count = count($this->errorMessages);
67 8
        $valid = ($count == 0);
68 8
        if ($valid) {
69 6
            $this->moveUploadedFiles();
70
        }
71 7
        return $valid;
72
    }
73
74
    /**
75
     * @param FieldCollection $fields
76
     */
77 8
    private function validateFields(FieldCollection $fields)
78
    {
79 8
        $fields->rewind();
80 8
        while ($fields->valid()) {
81 8
            $this->checkFieldForErrors($fields->current());
82 8
            $this->checkDynamicFormsForErrors($fields->current());
83 8
            $fields->next();
84
        }
85 8
        $fields->rewind();
86 8
    }
87
88
    /**
89
     * @param FieldInterface $field
90
     */
91 8
    private function checkFieldForErrors(FieldInterface $field)
92
    {
93 8
        if (!$field->isValid()) {
94 6
            $this->errorMessages[$field->getName()] = $field->getMessages();
95
        }
96 8
    }
97
98 8 View Code Duplication
    public function checkDynamicFormsForErrors(FieldInterface $field)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
99
    {
100 8
        if ($field->hasDynamicForms()) {
101
            $forms = $field->getDynamicForms();
102
            $value = $field->getValue();
103
            if (isset($forms[$value])) {
104
                $form  = $forms[$value];
105
                $fields = $form->getFields();
106
                $this->validateFields($fields);
107
            }
108
        }
109 8
    }
110
111
    /**
112
     * @return array
113
     */
114 4
    public function getValues()
115
    {
116 4
        $values = [];
117 4
        $this->fieldCollection->rewind();
118 4
        while ($this->fieldCollection->valid()) {
119 4
            $field = $this->fieldCollection->current();
120 4
            $values[$field->getName()] = $field->getValue();
121 4
            $this->fieldCollection->next();
122
        }
123 4
        $this->fieldCollection->rewind();
124 4
        return $values;
125
    }
126
127
    /**
128
     * @param array $data
129
     * @return $this
130
     */
131 5
    public function populate(array $data)
132
    {
133 5
        $this->fieldCollection->rewind();
134 5
        $this->populateFields($this->fieldCollection, $data);
135 5
        $this->fieldCollection->rewind();
136 5
        $this->displayErrors = true;
137 5
        return $this;
138
    }
139
140
    /**
141
     * @param array $dynamicForms
142
     * @param array $data
143
     */
144
    private function populateDynamicForms(array $dynamicForms, array $data)
145
    {
146
        /** @var FormInterface $form **/
147
        foreach ($dynamicForms as $form) {
148
            $fields = $form->getFields();
149
            $this->populateFields($fields, $data);
150
        }
151
    }
152
153
    /**
154
     * @param FieldCollection $fields
155
     * @param array $data
156
     */
157 5
    private function populateFields(FieldCollection $fields, array $data)
158
    {
159 5
        while ($fields->valid()) {
160 5
            $field = $fields->current();
161 5
            $this->populateField($field, $data);
162 5
            $fields->next();
163
        }
164 5
    }
165
166
    /**
167
     * @param FieldInterface $field
168
     * @param array $data
169
     */
170 5 View Code Duplication
    private function populateField(FieldInterface $field, array $data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
    {
172 5
        $name = $field->getName();
173 5
        if (isset($data[$name])) {
174 2
            $field->setValue($data[$name]);
175
        }
176 5
        if ($field->hasDynamicForms()) {
177
            $forms = $field->getDynamicForms();
178
            $this->populateDynamicForms($forms, $data);
179
        }
180 5
    }
181
182
    /**
183
     * @param string $name
184
     * @return FieldInterface|null
185
     */
186 2
    public function getField($name)
187
    {
188 2
        return $this->fieldCollection->findByName($name);
189
    }
190
191
    /**
192
     * @return FieldCollection
193
     */
194 30
    public function getFields()
195
    {
196 30
        return $this->fieldCollection;
197
    }
198
199
    /**
200
     * @param FieldInterface $field
201
     * @return $this
202
     */
203 38
    public function addField(FieldInterface $field)
204
    {
205 38
        $this->fieldCollection->append($field);
206 38
        return $this;
207
    }
208
209
    /**
210
     * @return string
211
     */
212 28
    public function render()
213
    {
214 28
        return $this->formRenderer->render($this, $this->isDisplayErrors());
215
    }
216
217
    /**
218
     * @param $url
219
     * @return $this
220
     */
221 2
    public function setAction($url)
222
    {
223 2
        $this->setAttribute('action', $url);
224 2
        return $this;
225
    }
226
227
    /**
228
     * @return string
229
     */
230 2
    public function getAction()
231
    {
232 2
        return $this->getAttribute('action');
233
    }
234
235
    /**
236
     * @return string
237
     */
238 29
    public function getId()
239
    {
240 29
        return $this->getAttribute('id');
241
    }
242
243
    /**
244
     * @param string $id
245
     * @return $this
246
     */
247 2
    public function setId($id)
248
    {
249 2
        $this->setAttribute('id', $id);
250 2
        return $this;
251
    }
252
253
    /**
254
     * @param $encType
255
     * @return $this
256
     */
257 2
    public function setEncType($encType)
258
    {
259 2
        $this->setAttribute('enctype', $encType);
260 2
        return $this;
261
    }
262
263
    /**
264
     * @return string
265
     */
266 1
    public function getEncType()
267
    {
268 1
        return $this->getAttribute('enctype');
269
    }
270
271
    /**
272
     * @param string $method
273
     * @return FormInterface
274
     */
275 2
    public function setMethod($method)
276
    {
277 2
        $this->setAttribute('method', $method);
278 2
        return $this;
279
    }
280
281
    /**
282
     * @return string
283
     */
284 29
    public function getMethod()
285
    {
286 29
        return $this->getAttribute('method');
287
    }
288
289
    /**
290
     * @param $class
291
     * @return FormInterface
292
     */
293 2
    public function setClass($class)
294
    {
295 2
        $this->setAttribute('class', $class);
296 2
        return $this;
297
    }
298
299
    /**
300
     * @return string
301
     */
302 2
    public function getClass()
303
    {
304 2
        return $this->getAttribute('class');
305
    }
306
307
    /**
308
     * @return boolean
309
     */
310 29
    public function isDisplayErrors()
311
    {
312 29
        return $this->displayErrors;
313
    }
314
315
    /**
316
     * @param boolean $displayErrors
317
     * @return AbstractForm
318
     */
319 3
    public function setDisplayErrors($displayErrors)
320
    {
321 3
        $this->displayErrors = $displayErrors;
322 3
        return $this;
323
    }
324
325
    /**
326
     * @param FormRendererInterface $renderer
327
     * @return AbstractForm
328
     */
329 2
    public function setFormRenderer(FormRendererInterface $renderer)
330
    {
331 2
        $this->formRenderer = $renderer;
332 2
        return $this;
333
    }
334
335 6
    public function moveUploadedFiles()
336
    {
337 6
        $this->fieldCollection->rewind();
338 6
        while ($this->fieldCollection->valid()) {
339 6
            $current = $this->fieldCollection->current();
340 6
            $this->moveFileIfUploadField($current);
341 5
            $this->fieldCollection->next() ;
342
        }
343 5
    }
344
345
    /**
346
     * @param FieldInterface $field
347
     * @return bool
348
     */
349 6
    public function moveFileIfUploadField(FieldInterface $field)
350
    {
351 6
        if ($field instanceof FileUpload) {
352 2
            $field->moveUploadToDestination();
353 1
            return true;
354
        }
355 4
        return false;
356
    }
357
}