Issues (368)

src/Admin/Form/Controls/SelectControl.php (3 issues)

1
<?php
2
3
namespace Arbory\Base\Admin\Form\Controls;
4
5
use Arbory\Base\Html\Html;
6
use Arbory\Base\Html\Elements\Content;
7
use Arbory\Base\Html\Elements\Element;
8
use Illuminate\Database\Eloquent\Model;
9
use Arbory\Base\Html\Elements\Inputs\Input;
10
use Illuminate\Support\Arr;
11
12
class SelectControl extends AbstractControl
13
{
14
    /**
15
     * @var bool
16
     */
17
    protected $multiple = false;
18
19
    /**
20
     * @var array
21
     */
22
    protected $options = [];
23
24
    /**
25
     * @var array
26
     */
27
    protected $selected = [];
28
29
    /**
30
     * @return Element
31
     */
32
    public function element(): Element
33
    {
34
        $select = Html::select($this->buildOptions());
35
36
        $select = $this->applyAttributesAndClasses($select);
37
38
        if ($this->isReadOnly()) {
39
            $select->addAttributes(['disabled' => '']);
40
        }
41
42
        return $select;
43
    }
44
45
    public function render(Element $control)
46
    {
47
        $content = new Content();
48
49
        if ($this->isMultiple()) {
50
            $control->setName(
0 ignored issues
show
The method setName() does not exist on Arbory\Base\Html\Elements\Element. It seems like you code against a sub-type of Arbory\Base\Html\Elements\Element such as Arbory\Base\Html\Element...puts\AbstractInputField. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
            $control->/** @scrutinizer ignore-call */ 
51
                      setName(
Loading history...
51
                $this->getName().'[]'
52
            );
53
54
            $control->addAttributes(['multiple' => true]);
55
        }
56
57
        $content->push($control);
58
59
        $values = Arr::wrap($this->getValue());
60
61
        if ($this->isReadOnly()) {
62
            foreach ($values as $value) {
63
                $name = $this->getName().($this->isMultiple() ? '[]' : '');
64
65
                $input = (new Input())
66
                    ->setType('hidden')
67
                    ->setValue($value)
68
                    ->setName($name);
69
70
                $input->attributes()->forget('id');
71
72
                $content->push(
73
                    $input
74
                );
75
            }
76
        }
77
78
        return $content;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $content returns the type Arbory\Base\Html\Elements\Content which is incompatible with the return type mandated by Arbory\Base\Admin\Form\C...stractControl::render() of Arbory\Base\Html\Elements\Element.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
79
    }
80
81
    /**
82
     * @return bool
83
     */
84
    public function isMultiple(): bool
85
    {
86
        return $this->multiple;
87
    }
88
89
    /**
90
     * @param  bool  $multiple
91
     * @return SelectControl
92
     */
93
    public function setMultiple(bool $multiple): self
94
    {
95
        $this->multiple = $multiple;
96
97
        return $this;
98
    }
99
100
    /**
101
     * @return array
102
     */
103
    public function getOptions(): array
104
    {
105
        return $this->options;
106
    }
107
108
    /**
109
     * @param  array  $options
110
     * @return SelectControl
111
     */
112
    public function setOptions(array $options): self
113
    {
114
        $this->options = $options;
115
116
        return $this;
117
    }
118
119
    /**
120
     * @return array
121
     */
122
    public function getSelected(): array
123
    {
124
        return $this->selected;
125
    }
126
127
    /**
128
     * @param  mixed  $selected
129
     * @return SelectControl
130
     */
131
    public function setSelected($selected): self
132
    {
133
        $this->selected = Arr::wrap($selected);
134
135
        return $this;
136
    }
137
138
    /**
139
     * @return array
140
     */
141
    protected function buildOptions()
142
    {
143
        $selected = array_map(function ($value) {
144
            if ($value instanceof Model) {
145
                return $value->getKey();
146
            }
147
148
            return $value;
149
        }, $this->getSelected());
150
151
        $items = new  Content();
152
153
        foreach ($this->getOptions() as $key => $value) {
154
            $option = Html::option((string) $value)->setValue($key);
155
156
            if (in_array($key, $selected)) {
157
                $option->select();
158
            }
159
160
            $items->push($option);
161
        }
162
163
        return $items;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $items returns the type Arbory\Base\Html\Elements\Content which is incompatible with the documented return type array.
Loading history...
164
    }
165
}
166