Completed
Pull Request — master (#1350)
by
unknown
02:37
created

Field::popover()   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 2
dl 0
loc 7
rs 9.4285
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 960.

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
     * Field constructor.
199
     *
200
     * @param       $column
201
     * @param array $arguments
202
     */
203
    public function __construct($column, $arguments = [])
204
    {
205
        $this->column = $column;
206
        $this->label = $this->formatLabel($arguments);
207
        $this->id = $this->formatId($column);
208
        $this->local = config('app.locale');
209
    }
210
211
    /**
212
     * Get assets required by this field.
213
     *
214
     * @return array
215
     */
216
    public static function getAssets()
217
    {
218
        return [
219
            'css' => static::$css,
220
            'js'  => static::$js,
221
        ];
222
    }
223
224
    /**
225
     * Format the field element id.
226
     *
227
     * @param string|array $column
228
     *
229
     * @return string|array
230
     */
231
    protected function formatId($column)
232
    {
233
        return str_replace('.', '_', $column);
234
    }
235
236
    /**
237
     * Format the label value.
238
     *
239
     * @param array $arguments
240
     *
241
     * @return string
242
     */
243
    protected function formatLabel($arguments = [])
244
    {
245
        $column = is_array($this->column) ? current($this->column) : $this->column;
246
247
        $trans_key = 'validation.attributes.' . strtolower($column);
248
        if (isset($arguments[0])) {
249
            $label = $arguments[0];
250
        } else if (Lang::has($trans_key)) {
251
            $label = Lang::get($trans_key);
252
        } else {
253
            $label = ucfirst($column);
254
        }
255
256
        return str_replace([
257
            '.',
258
            '_'
259
        ], ' ', $label);
260
    }
261
262
    /**
263
     * Format the name of the field.
264
     *
265
     * @param string $column
266
     *
267
     * @return array|mixed|string
268
     */
269
    protected function formatName($column)
270
    {
271
        if (is_string($column)) {
272
            $name = explode('.', $column);
273
274
            if (count($name) == 1) {
275
                return $name[0];
276
            }
277
278
            $html = array_shift($name);
279
            foreach ($name as $piece) {
280
                $html .= "[$piece]";
281
            }
282
283
            return $html;
284
        }
285
286
        if (is_array($this->column)) {
287
            $names = [];
288
            foreach ($this->column as $key => $name) {
289
                $names[$key] = $this->formatName($name);
290
            }
291
292
            return $names;
293
        }
294
295
        return '';
296
    }
297
298
    /**
299
     * Set form element name.
300
     *
301
     * @param string $name
302
     *
303
     * @return $this
304
     *
305
     * @author Edwin Hui
306
     */
307
    public function setElementName($name)
308
    {
309
        $this->elementName = $name;
310
311
        return $this;
312
    }
313
314
    /**
315
     * Fill data to the field.
316
     *
317
     * @param array $data
318
     *
319
     * @return void
320
     */
321 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...
322
    {
323
        // 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...
324
//        if (!is_null($this->value)) {
325
//            return;
326
//        }
327
328
        if (is_array($this->column)) {
329
            foreach ($this->column as $key => $column) {
330
                $this->value[$key] = array_get($data, $column);
331
            }
332
333
            return;
334
        }
335
336
        $this->value = array_get($data, $this->column);
337
    }
338
339
    /**
340
     * Set original value to the field.
341
     *
342
     * @param array $data
343
     *
344
     * @return void
345
     */
346 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...
347
    {
348
        if (is_array($this->column)) {
349
            foreach ($this->column as $key => $column) {
350
                $this->original[$key] = array_get($data, $column);
351
            }
352
353
            return;
354
        }
355
356
        $this->original = array_get($data, $this->column);
357
    }
358
359
    /**
360
     * @param Form $form
361
     *
362
     * @return $this
363
     */
364
    public function setForm(Form $form = null)
365
    {
366
        $this->form = $form;
367
368
        return $this;
369
    }
370
371
    /**
372
     * Set width for field and label.
373
     *
374
     * @param int $field
375
     * @param int $label
376
     *
377
     * @return $this
378
     */
379
    public function setWidth($field = 8, $label = 2)
380
    {
381
        $this->width = [
382
            'label' => $label,
383
            'field' => $field,
384
        ];
385
386
        return $this;
387
    }
388
389
    /**
390
     * Set the field options.
391
     *
392
     * @param array $options
393
     *
394
     * @return $this
395
     */
396 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...
397
    {
398
        if ($options instanceof Arrayable) {
399
            $options = $options->toArray();
400
        }
401
402
        $this->options = array_merge($this->options, $options);
403
404
        return $this;
405
    }
406
407
    /**
408
     * Get or set rules.
409
     *
410
     * @param null  $rules
411
     * @param array $messages
412
     *
413
     * @return $this
414
     */
415
    public function rules($rules = null, $messages = [])
416
    {
417
        if ($rules instanceof \Closure) {
418
            $this->rules = $rules;
419
        }
420
421
        if (is_string($rules)) {
422
            $rules = array_filter(explode('|', "{$this->rules}|$rules"));
423
424
            $this->rules = implode('|', $rules);
425
        }
426
427
        $this->validationMessages = $messages;
428
429
        return $this;
430
    }
431
432
    /**
433
     * Get field validation rules.
434
     *
435
     * @return string
436
     */
437
    public function getRules()
438
    {
439
        if ($this->rules instanceof \Closure) {
440
            return $this->rules->call($this, $this->form);
441
        }
442
443
        return $this->rules;
444
    }
445
446
    /**
447
     * Remove a specific rule.
448
     *
449
     * @param string $rule
450
     *
451
     * @return void
452
     */
453
    protected function removeRule($rule)
454
    {
455
        $this->rules = str_replace($rule, '', $this->rules);
456
    }
457
458
    /**
459
     * Set field validator.
460
     *
461
     * @param callable $validator
462
     *
463
     * @return $this
464
     */
465
    public function validator(callable $validator)
466
    {
467
        $this->validator = $validator;
468
469
        return $this;
470
    }
471
472
    /**
473
     * Get key for error message.
474
     *
475
     * @return string
476
     */
477
    public function getErrorKey()
478
    {
479
        return $this->errorKey ?: $this->column;
480
    }
481
482
    /**
483
     * Set key for error message.
484
     *
485
     * @param string $key
486
     *
487
     * @return $this
488
     */
489
    public function setErrorKey($key)
490
    {
491
        $this->errorKey = $key;
492
493
        return $this;
494
    }
495
496
    /**
497
     * Set or get value of the field.
498
     *
499
     * @param null $value
500
     *
501
     * @return mixed
502
     */
503
    public function value($value = null)
504
    {
505
        if (is_null($value)) {
506
            return is_null($this->value) ? $this->getDefault() : $this->value;
507
        }
508
509
        $this->value = $value;
510
511
        return $this;
512
    }
513
514
    /**
515
     * Set default value for field.
516
     *
517
     * @param $default
518
     *
519
     * @return $this
520
     */
521
    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...
522
    {
523
        $this->default = $default;
524
525
        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...
526
    }
527
528
    /**
529
     * Get default value.
530
     *
531
     * @return mixed
532
     */
533
    public function getDefault()
534
    {
535
        if ($this->default instanceof \Closure) {
536
            return call_user_func($this->default, $this->form);
537
        }
538
539
        return $this->default;
540
    }
541
542
    /**
543
     * Set help block for current field.
544
     *
545
     * @param string $text
546
     * @param string $icon
547
     *
548
     * @return $this
549
     */
550
    public function help($text = '', $icon = 'fa-info-circle')
551
    {
552
        $this->help = compact('text', 'icon');
553
554
        return $this;
555
    }
556
557
    /**
558
     * Get column of the field.
559
     *
560
     * @return string|array
561
     */
562
    public function column()
563
    {
564
        return $this->column;
565
    }
566
567
    /**
568
     * Get label of the field.
569
     *
570
     * @return string
571
     */
572
    public function label()
573
    {
574
        return $this->label;
575
    }
576
577
    /**
578
     * Get original value of the field.
579
     *
580
     * @return mixed
581
     */
582
    public function original()
583
    {
584
        return $this->original;
585
    }
586
587
    /**
588
     * Get validator for this field.
589
     *
590
     * @param array $input
591
     *
592
     * @return bool|Validator
593
     */
594
    public function getValidator(array $input)
595
    {
596
        if ($this->validator) {
597
            return $this->validator->call($this, $input);
598
        }
599
600
        $rules = $attributes = [];
601
602
        if (!$fieldRules = $this->getRules()) {
603
            return false;
604
        }
605
606
        if (is_string($this->column)) {
607
            if (!array_has($input, $this->column)) {
608
                return false;
609
            }
610
611
            $input = $this->sanitizeInput($input, $this->column);
612
613
            $rules[$this->column] = $fieldRules;
614
            $attributes[$this->column] = $this->label;
615
        }
616
617
        if (is_array($this->column)) {
618
            foreach ($this->column as $key => $column) {
619
                if (!array_key_exists($column, $input)) {
620
                    continue;
621
                }
622
                $input[$column . $key] = array_get($input, $column);
623
                $rules[$column . $key] = $fieldRules;
624
                $attributes[$column . $key] = $this->label . "[$column]";
625
            }
626
        }
627
628
        return Validator::make($input, $rules, $this->validationMessages, $attributes);
629
    }
630
631
    /**
632
     * Sanitize input data.
633
     *
634
     * @param array  $input
635
     * @param string $column
636
     *
637
     * @return array
638
     */
639
    protected function sanitizeInput($input, $column)
640
    {
641
        if ($this instanceof Field\MultipleSelect) {
642
            $value = array_get($input, $column);
643
            array_set($input, $column, array_filter($value));
644
        }
645
646
        return $input;
647
    }
648
649
    /**
650
     * Add html attributes to elements.
651
     *
652
     * @param array|string $attribute
653
     * @param mixed        $value
654
     *
655
     * @return $this
656
     */
657
    public function attribute($attribute, $value = null)
658
    {
659
        if (is_array($attribute)) {
660
            $this->attributes = array_merge($this->attributes, $attribute);
661
        } else {
662
            $this->attributes[$attribute] = (string)$value;
663
        }
664
665
        return $this;
666
    }
667
668
    /**
669
     * Set the field as readonly mode.
670
     *
671
     * @return Field
672
     */
673
    public function readOnly()
674
    {
675
        return $this->attribute('disabled', true);
676
    }
677
678
    /**
679
     * Set field placeholder.
680
     *
681
     * @param string $placeholder
682
     *
683
     * @return Field
684
     */
685
    public function placeholder($placeholder = '')
686
    {
687
        $this->placeholder = $placeholder;
688
689
        return $this;
690
    }
691
692
    /**
693
     * Get placeholder.
694
     *
695
     * @return string
696
     */
697
    public function getPlaceholder()
698
    {
699
        return $this->placeholder ?: trans('admin.input') . ' ' . $this->label;
700
    }
701
702
    /**
703
     * Prepare for a field value before update or insert.
704
     *
705
     * @param $value
706
     *
707
     * @return mixed
708
     */
709
    public function prepare($value)
710
    {
711
        return $value;
712
    }
713
714
    /**
715
     * Format the field attributes.
716
     *
717
     * @return string
718
     */
719
    protected function formatAttributes()
720
    {
721
        $html = [];
722
723
        foreach ($this->attributes as $name => $value) {
724
            $html[] = $name . '="' . e($value) . '"';
725
        }
726
727
        return implode(' ', $html);
728
    }
729
730
    /**
731
     * @return $this
732
     */
733
    public function disableHorizontal()
734
    {
735
        $this->horizontal = false;
736
737
        return $this;
738
    }
739
740
    /**
741
     * @return array
742
     */
743
    public function getViewElementClasses()
744
    {
745
        if ($this->horizontal) {
746
            return [
747
                'label'      => "col-sm-{$this->width['label']}",
748
                'field'      => "col-sm-{$this->width['field']}",
749
                'form-group' => 'form-group ',
750
            ];
751
        }
752
753
        return [
754
            'label'      => '',
755
            'field'      => '',
756
            'form-group' => ''
757
        ];
758
    }
759
760
    /**
761
     * Set form element class.
762
     *
763
     * @param string $class
764
     *
765
     * @return $this
766
     */
767
    public function setElementClass($class)
768
    {
769
        $this->elementClass = (array)$class;
770
771
        return $this;
772
    }
773
774
    /**
775
     * Get element class.
776
     *
777
     * @return array
778
     */
779
    protected function getElementClass()
780
    {
781
        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...
782
            $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...
783
784
            $this->elementClass = (array)str_replace([
785
                '[',
786
                ']'
787
            ], '_', $name);
788
        }
789
790
        return $this->elementClass;
791
    }
