Completed
Push — master ( f05a87...6b2b65 )
by wen
14:04
created

Select::getOptionsModel()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
c 0
b 0
f 0
rs 9.4285
cc 3
eloc 10
nc 4
nop 0
1
<?php
2
3
namespace Sco\Admin\Form\Elements;
4
5
use Illuminate\Database\Eloquent\Model;
6
use InvalidArgumentException;
7
use Sco\Admin\Contracts\RepositoryInterface;
8
9
class Select extends NamedElement
10
{
11
    protected $type = 'select';
12
13
    protected $options = [];
14
15
    protected $optionsLabelAttribute;
16
17
    protected $optionsValueAttribute;
18
19
    protected $size = '';
20
21
    public function __construct($name, $title, $options)
22
    {
23
        parent::__construct($name, $title);
24
        $this->setOptions($options);
25
    }
26
27
    public function getSize()
28
    {
29
        return $this->size;
30
    }
31
32
    public function setSize($value)
33
    {
34
        $this->size = $value;
35
36
        return $this;
37
    }
38
39
    public function getValue()
40
    {
41
        return (string)parent::getValue();
42
    }
43
44
    /**
45
     * @return \Illuminate\Support\Collection
46
     */
47
    public function getOptions()
48
    {
49
        if ($this->options instanceof \Closure) {
50
            $options = ($this->options)();
51
        } elseif (is_string($this->options) || $this->options instanceof Model) {
52
            $options = $this->setOptionsFromModel();
53
        } elseif (is_array($this->options)) {
54
            $options = $this->options;
55
        } else {
56
            throw new InvalidArgumentException(
57
                sprintf(
58
                    "The form %s element's options must be return array(key=>value)",
59
                    $this->getType()
60
                )
61
            );
62
        }
63
64
        return collect($options)->mapWithKeys(function ($value, $key) {
65
            return [
66
                $key => [
67
                    'label' => $value,
68
                    'value' => (string)$key,
69
                ],
70
            ];
71
        })->values();
72
    }
73
74
    /**
75
     * @param mixed $options
76
     *
77
     * @return $this
78
     */
79
    public function setOptions($options)
80
    {
81
        $this->options = $options;
0 ignored issues
show
Documentation Bug introduced by
It seems like $options of type * 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...
82
83
        return $this;
84
    }
85
86
    /**
87
     *
88
     * @return array
89
     */
90
    protected function setOptionsFromModel()
91
    {
92
        $model = $this->getOptionsModel();
93
94
        $key = $this->getOptionsValueAttribute() ?: $model->getKeyName();
95
96
        $repository = app(RepositoryInterface::class);
97
        $repository->setModel($model);
98
        $query = $repository->getQuery();
99
100
        $results = $query->get();
101
        if (is_null(($label = $this->getOptionsLabelAttribute()))) {
102
            throw new InvalidArgumentException('Form select element must set label attribute');
103
        }
104
        return $results->pluck($this->getOptionsLabelAttribute(), $key);
105
    }
106
107
    /**
108
     * @return Model
109
     */
110
    public function getOptionsModel()
111
    {
112
        $model = $this->options;
113
114
        if (is_string($model)) {
115
            $model = app($model);
116
        }
117
118
        if (!($model instanceof Model)) {
119
            throw new InvalidArgumentException(
120
                sprintf(
121
                    'Form select element options class must be instanced of "%s".',
122
                    Model::class
123
                )
124
            );
125
        }
126
127
        return $model;
128
    }
129
130
    /**
131
     * 获取 options 标题字段
132
     *
133
     * @return string
134
     */
135
    public function getOptionsLabelAttribute()
136
    {
137
        return $this->optionsLabelAttribute;
138
    }
139
140
    /**
141
     * 设置 options 标题字段
142
     *
143
     * @param string $value
144
     *
145
     * @return $this
146
     */
147
    public function setOptionsLabelAttribute($value)
148
    {
149
        $this->optionsLabelAttribute = $value;
150
151
        return $this;
152
    }
153
154
    /**
155
     * 获取 options value 字段
156
     *
157
     * @return string
158
     */
159
    public function getOptionsValueAttribute()
160
    {
161
        return $this->optionsValueAttribute;
162
    }
163
164
    /**
165
     * 设置 options value 字段
166
     *
167
     * @param string $value
168
     *
169
     * @return $this
170
     */
171
    public function setOptionsValueAttribute($value)
172
    {
173
        $this->optionsValueAttribute = $value;
174
175
        return $this;
176
    }
177
178
    public function toArray()
179
    {
180
        return parent::toArray() + [
181
                'options' => $this->getOptions(),
182
                'size'    => $this->getSize(),
183
            ];
184
    }
185
}
186