Passed
Push — master ( 9e997b...1490b2 )
by Rustam
02:32
created

Block::render()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 0
dl 0
loc 18
ccs 9
cts 9
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\Widgets;
6
7
use RuntimeException;
8
use Yiisoft\View\WebView;
9
use Yiisoft\Widget\Widget;
10
11
use function ob_end_clean;
12
use function ob_get_clean;
13
use function ob_start;
14
15
/**
16
 * Block records all output between {@see Widget::begin()} and {@see Widget::end()} calls and stores it in.
17
 *
18
 * The general idea is that you're defining block default in a view or layout:
19
 *
20
 * ```php
21
 * <?php Block::widget()
22
 *     ->id('my-block')
23
 *     ->begin() ?>
24
 *     Nothing.
25
 * <?php Block::end() ?>
26
 * ```
27
 *
28
 * And then overriding default in views:
29
 *
30
 * ```php
31
 * <?php Block::widget()
32
 *     ->id('my-block')
33
 *     ->begin() ?>
34
 *     Umm... hello?
35
 * <?php Block::end() ?>
36
 * ```
37
 *
38
 * in subviews show block:
39
 *
40
 * ```php
41
 * <?= $this->getBlock('my-block') ?>
42
 * ```
43
 */
44
final class Block extends Widget
45
{
46
    private string $id = '';
47 4
    private bool $renderInPlace = false;
48
49 4
    public function __construct(private WebView $webView)
50
    {
51
    }
52
53
    /**
54
     * Starts recording a block.
55
     */
56
    public function begin(): string|null
57
    {
58
        parent::begin();
59 3
60
        ob_start();
61 3
62 3
        return null;
63 3
    }
64
65
    /**
66
     * Returns a new instance with the specified Widget ID.
67
     *
68
     * @param string $value The Widget ID.
69
     */
70
    public function id(string $value): self
71
    {
72
        $new = clone $this;
73 2
        $new->id = $value;
74
75 2
        return $new;
76 2
    }
77 2
78
    /**
79
     * Enables in-place rendering and returns a new instance.
80
     *
81
     * Without calling this method, the captured content of the block is not displayed.
82
     */
83 3
    public function renderInPlace(): self
84
    {
85 3
        $new = clone $this;
86 3
        $new->renderInPlace = true;
87
88 3
        return $new;
89 3
    }
90
91
    /**
92
     * Ends recording a block.
93
     *
94
     * This method stops output buffering and saves the rendering result as a named block in the view.
95
     *
96
     * @return string The result of widget execution to be outputted.
97
     */
98
    public function render(): string
99 3
    {
100
        if ($this->id === '') {
101 3
            ob_end_clean();
102 1
            throw new RuntimeException('You must assign the "id" using the "id()" setter.');
103 1
        }
104
105
        $block = ob_get_clean();
106 2
107
        if ($this->renderInPlace) {
108 2
            return $block;
109 1
        }
110
111
        if (!empty($block)) {
112 1
            $this->webView->setBlock($this->id, $block);
113 1
        }
114
115
        return '';
116 1
    }
117
}
118