Passed
Push — master ( 566566...d0f53d )
by Alexander
02:18
created

ButtonGroup::renderButtons()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 33
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
nc 11
nop 0
dl 0
loc 33
ccs 17
cts 17
cp 1
crap 7
rs 8.8333
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bootstrap5;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Factory\Exceptions\InvalidConfigException;
9
use Yiisoft\Html\Html;
10
11
use function implode;
12
use function is_array;
13
14
/**
15
 * ButtonGroup renders a button group bootstrap component.
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
 *         Button::widget()->label('A'),
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 Widget
39
{
40
    private array $buttons = [];
41
    private bool $encodeLabels = true;
42
    private bool $encodeTags = false;
43
    private array $options = [];
44
45 9
    protected function run(): string
46
    {
47 9
        if (!isset($this->options['id'])) {
48 9
            $this->options['id'] = "{$this->getId()}-button-group";
49
        }
50
51
        /** @psalm-suppress InvalidArgument */
52 9
        Html::addCssClass($this->options, ['widget' => 'btn-group']);
53
54 9
        if (!isset($this->options['role'])) {
55 9
            $this->options['role'] = 'group';
56
        }
57
58 9
        if ($this->encodeTags === false) {
59 8
            $this->options['encode'] = false;
60
        }
61
62 9
        return Html::div($this->renderButtons(), $this->options);
63
    }
64
65
    /**
66
     * List of buttons. Each array element represents a single button which can be specified as a string or an array of
67
     * the following structure:
68
     *
69
     * - label: string, required, the button label.
70
     * - options: array, optional, the HTML attributes of the button.
71
     * - visible: bool, optional, whether this button is visible. Defaults to true.
72
     *
73
     * @param array $value
74
     *
75
     * @return $this
76
     */
77 9
    public function buttons(array $value): self
78
    {
79 9
        $new = clone $this;
80 9
        $new->buttons = $value;
81
82 9
        return $new;
83
    }
84
85
    /**
86
     * When tags Labels HTML should not be encoded.
87
     *
88
     * @return $this
89
     */
90 1
    public function withoutEncodeLabels(): self
91
    {
92 1
        $new = clone $this;
93 1
        $new->encodeLabels = false;
94
95 1
        return $new;
96
    }
97
98
    /**
99
     * The HTML attributes for the widget container tag. The following special options are recognized.
100
     *
101
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
102
     *
103
     * @param array $value
104
     *
105
     * @return $this
106
     */
107 5
    public function options(array $value): self
108
    {
109 5
        $new = clone $this;
110 5
        $new->options = $value;
111
112 5
        return $new;
113
    }
114
115
    /**
116
     * Allows you to enable the encoding tags html.
117
     *
118
     * @return self
119
     */
120 1
    public function encodeTags(): self
121
    {
122 1
        $new = clone $this;
123 1
        $new->encodeTags = true;
124
125 1
        return $new;
126
    }
127
128
    /**
129
     * Generates the buttons that compound the group as specified on {@see buttons}.
130
     *
131
     * @throws InvalidConfigException
132
     *
133
     * @return string the rendering result.
134
     */
135 9
    private function renderButtons(): string
136
    {
137 9
        $buttons = [];
138
139 9
        foreach ($this->buttons as $button) {
140 9
            if (is_array($button)) {
141 9
                $visible = ArrayHelper::remove($button, 'visible', true);
142
143 9
                if ($visible === false) {
144 1
                    continue;
145
                }
146
147 9
                if (!isset($button['encodeLabel'])) {
148 9
                    $button['encodeLabel'] = $this->encodeLabels;
149
                }
150
151 9
                if (!isset($button['options']['type'])) {
152 7
                    ArrayHelper::setValueByPath($button, 'options.type', 'button');
153
                }
154
155 9
                $buttonWidget = Button::widget()->label($button['label'])->options($button['options']);
0 ignored issues
show
Bug introduced by
The method label() does not exist on Yiisoft\Widget\Widget. It seems like you code against a sub-type of Yiisoft\Widget\Widget such as Yiisoft\Yii\Bootstrap5\Button or Yiisoft\Yii\Bootstrap5\Progress or Yiisoft\Yii\Bootstrap5\ButtonDropdown. ( Ignorable by Annotation )

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

155
                $buttonWidget = Button::widget()->/** @scrutinizer ignore-call */ label($button['label'])->options($button['options']);
Loading history...
156
157 9
                if ($button['encodeLabel'] === false) {
158 1
                    $buttonWidget = $buttonWidget->withoutEncodeLabels();
159
                }
160
161 9
                $buttons[] = $buttonWidget->render();
162
            } else {
163 1
                $buttons[] = $button;
164
            }
165
        }
166
167 9
        return implode("\n", $buttons);
168
    }
169
}
170