Completed
Push — master ( 0b8712...2f8bc7 )
by Mihail
04:21
created

Dom::__call()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

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