Completed
Push — master ( e7d339...709f36 )
by Timur
02:11
created

AbstractForm::shouldTruncateValue()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 9.4285
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 form option value.
113
     *
114
     * @param string $path
115
     * @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...
116
     *
117
     * @return mixed
118
     */
119
    public function get(string $path, $default = null)
120
    {
121
        return array_get($this->options(), $path, $default);
122
    }
123
124
    /**
125
     * Form's extra attributes.
126
     *
127
     * @param array $attributes
128
     *
129
     * @return string
130
     */
131
    public function extraAttributes(array $attributes = [])
132
    {
133
        return collect($this->onlyExtraAttributes($attributes))
134
            ->map(function (string $value, string $attribute) {
135
                return $attribute.'="'.$value.'"';
136
            })
137
            ->implode(' ');
138
    }
139
140
    /**
141
     * Get only extra form attributes.
142
     *
143
     * @param array $attributes
144
     *
145
     * @return array
146
     */
147
    public function onlyExtraAttributes(array $attributes = [])
148
    {
149
        $attributes = $attributes ?: $this->get('attributes', []);
150
151
        foreach ($this->excludeFromExtra as $attribute) {
152
            if (isset($attributes[$attribute])) {
153
                unset($attributes[$attribute]);
154
            }
155
        }
156
157
        return $attributes;
158
    }
159
160
    /**
161
     * Get the form field by name.
162
     *
163
     * @param string $name
164
     *
165
     * @return array|null
166
     */
167
    public function getField(string $name)
168
    {
169
        return array_get($this->fields(), $name);
170
    }
171
172
    /**
173
     * Determines if given field is a valid field.
174
     *
175
     * @param array $field
176
     *
177
     * @return bool
178
     */
179
    public function isValidField(array $field)
180
    {
181
        return in_array($this->fieldType($field), $this->validTypes);
182
    }
183
184
    /**
185
     * Generates ID for given input element.
186
     *
187
     * @param string $name
188
     *
189
     * @return string
190
     */
191
    public function inputId(string $name)
192
    {
193
        return 'input'.Str::ucfirst(Str::camel(Str::lower($name)));
194
    }
195
196
    /**
197
     * Determines if given field should be rendered with its markup only.
198
     *
199
     * @param array $field
200
     *
201
     * @return bool
202
     */
203
    public function fieldShouldUseOwnMarkup(array $field)
204
    {
205
        return in_array($this->fieldType($field), $this->typesWithOwnMarkup);
206
    }
207
208
    /**
209
     * Get the form field type.
210
     *
211
     * @param array $field
212
     *
213
     * @return string
214
     */
215
    public function fieldType(array $field)
216
    {
217
        return Str::lower($field['type'] ?? $this->defaultFieldType);
218
    }
219
220
    /**
221
     * Get the field attribute value.
222
     *
223
     * @param array  $field
224
     * @param string $attribute
225
     * @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...
226
     *
227
     * @return mixed
228
     */
229
    public function fieldAttributeValue(array $field, string $attribute, $default = null)
230
    {
231
        return array_get($field, 'attributes.'.$attribute, $default);
232
    }
233
234
    /**
235
     * Determines if given field type is 'password'.
236
     *
237
     * @param array $field
238
     *
239
     * @return bool
240
     */
241
    public function isPasswordField(array $field)
242
    {
243
        return $this->fieldAttributeValue($field, 'type') === 'password';
244
    }
245
246
    /**
247
     * Determines if form should truncate value for given field.
248
     *
249
     * @param array $field
250
     *
251
     * @return bool
252
     */
253
    public function shouldTruncateValue(array $field)
254
    {
255
        if ($this->isPasswordField($field) && $this->truncatePasswords) {
256
            return true;
257
        }
258
259
        return false;
260
    }
261
262
    /**
263
     * Get the field value.
264
     *
265
     * @param string $name
266
     * @param array  $field
267
     * @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...
268
     *
269
     * @return mixed|string
270
     */
271
    public function fieldValue(string $name, array $field, $default = null)
272
    {
273
        if ($this->shouldTruncateValue($field)) {
274
            return '';
275
        }
276
277
        $lookupName = $field['value_lookup'] ?? $name;
278
        $value = array_get($this->values(), $lookupName, $default);
279
280
        return old($name, $value);
281
    }
282
283
    /**
284
     * Get the field CSS classes.
285
     *
286
     * @param array $field
287
     * @param bool  $prependWithSpace = true
288
     *
289
     * @return string
290
     */
291
    public function fieldClasses(array $field, bool $prependWithSpace = true)
292
    {
293
        $classes = array_get($field, 'attributes.class', '');
294
295
        if (!$classes) {
296
            return '';
297
        }
298
299
        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

299
        return ($prependWithSpace ? ' ' : '')./** @scrutinizer ignore-type */ $classes;
Loading history...
300
    }
301
302
    /**
303
     * Get additional field attributes.
304
     *
305
     * @param array $field
306
     *
307
     * @return string
308
     */
309
    public function fieldAttributes(array $field)
310
    {
311
        if (empty($field['attributes'])) {
312
            return '';
313
        }
314
315
        return $this->extraAttributes($field['attributes']);
316
    }
317
}
318