Passed
Pull Request — master (#79)
by Wilmer
02:24
created

ProgressBar::render()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 5
nop 0
dl 0
loc 15
ccs 10
cts 10
cp 1
crap 4
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bulma;
6
7
use InvalidArgumentException;
8
use Yiisoft\Html\Html;
9
use Yiisoft\Html\Tag\CustomTag;
10
use Yiisoft\Widget\Widget;
11
12
use function array_key_exists;
13
use function implode;
14
use function in_array;
15
16
/**
17
 * Progress Bar widget.
18
 * Native HTML progress bar.
19
 *
20
 * ```php
21
 * echo ProgressBar::widget()->value(75);
22
 * ```
23
 *
24
 * @link https://bulma.io/documentation/elements/progress/
25
 */
26
final class ProgressBar extends Widget
27
{
28
    public const SIZE_SMALL = 'is-small';
29
    public const SIZE_MEDIUM = 'is-medium';
30
    public const SIZE_LARGE = 'is-large';
31
    private const SIZE_ALL = [
32
        self::SIZE_SMALL,
33
        self::SIZE_MEDIUM,
34
        self::SIZE_LARGE,
35
    ];
36
37
    public const COLOR_PRIMARY = 'is-primary';
38
    public const COLOR_LINK = 'is-link';
39
    public const COLOR_INFO = 'is-info';
40
    public const COLOR_SUCCESS = 'is-success';
41
    public const COLOR_WARNING = 'is-warning';
42
    public const COLOR_DANGER = 'is-danger';
43
    public const COLOR_DARK = 'is-dark';
44
    private const COLOR_ALL = [
45
        self::COLOR_PRIMARY,
46
        self::COLOR_LINK,
47
        self::COLOR_INFO,
48
        self::COLOR_SUCCESS,
49
        self::COLOR_WARNING,
50
        self::COLOR_DANGER,
51
        self::COLOR_DARK,
52
    ];
53
54
    private array $attributes = [];
55
    private string $autoIdPrefix = 'w';
56
    private string $color = '';
57
    private string $size = '';
58
59
    /**
60
     * Returns a new instance with the specified HTML attributes for widget.
61
     *
62
     * @param array $values Attribute values indexed by attribute names.
63
     *
64
     * @return self
65
     *
66
     * {@see \Yiisoft\Html\Html::renderTagAttributes()} For details on how attributes are being rendered.
67
     */
68 2
    public function attributes(array $values): self
69
    {
70 2
        $new = clone $this;
71 2
        $new->attributes = $values;
72 2
        return $new;
73
    }
74
75
    /**
76
     * Returns a new instance with the specified prefix to the automatically generated widget IDs.
77
     *
78
     * @param string $value The prefix to the automatically generated widget IDs.
79
     *
80
     * @return self
81
     */
82 1
    public function autoIdPrefix(string $value): self
83
    {
84 1
        $new = clone $this;
85 1
        $new->autoIdPrefix = $value;
86 1
        return $new;
87
    }
88
89
    /**
90
     * Returns a new instance with the specified progress bar color.
91
     *
92
     * @param string $value The progress bar color. By default there is no color.
93
     * Possible values: ProgressBar::COLOR_PRIMARY, ProgressBar::COLOR_LINK, ProgressBar::COLOR_INFO,
94
     * ProgressBar::COLOR_SUCCESS, ProgressBar::COLOR_WARNING, ProgressBar::COLOR_DANGER, ProgressBar::COLOR_DARK.
95
     *
96
     * @return self
97
     */
98 3
    public function color(string $value): self
99
    {
100 3
        if (!in_array($value, self::COLOR_ALL, true)) {
101 1
            $values = implode('", "', self::COLOR_ALL);
102 1
            throw new InvalidArgumentException("Invalid color. Valid values are: \"$values\".");
103
        }
104
105 2
        $new = clone $this;
106 2
        $new->color = $value;
107 2
        return $new;
108
    }
109
110
    /**
111
     * Returns a new instance with the specified ID of the widget.
112
     *
113
     * @param string $value The ID of the widget.
114
     *
115
     * @return self
116
     */
117 1
    public function id(string $value): self
118
    {
119 1
        $new = clone $this;
120 1
        $new->attributes['id'] = $value;
121 1
        return $new;
122
    }
123
124
    /**
125
     * Returns a new instance with the specified maximum progress value.
126
     *
127
     * @param int|null $value Maximum progress value. Set `0` for no maximum.
128
     *
129
     * @return self
130
     */
131 5
    public function maxValue(?int $value): self
132
    {
133 5
        if ($value < 0 || $value > 100) {
134 1
            throw new InvalidArgumentException('Invalid max value. It must be between 0 and 100.');
135
        }
136
137 4
        $new = clone $this;
138 4
        $new->attributes['max'] = $value;
139 4
        return $new;
140
    }
141
142
    /**
143
     * Returns a new instance with the specified progress bar size class.
144
     *
145
     * @param string $value The progress bar size class. Default setting is "normal".
146
     * Possible values: ProgressBar::SIZE_SMALL, ProgressBar::SIZE_MEDIUM, Model::SIZE_LARGE.
147
     *
148
     * @return self
149
     */
150 3
    public function size(string $value): self
151
    {
152 3
        if (!in_array($value, self::SIZE_ALL, true)) {
153 1
            $values = implode('", "', self::SIZE_ALL);
154 1
            throw new InvalidArgumentException("Invalid size. Valid values are: \"$values\".");
155
        }
156
157 2
        $new = clone $this;
158 2
        $new->size = $value;
159 2
        return $new;
160
    }
161
162
    /**
163
     * Returns a new instance with the specified value of the progress.
164
     *
165
     * @param float|null $value The value of the progress. Set `0` to display loading animation.
166
     *
167
     * @return self
168
     */
169 6
    public function value(?float $value): self
170
    {
171 6
        if ($value < 0 || $value > 100) {
172 2
            throw new InvalidArgumentException('Invalid value. It must be between 0 and 100.');
173
        }
174
175 4
        $new = clone $this;
176 4
        $new->attributes['value'] = $value;
177 4
        return $new;
178
    }
179
180 8
    public function render(): string
181
    {
182 8
        $attributes = $this->build($this->attributes);
183 8
        $content = '';
184
185 8
        if (array_key_exists('value', $attributes)) {
186
            /** @var float|null */
187 3
            $attributes['value'] = $attributes['value'] === 0.0 ? null : $attributes['value'];
188 3
            $content = $attributes['value'] > 0 ? $attributes['value'] . '%' : '';
189
        }
190
191 8
        return CustomTag::name('progress')
192 8
            ->attributes($attributes)
193 8
            ->content($content)
194 8
            ->render();
195
    }
196
197 8
    private function build(array $attributes): array
198
    {
199 8
        if (!array_key_exists('id', $attributes)) {
200
            /** @var string */
201 8
            $attributes['id'] = Html::generateId($this->autoIdPrefix) . '-progressbar';
202
        }
203
204 8
        if (array_key_exists('max', $attributes)) {
205
            /** @var int|null */
206 3
            $attributes['max'] = $attributes['max'] === 0 ? null : $attributes['max'];
207
        } else {
208 5
            $attributes['max'] = 100;
209
        }
210
211 8
        Html::addCssClass($attributes, 'progress');
212
213 8
        if ($this->size !== '') {
214 1
            Html::addCssClass($attributes, $this->size);
215
        }
216
217 8
        if ($this->color !== '') {
218 1
            Html::addCssClass($attributes, $this->color);
219
        }
220
221 8
        return $attributes;
222
    }
223
}
224