Passed
Push — master ( ffff93...b22ebb )
by Chris
15:20
created

ElementConstructorTrait::resolvesToAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 1
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
namespace WebTheory\Html\Traits;
4
5
use WebTheory\Html\Contracts\HtmlAttributeInterface;
6
use WebTheory\Html\TagSage;
7
8
/**
9
 *
10
 */
11
trait ElementConstructorTrait
12
{
13
    /**
14
     *
15
     */
16
    protected static function parseAttributes($attributesArray, $options)
17
    {
18
        return static::_parseAttributes($attributesArray, $options);
19
    }
20
21
    /**
22
     *
23
     */
24
    private static function _parseAttributes($attributesArray, $options, &$attrStr = '')
25
    {
26
        foreach ($attributesArray as $attr => $val) {
27
28
            // don't add empty strings or null values
29
            if ('' === $val || null === $val) {
30
                continue;
31
            }
32
33
            // simple attribute
34
            if (is_string($val) || is_numeric($val)) {
35
                $attrStr .= static::attribute($attr, $val, true, $options);
36
                continue;
37
            }
38
39
            // support interface for defining custom parsing schemes
40
            if ($val instanceof HtmlAttributeInterface) {
41
                $attrStr .= static::attribute($attr, $val->parse(), true, $options);
42
                continue;
43
            }
44
45
            // boolean attribute
46
            if ($val === true) {
47
                $attrStr .= static::attribute($attr, $attr, true, $options);
48
                continue;
49
            }
50
51
            // treat numerical keys as boolean values
52
            if (is_int($attr)) {
53
                $attrStr .= static::attribute($val, $val, true, $options);
54
                continue;
55
            }
56
57
            // support for passing an array of boolean values
58
            if ('@boolean' === $attr) {
59
                foreach ((array) $val as $bool) {
60
                    $attrStr .= static::attribute($bool, $bool, true, $options);
61
                }
62
                continue;
63
            }
64
65
            // support for converting indexed array to DOMTokenList
66
            if (is_array($val) && isset($val[0])) {
67
                $val = implode(' ', array_filter($val));
68
                $attrStr .= static::attribute($attr, $val, true, $options);
69
                continue;
70
            }
71
72
            // support for converting associative array to DOMStringMap
73
            if (is_array($val)) {
74
                foreach ($val as $set => $setval) {
75
                    static::_parseAttributes(["{$attr}-{$set}" => $setval], $options, $attrStr);
76
                }
77
                continue;
78
            }
79
        }
80
81
        return ltrim(($attrStr));
82
    }
83
84
    /**
85
     *
86
     */
87
    protected static function attribute($attribute, $value, $space = false, $options = [])
88
    {
89
        $space = $space ? ' ' : '';
90
91
        $flags = $options['flags'] ?? null;
92
        $encode = $options['encoding'] ?? null;
93
94
        $value = htmlspecialchars($value, $flags, $encode, false);
95
96
        return "{$space}{$attribute}=\"{$value}\"";
97
    }
98
99
    /**
100
     *
101
     */
102
    protected static function open(string $tag, $attributes = null, $options = [])
103
    {
104
        $attributes = isset($attributes) ? ' ' . static::parseAttributes($attributes, $options) : '';
105
106
        $newLine = static::newLine($options['new_line'] ?? false);
107
        $indentation = static::indentation($options['indentation'] ?? 0);
108
        $slash = static::indentation($options['trailing_slash'] ?? false, $tag);
0 ignored issues
show
Unused Code introduced by
The call to WebTheory\Html\Traits\El...torTrait::indentation() has too many arguments starting with $tag. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
        /** @scrutinizer ignore-call */ 
109
        $slash = static::indentation($options['trailing_slash'] ?? false, $tag);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
It seems like $options['trailing_slash'] ?? false can also be of type false; however, parameter $levels of WebTheory\Html\Traits\El...torTrait::indentation() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

108
        $slash = static::indentation(/** @scrutinizer ignore-type */ $options['trailing_slash'] ?? false, $tag);
Loading history...
109
110
        return "{$indentation}<{$tag}{$attributes}{$slash}>{$newLine}";
111
    }
112
113
    /**
114
     *
115
     */
116
    protected static function close(string $tag, $options = [])
117
    {
118
        if (TagSage::isIt('self_closing', $tag)) {
119
            return '';
120
        }
121
122
        $indentation = static::indentation($options['indentation'] ?? 0);
123
124
        return "{$indentation}</{$tag}>";
125
    }
126
127
    /**
128
     *
129
     */
130
    protected static function tag(string $tag, ?string $content = '', $attributes = null, $options = [])
131
    {
132
        return static::open($tag, $attributes, $options) . $content . static::close($tag, $options);
133
    }
134
135
    /**
136
     *
137
     */
138
    protected static function trailingSlash(bool $addTrailingSlash, string $tag)
139
    {
140
        return $addTrailingSlash && TagSage::isIt('self_closing', $tag) ? ' /' : '';
141
    }
142
143
    /**
144
     *
145
     */
146
    protected static function indentation(int $levels)
147
    {
148
        $indentation = '';
149
150
        if ($levels > 0) {
151
            $indentation = str_repeat('&nbsp;', $levels);
152
        }
153
154
        return $indentation;
155
    }
156
157
    /**
158
     *
159
     */
160
    protected static function newLine(bool $newLine)
161
    {
162
        return true === $newLine ? "\n" : '';
163
    }
164
}
165