yiisoft /
yii-bootstrap5
| 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
|
|||
| 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 |
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.