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 \Illuminate\Support\Collection */ |
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 string */ |
49
|
|
|
public $autocomplete = 'off'; |
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 = collect($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
|
|
|
$this->model = $this->params->get('model', $this->form->model); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
protected function setCommonAttributes() |
78
|
|
|
{ |
79
|
|
|
$this->setName(); |
80
|
|
|
$this->setLabel(); |
81
|
|
|
$this->setValue(); |
82
|
|
|
$this->setClass(); |
83
|
|
|
$this->setRequired(); |
84
|
|
|
$this->setDisabled(); |
85
|
|
|
$this->setReadonly(); |
86
|
|
|
$this->setAutocomplete(); |
87
|
|
|
$this->setDesc(); |
88
|
|
|
$this->setHelp(); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
protected function setSpecificAttributes() |
92
|
|
|
{ |
93
|
|
|
// ... |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
protected function setName() |
97
|
|
|
{ |
98
|
|
|
$this->name = $this->id = $this->params->get('name'); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
protected function setLabel() |
102
|
|
|
{ |
103
|
|
|
// Check if we receive a label that is false, so we don't display it |
104
|
|
|
if ($this->params->get('label') === false) { |
105
|
|
|
$this->label = ''; |
106
|
|
|
|
107
|
|
|
return; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
// Fallback: construct the label from the name |
111
|
|
|
$fallbackLabel = ! empty($this->name) ? ucwords(str_replace('_', ' ', $this->name)) : ''; |
112
|
|
|
|
113
|
|
|
// Check if we receive an explicit label |
114
|
|
|
$this->label = $this->params->get('label', $fallbackLabel); |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
protected function setRequired() |
118
|
|
|
{ |
119
|
|
|
$this->required = $this->params->get('required', false); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
protected function setDisabled() |
123
|
|
|
{ |
124
|
|
|
$this->disabled = $this->params->get('disabled', false); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
protected function setReadonly() |
128
|
|
|
{ |
129
|
|
|
$this->readonly = $this->params->get('readonly', false); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
protected function setValue() |
133
|
|
|
{ |
134
|
|
|
if (empty($this->name)) { |
135
|
|
|
return; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
if (! is_null($this->value)) { |
139
|
|
|
$computedValue = $this->value; |
140
|
|
|
} elseif (! is_null($this->model) && isset($this->model->{str_replace('[]', '', $this->name)})) { |
141
|
|
|
$computedValue = $this->model->{str_replace('[]', '', $this->name)}; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
$this->value = old($this->name, $computedValue ?? ''); |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
protected function setAutocomplete() |
148
|
|
|
{ |
149
|
|
|
// Set default autocomplete option (on/off) from cofing file |
150
|
|
|
$this->autocomplete = $this->params->get('autocomplete', config('blade-form-components.autocomplete')); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
protected function setDesc() |
154
|
|
|
{ |
155
|
|
|
$this->desc = $this->params->get('desc'); |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
protected function setHelp() |
159
|
|
|
{ |
160
|
|
|
$this->help = $this->params->get('help'); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
protected function setClass() |
164
|
|
|
{ |
165
|
|
|
$this->setDefaultClass(); |
166
|
|
|
|
167
|
|
|
// Attach the error class if an error is displayed against this field |
168
|
|
|
$errors = session()->get('errors', app(ViewErrorBag::class)); |
169
|
|
|
if (! empty($this->name) && $errors->has($this->name)) { |
170
|
|
|
$this->class[] = config('blade-form-components.styles.field.error'); |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
// Attach other user-defined classes |
174
|
|
|
if ($this->params->has('class')) { |
175
|
|
|
$this->class[] = $this->params->get('class'); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
protected function setDefaultClass() |
180
|
|
|
{ |
181
|
|
|
// Default class applied to all form elements (Eg 'form-control' for Bootstrap) |
182
|
|
|
$this->class[] = config('blade-form-components.styles.field.input'); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
protected function customAttributes() |
186
|
|
|
{ |
187
|
|
|
// Additional, custom attributes set by the user (eg: data, v-model) |
188
|
|
|
$customAttributes = $this->params->get('attributes', []); |
189
|
|
|
|
190
|
|
|
return isset($customAttributes['input']) |
191
|
|
|
? $customAttributes['input'] |
192
|
|
|
: []; |
193
|
|
|
} |
194
|
|
|
} |
195
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.