Progress   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 166
Duplicated Lines 0 %

Test Coverage

Coverage 91.11%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 42
c 1
b 0
f 0
dl 0
loc 166
ccs 41
cts 45
cp 0.9111
rs 10
wmc 12

8 Methods

Rating   Name   Duplication   Size   Complexity  
A barOptions() 0 5 1
A run() 0 9 2
A percent() 0 5 1
A renderProgress() 0 25 4
A bars() 0 5 1
A options() 0 5 1
A label() 0 5 1
A renderBar() 0 15 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bootstrap4;
6
7
use JsonException;
8
use RuntimeException;
9
use Yiisoft\Arrays\ArrayHelper;
10
use Yiisoft\Html\Html;
11
12
use function array_merge;
13
use function implode;
14
use function rtrim;
15
use function trim;
16
17
/**
18
 * Progress renders a bootstrap progress bar component.
19
 *
20
 * For example,
21
 *
22
 * ```php
23
 * // default with label
24
 * echo Progress::widget()
25
 *     ->percent('60')
26
 *     ->label(test);
27
 *
28
 * // styled
29
 * echo Progress::widget()
30
 *     ->bars([
31
 *         ['percent' => '65', 'options' => ['class' => 'bg-danger']]
32
 *     ]);
33
 *
34
 * // striped
35
 * echo Progress::widget()
36
 *     ->bars([
37
 *         ['percent' => '70', 'options' => ['class' => 'bg-warning progress-bar-striped']]
38
 *     ]);
39
 *
40
 * // striped animated
41
 * echo Progress::widget()
42
 *     ->percent('70')
43
 *     ->options'(['class' => 'bg-success progress-bar-animated progress-bar-striped']);
44
 *
45
 * // stacked bars
46
 * echo Progress::widget()
47
 *     ->bars([
48
 *         ['percent' => '30', 'options' => ['class' => 'bg-danger']],
49
 *         ['percent' => '30', 'label' => 'test', 'options' => ['class' => 'bg-success']],
50
 *         ['percent' => '35', 'options' => ['class' => 'bg-warning']],
51
 *     ]);
52
 * ```
53
 */
54
class Progress extends Widget
55
{
56
    private ?string $label = null;
57
    private ?string $percent = null;
58
    private array $bars = [];
59
    private array $options = [];
60
    private array $barOptions = [];
61
62 3
    protected function run(): string
63
    {
64 3
        if (!isset($this->options['id'])) {
65 3
            $this->options['id'] = "{$this->getId()}-progress";
66
        }
67
68 3
        Html::addCssClass($this->options, ['widget' => 'progress']);
69
70 3
        return $this->renderProgress();
71
    }
72
73
    /**
74
     * Renders the progress.
75
     *
76
     * @throws JsonException|RuntimeException if the "percent" option is not set in a stacked progress bar.
77
     *
78
     * @return string the rendering result.
79
     */
80 3
    protected function renderProgress(): string
81
    {
82 3
        $out = Html::beginTag('div', $this->options) . "\n";
83
84 3
        if (empty($this->bars)) {
85 1
            $this->bars = [
86 1
                ['label' => $this->label, 'percent' => $this->percent, 'options' => $this->barOptions],
87
            ];
88
        }
89
90 3
        $bars = [];
91
92 3
        foreach ($this->bars as $bar) {
93 3
            $label = ArrayHelper::getValue($bar, 'label', '');
94 3
            if (!isset($bar['percent'])) {
95
                throw new RuntimeException('The "percent" option is required.');
96
            }
97 3
            $options = ArrayHelper::getValue($bar, 'options', []);
98 3
            $bars[] = $this->renderBar($bar['percent'], $label, $options);
99
        }
100
101 3
        $out .= implode("\n", $bars) . "\n";
102 3
        $out .= Html::endTag('div');
103
104 3
        return $out;
105
    }
106
107
    /**
108
     * Generates a bar.
109
     *
110
     * @param string $percent the percentage of the bar
111
     * @param string $label , optional, the label to display at the bar
112
     * @param array $options the HTML attributes of the bar
113
     *
114
     * @throws JsonException
115
     *
116
     * @return string the rendering result.
117
     */
118 3
    protected function renderBar(string $percent, string $label = '', array $options = []): string
119
    {
120 3
        $valuePercent = (float)trim(rtrim($percent, '%'));
121
122 3
        $options = array_merge($options, [
123 3
            'role' => 'progressbar',
124 3
            'aria-valuenow' => $percent,
125 3
            'aria-valuemin' => 0,
126 3
            'aria-valuemax' => 100,
127
        ]);
128
129 3
        Html::addCssClass($options, ['widget' => 'progress-bar']);
130 3
        Html::addCssStyle($options, ['width' => $valuePercent . '%'], true);
131
132 3
        return Html::tag('div', $label, $options);
133
    }
134
135
    /**
136
     * Set of bars that are stacked together to form a single progress bar.
137
     *
138
     * Each bar is an array of the following structure:
139
     *
140
     * ```php
141
     * [
142
     *     // required, the amount of progress as a percentage.
143
     *     'percent' => '30',
144
     *     // optional, the label to be displayed on the bar
145
     *     'label' => '30%',
146
     *     // optional, array, additional HTML attributes for the bar tag
147
     *     'options' => [],
148
     * ]
149
     * ```
150
     *
151
     * @param array $value
152
     *
153
     * @return $this
154
     */
155 2
    public function bars(array $value): self
156
    {
157 2
        $this->bars = $value;
158
159 2
        return $this;
160
    }
161
162
    /**
163
     * The HTML attributes of the bar. This property will only be considered if {@see bars} is empty.
164
     *
165
     * {@see \Yiisoft\Html\Html::renderTagAttributes() for details on how attributes are being rendered}
166
     *
167
     * @param array $value
168
     *
169
     * @return $this
170
     */
171 1
    public function barOptions(array $value): self
172
    {
173 1
        $this->barOptions = $value;
174
175 1
        return $this;
176
    }
177
178
    /**
179
     * The button label.
180
     *
181
     * @param string|null $value
182
     *
183
     * @return $this
184
     */
185 1
    public function label(?string $value): self
186
    {
187 1
        $this->label = $value;
188
189 1
        return $this;
190
    }
191
192
    /**
193
     * The HTML attributes for the widget container tag. The following special options are recognized.
194
     *
195
     * @param array $value
196
     *
197
     * @return $this
198
     *
199
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} for details on how attributes are being rendered.
200
     */
201
    public function options(array $value): self
202
    {
203
        $this->options = $value;
204
205
        return $this;
206
    }
207
208
    /**
209
     * The amount of progress as a percentage.
210
     *
211
     * @param string|null $value
212
     *
213
     * @return $this
214
     */
215 1
    public function percent(?string $value): self
216
    {
217 1
        $this->percent = $value;
218
219 1
        return $this;
220
    }
221
}
222