Completed
Push — master ( f06f95...cfadd2 )
by Song
03:17
created

Field::validate()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 36
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 8
nop 1
dl 0
loc 36
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Form;
4
5
use Encore\Admin\Admin;
6
use Encore\Admin\Form;
7
use Illuminate\Contracts\Support\Arrayable;
8
use Illuminate\Support\Facades\Validator;
9
10
/**
11
 * Class Field.
12
 *
13
 * @method Field default($value) set field default value
14
 */
15
class Field
16
{
17
    /**
18
     * Element id.
19
     *
20
     * @var array|string
21
     */
22
    protected $id;
23
24
    /**
25
     * Element value.
26
     *
27
     * @var mixed
28
     */
29
    protected $value;
30
31
    /**
32
     * Field original value.
33
     *
34
     * @var mixed
35
     */
36
    protected $original;
37
38
    /**
39
     * Field default value.
40
     *
41
     * @var mixed
42
     */
43
    protected $default;
44
45
    /**
46
     * Element label.
47
     *
48
     * @var string
49
     */
50
    protected $label = '';
51
52
    /**
53
     * Column name.
54
     *
55
     * @var string
56
     */
57
    protected $column = '';
58
59
    /**
60
     * Variables of elements.
61
     *
62
     * @var array
63
     */
64
    protected $variables = [];
65
66
    /**
67
     * Options for specify elements.
68
     *
69
     * @var array
70
     */
71
    protected $options = [];
72
73
    /**
74
     * Validation rules.
75
     *
76
     * @var string
77
     */
78
    protected $rules = '';
79
80
    /**
81
     * Css required by this field.
82
     *
83
     * @var array
84
     */
85
    protected static $css = [];
86
87
    /**
88
     * Js required by this field.
89
     *
90
     * @var array
91
     */
92
    protected static $js = [];
93
94
    /**
95
     * Script for field.
96
     *
97
     * @var string
98
     */
99
    protected $script = '';
100
101
    /**
102
     * Element attributes.
103
     *
104
     * @var array
105
     */
106
    protected $attributes = [];
107
108
    /**
109
     * Parent form.
110
     *
111
     * @var Form
112
     */
113
    protected $form = null;
114
115
    /**
116
     * View for field to render.
117
     *
118
     * @var string
119
     */
120
    protected $view = '';
121
122
    /**
123
     * Help block.
124
     *
125
     * @var array
126
     */
127
    protected $help = [];
128
129
    /**
130
     * Field constructor.
131
     *
132
     * @param $column
133
     * @param array $arguments
134
     */
135
    public function __construct($column, $arguments = [])
136
    {
137
        $this->column = $column;
138
        $this->label = $this->formatLabel($arguments);
139
        $this->id = $this->formatId($column);
140
    }
141
142
    /**
143
     * Get assets required by this field.
144
     *
145
     * @return array
146
     */
147
    public static function getAssets()
148
    {
149
        return [
150
            'css' => static::$css,
151
            'js'  => static::$js,
152
        ];
153
    }
154
155
    /**
156
     * Format the field element id.
157
     *
158
     * @param string|array $column
159
     *
160
     * @return string|array
161
     */
162
    protected function formatId($column)
163
    {
164
        return str_replace('.', '_', $column);
165
    }
166
167
    /**
168
     * Format the label value.
169
     *
170
     * @param array $arguments
171
     *
172
     * @return string
173
     */
174
    protected function formatLabel($arguments = [])
175
    {
176
        $column = is_array($this->column) ? current($this->column) : $this->column;
177
178
        $label = isset($arguments[0]) ? $arguments[0] : ucfirst($column);
179
180
        return str_replace(['.', '_'], ' ', $label);
181
    }
182
183
    /**
184
     * Format the name of the field.
185
     *
186
     * @param string $column
187
     *
188
     * @return array|mixed|string
189
     */
190
    protected function formatName($column)
191
    {
192
        if (is_string($column)) {
193
            $name = explode('.', $column);
194
195
            if (count($name) == 1) {
196
                return $name[0];
197
            }
198
199
            $html = array_shift($name);
200
            foreach ($name as $piece) {
201
                $html .= "[$piece]";
202
            }
203
204
            return $html;
205
        }
206
207
        if (is_array($this->column)) {
208
            $names = [];
209
            foreach ($this->column as $key => $name) {
210
                $names[$key] = $this->formatName($name);
211
            }
212
213
            return $names;
214
        }
215
216
        return '';
217
    }
218
219
    /**
220
     * Fill data to the field.
221
     *
222
     * @param $data
223
     *
224
     * @return void
225
     */
226 View Code Duplication
    public function fill($data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
227
    {
228
        if (is_array($this->column)) {
229
            foreach ($this->column as $key => $column) {
230
                $this->value[$key] = array_get($data, $column);
231
            }
232
233
            return;
234
        }
235
236
        $this->value = array_get($data, $this->column);
237
    }
238
239
    /**
240
     * Set original value to the field.
241
     *
242
     * @param array $data
243
     *
244
     * @return void
245
     */
246 View Code Duplication
    public function setOriginal($data)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
247
    {
248
        if (is_array($this->column)) {
249
            foreach ($this->column as $key => $column) {
250
                $this->original[$key] = array_get($data, $column);
251
            }
252
253
            return;
254
        }
255
256
        $this->original = array_get($data, $this->column);
257
    }
258
259
    /**
260
     * @param Form $form
261
     *
262
     * @return $this
263
     */
264
    public function setForm(Form $form)
265
    {
266
        $this->form = $form;
267
268
        return $this;
269
    }
270
271
    /**
272
     * Set the field options.
273
     *
274
     * @param array $options
275
     *
276
     * @return $this
277
     */
278
    public function options($options = [])
279
    {
280
        if ($options instanceof Arrayable) {
281
            $options = $options->toArray();
282
        }
283
284
        $this->options = array_merge($this->options, $options);
285
286
        return $this;
287
    }
288
289
    /**
290
     * Get or set rules.
291
     *
292
     * @param null $rules
293
     *
294
     * @return $this|array
295
     */
296
    public function rules($rules = null)
297
    {
298
        if (is_null($rules)) {
299
            return $this->rules;
300
        }
301
302
        $rules = array_filter(explode('|', "{$this->rules}|$rules"));
303
304
        $this->rules = implode('|', $rules);
305
306
        return $this;
307
    }
308
309
310
    protected function getRules()
311
    {
312
        return $this->rules;
313
    }
314
315
    /**
316
     * Set or get value of the field.
317
     *
318
     * @param null $value
319
     *
320
     * @return mixed
321
     */
322
    public function value($value = null)
323
    {
324
        if (is_null($value)) {
325
            return is_null($this->value) ? $this->default : $this->value;
326
        }
327
328
        $this->value = $value;
329
330
        return $this;
331
    }
332
333
    /**
334
     * Set help block for current field.
335
     *
336
     * @param string $text
337
     * @param string $icon
338
     *
339
     * @return $this
340
     */
341
    public function help($text = '', $icon = 'fa-info-circle')
342
    {
343
        $this->help = compact('text', 'icon');
344
345
        return $this;
346
    }
347
348
    /**
349
     * Get column of the field.
350
     *
351
     * @return string
352
     */
353
    public function column()
354
    {
355
        return $this->column;
356
    }
357
358
    /**
359
     * Get label of the field.
360
     *
361
     * @return string
362
     */
363
    public function label()
364
    {
365
        return $this->label;
366
    }
367
368
    /**
369
     * Get original value of the field.
370
     *
371
     * @return mixed
372
     */
373
    public function original()
374
    {
375
        return $this->original;
376
    }
377
378
    /**
379
     * Validate input field data.
380
     *
381
     * @param array $input
382
     *
383
     * @return bool|Validator
384
     */
385
    public function validate(array $input)
386
    {
387
        $data = $rules = [];
388
389
        if (!$fieldRules = $this->getRules()) {
390
            return false;
391
        }
392
393
        if (is_string($this->column)) {
394
            if (!array_has($input, $this->column)) {
395
                return false;
396
            }
397
398
            $value = array_get($input, $this->column);
399
400
            // remove empty options from multiple select.
401
            if ($this instanceof Field\MultipleSelect) {
402
                $value = array_filter($value);
403
            }
404
405
            $data[$this->label] = $value;
406
            $rules[$this->label] = $fieldRules;
407
        }
408
409
        if (is_array($this->column)) {
410
            foreach ($this->column as $key => $column) {
411
                if (!array_key_exists($column, $input)) {
412
                    continue;
413
                }
414
                $data[$this->label.$key] = array_get($input, $column);
415
                $rules[$this->label.$key] = $fieldRules;
416
            }
417
        }
418
419
        return Validator::make($data, $rules);
420
    }
421
422
    /**
423
     * Add html attributes to elements.
424
     *
425
     * @param array|string $attribute
426
     * @param mixed        $value
427
     *
428
     * @return $this
429
     */
430
    public function attribute($attribute, $value = null)
431
    {
432
        if (is_array($attribute)) {
433
            $this->attributes = array_merge($this->attributes, $attribute);
434
        } else {
435
            $this->attributes[$attribute] = (string) $value;
436
        }
437
438
        return $this;
439
    }
440
441
    /**
442
     * Set the field as readonly mode.
443
     *
444
     * @return Field
445
     */
446
    public function readOnly()
447
    {
448
        return $this->attribute('disabled', true);
449
    }
450
451
    /**
452
     * Format the field attributes.
453
     *
454
     * @return string
455
     */
456
    protected function formatAttributes()
457
    {
458
        $html = [];
459
460
        foreach ($this->attributes as $name => $value) {
461
            $html[] = "$name=\"$value\"";
462
        }
463
464
        return implode(' ', $html);
465
    }
466
467
    /**
468
     * Get the view variables of this field.
469
     *
470
     * @return array
471
     */
472
    protected function variables()
473
    {
474
        $this->variables['id'] = $this->id;
475
        $this->variables['name'] = $this->formatName($this->column);
476
        $this->variables['value'] = $this->value();
477
        $this->variables['label'] = $this->label;
478
        $this->variables['column'] = $this->column;
479
        $this->variables['attributes'] = $this->formatAttributes();
480
        $this->variables['help'] = $this->help;
481
482
        return $this->variables;
483
    }
484
485
    /**
486
     * Get view of this field.
487
     *
488
     * @return string
489
     */
490
    public function getView()
491
    {
492
        if (!empty($this->view)) {
493
            return $this->view;
494
        }
495
496
        $class = explode('\\', get_called_class());
497
498
        return 'admin::form.'.strtolower(end($class));
499
    }
500
501
    /**
502
     * Render this filed.
503
     *
504
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
505
     */
506
    public function render()
507
    {
508
        Admin::script($this->script);
509
510
        return view($this->getView(), $this->variables());
511
    }
512
513
    /**
514
     * @param $method
515
     * @param $arguments
516
     *
517
     * @return $this
518
     */
519
    public function __call($method, $arguments)
520
    {
521
        if ($method === 'default') {
522
            $this->default = $arguments[0];
523
524
            return $this;
525
        }
526
    }
527
}
528