792
793
    /**
794
     * Get element class string.
795
     *
796
     * @return mixed
797
     */
798 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...
799
    {
800
        $elementClass = $this->getElementClass();
801
802
        if (Arr::isAssoc($elementClass)) {
803
            $classes = [];
804
805
            foreach ($elementClass as $index => $class) {
806
                $classes[$index] = is_array($class) ? implode(' ', $class) : $class;
807
            }
808
809
            return $classes;
810
        }
811
812
        return implode(' ', $elementClass);
813
    }
814
815
    /**
816
     * Get element class selector.
817
     *
818
     * @return string
819
     */
820 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...
821
    {
822
        $elementClass = $this->getElementClass();
823
824
        if (Arr::isAssoc($elementClass)) {
825
            $classes = [];
826
827
            foreach ($elementClass as $index => $class) {
828
                $classes[$index] = '.' . (is_array($class) ? implode('.', $class) : $class);
829
            }
830
831
            return $classes;
832
        }
833
834
        return '.' . implode('.', $elementClass);
835
    }
836
837
    /**
838
     * Add the element class.
839
     *
840
     * @param $class
841
     *
842
     * @return $this
843
     */
844
    public function addElementClass($class)
845
    {
846
        if (is_array($class) || is_string($class)) {
847
            $this->elementClass = array_merge($this->elementClass, (array)$class);
848
849
            $this->elementClass = array_unique($this->elementClass);
850
        }
851
852
        return $this;
853
    }
