Completed
Push — master ( 797ef7...545216 )
by wen
13:55
created

Select::save()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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