Passed
Push — master ( ef6f5d...60f4bc )
by Alexander
02:52
created

ButtonGroup::containerId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Form\Widget;
6
7
use Yiisoft\Form\Widget\Attribute\ButtonAttributes;
8
use Yiisoft\Html\Tag\Input;
9
use Yiisoft\Html\Tag\Div;
10
11
use function implode;
12
use function is_array;
13
14
/**
15
 * ButtonGroup renders a button group widget.
16
 *
17
 * For example,
18
 *
19
 * ```php
20
 * // a button group with items configuration
21
 * echo ButtonGroup::widget()
22
 *     ->buttons([
23
 *         ['label' => 'A'],
24
 *         ['label' => 'B'],
25
 *         ['label' => 'C', 'visible' => false],
26
 *     ]);
27
 *
28
 * // button group with an item as a string
29
 * echo ButtonGroup::widget()
30
 *     ->buttons([
31
 *         SubmitButton::widget()->content('A')->render(),
32
 *         ['label' => 'B'],
33
 *     ]);
34
 * ```
35
 *
36
 * Pressing on the button should be handled via JavaScript. See the following for details:
37
 */
38
final class ButtonGroup extends ButtonAttributes
39
{
40
    private array $buttons = [];
41
    private bool $container = true;
42
    private array $containerAttributes = [];
43
    private string $containerClass = '';
44
    /** @psalm-var array[] */
45
    private array $individualButtonAttributes = [];
46
47
    /**
48
     * List of buttons. Each array element represents a single button which can be specified as a string or an array of
49
     * the following structure:
50
     *
51
     * - label: string, required, the button label.
52
     * - attributes: array, optional, the HTML attributes of the button.
53
     * - type: string, optional, the button type.
54
     * - visible: bool, optional, whether this button is visible. Defaults to true.
55
     *
56
     * @param array $values The buttons' configuration.
57
     *
58
     * @return self
59
     */
60 27
    public function buttons(array $values): self
61
    {
62 27
        $new = clone $this;
63 27
        $new->buttons = $values;
64
65 27
        return $new;
66
    }
67
68
    /**
69
     * Enable, disabled container for field.
70
     *
71
     * @param bool $value Is the container disabled or not.
72
     *
73
     * @return static
74
     */
75 10
    public function container(bool $value): self
76
    {
77 10
        $new = clone $this;
78 10
        $new->container = $value;
79 10
        return $new;
80
    }
81
82
    /**
83
     * Set container attributes.
84
     *
85
     * @param array $values Attribute values indexed by attribute names.
86
     *
87
     * ```php
88
     * ['class' => 'test-class']
89
     * ```
90
     *
91
     * @return static
92
     *
93
     * @psalm-param array<string, string> $values
94
     */
95 2
    public function containerAttributes(array $values): self
96
    {
97 2
        $new = clone $this;
98 2
        $new->containerAttributes = array_merge($new->containerAttributes, $values);
99 2
        return $new;
100
    }
101
102
    /**
103
     * Set container css class.
104
     *
105
     * @return static
106
     */
107 2
    public function containerClass(string $value): self
108
    {
109 2
        $new = clone $this;
110 2
        $new->containerClass = $value;
111 2
        return $new;
112
    }
113
114
    /**
115
     * Set the ID of the container field.
116
     *
117
     * @param string|null $id
118
     *
119
     * @return static
120
     */
121 2
    public function containerId(?string $id): self
122
    {
123 2
        $new = clone $this;
124 2
        $new->containerAttributes['id'] = $id;
125 2
        return $new;
126
    }
127
128
    /**
129
     * Set the name of the container field.
130
     *
131
     * @param string|null $id
132
     *
133
     * @return static
134
     */
135 2
    public function containerName(?string $id): self
136
    {
137 2
        $new = clone $this;
138 2
        $new->containerAttributes['name'] = $id;
139 2
        return $new;
140
    }
141
142
    /**
143
     * The specified attributes for button.
144
     *
145
     * @param array $values The button attributes.
146
     *
147
     * @return static
148
     *
149
     * @psalm-param array[] $values
150
     */
151 2
    public function individualButtonAttributes(array $values = []): self
152
    {
153 2
        $new = clone $this;
154 2
        $new->individualButtonAttributes = $values;
155 2
        return $new;
156
    }
157
158 26
    protected function run(): string
159
    {
160 26
        $div = Div::tag();
161
162 26
        if ($this->containerClass !== '') {
163 1
            $div = $div->class($this->containerClass);
164
        }
165
166 26
        if ($this->containerAttributes !== []) {
167 3
            $div = $div->attributes($this->containerAttributes);
168
        }
169
170 26
        return $this->container ?
171 26
            $div->content(PHP_EOL . $this->renderButtons() . PHP_EOL)->encode(false)->render() : $this->renderButtons();
172
    }
173
174
    /**
175
     * Generates the buttons that compound the group as specified on {@see buttons}.
176
     *
177
     * @return string the rendering result.
178
     */
179 26
    private function renderButtons(): string
180
    {
181 26
        $htmlButtons = [];
182
183
        /** @psalm-var array<string, array|string> */
184 26
        $buttons = $this->buttons;
185
186 26
        foreach ($buttons as $key => $button) {
187 26
            if (is_array($button)) {
188
                /** @var array */
189 26
                $attributes = $button['attributes'] ?? [];
190 26
                $attributes = array_merge($attributes, $this->build($this->attributes, '-button'));
191
192
                // Set individual button attributes.
193 26
                $individualButtonAttributes = $this->individualButtonAttributes[$key] ?? [];
194 26
                $attributes = array_merge($attributes, $individualButtonAttributes);
195
196
                /** @var string */
197 26
                $label = $button['label'] ?? '';
198
199
                /** @var string */
200 26
                $type = $button['type'] ?? 'button';
201
202
                /** @var bool */
203 26
                $visible = $button['visible'] ?? true;
204
205 26
                if ($visible === false) {
206 1
                    continue;
207
                }
208
209 26
                $htmlButtons[] = Input::tag()->attributes($attributes)->value($label)->type($type)->render();
210
            } else {
211
                $htmlButtons[] = $button;
212
            }
213
        }
214
215 26
        return implode("\n", $htmlButtons);
216
    }
217
}
218