Passed
Push — main ( 1402e3...cedac2 )
by Thierry
18:03
created

HtmlBuilder::endShorted()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
c 0
b 0
f 0
nc 2
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
/*
4
 * This file is part of the PhpHtmlBuilder package.
5
 *
6
 * (c) Andrew Polupanov <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Lagdo\UiBuilder\Html\Support;
13
14
use AvpLab\Element\Comment;
15
use AvpLab\Element\Element;
16
use AvpLab\Element\Text;
17
use LogicException;
18
use RuntimeException;
19
20
use function strtolower;
21
use function preg_replace;
22
use function stripos;
23
use function substr;
24
use function implode;
25
26
/**
27
 * Provides API for easy building of HTML code in php
28
 */
29
class HtmlBuilder
30
{
31
    /**
32
     * @var Element[]
33
     */
34
    protected $elements = [];
35
36
    /**
37
     * @var Scope
38
     */
39
    protected $scope = null;
40
41
    /**
42
     * @param string $method
43
     * @param array $arguments
44
     * @return void
45
     * @throws LogicException When element is not initialized yet
46
     */
47
    public function __call(string $method, array $arguments)
48
    {
49
        $tagName = strtolower(preg_replace('/(?<!^)([A-Z])/', '-$1', $method));
50
        if (stripos($tagName, 'set-') === 0) {
51
            if ($this->scope === null) {
52
                throw new LogicException('Attributes can be set for elements only');
53
            }
54
            $this->scope->attributes[substr($tagName, 4)] = isset($arguments[0]) ? $arguments[0] : null;
55
            return;
56
        }
57
        $this->createScope($tagName, $arguments);
58
    }
59
60
    /**
61
     * @return void
62
     */
63
    public function clear()
64
    {
65
        $this->elements = [];
66
        $this->scope = null;
67
    }
68
69
    /**
70
     * @param string $name
71
     * @param array $arguments
72
     * @return void
73
     */
74
    protected function createScope(string $name, array $arguments = [])
75
    {
76
        $this->scope = new Scope($name, $arguments, $this->scope);
77
    }
78
79
    /**
80
     * @param Element $element
81
     * @return void
82
     */
83
    protected function addElementToScope(Element $element)
84
    {
85
        if ($this->scope === null) {
86
            $this->elements[] = $element;
87
            return;
88
        }
89
        $this->scope->elements[] = $element;
90
    }
91
92
    /**
93
     * @param string $name
94
     * @return void
95
     */
96
    public function tag(string $name, ...$arguments)
97
    {
98
        $this->createScope($name, $arguments);
99
    }
100
101
    /**
102
     * @param string $text
103
     * @return void
104
     */
105
    public function addText(string $text)
106
    {
107
        $this->addElementToScope(new Text($text));
108
    }
109
110
    /**
111
     * @param string $html
112
     * @return void
113
     */
114
    public function addHtml(string $html)
115
    {
116
        $this->addElementToScope(new Text($html, false));
117
    }
118
119
    /**
120
     * @param string $comment
121
     * @return void
122
     */
123
    public function addComment($comment)
124
    {
125
        $this->addElementToScope(new Comment($comment));
126
    }
127
128
    /**
129
     * @return void
130
     * @throws RuntimeException When element is not initialized yet.
131
     */
132
    public function end()
133
    {
134
        if ($this->scope === null) {
135
            throw new RuntimeException('Abnormal element completion');
136
        }
137
        $element = new Tag($this->scope->name, $this->scope, $this->scope->elements);
138
        $this->scope = $this->scope->parent;
139
        $this->addElementToScope($element);
140
    }
141
142
    /**
143
     * @return void
144
     * @throws RuntimeException When element is not initialized yet.
145
     */
146
    public function endShorted()
147
    {
148
        if ($this->scope === null) {
149
            throw new RuntimeException('Abnormal element completion');
150
        }
151
        $element = new Tag($this->scope->name, $this->scope);
152
        $element->setShort(true);
153
        $this->scope = $this->scope->parent;
154
        $this->addElementToScope($element);
155
    }
156
157
    /**
158
     * @return void
159
     * @throws RuntimeException When element is not initialized yet.
160
     */
161
    public function endOpened()
162
    {
163
        if ($this->scope === null) {
164
            throw new RuntimeException('Abnormal element completion');
165
        }
166
        $element = new Tag($this->scope->name, $this->scope);
167
        $element->setOpened(true);
168
        $this->scope = $this->scope->parent;
169
        $this->addElementToScope($element);
170
    }
171
172
    /**
173
     * @return string
174
     */
175
    public function build(): string
176
    {
177
        return implode('', $this->elements);
178
    }
179
}
180