Alert::encode()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bootstrap5;
6
7
use Stringable;
8
use Yiisoft\Arrays\ArrayHelper;
9
use Yiisoft\Html\Html;
10
11
use function array_merge;
12
13
/**
14
 * Alert renders an alert bootstrap component.
15
 *
16
 * For example,
17
 *
18
 * ```php
19
 * echo Alert::widget()
20
 *     ->options([
21
 *         'class' => 'alert-info',
22
 *     ])
23
 *     ->body('Say hello...');
24
 * ```
25
 *
26
 * @link https://getbootstrap.com/docs/5.0/components/alerts/
27
 */
28
final class Alert extends Widget
29
{
30
    use CloseButtonTrait;
31
32
    private string|Stringable $body = '';
33
    private ?string $header = null;
34
    private array $headerOptions = [];
35
    /** @psalm-var non-empty-string */
36
    private string $headerTag = 'h4';
37
    private bool $encode = false;
38
    private array $options = [];
39
    private array $classNames = [];
40
    private bool $fade = false;
41
42 18
    public function getId(?string $suffix = '-alert'): ?string
43
    {
44 18
        return $this->options['id'] ?? parent::getId($suffix);
0 ignored issues
show
Unused Code introduced by
The call to Yiisoft\Yii\Bootstrap5\CloseButtonTrait::getId() has too many arguments starting with $suffix. ( Ignorable by Annotation )

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

44
        return $this->options['id'] ?? parent::/** @scrutinizer ignore-call */ getId($suffix);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
45
    }
46
47 8
    protected function toggleComponent(): string
48
    {
49 8
        return 'alert';
50
    }
51
52 18
    public function render(): string
53
    {
54 18
        $options = $this->prepareOptions();
55 18
        $tag = ArrayHelper::remove($options, 'tag', 'div');
56
57 18
        return Html::tag($tag, '', $options)
58 18
            ->encode(false)
59 18
            ->content(
60 18
                (string) $this->renderHeader(),
61 18
                $this->encode ? Html::encode($this->body) : $this->body,
62 18
                (string) $this->renderCloseButton(true)
63 18
            )
64 18
            ->render();
65
    }
66
67
    /**
68
     * The body content in the alert component. Alert widget will also be treated as the body content, and will be
69
     * rendered before this.
70
     */
71 18
    public function body(string|Stringable $value): self
72
    {
73 18
        $new = clone $this;
74 18
        $new->body = $value;
75
76 18
        return $new;
77
    }
78
79
    /**
80
     * The header content in alert component
81
     */
82 1
    public function header(?string $header): self
83
    {
84 1
        $new = clone $this;
85 1
        $new->header = $header;
86
87 1
        return $new;
88
    }
89
90
    /**
91
     * The HTML attributes for the widget header tag. The following special options are recognized.
92
     *
93
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
94
     */
95 1
    public function headerOptions(array $options): self
96
    {
97 1
        $new = clone $this;
98 1
        $new->headerOptions = $options;
99
100 1
        return $new;
101
    }
102
103
    /**
104
     * Set tag name for header
105
     *
106
     * @psalm-param non-empty-string $tag
107
     */
108 1
    public function headerTag(string $tag): self
109
    {
110 1
        $new = clone $this;
111 1
        $new->headerTag = $tag;
112
113 1
        return $new;
114
    }
115
116
    /**
117
     * The HTML attributes for the widget container tag. The following special options are recognized.
118
     *
119
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
120
     */
121 3
    public function options(array $value): self
122
    {
123 3
        $new = clone $this;
124 3
        $new->options = $value;
125
126 3
        return $new;
127
    }
128
129
    /**
130
     * Enable/Disable encode body
131
     */
132
    public function encode(bool $encode = true): self
133
    {
134
        $new = clone $this;
135
        $new->encode = $encode;
136
137
        return $new;
138
    }
139
140
    /**
141
     * Enable/Disable dissmiss animation
142
     */
143 2
    public function fade(bool $fade = true): self
144
    {
145 2
        $new = clone $this;
146 2
        $new->fade = $fade;
147
148 2
        return $new;
149
    }
150
151
    /**
152
     * Set type of alert, 'alert-success', 'alert-danger', 'custom-alert' etc
153
     */
154 9
    public function addClassNames(string ...$classNames): self
155
    {
156 9
        $new = clone $this;
157 9
        $new->classNames = array_filter($classNames, static fn ($name) => $name !== '');
158
159 9
        return $new;
160
    }
161
162
    /**
163
     * Short method for primary alert type
164
     */
165 1
    public function primary(): self
166
    {
167 1
        return $this->addClassNames('alert-primary');
168
    }
169
170
    /**
171
     * Short method for secondary alert type
172
     */
173 1
    public function secondary(): self
174
    {
175 1
        return $this->addClassNames('alert-secondary');
176
    }
177
178
    /**
179
     * Short method for success alert type
180
     */
181 1
    public function success(): self
182
    {
183 1
        return $this->addClassNames('alert-success');
184
    }
185
186
    /**
187
     * Short method for danger alert type
188
     */
189 1
    public function danger(): self
190
    {
191 1
        return $this->addClassNames('alert-danger');
192
    }
193
194
    /**
195
     * Short method for warning alert type
196
     */
197 1
    public function warning(): self
198
    {
199 1
        return $this->addClassNames('alert-warning');
200
    }
201
202
    /**
203
     * Short method for info alert type
204
     */
205 1
    public function info(): self
206
    {
207 1
        return $this->addClassNames('alert-info');
208
    }
209
210
    /**
211
     * Short method for light alert type
212
     */
213 1
    public function light(): self
214
    {
215 1
        return $this->addClassNames('alert-light');
216
    }
217
218
    /**
219
     * Short method for dark alert type
220
     */
221 1
    public function dark(): self
222
    {
223 1
        return $this->addClassNames('alert-dark');
224
    }
225
226
    /**
227
     * Render header tag
228
     */
229 18
    private function renderHeader(): ?string
230
    {
231 18
        if ($this->header === null) {
232 17
            return null;
233
        }
234
235 1
        $options = $this->headerOptions;
236 1
        $encode = ArrayHelper::remove($options, 'encode', true);
237
238 1
        Html::addCssClass($options, ['alert-heading']);
239
240 1
        return Html::tag($this->headerTag, $this->header, $options)
241 1
            ->encode($encode)
242 1
            ->render();
243
    }
244
245
    /**
246
     * Prepare the widget options.
247
     *
248
     * This method returns the default values for various options.
249
     */
250 18
    private function prepareOptions(): array
251
    {
252 18
        $options = $this->options;
253 18
        $options['id'] = $this->getId();
254 18
        $classNames = array_merge(['alert'], $this->classNames);
255
256 18
        if ($this->showCloseButton) {
257 8
            $classNames[] = 'alert-dismissible';
258
        }
259
260 18
        if ($this->fade) {
261 2
            $classNames[] = 'fade show';
262
        }
263
264 18
        Html::addCssClass($options, $classNames);
265
266 18
        if (!isset($options['role'])) {
267 18
            $options['role'] = 'alert';
268
        }
269
270 18
        return $options;
271
    }
272
}
273