Passed
Push — main ( 7f60ea...60225c )
by Thierry
08:29
created

ElementBlock::renderAttributes()   B

Complexity

Conditions 7
Paths 20

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
c 0
b 0
f 0
dl 0
loc 26
rs 8.8333
cc 7
nc 20
nop 0
1
<?php
2
3
namespace Lagdo\UiBuilder\Builder\Html;
4
5
use AvpLab\Element\Element as Block;
6
7
use function array_merge;
8
use function htmlspecialchars;
9
use function implode;
10
use function is_numeric;
11
use function sprintf;
12
13
class ElementBlock extends Block
14
{
15
    /**
16
     * @var Element
17
     */
18
    private $element;
19
20
    /**
21
     * @var bool
22
     */
23
    private $isShort = false;
24
25
    /**
26
     * @var bool
27
     */
28
    private $isOpened = false;
29
30
    /**
31
     * @var Block[]
32
     */
33
    private $children = [];
34
35
    /**
36
     * @param Element $element
37
     * @param Block[] $children
38
     */
39
    public function __construct(Element $element, array $children = [])
40
    {
41
        $this->element = $element;
42
        $this->setChildren($children);
43
    }
44
45
    /**
46
     * @param Block[] $children
47
     */
48
    public function setChildren(array $children)
49
    {
50
        $this->children = array_merge($this->children, $children);
51
    }
52
53
    /**
54
     * @param bool $isShort
55
     */
56
    public function setShort($isShort)
57
    {
58
        $this->isShort = $isShort;
59
    }
60
61
    /**
62
     * @param bool $isOpened
63
     */
64
    public function setOpened($isOpened)
65
    {
66
        $this->isOpened = $isOpened;
67
    }
68
69
    /**
70
     * [@inheritdoc}
71
     */
72
    protected function render()
73
    {
74
        return match(true) {
75
            $this->isShort => $this->renderShort(),
76
            $this->isOpened => $this->renderOpened(),
77
            default => $this->renderTag(),
78
        };
79
    }
80
81
    /**
82
     * @return string
83
     */
84
    private function renderAttributes()
85
    {
86
        // Merge the classes.
87
        $classes = $this->element->classes;
88
        $classes[0] = implode(' ', $classes[0]);
89
        if (isset($this->element->attributes['class'])) {
90
            $classes[] = $this->element->attributes['class'];
91
        }
92
        $this->element->attributes['class'] = trim(implode(' ', $classes));
93
94
        $attributes = [];
95
        foreach ($this->element->attributes as $name => $value) {
96
            if (is_numeric($name)) {
97
                $attributes[] = $this->escape($value);
98
                continue;
99
            }
100
            if ($value === '') {
101
                continue;
102
            }
103
104
            if (($this->element->escapes[$name] ?? true) === true) {
105
                $value = $this->escape($value);
106
            }
107
            $attributes[] = sprintf('%s="%s"', $this->escape($name), $value);
108
        }
109
        return !$attributes ? '' : ' ' . implode(' ', $attributes);
110
    }
111
112
    /**
113
     * @return string
114
     */
115
    private function renderShort()
116
    {
117
        return sprintf('<%s%s />', $this->element->name, $this->renderAttributes());
118
    }
119
120
    /**
121
     * @return string
122
     */
123
    private function renderOpened()
124
    {
125
        return sprintf('<%s%s>', $this->element->name, $this->renderAttributes());
126
    }
127
128
    /**
129
     * @return string
130
     */
131
    private function renderTag()
132
    {
133
        $children = '';
134
        foreach ($this->children as $child) {
135
            $children .= $child;
136
        }
137
        return sprintf('%s%s</%s>', $this->renderOpened(),
138
            $children, $this->element->name);
139
    }
140
141
    /**
142
     * Helper for escaping
143
     *
144
     * @param $value
145
     * @return string
146
     */
147
    private function escape($value)
148
    {
149
        return htmlspecialchars($value, ENT_COMPAT);
150
    }
151
}
152