854
855
    /**
856
     * Remove element class.
857
     *
858
     * @param $class
859
     *
860
     * @return $this
861
     */
862
    public function removeElementClass($class)
863
    {
864
        $delClass = [];
865
866
        if (is_string($class) || is_array($class)) {
867
            $delClass = (array)$class;
868
        }
869
870
        foreach ($delClass as $del) {
871
            if (($key = array_search($del, $this->elementClass))) {
872
                unset($this->elementClass[$key]);
873
            }
874
        }
875
876
        return $this;
877
    }
878
879
    /**
880
     * Get the view variables of this field.
881
     *
882
     * @return array
883
     */
884
    protected function variables()
885
    {
886
        return array_merge($this->variables, [
887
            'id'          => $this->id,
888
            '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...
889
            'help'        => $this->help,
890
            'class'       => $this->getElementClassString(),
891
            'value'       => $this->value(),
892
            'label'       => $this->label,
893
            'viewClass'   => $this->getViewElementClasses(),
894
            'column'      => $this->column,
895
            'errorKey'    => $this->getErrorKey(),
896
            'attributes'  => $this->formatAttributes(),
897
            'placeholder' => $this->getPlaceholder(),
898
        ]);
899
    }
900
901
    /**
902
     * popover data-popover
903
     * @param null $title
904
     * @param      $content
905
     * @return Field
906
     */
907
    public function popover($title = null, $content)
908
    {
909
      return  $this->attribute([
910
            'data-popover-title' => $title,
911
            'data-popover'       => $content,
912
        ]);
913
    }
914
915
    /**
916
     * Get view of this field.
917
     *
918
     * @return string
919
     */
920
    public function getView()
921
    {
922
        if (!empty($this->view)) {
923
            return $this->view;
924
        }
925
926
        $class = explode('\\', get_called_class());
927
928
        return 'admin::form.' . strtolower(end($class));
929
    }
930
931
    /**
932
     * Get script of current field.
933
     *
934
     * @return string
935
     */
936
    public function getScript()
937
    {
938
        return $this->script;
939
    }
940
941
    /**
942
     * Render this filed.
943
     *
944
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
945
     */
946
    public function render()
947
    {
948
        Admin::script($this->script);
949
950
        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 950 which is incompatible with the return type declared by the interface Illuminate\Contracts\Support\Renderable::render of type string.
Loading history...
951
    }
952
953
    /**
954
     * @return string
955
     */
956
    public function __toString()
957
    {
958
        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...
959
    }
960
}
961