FormFactory::addValidators()   B
last analyzed

Complexity

Conditions 10
Paths 17

Size

Total Lines 34
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 10

Importance

Changes 0
Metric Value
eloc 28
c 0
b 0
f 0
dl 0
loc 34
ccs 28
cts 28
cp 1
rs 7.6666
cc 10
nc 17
nop 2
crap 10

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Del\Form\Factory;
6
7
use Del\Form\Field\Attributes\Field;
8
use Del\Form\Field\CheckBox;
9
use Del\Form\Field\FieldInterface;
10
use Del\Form\Field\FileUpload;
11
use Del\Form\Field\Hidden;
12
use Del\Form\Field\MultiSelect;
13
use Del\Form\Field\Radio;
14
use Del\Form\Field\Select;
15
use Del\Form\Field\Submit;
16
use Del\Form\Field\Text;
17
use Del\Form\Field\Text\EmailAddress;
18
use Del\Form\Field\Text\FloatingPoint;
19
use Del\Form\Field\Text\Integer;
20
use Del\Form\Field\Text\Password;
21
use Del\Form\Field\TextArea;
22
use Del\Form\Form;
23
use Del\Form\FormInterface;
24
use Del\Form\Validator\FileExtensionValidator;
25
use Del\Form\Validator\MaxLength;
26
use Del\Form\Validator\MimeTypeValidator;
27
use Del\Form\Validator\MinLength;
28
use ReflectionClass;
29
use function array_shift;
30
use function count;
31
use function explode;
32
use function strpos;
33
34
class FormFactory
35
{
36
    private Form $form;
37
38 1
    public function createFromEntity(string $name, object $entity): FormInterface
39
    {
40 1
        $this->form = new Form($name);
41 1
        $mirror = new ReflectionClass($entity);
42 1
        $properties = $mirror->getProperties();
43
44 1
        foreach ($properties as $property) {
45 1
            $fieldName = $property->getName();
46 1
            $attributes = $property->getAttributes(Field::class);
47
48 1
            if (count($attributes) > 0) {
49 1
                $rules = $attributes[0]->newInstance()->rules;
50
51 1
                if (strpos($rules, '|') !== false) {
52 1
                    $rules = explode('|', $rules);
53 1
                    $fieldType = array_shift($rules);
54
                } else {
55 1
                    $fieldType = $rules;
56 1
                    $rules = [];
57
                }
58
59 1
                $field = $this->createField($fieldName, $fieldType);
60 1
                $this->addValidators($field, $rules);
61 1
                $value = $property->getValue($entity);
62 1
                $this->setValue($field, $value);
63 1
                $this->form->addField($field);
64
65 1
                if ($field instanceof FileUpload) {
66 1
                    $this->form->setEncType(Form::ENC_TYPE_MULTIPART_FORM_DATA);
67
                }
68
            }
69
        }
70
71 1
        $this->form->addField(new Submit('submit'));
72
73 1
        return $this->form;
74
    }
75
76 1
    private function createField(string $fieldName, string $fieldType): FieldInterface
77
    {
78
        switch ($fieldType) {
79 1
            case 'bool':
80 1
            case 'boolean':
81 1
            case 'checkbox':
82 1
                $field = new CheckBox($fieldName);
83 1
                break;
84 1
            case 'email':
85 1
                $field = new EmailAddress($fieldName);
86 1
                break;
87 1
            case 'file':
88 1
                $field = new FileUpload($fieldName);
89 1
                break;
90 1
            case 'float':
91 1
                $field = new FloatingPoint($fieldName);
92 1
                break;
93 1
            case 'hidden':
94 1
                $field = new Hidden($fieldName);
95 1
                break;
96 1
            case 'integer':
97 1
                $field = new Integer($fieldName);
98 1
                break;
99 1
            case 'multiselect':
100 1
                $field = new MultiSelect($fieldName);
101 1
                break;
102 1
            case 'password':
103 1
                $field = new Password($fieldName);
104 1
                break;
105 1
            case 'radio':
106 1
                $field = new Radio($fieldName);
107 1
                break;
108 1
            case 'select':
109 1
                $field = new Select($fieldName);
110 1
                break;
111 1
            case 'textarea':
112 1
                $field = new TextArea($fieldName);
113 1
                break;
114 1
            case 'string':
115 1
            case 'text':
116
            default:
117 1
                $field = new Text($fieldName);
118 1
                break;
119
        }
120
121 1
        return $field;
122
    }
123
124 1
    private function addValidators(FieldInterface $field, array $rules): void
125
    {
126 1
        foreach ($rules as $rule) {
127 1
            $arg = null;
128
129 1
            if (strpos($rule, ':') !== false) {
130 1
                $debris = explode(':', $rule);
131 1
                $rule = $debris[0];
132 1
                $arg = $debris[1];
133
            }
134
135
            switch ($rule) {
136 1
                case 'file_ext':
137 1
                    $extensions = explode(',', $arg);
138 1
                    $field->addValidator(new FileExtensionValidator($extensions));
139 1
                    break;
140 1
                case 'max':
141 1
                    $field->addValidator(new MaxLength((int) $arg));
142 1
                    break;
143 1
                case 'mime':
144 1
                    $mimeTypes = explode(',', $arg);
145 1
                    $field->addValidator(new MimeTypeValidator($mimeTypes, $field->getName()));
146 1
                    break;
147 1
                case 'min':
148 1
                    $field->addValidator(new MinLength((int) $arg));
149 1
                    break;
150 1
                case 'required':
151 1
                    $field->setRequired(true);
152 1
                    break;
153 1
                case 'upload':
154 1
                    if ($field instanceof FileUpload) {
155 1
                        $field->setUploadDirectory($arg);
156
                    }
157 1
                    break;
158
            }
159
        }
160
    }
161
162 1
    private function setValue(FieldInterface $field, mixed $value): void
163
    {
164 1
        if ($value !== null) {
165 1
            $field->setValue($value);
166
        }
167
    }
168
}
169