ElementConstructorTrait::renderAttribute()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace WebTheory\Html\Traits;
4
5
use WebTheory\Html\Contracts\HtmlAttributeInterface;
6
use WebTheory\Html\TagSage;
7
8
trait ElementConstructorTrait
9
{
10
    protected static function parseAttributes(array $attributes): string
11
    {
12
        return static::parseAttributesRealSwitch($attributes);
13
    }
14
15
    protected static function parseAttributesReal(array $attrArr, string &$attrStr = ''): string
16
    {
17
        foreach ($attrArr as $attr => $val) {
18
19
            // don't add empty strings or null values
20
            if ('' === $val && 'value' !== $attr || null === $val) {
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: ('' === $val && 'value' ...$attr) || null === $val, Probably Intended Meaning: '' === $val && ('value' ...$attr || null === $val)
Loading history...
21
                continue;
22
            }
23
24
            // treat numerical keys as boolean values
25
            if (is_int($attr)) {
26
                $attrStr .= static::renderAttribute($val, (string) $val);
27
28
                continue;
29
            }
30
31
            // simple attribute
32
            if (is_string($val) || is_numeric($val)) {
33
                $attrStr .= static::renderAttribute($attr, $val);
34
35
                continue;
36
            }
37
38
            // support interface for defining custom parsing schemes
39
            if ($val instanceof HtmlAttributeInterface) {
40
                $attrStr .= static::renderAttribute($attr, $val->parse());
41
42
                continue;
43
            }
44
45
            // boolean attribute
46
            if ($val === true) {
47
                $attrStr .= static::renderAttribute($attr, $attr);
48
49
                continue;
50
            }
51
52
            // support for passing an array of boolean values
53
            if ('@boolean' === $attr) {
54
                foreach ((array) $val as $bool) {
55
                    $attrStr .= static::renderAttribute($bool, $bool);
56
                }
57
58
                continue;
59
            }
60
61
            // support for converting indexed array to DOMTokenList
62
            if (is_array($val) && isset($val[0])) {
63
                $val = implode(' ', array_filter($val));
64
                $attrStr .= static::renderAttribute($attr, $val);
65
66
                continue;
67
            }
68
69
            // support for converting associative array to DOMStringMap
70
            if (is_array($val)) {
71
                foreach ($val as $set => $setval) {
72
                    static::parseAttributesReal(["{$attr}-{$set}" => $setval], $attrStr);
73
                }
74
75
                continue;
76
            }
77
        }
78
79
        return $attrStr;
80
    }
81
82
    protected static function parseAttributesRealSwitch(array $attrArr, string &$attrStr = ''): string
83
    {
84
        foreach ($attrArr as $attr => $val) {
85
            switch (true) {
86
                    // don't add empty strings or null values
87
                case ('' === $val && 'value' !== $attr || null === $val):
88
                    break;
89
90
                    // treat numerical keys as boolean values
91
                case (is_int($attr)):
92
                    $attrStr .= static::renderAttribute($val, (string) $val);
93
94
                    break;
95
96
                    // simple attribute
97
                case (is_string($val) || is_numeric($val)):
98
                    $attrStr .= static::renderAttribute($attr, $val);
99
100
                    break;
101
102
                    // support interface for defining custom parsing schemes
103
                case ($val instanceof HtmlAttributeInterface):
104
                    $attrStr .= static::renderAttribute($attr, $val->parse());
105
106
                    break;
107
108
                    // boolean attribute
109
                case ($val === true):
110
                    $attrStr .= static::renderAttribute($attr, $attr);
111
112
                    break;
113
114
                    // support for passing an array of boolean values
115
                case ('@bool' === $attr):
116
                    foreach ((array) $val as $bool) {
117
                        $attrStr .= static::renderAttribute($bool, $bool);
118
                    }
119
120
                    break;
121
122
                    // support for converting indexed array to DOMTokenList
123
                case (is_array($val) && isset($val[0])):
124
                    $val = implode(' ', array_filter($val));
125
                    $attrStr .= static::renderAttribute($attr, $val);
126
127
                    break;
128
129
                    // support for converting associative array to DOMStringMap
130
                case (is_array($val)):
131
                    foreach ($val as $set => $setval) {
132
                        static::parseAttributesRealSwitch(["{$attr}-{$set}" => $setval], $attrStr);
133
                    }
134
135
                    break;
136
            }
137
        }
138
139
        return $attrStr;
140
    }
141
142
    protected static function renderAttribute(string $attribute, string $value): string
143
    {
144
        $value = static::escapeAttribute($value);
145
146
        return " {$attribute}=\"{$value}\"";
147
    }
148
149
    protected static function escapeAttribute(string $attribute): string
150
    {
151
        return htmlspecialchars($attribute);
152
    }
153
154
    protected static function tag(string $tag, array $attributes = [], string $inner = ''): string
155
    {
156
        return static::open($tag, $attributes) . static::maybeClose($tag, $inner);
157
    }
158
159
    protected static function open(string $tag, array $attributes = []): string
160
    {
161
        $attributes = static::maybeParseAttributes($attributes);
162
        $slash = static::maybeAddSlash($tag);
163
164
        return "<{$tag}{$attributes}{$slash}>";
165
    }
166
167
    protected static function close(string $tag): string
168
    {
169
        return "</{$tag}>";
170
    }
171
172
    protected static function maybeClose(string $tag, string $inner = ''): string
173
    {
174
        return static::tagIsVoid($tag) ? '' : $inner . static::close($tag);
175
    }
176
177
    protected static function maybeParseAttributes(array $attributes): string
178
    {
179
        return empty($attributes) ? '' : static::parseAttributes($attributes);
180
    }
181
182
    protected static function maybeAddSlash(string $tag): string
183
    {
184
        return static::tagIsVoid($tag) ? ' /' : '';
185
    }
186
187
    protected static function tagIsVoid(string $tag): bool
188
    {
189
        return TagSage::isIt('self_closing', $tag);
190
    }
191
192
    protected static function indent(int $levels = 0): string
193
    {
194
        return str_repeat('&nbsp;', $levels);
195
    }
196
197
    protected static function newLine(bool $newLine = false): string
198
    {
199
        return $newLine ? "\n" : '';
200
    }
201
}
202