Passed
Push — main ( f51ec7...6cfe97 )
by Sammy
01:30
created

Element::__callStatic()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 8
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace HexMakina\Marker;
5
6
class Element
7
{
8
    /**
9
     * @var string[]
10
     */
11
    public const VOID_ELEMENTS = [
12
      'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
13
      'link', 'meta', 'param', 'source', 'track', 'wbr'
14
    ];
15
16
    /**
17
     * @var string
18
     */
19
    public const FORMAT_VOID = '<%s%s/>';
20
21
    /**
22
     * @var string
23
     */
24
    public const FORMAT_ELEMENT = '<%s%s>%s</%s>';
25
26
    /**
27
     * @var string
28
     */
29
    public const FORMAT_ATTRIBUTES = '%s="%s"';
30
31
32
    protected string $tag;
33
34
    protected array $attributes;
35
36
    protected string $content;
37
38
39
    /**
40
     * ::span('inner text', ['class' => 'd-block'])
41
     * ::p('lorem ipsum')
42
     * ::img('alternative text', ['src' => 'path/to/img', 'width' => 100, 'height'=>100])
43
     * ::a('click here', ['href' => 'url/to/destination', 'class' => 'nav-link'])
44
     * ::a('anchor title', ['name' => 'anchor_name'])
45
     *
46
     * @param mixed[] $arguments
47
     */
48
    public static function __callStatic(string $tag, array $arguments): Element
49
    {
50
        // first argument is the inner text
51
        $inner_text = $arguments[0] ?? null;
52
        // second argument, an array for HTML attributes
53
        $attributes = $arguments[1] ?? [];
54
55
        return new Element($tag, $inner_text, $attributes);
56
    }
57
58
    /**
59
     * @param mixed[] $attributes
60
     */
61
    public function __construct(string $tag, string $content = null, array $attributes = [])
62
    {
63
        $this->tag = $tag;
64
        $this->content = $content ?? '';
65
        $this->attributes = $attributes;
66
    }
67
68
    public function __toString(): string
69
    {
70
        $attributes = self::attributesAsString($this->attributes);
71
72
        if ($this->isVoid()) {
73
            return sprintf(
74
                self::FORMAT_VOID,
75
                $this->tag,
76
                $attributes,
77
            );
78
        }
79
80
        return sprintf(
81
            self::FORMAT_ELEMENT,
82
            $this->tag,
83
            $attributes,
84
            $this->content,
85
            $this->tag
86
        );
87
    }
88
89
    public function isVoid(): bool
90
    {
91
        return in_array($this->tag, self::VOID_ELEMENTS);
92
    }
93
94
95
    private static function isBooleanAttribute($k): bool
96
    {
97
        return is_int($k);
98
    }
99
100
    private static function isValidValue($v): bool
101
    {
102
        return !is_null($v) && $v != '' && !is_array($v);
103
    }
104
105
    public static function attributesAsString(array $attributes = []): string
106
    {
107
        $ret = '';
108
        foreach ($attributes as $k => $v) {
109
            if (self::isValidValue($v)) {
110
                $ret .=  ' ' . (self::isBooleanAttribute($k) ? $v : sprintf(self::FORMAT_ATTRIBUTES, $k, $v));
111
            }
112
        }
113
114
        return $ret;
115
    }
116
}
117