Passed
Pull Request — master (#35)
by Wilmer
02:14
created

ButtonGroup   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 132
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 42
c 1
b 0
f 0
dl 0
loc 132
ccs 43
cts 43
cp 1
rs 10
wmc 14

6 Methods

Rating   Name   Duplication   Size   Complexity  
A withoutEncodeLabels() 0 6 1
A withButtons() 0 6 1
A renderButtons() 0 31 6
A withEncodeTags() 0 6 1
A run() 0 18 4
A withOptions() 0 6 1
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
 *     ->withButtons([
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
 *     ->withButtons([
31
 *         Button::widget()
32
 *             ->label('A'),
33
 *         ['label' => 'B'],
34
 *     ]);
35
 * ```
36
 *
37
 * Pressing on the button should be handled via JavaScript. See the following for details:
38
 */
39
final class ButtonGroup extends Widget
40
{
41
    private array $buttons = [];
42
    private bool $encodeLabels = true;
43
    private bool $encodeTags = false;
44
    private array $options = [];
45
46 9
    public function run(): string
47
    {
48 9
        if (!isset($this->options['id'])) {
49 9
            $this->options['id'] = "{$this->getId()}-button-group";
50
        }
51
52
        /** @psalm-suppress InvalidArgument */
53 9
        Html::addCssClass($this->options, ['widget' => 'btn-group']);
54
55 9
        if (!isset($this->options['role'])) {
56 9
            $this->options['role'] = 'group';
57
        }
58
59 9
        if ($this->encodeTags === false) {
60 8
            $this->options = array_merge($this->options, ['encode' => false]);
61
        }
62
63 9
        return Html::div($this->renderButtons(), $this->options);
64
    }
65
66
    /**
67
     * List of buttons. Each array element represents a single button which can be specified as a string or an array of
68
     * the following structure:
69
     *
70
     * - label: string, required, the button label.
71
     * - options: array, optional, the HTML attributes of the button.
72
     * - visible: bool, optional, whether this button is visible. Defaults to true.
73
     *
74
     * @param array $value
75
     *
76
     * @return $this
77
     */
78 9
    public function withButtons(array $value): self
79
    {
80 9
        $new = clone $this;
81 9
        $new->buttons = $value;
82
83 9
        return $new;
84
    }
85
86
    /**
87
     * Whether to HTML-encode the button labels.
88
     *
89
     * @param bool $value
90
     *
91
     * @return $this
92
     */
93 1
    public function withoutEncodeLabels(bool $value = false): self
94
    {
95 1
        $new = clone $this;
96 1
        $new->encodeLabels = $value;
97
98 1
        return $new;
99
    }
100
101
    /**
102
     * The HTML attributes for the widget container tag. The following special options are recognized.
103
     *
104
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
105
     *
106
     * @param array $value
107
     *
108
     * @return $this
109
     */
110 5
    public function withOptions(array $value): self
111
    {
112 5
        $new = clone $this;
113 5
        $new->options = $value;
114
115 5
        return $new;
116
    }
117
118
    /**
119
     * Allows you to enable or disable the encoding tags html.
120
     *
121
     * @param bool $value
122
     *
123
     * @return self
124
     */
125 1
    public function withEncodeTags(bool $value = true): self
126
    {
127 1
        $new = clone $this;
128 1
        $new->encodeTags = $value;
129
130 1
        return $new;
131
    }
132
133
    /**
134
     * Generates the buttons that compound the group as specified on {@see buttons}.
135
     *
136
     * @throws InvalidConfigException
137
     *
138
     * @return string the rendering result.
139
     */
140 9
    private function renderButtons(): string
141
    {
142 9
        $buttons = [];
143
144 9
        foreach ($this->buttons as $button) {
145 9
            if (is_array($button)) {
146 9
                $visible = ArrayHelper::remove($button, 'visible', true);
147
148 9
                if ($visible === false) {
149 1
                    continue;
150
                }
151
152 9
                if (!isset($button['encodeLabel'])) {
153 9
                    $button['encodeLabel'] = $this->encodeLabels;
154
                }
155
156 9
                if (!isset($button['options']['type'])) {
157 7
                    ArrayHelper::setValueByPath($button, 'options.type', 'button');
158
                }
159
160 9
                $buttons[] = Button::widget()
161 9
                    ->withoutEncodeLabels($button['encodeLabel'])
0 ignored issues
show
Bug introduced by
The method withoutEncodeLabels() 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\Nav or Yiisoft\Yii\Bootstrap5\Button or Yiisoft\Yii\Bootstrap5\Dropdown or Yiisoft\Yii\Bootstrap5\ButtonDropdown or Yiisoft\Yii\Bootstrap5\Tabs or Yiisoft\Yii\Bootstrap5\Accordion or Yiisoft\Yii\Bootstrap5\Breadcrumbs or Yiisoft\Yii\Bootstrap5\ButtonGroup. ( Ignorable by Annotation )

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

161
                    ->/** @scrutinizer ignore-call */ withoutEncodeLabels($button['encodeLabel'])
Loading history...
162 9
                    ->withLabel($button['label'])
163 9
                    ->withOptions($button['options'])
164 9
                    ->render();
165
            } else {
166 1
                $buttons[] = $button;
167
            }
168
        }
169
170 9
        return implode("\n", $buttons);
171
    }
172
}
173