Passed
Push — master ( e80b4e...741461 )
by Alexander
02:19
created

Message::withoutCloseButton()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Bulma;
6
7
use Yiisoft\Arrays\ArrayHelper;
8
use Yiisoft\Html\Html;
9
10
/**
11
 * Message renders Bulma message component.
12
 *
13
 * For example,
14
 *
15
 * ```php
16
 * <?= Message::widget()->headerColor('success')->header('System info')->body('Say hello...') ?>
17
 * ```
18
 *
19
 * @link https://bulma.io/documentation/components/message/
20
 */
21
final class Message extends Widget
22
{
23
    private string $body = '';
24
    private string $headerColor = 'is-dark';
25
    private string $headerMessage = '';
26
    private array $options = [];
27
    private array $bodyOptions = [];
28
    private array $closeButtonOptions = [];
29
    private array $headerOptions = [];
30
    private string $size = '';
31
    private bool $withoutCloseButton = false;
32
    private bool $withoutHeader = true;
33
    private bool $encodeTags = false;
34
35 11
    protected function run(): string
36
    {
37 11
        $this->buildOptions();
38
39
        return
40 11
            Html::beginTag('div', $this->options) . "\n" .
41 11
                $this->renderHeader() .
42 11
                Html::beginTag('div', $this->bodyOptions) . "\n" .
43 11
                    $this->renderBodyEnd() . "\n" .
44 11
                Html::endTag('div') . "\n" .
45 11
            Html::endTag('div');
46
    }
47
48
    /**
49
     * The body content in the message component. Message widget will also be treated as the body content, and will be
50
     * rendered before this.
51
     *
52
     * @param string $value
53
     *
54
     * @return self
55
     */
56 11
    public function body(string $value): self
57
    {
58 11
        $new = clone $this;
59 11
        $new->body = $value;
60 11
        return $new;
61
    }
62
63
    /**
64
     * Set color header message.
65
     *
66
     * @param string $value setting default 'is-dark', 'is-primary', 'is-link', 'is-info', 'is-success', 'is-warning',
67
     * 'is-danger'.
68
     *
69
     * @return self
70
     */
71 1
    public function headerColor(string $value): self
72
    {
73 1
        $new = clone $this;
74 1
        $new->headerColor = $value;
75 1
        return $new;
76
    }
77
78
    /**
79
     * The header message in the message component. Message widget will also be treated as the header content, and will
80
     * be rendered before body.
81
     *
82
     * @param string $value
83
     *
84
     * @return self
85
     */
86 11
    public function headerMessage(string $value): self
87
    {
88 11
        $new = clone $this;
89 11
        $new->headerMessage = $value;
90 11
        return $new;
91
    }
92
93
    /**
94
     * The HTML attributes for the widget container tag.
95
     *
96
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
97
     *
98
     * @param array $value
99
     *
100
     * @return self
101
     */
102 1
    public function options(array $value): self
103
    {
104 1
        $new = clone $this;
105 1
        $new->options = $value;
106 1
        return $new;
107
    }
108
109
    /**
110
     * The HTML attributes for the widget body tag.
111
     *
112
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
113
     *
114
     * @param array $value
115
     *
116
     * @return self
117
     */
118 1
    public function bodyOptions(array $value): self
119
    {
120 1
        $new = clone $this;
121 1
        $new->bodyOptions = $value;
122 1
        return $new;
123
    }
124
125
    /**
126
     * The options for rendering the close button tag.
127
     *
128
     * The close button is displayed in the header of the modal window. Clicking on the button will hide the modal
129
     * window. If {@see withoutCloseButton} is false, no close button will be rendered.
130
     *
131
     * @param array $value
132
     *
133
     * @return self
134
     */
135 1
    public function closeButtonOptions(array $value): self
136
    {
137 1
        $new = clone $this;
138 1
        $new->closeButtonOptions = $value;
139 1
        return $new;
140
    }
141
142
    /**
143
     * The HTML attributes for the widget header tag.
144
     *
145
     * {@see Html::renderTagAttributes()} for details on how attributes are being rendered.
146
     *
147
     * @param array $value
148
     *
149
     * @return self
150
     */
151 1
    public function headerOptions(array $value): self
152
    {
153 1
        $new = clone $this;
154 1
        $new->headerOptions = $value;
155 1
        return $new;
156
    }
157
158
    /**
159
     * Set size message widget.
160
     *
161
     * @param string $value default setting empty normal, 'is-small', 'is-medium', 'is-large'.
162
     *
163
     * @return self
164
     */
165 1
    public function size(string $value): self
166
    {
167 1
        $new = clone $this;
168 1
        $new->size = $value;
169 1
        return $new;
170
    }
171
172
    /**
173
     * Allows you to enable close button message widget.
174
     *
175
     * @return self
176
     */
177 1
    public function closeButton(): self
178
    {
179 1
        $new = clone $this;
180 1
        $new->withoutCloseButton = true;
181 1
        return $new;
182
    }
183
184
    /**
185
     * Allows you to disable header widget.
186
     *
187
     * @return self
188
     */
189 1
    public function withoutHeader(): self
190
    {
191 1
        $new = clone $this;
192 1
        $new->withoutHeader = false;
193 1
        return $new;
194
    }
195
196 11
    private function buildOptions(): void
197
    {
198 11
        if (!isset($this->options['id'])) {
199 11
            $this->options['id'] = "{$this->getId()}-message";
200
        }
201
202 11
        $this->options = $this->addOptions($this->options, 'message');
203
204 11
        Html::addCssClass($this->options, $this->headerColor);
205
206 11
        if ($this->size !== '') {
207 1
            Html::addCssClass($this->options, $this->size);
208
        }
209
210 11
        $this->bodyOptions = $this->addOptions($this->bodyOptions, 'message-body');
211 11
        $this->closeButtonOptions = $this->addOptions($this->closeButtonOptions, 'delete');
212 11
        $this->headerOptions = $this->addOptions($this->headerOptions, 'message-header');
213
214 11
        if ($this->encodeTags === false) {
215 11
            $this->closeButtonOptions['encode'] = false;
216 11
            $this->options['encode'] = false;
217
        }
218 11
    }
219
220 11
    private function renderHeader(): string
221
    {
222 11
        $html = '';
223
224 11
        if ($this->withoutHeader) {
225 10
            $html = Html::beginTag('div', $this->headerOptions) . "\n" . $this->renderHeaderMessage() . "\n" .
226 10
                Html::endTag('div') . "\n";
227
        }
228
229 11
        return $html;
230
    }
231
232 10
    private function renderHeaderMessage(): string
233
    {
234 10
        $result = $this->headerMessage;
235
236 10
        if ($this->renderCloseButton() !== null) {
237 9
            $result = '<p>' . $this->headerMessage . '</p>' . "\n" . $this->renderCloseButton();
238
        }
239
240 10
        return $result;
241
    }
242
243 11
    private function renderBodyEnd(): string
244
    {
245 11
        return $this->body;
246
    }
247
248 10
    private function renderCloseButton(): ?string
249
    {
250 10
        if ($this->withoutCloseButton === true) {
251 1
            return null;
252
        }
253
254 9
        $spanOptions = ['aria-hidden' => 'true', 'encode' => false];
255 9
        $tag = ArrayHelper::remove($this->closeButtonOptions, 'tag', 'button');
256 9
        $label = ArrayHelper::remove(
257 9
            $this->closeButtonOptions,
258 9
            'label',
259 9
            Html::tag('span', '&times;', $spanOptions)
260
        );
261
262 9
        if ($tag === 'button') {
263 9
            $this->closeButtonOptions['type'] = 'button';
264
        }
265
266 9
        if ($this->size !== '') {
267 1
            Html::addCssClass($this->closeButtonOptions, $this->size);
268
        }
269
270 9
        return Html::tag($tag, $label, $this->closeButtonOptions);
271
    }
272
}
273