Passed
Branch master (cbf361)
by Mihail
04:19
created

Dom   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 121
rs 10
c 0
b 0
f 0
wmc 18

6 Methods

Rating   Name   Duplication   Size   Complexity  
A buildTag() 0 11 3
A __isset() 0 3 1
B applyProperties() 0 21 7
A __get() 0 3 1
A __set() 0 3 1
B __call() 0 16 5
1
<?php
2
3
namespace Ffcms\Core\Helper\HTML\System;
4
5
use Ffcms\Core\Helper\Type\Arr;
6
7
/**
8
 * Class Dom - build html DOM structure based on anonymous callbacks
9
 * @package Ffcms\Core\Helper\HTML
10
 * @method string hr(\Closure $obj, array $properties = null)
11
 * @method string br(\Closure $obj, array $properties = null)
12
 * @method string img(\Closure $obj, array $properties = null)
13
 * @method string input(\Closure $obj, array $properties = null)
14
 * @method string article(\Closure $obj, array $properties = null)
15
 * @method string nav(\Closure $obj, array $properties = null)
16
 * @method string div(\Closure $obj, array $properties = null)
17
 * @method string p(\Closure $obj, array $properties = null)
18
 * @method string a(\Closure $obj, array $properties = null)
19
 * @method string b(\Closure $obj, array $properties = null)
20
 * @method string s(\Closure $obj, array $properties = null)
21
 * @method string strong(\Closure $obj, array $properties = null)
22
 * @method string strike(\Closure $obj, array $properties = null)
23
 * @method string u(\Closure $obj, array $properties = null)
24
 * @method string span(\Closure $obj, array $properties = null)
25
 * @method string ul(\Closure $obj, array $properties = null)
26
 * @method string ol(\Closure $obj, array $properties = null)
27
 * @method string li(\Closure $obj, array $properties = null)
28
 * @method string table(\Closure $obj, array $properties = null)
29
 * @method string thead(\Closure $obj, array $properties = null)
30
 * @method string tbody(\Closure $obj, array $properties = null)
31
 * @method string tr(\Closure $obj, array $properties = null)
32
 * @method string td(\Closure $obj, array $properties = null)
33
 * @method string th(\Closure $obj, array $properties = null)
34
 * @method string dt(\Closure $obj, array $properties = null)
35
 * @method string dd(\Closure $obj, array $properties = null)
36
 * @method string form(\Closure $obj, array $properties = null)
37
 * @method string label(\Closure $obj, array $properties = null)
38
 * @method string button(\Closure $obj, array $properties = null)
39
 */
40
class Dom
41
{
42
    // single standalone tags
43
    public static $singleTags = [
44
        'hr', 'br', 'img', 'input'
45
    ];
46
47
    // container tags
48
    public static $containerTags = [
49
        'article', 'nav',
50
        'div', 'p', 'a',
51
        'b', 's', 'strong', 'strike', 'u', 'span',
52
        'ul', 'ol', 'li',
53
        'table', 'thead', 'tbody', 'tr', 'td', 'th', 'dt', 'dd',
54
        'form', 'label',
55
        'button'
56
    ];
57
58
    // private variables storage
59
    private $_vars = [];
60
61
    /**
62
     * Catch all callbacks
63
     * @param $name
64
     * @param $arguments
65
     * @return null|string
66
     */
67
    public function __call($name, $arguments)
68
    {
69
        $content = null;
70
        $properties = null;
71
        // get closure anonymous function and call it
72
        if (isset($arguments[0]) && $arguments[0] instanceof \Closure) {
73
            $closure = array_shift($arguments);
74
            $content = call_user_func_array($closure, $arguments);
75
        }
76
        // get properties for current lvl
77
        if (isset($arguments[0]) && is_array($arguments[0])) {
78
            $properties = $arguments[0];
79
        }
80
81
        // build tag output html
82
        return $this->buildTag($name, $content, $properties);
83
    }
84
85
    /**
86
     * Build output content by tag name, tag content and properties
87
     * @param string $name
88
     * @param string|null $content
89
     * @param array|null $properties
90
     * @return null|string
91
     */
92
    private function buildTag($name, $content = null, array $properties = null)
93
    {
94
        // looks like a single tag, <img src="" class="" />, <hr class="" />
95
        if (Arr::in($name, self::$singleTags)) {
96
            return '<' . $name . self::applyProperties($properties) . ' />';
97
        } elseif (Arr::in($name, self::$containerTags)) { // looks like a container tag, <div class=""></div>
98
            return '<' . $name . self::applyProperties($properties) . '>' . $content . '</' . $name . '>';
99
        }
100
101
        // empty response
102
        return null;
103
    }
104
105
    /**
106
     * Parse properties from array to html string
107
     * @param array|null $properties
108
     * @return null|string
109
     */
110
    public static function applyProperties(array $properties = null)
111
    {
112
        // if looks like nothing - return
113
        if ($properties === null || count($properties) < 1) {
114
            return null;
115
        }
116
117
        // build output string
118
        $build = null;
119
        foreach ($properties as $property => $value) {
120
            if (!is_string($property)) {
121
                continue;
122
            }
123
            // sounds like single standalone property, ex required, selected etc
124
            if ($value === null || $value === false) {
125
                $build .= ' ' . htmlentities($property, ENT_QUOTES, "UTF-8");
126
            } else { // sounds like a classic key="value" property
127
                $build .= ' ' . htmlentities($property, ENT_QUOTES, "UTF-8") . '="' . htmlentities($value, ENT_QUOTES, "UTF-8") . '"';
128
            }
129
        }
130
        return $build;
131
    }
132
133
    /**
134
     * Variable magic set
135
     * @param string $name
136
     * @param string $value
137
     */
138
    public function __set($name, $value)
139
    {
140
        $this->_vars[$name] = $value;
141
    }
142
143
    /**
144
     * Variable magic get
145
     * @param string $name
146
     * @return mixed
147
     */
148
    public function __get($name)
149
    {
150
        return $this->_vars[$name];
151
    }
152
153
    /**
154
     * Check dynamic binded variable isset. Required for php 7.0.6 and highter
155
     * @param string $name
156
     * @return bool
157
     */
158
    public function __isset($name)
159
    {
160
        return array_key_exists($name, $this->_vars);
161
    }
162
}
163