ElementConstructorTrait   B
last analyzed

Complexity

Total Complexity 48

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
eloc 73
dl 0
loc 192
ccs 0
cts 86
cp 0
rs 8.5599
c 5
b 1
f 0
wmc 48

14 Methods

Rating   Name   Duplication   Size   Complexity  
A renderAttribute() 0 5 1
A indent() 0 3 1
A open() 0 6 1
A maybeClose() 0 3 2
A escapeAttribute() 0 3 1
A tag() 0 3 1
A newLine() 0 3 2
A tagIsVoid() 0 3 1
A maybeParseAttributes() 0 3 2
A parseAttributes() 0 3 1
A close() 0 3 1
A maybeAddSlash() 0 3 2
C parseAttributesRealSwitch() 0 58 16
C parseAttributesReal() 0 65 16

How to fix   Complexity   

Complex Class

Complex classes like ElementConstructorTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ElementConstructorTrait, and based on these observations, apply Extract Interface, too.

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