Completed
Push — master ( 545216...bb1888 )
by wen
14:38
created

Select::getOptions()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 27
Code Lines 18

Duplication

Lines 11
Ratio 40.74 %

Importance

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