AbstractForm::submitLabel()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Zurbaev\Forms;
4
5
use Illuminate\Support\Str;
6
7
abstract class AbstractForm
8
{
9
    /**
10
     * @var array
11
     */
12
    protected $validTypes = [
13
        'hidden', 'text', 'textarea', 'file', 'select', 'checkbox', 'radio',
14
    ];
15
16
    /**
17
     * @var array
18
     */
19
    protected $typesWithOwnMarkup = [
20
        'hidden', 'checkbox',
21
    ];
22
23
    /**
24
     * @var string
25
     */
26
    protected $defaultFieldType = 'text';
27
28
    /**
29
     * @var bool
30
     */
31
    protected $truncatePasswords = true;
32
33
    /**
34
     * @var array
35
     */
36
    protected $excludeFromExtra = [
37
        'method', 'action', 'class', 'enctype',
38
    ];
39
40
    /**
41
     * Get the form's HTTP method.
42
     *
43
     * @return string
44
     */
45
    abstract public function method();
46
47
    /**
48
     * Get the form's action URL.
49
     *
50
     * @return string
51
     */
52
    abstract public function action();
53
54
    /**
55
     * Get the form's fields.
56
     *
57
     * @return array
58
     */
59
    abstract public function fields();
60
61
    /**
62
     * Additional form options.
63
     *
64
     * @return array
65
     */
66
    public function options()
67
    {
68
        return [];
69
    }
70
71
    /**
72
     * Determines if current form contains file fields.
73
     *
74
     * @return bool
75
     */
76
    public function withUploads()
77
    {
78
        return false;
79
    }
80
81
    /**
82
     * Form values (editing mode).
83
     *
84
     * @return array
85
     */
86
    public function values()
87
    {
88
        return [];
89
    }
90
91
    /**
92
     * Unique form ID.
93
     *
94
     * @return string
95
     */
96
    public function id()
97
    {
98
        return 'abstract-form-'.rand();
99
    }
100
101
    /**
102
     * Get the submit button label.
103
     *
104
     * @return string
105
     */
106
    public function submitLabel()
107
    {
108
        return 'Submit';
109
    }
110
111
    /**
112
     * Get the cancel button label.
113
     *
114
     * @return string
115
     */
116
    public function cancelLabel()
117
    {
118
        return 'Cancel';
119
    }
120
121
    /**
122
     * Get the form option value.
123
     *
124
     * @param string $path
125
     * @param null   $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
126
     *
127
     * @return mixed
128
     */
129
    public function get(string $path, $default = null)
130
    {
131
        return array_get($this->options(), $path, $default);
132
    }
133
134
    /**
135
     * Form's extra attributes.
136
     *
137
     * @param array $attributes
138
     *
139
     * @return string
140
     */
141
    public function extraAttributes(array $attributes = [])
142
    {
143
        return collect($this->onlyExtraAttributes($attributes))
144
            ->map(function (string $value, string $attribute) {
145
                return $attribute.'="'.$value.'"';
146
            })
147
            ->implode(' ');
148
    }
149
150
    /**
151
     * Get only extra form attributes.
152
     *
153
     * @param array $attributes
154
     *
155
     * @return array
156
     */
157
    public function onlyExtraAttributes(array $attributes = [])
158
    {
159
        $attributes = $attributes ?: $this->get('attributes', []);
160
161
        foreach ($this->excludeFromExtra as $attribute) {
162
            if (isset($attributes[$attribute])) {
163
                unset($attributes[$attribute]);
164
            }
165
        }
166
167
        return $attributes;
168
    }
169
170
    /**
171
     * Get the form field by name.
172
     *
173
     * @param string $name
174
     *
175
     * @return array|null
176
     */
177
    public function getField(string $name)
178
    {
179
        return array_get($this->fields(), $name);
180
    }
181
182
    /**
183
     * Determines if given field is a valid field.
184
     *
185
     * @param array $field
186
     *
187
     * @return bool
188
     */
189
    public function isValidField(array $field)
190
    {
191
        return in_array($this->fieldType($field), $this->validTypes);
192
    }
193
194
    /**
195
     * Generates ID for given input element.
196
     *
197
     * @param string $name
198
     *
199
     * @return string
200
     */
201
    public function inputId(string $name)
202
    {
203
        return 'input'.Str::ucfirst(Str::camel(Str::lower($name)));
204
    }
205
206
    /**
207
     * Determines if given field should be rendered with its markup only.
208
     *
209
     * @param array $field
210
     *
211
     * @return bool
212
     */
213
    public function fieldShouldUseOwnMarkup(array $field)
214
    {
215
        return in_array($this->fieldType($field), $this->typesWithOwnMarkup);
216
    }
217
218
    /**
219
     * Get the form field type.
220
     *
221
     * @param array $field
222
     *
223
     * @return string
224
     */
225
    public function fieldType(array $field)
226
    {
227
        return Str::lower($field['type'] ?? $this->defaultFieldType);
228
    }
229
230
    /**
231
     * Get the field attribute value.
232
     *
233
     * @param array  $field
234
     * @param string $attribute
235
     * @param null   $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
236
     *
237
     * @return mixed
238
     */
239
    public function fieldAttributeValue(array $field, string $attribute, $default = null)
240
    {
241
        return array_get($field, 'attributes.'.$attribute, $default);
242
    }
243
244
    /**
245
     * Determines if given field type is 'password'.
246
     *
247
     * @param array $field
248
     *
249
     * @return bool
250
     */
251
    public function isPasswordField(array $field)
252
    {
253
        return $this->fieldAttributeValue($field, 'type') === 'password';
254
    }
255
256
    /**
257
     * Determines if form should truncate value for given field.
258
     *
259
     * @param array $field
260
     *
261
     * @return bool
262
     */
263
    public function shouldTruncateValue(array $field)
264
    {
265
        if ($this->isPasswordField($field) && $this->truncatePasswords) {
266
            return true;
267
        }
268
269
        return false;
270
    }
271
272
    /**
273
     * Get the field value.
274
     *
275
     * @param string $name
276
     * @param array  $field
277
     * @param null   $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
278
     *
279
     * @return mixed|string
280
     */
281
    public function fieldValue(string $name, array $field, $default = null)
282
    {
283
        if ($this->shouldTruncateValue($field)) {
284
            return '';
285
        }
286
287
        $lookupName = $field['value_lookup'] ?? $name;
288
        $value = array_get($this->values(), $lookupName, $default);
289
        $oldValue = old($name);
290
        $mutatorMethod = Str::camel('get_'.$name.'_value');
291
292
        if ($oldValue && method_exists($this, $mutatorMethod)) {
293
            return call_user_func([$this, $mutatorMethod], $oldValue);
294
        }
295
296
        return $oldValue ?? $value;
297
    }
298
299
    /**
300
     * Get the field CSS classes.
301
     *
302
     * @param array $field
303
     * @param bool  $prependWithSpace = true
304
     *
305
     * @return string
306
     */
307
    public function fieldClasses(array $field, bool $prependWithSpace = true)
308
    {
309
        $classes = array_get($field, 'attributes.class', '');
310
311
        if (!$classes) {
312
            return '';
313
        }
314
315
        return ($prependWithSpace ? ' ' : '').$classes;
0 ignored issues
show
Bug introduced by
Are you sure $classes of type mixed|string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

315
        return ($prependWithSpace ? ' ' : '')./** @scrutinizer ignore-type */ $classes;
Loading history...
316
    }
317
318
    /**
319
     * Get additional field attributes.
320
     *
321
     * @param array $field
322
     *
323
     * @return string
324
     */
325
    public function fieldAttributes(array $field)
326
    {
327
        if (empty($field['attributes'])) {
328
            return '';
329
        }
330
331
        return $this->extraAttributes($field['attributes']);
332
    }
333
}
334