Passed
Push — master ( 34e66c...44dbec )
by Sergei
03:09
created

Alert::closeButtonTag()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 10
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
use function array_merge;
11
12
/**
13
 * Alert renders an alert bootstrap component.
14
 *
15
 * For example,
16
 *
17
 * ```php
18
 * echo Alert::widget()
19
 *     ->options([
20
 *         'class' => 'alert-info',
21
 *     ])
22
 *     ->body('Say hello...');
23
 * ```
24
 *
25
 * @link https://getbootstrap.com/docs/5.0/components/alerts/
26
 */
27
final class Alert extends Widget
28
{
29
    use CloseButtonTrait;
30
31
    private string|Stringable $body = '';
32
    private ?string $header = null;
33
    private array $headerOptions = [];
34
    /** @psalm-var non-empty-string */
35
    private string $headerTag = 'h4';
36
    private bool $encode = false;
37
    private array $options = [];
38
    private array $classNames = [];
39
    private bool $fade = false;
40
41 18
    public function getId(?string $suffix = '-alert'): ?string
42
    {
43 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

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