Completed
Push — master ( b5f959...da0e5f )
by Costin
02:20
created

FormElement   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 214
Duplicated Lines 0 %

Importance

Changes 3
Bugs 2 Features 1
Metric Value
wmc 45
eloc 77
c 3
b 2
f 1
dl 0
loc 214
rs 8.8

17 Methods

Rating   Name   Duplication   Size   Complexity  
A setLabel() 0 19 6
A setDesc() 0 4 2
A __construct() 0 8 1
A setDefaultClass() 0 4 1
A setCommonAttributes() 0 12 1
A setModel() 0 9 5
A setName() 0 4 3
A setSpecificAttributes() 0 2 1
A setReadonly() 0 4 3
A setRequired() 0 4 3
A setValue() 0 13 5
A setClass() 0 13 3
A setForm() 0 3 1
A setHelp() 0 4 2
A setAutocomplete() 0 7 2
A customAttributes() 0 8 3
A setDisabled() 0 4 3

How to fix   Complexity   

Complex Class

Complex classes like FormElement often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FormElement, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace SoareCostin\BladeFormComponents;
4
5
use Illuminate\Support\ViewErrorBag;
6
use SoareCostin\BladeFormComponents\Traits\GluesAttributes;
7
8
abstract class FormElement
9
{
10
    use GluesAttributes;
11
12
    /** @var array */
13
    protected $params;
14
15
    /** @var Form */
16
    protected $form;
17
18
    /** @var object */
19
    public $model = null;
20
21
    /** @var string */
22
    public $id;
23
24
    /** @var string */
25
    public $name;
26
27
    /** @var mixed */
28
    public $value;
29
30
    /** @var string */
31
    public $label;
32
33
    /** @var array */
34
    public $class = [];
35
36
    /** @var array */
37
    public $labelClass = [];
38
39
    /** @var bool */
40
    public $required = false;
41
42
    /** @var bool */
43
    public $disabled = false;
44
45
    /** @var bool */
46
    public $readonly = false;
47
48
    /** @var bool */
49
    public $autocomplete;
50
51
    /** @var string */
52
    public $desc;
53
54
    /** @var string */
55
    public $help;
56
57
    public function __construct(array $params)
58
    {
59
        $this->params = $params;
60
61
        $this->setForm();
62
        $this->setModel();
63
        $this->setCommonAttributes();
64
        $this->setSpecificAttributes();
65
    }
66
67
    protected function setForm()
68
    {
69
        $this->form = app(Form::class);
70
    }
71
72
    protected function setModel()
73
    {
74
        if (isset($this->params['model']) && ! empty($this->params['model'])) {
75
            $this->model = $this->params['model'];
76
        }
77
78
        // Check to see if the model was added on the form opening tag
79
        if (is_null($this->model) && ! is_null($this->form->model)) {
80
            $this->model = $this->form->model;
81
        }
82
    }
83
84
    protected function setCommonAttributes()
85
    {
86
        $this->setName();
87
        $this->setLabel();
88
        $this->setValue();
89
        $this->setClass();
90
        $this->setRequired();
91
        $this->setDisabled();
92
        $this->setReadonly();
93
        $this->setAutocomplete();
94
        $this->setDesc();
95
        $this->setHelp();
96
    }
97
98
    protected function setSpecificAttributes()
99
    {
100
        // ...
101
    }
102
103
    protected function setName()
104
    {
105
        if (isset($this->params['name']) && ! empty($this->params['name'])) {
106
            $this->name = $this->id = $this->params['name'];
107
        }
108
    }
109
110
    protected function setLabel()
111
    {
112
        // First, check if we receive an explicit label
113
        if (isset($this->params['label']) && ! empty($this->params['label'])) {
114
            $this->label = $this->params['label'];
115
116
            return;
117
        }
118
119
        // Check if we receive a label that is false, so we don't display it
120
        if (isset($this->params['label']) && $this->params['label'] === false) {
121
            $this->label = false;
0 ignored issues
show
Documentation Bug introduced by
The property $label was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
122
123
            return;
124
        }
125
126
        // Fallback: construct the label from the name
127
        if (isset($this->name)) {
128
            $this->label = ucwords(str_replace('_', ' ', $this->name));
129
        }
130
    }
131
132
    protected function setRequired()
133
    {
134
        if (isset($this->params['required']) && $this->params['required'] == true) {
135
            $this->required = true;
136
        }
137
    }
138
139
    protected function setDisabled()
140
    {
141
        if (isset($this->params['disabled']) && $this->params['disabled'] == true) {
142
            $this->disabled = true;
143
        }
144
    }
145
146
    protected function setReadonly()
147
    {
148
        if (isset($this->params['readonly']) && $this->params['readonly'] == true) {
149
            $this->readonly = true;
150
        }
151
    }
152
153
    protected function setValue()
154
    {
155
        if (is_null($this->name)) {
0 ignored issues
show
introduced by
The condition is_null($this->name) is always false.
Loading history...
156
            return;
157
        }
158
159
        if (! is_null($this->value)) {
160
            $computedValue = $this->value;
161
        } elseif (! is_null($this->model) && isset($this->model->{str_replace('[]', '', $this->name)})) {
162
            $computedValue = $this->model->{str_replace('[]', '', $this->name)};
163
        }
164
165
        $this->value = old($this->name, $computedValue ?? '');
166
    }
167
168
    protected function setAutocomplete()
169
    {
170
        // Set default autocomplete option (true/false) from cofing file
171
        $this->autocomplete = config('blade-form-components.autocomplete');
172
173
        if (isset($this->params['autocomplete'])) {
174
            $this->autocomplete = $this->params['autocomplete'];
175
        }
176
    }
177
178
    protected function setDesc()
179
    {
180
        if (isset($this->params['desc'])) {
181
            $this->desc = $this->params['desc'];
182
        }
183
    }
184
185
    protected function setHelp()
186
    {
187
        if (isset($this->params['help'])) {
188
            $this->help = $this->params['help'];
189
        }
190
    }
191
192
    protected function setClass()
193
    {
194
        $this->setDefaultClass();
195
196
        // Attach the error class if an error is displayed against this field
197
        $errors = session()->get('errors', app(ViewErrorBag::class));
198
        if ($errors->has($this->name)) {
199
            $this->class[] = config('blade-form-components.styles.field.error');
200
        }
201
202
        // Attach other user-defined classes
203
        if (isset($this->params['class'])) {
204
            $this->class[] = $this->params['class'];
205
        }
206
    }
207
208
    protected function setDefaultClass()
209
    {
210
        // Default class applied to all form elements (Eg 'form-control' for Bootstrap)
211
        $this->class[] = config('blade-form-components.styles.field.input');
212
    }
213
214
    protected function customAttributes()
215
    {
216
        // Additional, custom attributes set by the user (eg: data, v-model)
217
        
218
        if (isset($this->params['attributes']['input']) && ! empty($this->params['attributes']['input'])) {
219
            return $this->params['attributes']['input'];
220
        }
221
        return [];
222
    }
223
}
224