Completed
Pull Request — master (#163)
by
unknown
08:39
created

Field::getAssets()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
rs 9.4285
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
9
/**
10
 * Class Field.
11
 *
12
 * @method Field default($value) set field default value
13
 */
14
class Field
15
{
16
    /**
17
     * Element id.
18
     *
19
     * @var array|string
20
     */
21
    protected $id;
22
23
    /**
24
     * Element value.
25
     *
26
     * @var mixed
27
     */
28
    protected $value;
29
30
    /**
31
     * Field original value.
32
     *
33
     * @var mixed
34
     */
35
    protected $original;
36
37
    /**
38
     * Field default value.
39
     *
40
     * @var mixed
41
     */
42
    protected $default;
43
44
    /**
45
     * Element label.
46
     *
47
     * @var string
48
     */
49
    protected $label = '';
50
51
    /**
52
     * Column name.
53
     *
54
     * @var string
55
     */
56
    protected $column = '';
57
58
    /**
59
     * Variables of elements.
60
     *
61
     * @var array
62
     */
63
    protected $variables = [];
64
65
    /**
66
     * Options for specify elements.
67
     *
68
     * @var array
69
     */
70
    protected $options = [];
71
72
    /**
73
     * Validation rules.
74
     *
75
     * @var string
76
     */
77
    protected $rules = '';
78
79
    /**
80
     * Css required by this field.
81
     *
82
     * @var array
83
     */
84
    protected static $css = [];
85
86
    /**
87
     * Js required by this field.
88
     *
89
     * @var array
90
     */
91
    protected static $js = [];
92
93
    /**
94
     * Script for field.
95
     *
96
     * @var string
97
     */
98
    protected $script = '';
99
100
    /**
101
     * Element attributes.
102
     *
103
     * @var array
104
     */
105
    protected $attributes = [];
106
107
    /**
108
     * Parent form.
109
     *
110
     * @var Form
111
     */
112
    protected $form = null;
113
114
    /**
115
     * View for field to render.
116
     *
117
     * @var string
118
     */
119
    protected $view = '';
120
121
    /**
122
     * Field constructor.
123
     *
124
     * @param $column
125
     * @param array $arguments
126
     */
127
    public function __construct($column, $arguments = [])
128
    {
129
        $this->column = $column;
130
        $this->label = $this->formatLabel($arguments);
131
        $this->id = $this->formatId($column);
132
    }
133
134
    /**
135
     * Get assets required by this field.
136
     *
137
     * @return array
138
     */
139
    public static function getAssets()
140
    {
141
        return [
142
            'css' => static::$css,
143
            'js'  => static::$js,
144
        ];
145
    }
146
147
    /**
148
     * Format the field element id.
149
     *
150
     * @param string|array $column
151
     *
152
     * @return string|array
153
     */
154
    protected function formatId($column)
155
    {
156
        return str_replace('.', '_', $column);
157
    }
158
159
    /**
160
     * Format the label value.
161
     *
162
     * @param array $arguments
163
     *
164
     * @return string
165
     */
166
    protected function formatLabel($arguments = [])
167
    {
168
        $column = is_array($this->column) ? current($this->column) : $this->column;
169
170
        $label = isset($arguments[0]) ? $arguments[0] : ucfirst($column);
171
172
        return str_replace(['.', '_'], ' ', $label);
173
    }
174
175
    /**
176
     * Format the name of the field.
177
     *
178
     * @param string $column
179
     *
180
     * @return array|mixed|string
181
     */
182
    protected function formatName($column)
183
    {
184
        if (is_string($column)) {
185
            $name = explode('.', $column);
186
187
            if (count($name) == 1) {
188
                return $name[0];
189
            }
190
191
            $html = array_shift($name);
192
            foreach ($name as $piece) {
193
                $html .= "[$piece]";
194
            }
195
196
            return $html;
197
        }
198
199
        if (is_array($this->column)) {
200
            $names = [];
201
            foreach ($this->column as $key => $name) {
202
                $names[$key] = $this->formatName($name);
203
            }
204
205
            return $names;
206
        }
207
208
        return '';
209
    }
210
211
    /**
212
     * Fill data to the field.
213
     *
214
     * @param $data
215
     *
216
     * @return void
217
     */
218 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...
219
    {
220
        if (is_array($this->column)) {
221
            foreach ($this->column as $key => $column) {
222
                $this->value[$key] = array_get($data, $column);
223
            }
224
225
            return;
226
        }
227
228
        $this->value = array_get($data, $this->column);
229
    }
230
231
    /**
232
     * Set original value to the field.
233
     *
234
     * @param array $data
235
     *
236
     * @return void
237
     */
238 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...
239
    {
240
        if (is_array($this->column)) {
241
            foreach ($this->column as $key => $column) {
242
                $this->original[$key] = array_get($data, $column);
243
            }
244
245
            return;
246
        }
247
248
        $this->original = array_get($data, $this->column);
249
    }
250
251
    /**
252
     * @param Form $form
253
     *
254
     * @return $this
255
     */
256
    public function setForm(Form $form)
257
    {
258
        $this->form = $form;
259
260
        return $this;
261
    }
262
263
    /**
264
     * Set the field options.
265
     *
266
     * @param array $options
267
     *
268
     * @return $this
269
     */
270
    public function options($options = [])
271
    {
272
        if ($options instanceof Arrayable) {
273
            $options = $options->toArray();
274
        }
275
276
        $this->options = array_merge($this->options, $options);
277
278
        return $this;
279
    }
280
281
    /**
282
     * Get or set rules.
283
     *
284
     * @param null $rules
285
     *
286
     * @return $this
287
     */
288
    public function rules($rules = null)
289
    {
290
        if (is_null($rules)) {
291
            return $this->rules;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->rules; (string) is incompatible with the return type documented by Encore\Admin\Form\Field::rules of type Encore\Admin\Form\Field.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
292
        }
293
294
        $rules = array_filter(explode('|', "{$this->rules}|$rules"));
295
296
        $this->rules = implode('|', $rules);
297
298
        return $this;
299
    }
300
301
    /**
302
     * Set or get value of the field.
303
     *
304
     * @param null $value
305
     *
306
     * @return mixed
307
     */
308
    public function value($value = null)
309
    {
310
        if (is_null($value)) {
311
            return is_null($this->value) ? $this->default : $this->value;
312
        }
313
314
        $this->value = $value;
315
316
        return $this;
317
    }
318
319
    /**
320
     * Get column of the field.
321
     *
322
     * @return string
323
     */
324
    public function column()
325
    {
326
        return $this->column;
327
    }
328
329
    /**
330
     * Get label of the field.
331
     *
332
     * @return string
333
     */
334
    public function label()
335
    {
336
        return $this->label;
337
    }
338
339
    /**
340
     * Get original value of the field.
341
     *
342
     * @return mixed
343
     */
344
    public function original()
345
    {
346
        return $this->original;
347
    }
348
349
    /**
350
     * Add html attributes to elements.
351
     *
352
     * @param array|string $attribute
353
     * @param mixed        $value
354
     *
355
     * @return $this
356
     */
357
    public function attribute($attribute, $value = null)
358
    {
359
        if (is_array($attribute)) {
360
            $this->attributes = array_merge($this->attributes, $attribute);
361
        } else {
362
            $this->attributes[$attribute] = (string) $value;
363
        }
364
365
        return $this;
366
    }
367
368
    /**
369
     * Set the field as readonly mode.
370
     *
371
     * @return Field
372
     */
373
    public function readOnly()
374
    {
375
        return $this->attribute('disabled', true);
376
    }
377
378
    /**
379
     * Format the field attributes.
380
     *
381
     * @return string
382
     */
383
    protected function formatAttributes()
384
    {
385
        $html = [];
386
387
        foreach ($this->attributes as $name => $value) {
388
            $html[] = "$name=\"$value\"";
389
        }
390
391
        return implode(' ', $html);
392
    }
393
394
    /**
395
     * Get the view variables of this field.
396
     *
397
     * @return array
398
     */
399
    protected function variables()
400
    {
401
        $this->variables['id'] = $this->id;
402
        $this->variables['name'] = $this->formatName($this->column);
403
        $this->variables['value'] = $this->value();
404
        $this->variables['label'] = $this->label;
405
        $this->variables['column'] = $this->column;
406
        $this->variables['attributes'] = $this->formatAttributes();
407
408
        return $this->variables;
409
    }
410
411
    /**
412
     * Get view of this field.
413
     *
414
     * @return string
415
     */
416
    public function getView()
417
    {
418
        if (!empty($this->view)) {
419
            return $this->view;
420
        }
421
422
        $class = explode('\\', get_called_class());
423
424
        return 'admin::form.'.strtolower(end($class));
425
    }
426
427
    /**
428
     * Render this filed.
429
     *
430
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
431
     */
432
    public function render()
433
    {
434
        Admin::script($this->script);
435
436
        return view($this->getView(), $this->variables());
437
    }
438
439
    /**
440
     * @param $method
441
     * @param $arguments
442
     *
443
     * @return $this
444
     */
445
    public function __call($method, $arguments)
446
    {
447
        if ($method === 'default') {
448
            $this->default = $arguments[0];
449
450
            return $this;
451
        }
452
    }
453
}
454