Completed
Push — master ( 243f23...de48bf )
by Song
07:06
created

Select::load()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 2
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Encore\Admin\Form\Field;
4
5
use Encore\Admin\Facades\Admin;
6
use Encore\Admin\Form\Field;
7
use Illuminate\Contracts\Support\Arrayable;
8
9
class Select extends Field
10
{
11
    public function render()
12
    {
13
        if (empty($this->script)) {
14
            $this->script = "$(\"#{$this->id}\").select2({allowClear: true});";
15
        }
16
17
18
        if (is_callable($this->options)) {
19
            $options = call_user_func($this->options, $this->value);
20
            $this->options($options);
21
        }
22
23
        $this->options = array_filter($this->options);
24
25
        return parent::render()->with(['options' => $this->options]);
0 ignored issues
show
Bug introduced by
The method with 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...
26
    }
27
28
    /**
29
     * Set options.
30
     *
31
     * @param array|callable|string $options
32
     *
33
     * @return $this|mixed
34
     */
35
    public function options($options = [])
36
    {
37
        // remote options
38
        if (is_string($options)) {
39
            return call_user_func_array([$this, 'loadOptionsFromRemote'], func_get_args());
40
        }
41
42
        if ($options instanceof Arrayable) {
43
            $options = $options->toArray();
44
        }
45
46
        if (is_callable($options)) {
47
            $this->options = $options;
0 ignored issues
show
Documentation Bug introduced by
It seems like $options of type callable is incompatible with the declared type array of property $options.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
48
        } else {
49
            $this->options = (array) $options;
50
        }
51
52
        return $this;
53
    }
54
55
    /**
56
     * Load options for other select on change.
57
     *
58
     * @param $field
59
     * @param $source
60
     */
61
    public function load($field, $source)
62
    {
63
        $script = <<<EOT
64
65
$("#{$this->id}").change(function () {
66
    $.get("$source?q="+this.value, function (data) {
67
        $("#$field option").remove();
68
        $("#$field").select2({data: data});
69
    });
70
});
71
EOT;
72
73
        Admin::script($script);
74
    }
75
76
    /**
77
     * Load options from remote.
78
     *
79
     * @param string $url
80
     * @param array  $parameters
81
     * @param array  $options
82
     *
83
     * @return $this
84
     */
85
    protected function loadOptionsFromRemote($url, $parameters = [], $options = [])
86
    {
87
        $ajaxOptions = [
88
            'url' => $url.'?'.http_build_query($parameters),
89
        ];
90
91
        $ajaxOptions = json_encode(array_merge($ajaxOptions, $options));
92
93
        $this->script = <<<EOT
94
95
$.ajax($ajaxOptions).done(function(data) {
96
  $("#{$this->id}").select2({data: data});
97
});
98
99
EOT;
100
101
        return $this;
102
    }
103
104
    /**
105
     * Load options from ajax results.
106
     *
107
     * @param string $url
108
     *
109
     * @return $this
110
     */
111
    public function ajax($url)
112
    {
113
        $this->script = <<<EOT
114
115
$("#{$this->id}").select2({
116
  ajax: {
117
    url: "$url",
118
    dataType: 'json',
119
    delay: 250,
120
    data: function (params) {
121
      return {
122
        q: params.term,
123
        page: params.page
124
      };
125
    },
126
    processResults: function (data, params) {
127
      params.page = params.page || 1;
128
129
      return {
130
        results: data.data,
131
        pagination: {
132
          more: data.next_page_url
133
        }
134
      };
135
    },
136
    cache: true
137
  },
138
  minimumInputLength: 1,
139
  escapeMarkup: function (markup) {
140
      return markup;
141
  }
142
});
143
144
EOT;
145
146
        return $this;
147
    }
148
}
149