Completed
Pull Request — master (#1350)
by
unknown
03:06
created

Field::column()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 16 and the first side effect is on line 988.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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\Contracts\Support\Renderable;
9
use Illuminate\Support\Arr;
10
use Illuminate\Support\Facades\Lang;
11
use Illuminate\Support\Facades\Validator;
12
13
/**
14
 * Class Field.
15
 */
16
class Field implements Renderable
17
{
18
    const FILE_DELETE_FLAG = '_file_del_';
19
20
    /**
21
     * Element id.
22
     *
23
     * @var array|string
24
     */
25
    public $id;
26
27
    /**
28
     * Element value.
29
     *
30
     * @var mixed
31
     */
32
    protected $value;
33
34
    /**
35
     * Field original value.
36
     *
37
     * @var mixed
38
     */
39
    protected $original;
40
41
    /**
42
     * Field default value.
43
     *
44
     * @var mixed
45
     */
46
    protected $default;
47
48
    /**
49
     * Element label.
50
     *
51
     * @var string
52
     */
53
    protected $label = '';
54
55
    /**
56
     * Column name.
57
     *
58
     * @var string|array
59
     */
60
    protected $column = '';
61
62
    /**
63
     * Form element name.
64
     *
65
     * @var string
66
     */
67
    protected $elementName = [];
68
69
    /**
70
     * Form element classes.
71
     *
72
     * @var array
73
     */
74
    protected $elementClass = [];
75
76
    /**
77
     * Variables of elements.
78
     *
79
     * @var array
80
     */
81
    protected $variables = [];
82
83
    /**
84
     * Options for specify elements.
85
     *
86
     * @var array
87
     */
88
    protected $options = [];
89
90
    /**
91
     * Validation rules.
92
     *
93
     * @var string|\Closure
94
     */
95
    protected $rules = '';
96
97
    /**
98
     * @var callable
99
     */
100
    protected $validator;
101
102
    /**
103
     * Validation messages.
104
     *
105
     * @var array
106
     */
107
    public $validationMessages = [];
108
109
    /**
110
     * Css required by this field.
111
     *
112
     * @var array
113
     */
114
    protected static $css = [];
115
116
    /**
117
     * Js required by this field.
118
     *
119
     * @var array
120
     */
121
    protected static $js = [];
122
123
    /**
124
     * Script for field.
125
     *
126
     * @var string
127
     */
128
    protected $script = '';
129
130
    /**
131
     * Element attributes.
132
     *
133
     * @var array
134
     */
135
    protected $attributes = [];
136
137
    /**
138
     * Parent form.
139
     *
140
     * @var Form
141
     */
142
    protected $form = null;
143
144
    /**
145
     * View for field to render.
146
     *
147
     * @var string
148
     */
149
    protected $view = '';
150
151
    /**
152
     * Help block.
153
     *
154
     * @var array
155
     */
156
    protected $help = [];
157
158
    /**
159
     * Key for errors.
160
     *
161
     * @var mixed
162
     */
163
    protected $errorKey;
164
165
    /**
166
     * Placeholder for this field.
167
     *
168
     * @var string|array
169
     */
170
    protected $placeholder;
171
172
    /**
173
     * Width for label and field.
174
     *
175
     * @var array
176
     */
177
    protected $width = [
178
        'label' => 2,
179
        'field' => 8,
180
    ];
181
182
    /**
183
     * If the form horizontal layout.
184
     *
185
     * @var bool
186
     */
187
    protected $horizontal = true;
188
189
    /**
190
     * default local use for translate field label
191
     * or used in jquery plugin as local or language.
192
     *
193
     * @var bool
194
     */
195
    protected $local = "en";
196
197
    /**
198
     * ltr or rtl
199
     *
200
     * @var string
201
     */
202
    protected $direction = "ltr";
203
204
    /**
205
     * Field constructor.
206
     *
207
     * @param       $column
208
     * @param array $arguments
209
     */
210
    public function __construct($column, $arguments = [])
211
    {
212
        $this->column = $column;
213
        $this->label = $this->formatLabel($arguments);
214
        $this->id = $this->formatId($column);
215
        $this->local = config('app.locale');
216
    }
217
218
    /**
219
     * Get assets required by this field.
220
     *
221
     * @return array
222
     */
223
    public static function getAssets()
224
    {
225
        return [
226
            'css' => static::$css,
227
            'js'  => static::$js,
228
        ];
229
    }
230
231
    /**
232
     * Format the field element id.
233
     *
234
     * @param string|array $column
235
     *
236
     * @return string|array
237
     */
238
    protected function formatId($column)
239
    {
240
        return str_replace('.', '_', $column);
241
    }
242
243
    /**
244
     * Format the label value.
245
     *
246
     * @param array $arguments
247
     *
248
     * @return string
249
     */
250
    protected function formatLabel($arguments = [])
251
    {
252
        $column = is_array($this->column) ? current($this->column) : $this->column;
253
254
        $trans_key = 'validation.attributes.' . strtolower($column);
255
        if (isset($arguments[0])) {
256
            $label = $arguments[0];
257
        } else if (Lang::has($trans_key)) {
258
            $label = Lang::get($trans_key);
259
        } else {
260
            $label = ucfirst($column);
261
        }
262
263
        return str_replace([
264
            '.',
265
            '_'
266
        ], ' ', $label);
267
    }
268
269
    /**
270
     * Format the name of the field.
271
     *
272
     * @param string $column
273
     *
274
     * @return array|mixed|string
275
     */
276
    protected function formatName($column)
277
    {
278
        if (is_string($column)) {
279
            $name = explode('.', $column);
280
281
            if (count($name) == 1) {
282
                return $name[0];
283
            }
284
285
            $html = array_shift($name);
286
            foreach ($name as $piece) {
287
                $html .= "[$piece]";
288
            }
289
290
            return $html;
291
        }
292
293
        if (is_array($this->column)) {
294
            $names = [];
295
            foreach ($this->column as $key => $name) {
296
                $names[$key] = $this->formatName($name);
297
            }
298
299
            return $names;
300
        }
301
302
        return '';
303
    }
304
305
    /**
306
     * Set form element name.
307
     *
308
     * @param string $name
309
     *
310
     * @return $this
311
     *
312
     * @author Edwin Hui
313
     */
314
    public function setElementName($name)
315
    {
316
        $this->elementName = $name;
317
318
        return $this;
319
    }
320
321
    /**
322
     * Fill data to the field.
323
     *
324
     * @param array $data
325
     *
326
     * @return void
327
     */
328 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...
329
    {
330
        // Field value is already setted.
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
331
//        if (!is_null($this->value)) {
332
//            return;
333
//        }
334
335
        if (is_array($this->column)) {
336
            foreach ($this->column as $key => $column) {
337
                $this->value[$key] = array_get($data, $column);
338
            }
339
340
            return;
341
        }
342
343
        $this->value = array_get($data, $this->column);
344
    }
345
346
    /**
347
     * Set original value to the field.
348
     *
349
     * @param array $data
350
     *
351
     * @return void
352
     */
353 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...
354
    {
355
        if (is_array($this->column)) {
356
            foreach ($this->column as $key => $column) {
357
                $this->original[$key] = array_get($data, $column);
358
            }
359
360
            return;
361
        }
362
363
        $this->original = array_get($data, $this->column);
364
    }
365
366
    /**
367
     * @param Form $form
368
     *
369
     * @return $this
370
     */
371
    public function setForm(Form $form = null)
372
    {
373
        $this->form = $form;
374
375
        return $this;
376
    }
377
378
    /**
379
     * Set width for field and label.
380
     *
381
     * @param int $field
382
     * @param int $label
383
     *
384
     * @return $this
385
     */
386
    public function setWidth($field = 8, $label = 2)
387
    {
388
        $this->width = [
389
            'label' => $label,
390
            'field' => $field,
391
        ];
392
393
        return $this;
394
    }
395
396
    /**
397
     * Set the field options.
398
     *
399
     * @param array $options
400
     *
401
     * @return $this
402
     */
403 View Code Duplication
    public function options($options = [])
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...
404
    {
405
        if ($options instanceof Arrayable) {
406
            $options = $options->toArray();
407
        }
408
409
        $this->options = array_merge($this->options, $options);
410
411
        return $this;
412
    }
413
414
    /**
415
     * Get or set rules.
416
     *
417
     * @param null  $rules
418
     * @param array $messages
419
     *
420
     * @return $this
421
     */
422
    public function rules($rules = null, $messages = [])
423
    {
424
        if ($rules instanceof \Closure) {
425
            $this->rules = $rules;
426
        }
427
428
        if (is_string($rules)) {
429
            $rules = array_filter(explode('|', "{$this->rules}|$rules"));
430
431
            $this->rules = implode('|', $rules);
432
        }
433
434
        $this->validationMessages = $messages;
435
436
        return $this;
437
    }
438
439
    /**
440
     * Get field validation rules.
441
     *
442
     * @return string
443
     */
444
    public function getRules()
445
    {
446
        if ($this->rules instanceof \Closure) {
447
            return $this->rules->call($this, $this->form);
448
        }
449
450
        return $this->rules;
451
    }
452
453
    /**
454
     * Remove a specific rule.
455
     *
456
     * @param string $rule
457
     *
458
     * @return void
459
     */
460
    protected function removeRule($rule)
461
    {
462
        $this->rules = str_replace($rule, '', $this->rules);
463
    }
464
465
    /**
466
     * Set field validator.
467
     *
468
     * @param callable $validator
469
     *
470
     * @return $this
471
     */
472
    public function validator(callable $validator)
473
    {
474
        $this->validator = $validator;
475
476
        return $this;
477
    }
478
479
    /**
480
     * Get key for error message.
481
     *
482
     * @return string
483
     */
484
    public function getErrorKey()
485
    {
486
        return $this->errorKey ?: $this->column;
487
    }
488
489
    /**
490
     * Set key for error message.
491
     *
492
     * @param string $key
493
     *
494
     * @return $this
495
     */
496
    public function setErrorKey($key)
497
    {
498
        $this->errorKey = $key;
499
500
        return $this;
501
    }
502
503
    /**
504
     * Set or get value of the field.
505
     *
506
     * @param null $value
507
     *
508
     * @return mixed
509
     */
510 View Code Duplication
    public function value($value = null)
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...
511
    {
512
        if (is_null($value)) {
513
            return is_null($this->value) ? $this->getDefault() : $this->value;
514
        }
515
516
        $this->value = $value;
517
518
        return $this;
519
    }
520
521
    /**
522
     * Set default value for field.
523
     *
524
     * @param $default
525
     *
526
     * @return $this
527
     */
528
    public function default($default)
0 ignored issues
show
Coding Style introduced by
Possible parse error: non-abstract method defined as abstract
Loading history...
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
529
    {
530
        $this->default = $default;
531
532
        return $this;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $this.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
533
    }
534
535
    /**
536
     * Get default value.
537
     *
538
     * @return mixed
539
     */
540
    public function getDefault()
541
    {
542
        if ($this->default instanceof \Closure) {
543
            return call_user_func($this->default, $this->form);
544
        }
545
546
        return $this->default;
547
    }
548
549
    /**
550
     * Set help block for current field.
551
     *
552
     * @param string $text
553
     * @param string $icon
554
     *
555
     * @return $this
556
     */
557
    public function help($text = '', $icon = 'fa-info-circle')
558
    {
559
        $this->help = compact('text', 'icon');
560
561
        return $this;
562
    }
563
564
    /**
565
     * Get column of the field.
566
     *
567
     * @return string|array
568
     */
569
    public function column()
570
    {
571
        return $this->column;
572
    }
573
574
    /**
575
     * Get label of the field.
576
     *
577
     * @return string
578
     */
579
    public function label()
580
    {
581
        return $this->label;
582
    }
583
584
    /**
585
     * Get original value of the field.
586
     *
587
     * @return mixed
588
     */
589
    public function original()
590
    {
591
        return $this->original;
592
    }
593
594
    /**
595
     * Get validator for this field.
596
     *
597
     * @param array $input
598
     *
599
     * @return bool|Validator
600
     */
601
    public function getValidator(array $input)
602
    {
603
        if ($this->validator) {
604
            return $this->validator->call($this, $input);
605
        }
606
607
        $rules = $attributes = [];
608
609
        if (!$fieldRules = $this->getRules()) {
610
            return false;
611
        }
612
613
        if (is_string($this->column)) {
614
            if (!array_has($input, $this->column)) {
615
                return false;
616
            }
617
618
            $input = $this->sanitizeInput($input, $this->column);
619
620
            $rules[$this->column] = $fieldRules;
621
            $attributes[$this->column] = $this->label;
622
        }
623
624
        if (is_array($this->column)) {
625
            foreach ($this->column as $key => $column) {
626
                if (!array_key_exists($column, $input)) {
627
                    continue;
628
                }
629
                $input[$column . $key] = array_get($input, $column);
630
                $rules[$column . $key] = $fieldRules;
631
                $attributes[$column . $key] = $this->label . "[$column]";
632
            }
633
        }
634
635
        return Validator::make($input, $rules, $this->validationMessages, $attributes);
636
    }
637
638
    /**
639
     * Sanitize input data.
640
     *
641
     * @param array  $input
642
     * @param string $column
643
     *
644
     * @return array
645
     */
646
    protected function sanitizeInput($input, $column)
647
    {
648
        if ($this instanceof Field\MultipleSelect) {
649
            $value = array_get($input, $column);
650
            array_set($input, $column, array_filter($value));
651
        }
652
653
        return $input;
654
    }
655
656
    /**
657
     * Add html attributes to elements.
658
     *
659
     * @param array|string $attribute
660
     * @param mixed        $value
661
     *
662
     * @return $this
663
     */
664
    public function attribute($attribute, $value = null)
665
    {
666
        if (is_array($attribute)) {
667
            $this->attributes = array_merge($this->attributes, $attribute);
668
        } else {
669
            $this->attributes[$attribute] = (string)$value;
670
        }
671
672
        return $this;
673
    }
674
675
    /**
676
     * Set the field as readonly mode.
677
     *
678
     * @return Field
679
     */
680
    public function readOnly()
681
    {
682
        return $this->attribute('disabled', true);
683
    }
684
685
    /**
686
     * Set field placeholder.
687
     *
688
     * @param string $placeholder
689
     *
690
     * @return Field
691
     */
692
    public function placeholder($placeholder = '')
693
    {
694
        $this->placeholder = $placeholder;
695
696
        return $this;
697
    }
698
699
    /**
700
     * Get placeholder.
701
     *
702
     * @return string
703
     */
704
    public function getPlaceholder()
705
    {
706
        return $this->placeholder ?: trans('admin.input') . ' ' . $this->label;
707
    }
708
709
    /**
710
     * Prepare for a field value before update or insert.
711
     *
712
     * @param $value
713
     *
714
     * @return mixed
715
     */
716
    public function prepare($value)
717
    {
718
        return $value;
719
    }
720
721
    /**
722
     * Format the field attributes.
723
     *
724
     * @return string
725
     */
726
    protected function formatAttributes()
727
    {
728
        $html = [];
729
730
        foreach ($this->attributes as $name => $value) {
731
            $html[] = $name . '="' . e($value) . '"';
732
        }
733
734
        return implode(' ', $html);
735
    }
736
737
    /**
738
     * @return $this
739
     */
740
    public function disableHorizontal()
741
    {
742
        $this->horizontal = false;
743
744
        return $this;
745
    }
746
747
    /**
748
     * @return array
749
     */
750
    public function getViewElementClasses()
751
    {
752
        if ($this->horizontal) {
753
            return [
754
                'label'      => "col-sm-{$this->width['label']}",
755
                'field'      => "col-sm-{$this->width['field']}",
756
                'form-group' => 'form-group ',
757
            ];
758
        }
759
760
        return ['label' => '', 'field' => '', 'form-group' => ''];
761
    }
762
763
    /**
764
     * Set form element class.
765
     *
766
     * @param string|array $class
767
     *
768
     * @return $this
769
     */
770
    public function setElementClass($class)
771
    {
772
        $this->elementClass = (array)$class;
773
774
        return $this;
775
    }
776
777
    /**
778
     * Get element class.
779
     *
780
     * @return array
781
     */
782
    protected function getElementClass()
783
    {
784
        if (!$this->elementClass) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->elementClass of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
785
            $name = $this->elementName ?: $this->formatName($this->column);
0 ignored issues
show
Bug introduced by
It seems like $this->column can also be of type array; however, Encore\Admin\Form\Field::formatName() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
786
787
            $this->elementClass = (array)str_replace([
788
                '[',
789
                ']'
790
            ], '_', $name);
791
        }
792
793
        return $this->elementClass;
794
    }
795
796
    /**
797
     * Get element class string.
798
     *
799
     * @return mixed
800
     */
801 View Code Duplication
    protected function getElementClassString()
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...
802
    {
803
        $elementClass = $this->getElementClass();
804
805
        if (Arr::isAssoc($elementClass)) {
806
            $classes = [];
807
808
            foreach ($elementClass as $index => $class) {
809
                $classes[$index] = is_array($class) ? implode(' ', $class) : $class;
810
            }
811
812
            return $classes;
813
        }
814
815
        return implode(' ', $elementClass);
816
    }
817
818
    /**
819
     * Get element class selector.
820
     *
821
     * @return string
822
     */
823 View Code Duplication
    protected function getElementClassSelector()
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...
824
    {
825
        $elementClass = $this->getElementClass();
826
827
        if (Arr::isAssoc($elementClass)) {
828
            $classes = [];
829
830
            foreach ($elementClass as $index => $class) {
831
                $classes[$index] = '.' . (is_array($class) ? implode('.', $class) : $class);
832
            }
833
834
            return $classes;
835
        }
836
837
        return '.' . implode('.', $elementClass);
838
    }
839
840
    /**
841
     * Add the element class.
842
     *
843
     * @param $class
844
     *
845
     * @return $this
846
     */
847
    public function addElementClass($class)
848
    {
849
        if (is_array($class) || is_string($class)) {
850
            $this->elementClass = array_merge($this->elementClass, (array)$class);
851
852
            $this->elementClass = array_unique($this->elementClass);
853
        }
854
855
        return $this;
856
    }
857
858
    /**
859
     * Remove element class.
860
     *
861
     * @param $class
862
     *
863
     * @return $this
864
     */
865
    public function removeElementClass($class)
866
    {
867
        $delClass = [];
868
869
        if (is_string($class) || is_array($class)) {
870
            $delClass = (array)$class;
871
        }
872
873
        foreach ($delClass as $del) {
874
            if (($key = array_search($del, $this->elementClass))) {
875
                unset($this->elementClass[$key]);
876
            }
877
        }
878
879
        return $this;
880
    }
881
882
    /**
883
     * Get the view variables of this field.
884
     *
885
     * @return array
886
     */
887
    protected function variables()
888
    {
889
        return array_merge($this->variables, [
890
            'id'          => $this->id,
891
            'name'        => $this->elementName ?: $this->formatName($this->column),
0 ignored issues
show
Bug introduced by
It seems like $this->column can also be of type array; however, Encore\Admin\Form\Field::formatName() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
892
            'help'        => $this->help,
893
            'class'       => $this->getElementClassString(),
894
            'value'       => $this->value(),
895
            'label'       => $this->label,
896
            'viewClass'   => $this->getViewElementClasses(),
897
            'column'      => $this->column,
898
            'errorKey'    => $this->getErrorKey(),
899
            'attributes'  => $this->formatAttributes(),
900
            'placeholder' => $this->getPlaceholder(),
901
902
        ]);
903
    }
904
905
    /**
906
     * popover data-popover
907
     * @param null $title
908
     * @param      $content
909
     * @return Field
910
     */
911
    public function popover($title = null, $content)
912
    {
913
      return  $this->attribute([
914
            'data-popover-title' => $title,
915
            'data-popover'       => $content,
916
        ]);
917
    }
918
919
    /**
920
     * Get view of this field.
921
     *
922
     * @return string
923
     */
924
    public function getView()
925
    {
926
        if (!empty($this->view)) {
927
            return $this->view;
928
        }
929
930
        $class = explode('\\', get_called_class());
931
932
        return 'admin::form.' . strtolower(end($class));
933
    }
934
935
    /**
936
     * Get script of current field.
937
     *
938
     * @return string
939
     */
940
    public function getScript()
941
    {
942
        return $this->script;
943
    }
944
945
    /**
946
     * Set direction setting.
947
     * @param string $dir ltr or rtl
948
     * @return $this
949
     */
950
    public function direction($dir = 'ltr')
951
    {
952
        $this->direction = $dir;
953
954
        return $this;
955
    }
956
957
    /**
958
     * set local
959
     * @param string $local
960
     * @return $this
961
     */
962
    public function setLocal($local = 'en')
963
    {
964
        $this->local = $local;
0 ignored issues
show
Documentation Bug introduced by
The property $local was declared of type boolean, but $local is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
965
966
        return $this;
967
    }
968
969
    /**
970
     * Render this filed.
971
     *
972
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
973
     */
974
    public function render()
975
    {
976
        Admin::script($this->script);
977
978
        return view($this->getView(), $this->variables());
0 ignored issues
show
Bug Compatibility introduced by
The expression view($this->getView(), $this->variables()); of type Illuminate\View\View|Ill...\Contracts\View\Factory adds the type Illuminate\Contracts\View\Factory to the return on line 978 which is incompatible with the return type declared by the interface Illuminate\Contracts\Support\Renderable::render of type string.
Loading history...
979
    }
980
981
    /**
982
     * @return string
983
     */
984
    public function __toString()
985
    {
986
        return $this->render()->render();
0 ignored issues
show
Bug introduced by
The method render does only exist in Illuminate\View\View, but not in Illuminate\Contracts\View\Factory.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
987
    }
988
}
989