FormFactory::addValidators()   B
last analyzed

Complexity

Conditions 10
Paths 17

Size

Total Lines 35
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 13.7025

Importance

Changes 0
Metric Value
eloc 30
c 0
b 0
f 0
dl 0
loc 35
ccs 20
cts 30
cp 0.6667
rs 7.6666
cc 10
nc 17
nop 2
crap 13.7025

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