Passed
Pull Request — master (#29)
by
unknown
02:42
created

Panel::renderTab()   B

Complexity

Conditions 7
Paths 9

Size

Total Lines 28
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 7.0119

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 15
c 1
b 0
f 0
nc 9
nop 2
dl 0
loc 28
ccs 15
cts 16
cp 0.9375
crap 7.0119
rs 8.8333
1
<?php
2
3
namespace Yiisoft\Yii\Bulma;
4
5
use InvalidArgumentException;
6
use Yiisoft\Arrays\ArrayHelper;
7
use Yiisoft\Html\Html;
8
9
final class Panel extends Widget
10
{
11
    public const COLOR_PRIMARY = 'is-primary';
12
    public const COLOR_LINK = 'is-link';
13
    public const COLOR_INFO = 'is-info';
14
    public const COLOR_SUCCESS = 'is-success';
15
    public const COLOR_WARNING = 'is-warning';
16
    public const COLOR_DANGER = 'is-danger';
17
    private const COLOR_ALL = [
18
        self::COLOR_PRIMARY,
19
        self::COLOR_LINK,
20
        self::COLOR_INFO,
21
        self::COLOR_SUCCESS,
22
        self::COLOR_WARNING,
23
        self::COLOR_DANGER,
24
    ];
25
26
    private array $options = [];
27
    private array $headingOptions = [];
28
    private ?string $heading = null;
29
    private string $color = '';
30
    private array $tabs = [];
31
    private array $tabsOptions = [];
32
    private bool $encodeLabels = true;
33
    private string $template = '{panelBegin}{panelHeading}{panelTabs}{panelItems}{panelEnd}';
34
    private array $items = [];
35
36 9
    protected function run(): string
37
    {
38 9
        $this->buildOptions();
39
40 9
        return strtr($this->template, [
41 9
            '{panelBegin}' => Html::beginTag('nav', $this->options),
42 9
            '{panelHeading}' => $this->renderHeading(),
43 9
            '{panelTabs}' => $this->renderTabs(),
44 9
            '{panelItems}' => implode("\n", $this->items),
45 9
            '{panelEnd}' => Html::endTag('nav'),
46
        ]);
47
    }
48
49 9
    private function buildOptions(): void
50
    {
51 9
        Html::addCssClass($this->options, 'panel');
52
53 9
        $this->options['id'] ??= "{$this->getId()}-panel";
54
55 9
        if ($this->color !== '') {
56 1
            Html::addCssClass($this->options, $this->color);
57
        }
58 9
    }
59
60
    /**
61
     * String the template for rendering panel.
62
     *
63
     * - `{panelBegin}`: _string_, which will render the panel container begin.
64
     * - `{panelHeading}`: _string_, which will render the panel heading.
65
     * - `{panelTabs}`: _string_, which will render the panel tabs.
66
     * - `{panelItems}`: _string_, which will render the panel items.
67
     * - `{panelEnd}`: _string_, which will render the panel container end.
68
     *
69
     * @param string $value
70
     *
71
     * @return self
72
     */
73
    public function template(string $value): self
74
    {
75
        $new = clone $this;
76
        $new->template = $value;
77
78
        return $new;
79
    }
80
81
    /**
82
     * @param array $value
83
     *
84
     * @return self
85
     */
86 1
    public function options(array $value): self
87
    {
88 1
        $new = clone $this;
89 1
        $new->options = $value;
90
91 1
        return $new;
92
    }
93
94
    /**
95
     * @param string $value
96
     *
97
     * @return self
98
     */
99 3
    public function heading(string $value): self
100
    {
101 3
        $new = clone $this;
102 3
        $new->heading = $value;
103
104 3
        return $new;
105
    }
106
107
    /**
108
     * @param array $value
109
     *
110
     * @return self
111
     */
112 1
    public function headingOptions(array $value): self
113
    {
114 1
        $new = clone $this;
115 1
        $new->headingOptions = $value;
116
117 1
        return $new;
118
    }
119
120
    /**
121
     * Set progress bar color.
122
     *
123
     * @var string $value Color class.
124
     *
125
     * @return self
126
     */
127 2
    public function color(string $value): self
128
    {
129 2
        if (!in_array($value, self::COLOR_ALL)) {
130 1
            $values = implode('", "', self::COLOR_ALL);
131 1
            throw new InvalidArgumentException("Invalid color. Valid values are: \"$values\".");
132
        }
133
134 1
        $new = clone $this;
135 1
        $new->color = $value;
136
137 1
        return $new;
138
    }
139
140
    /**
141
     * @param array $value
142
     *
143
     * @return self
144
     */
145 4
    public function tabs(array $value): self
146
    {
147 4
        $new = clone $this;
148 4
        $new->tabs = $value;
149
150 4
        return $new;
151
    }
152
153
    /**
154
     * @param array $value
155
     *
156
     * @return self
157
     */
158 1
    public function tabsOptions(array $value): self
159
    {
160 1
        $new = clone $this;
161 1
        $new->tabsOptions = $value;
162
163 1
        return $new;
164
    }
165
166
    /**
167
     * @throws \JsonException
168
     *
169
     * @return string
170
     */
171 9
    private function renderHeading(): string
172
    {
173 9
        if ($this->heading !== null) {
174 3
            Html::addCssClass($this->headingOptions, 'panel-heading');
175 3
            return "\n" . Html::tag('p', $this->heading, $this->headingOptions) . "\n";
176
        }
177
178 6
        return '';
179
    }
180
181
    /**
182
     * @throws \JsonException
183
     *
184
     * @return string
185
     */
186 9
    private function renderTabs(): string
187
    {
188 9
        if (!empty($this->tabs)) {
189 4
            $tabs = '';
190 4
            foreach ($this->tabs as $index => $item) {
191 4
                $tabs .= $this->renderTab($index, $item) . "\n";
192
            }
193
194 4
            Html::addCssClass($this->tabsOptions, 'panel-tabs');
195
196 4
            return "\n" . Html::tag('p', "\n" . $tabs, $this->tabsOptions) . "\n";
197
        }
198
199 5
        return '';
200
    }
201
202
    /**
203
     * @param int $index
204
     * @param array $item
205
     *
206
     * @throws \JsonException
207
     *
208
     * @return string
209
     */
210 4
    private function renderTab(int $index, array $item): string
211
    {
212 4
        $label = ArrayHelper::getValue($item, 'label', '');
213 4
        $encode = ArrayHelper::getValue($item, 'encode', $this->encodeLabels);
214 4
        $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
215 4
        $items = ArrayHelper::getValue($item, 'items', []);
216
217 4
        $linkOptions['id'] = ArrayHelper::getValue($item, 'id', $this->options['id'] . '-tab-' . $index);
218
219 4
        if ($label === '') {
220
            throw new InvalidArgumentException("The 'label' option is required.");
221
        }
222
223 4
        if ($encode === true) {
224 4
            $label = Html::encode($label);
225
        }
226
227 4
        if ($this->isActive($item)) {
228 2
            Html::addCssClass($linkOptions, 'is-active');
229
        }
230
231 4
        if (is_array($items) && !empty($items)) {
232 1
            foreach ($items as $item) {
233 1
                $this->items[$index] = $this->renderItem($index, $item);
234
            }
235
        }
236
237 4
        return Html::tag('a', $label, $linkOptions);
238
    }
239
240 1
    private function renderItem(int $index, array $item): string
0 ignored issues
show
Unused Code introduced by
The parameter $index is not used and could be removed. ( Ignorable by Annotation )

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

240
    private function renderItem(/** @scrutinizer ignore-unused */ int $index, array $item): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
241
    {
242 1
        $options = (array)ArrayHelper::getValue($item, 'options', []);
243 1
        $label = (string)ArrayHelper::getValue($item, 'label', '');
244 1
        $icon = (string)ArrayHelper::getValue($item, 'icon', '');
245
246 1
        Html::addCssClass($options, 'panel-block');
247
248 1
        if ($this->isActive($item)) {
249 1
            Html::addCssClass($options, 'is-active');
250
        }
251
252 1
        if ($icon !== '') {
253 1
            $icon = "\n". Html::tag('i', '', ['class' => $icon, 'aria-hidden' => 'true']) . "\n";
254 1
            $label = "\n" . Html::tag('span', $icon, ['class' => 'panel-icon']) . "\n" . $label . "\n";
255
        }
256
257 1
        return Html::tag('a', $label, $options) . "\n";
258
    }
259
260
    /**
261
     * Checking if active item.
262
     *
263
     * @param array $item
264
     *
265
     * @return bool
266
     */
267 4
    private function isActive(array $item): bool
268
    {
269 4
        return (bool)ArrayHelper::getValue($item, 'active', false);
270
    }
271
}
272