Completed
Push — master ( 7b8908...ffc510 )
by Mihail
12:46
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
 */
17
class Dom
18
{
19
    // single standalone tags
20
    public static $singleTags = [
21
        'hr', 'br', 'img', 'input'
22
    ];
23
24
    // container tags
25
    public static $containerTags = [
26
        'article', 'nav',
27
        'div', 'p', 'a',
28
        'b', 's', 'strong', 'strike', 'u', 'span',
29
        'ul', 'ol', 'li',
30
        'table', 'thead', 'tbody', 'tr', 'td', 'th', 'dt', 'dd',
31
        'form', 'label'
32
    ];
33
34
    // private variables storage
35
    private $_vars;
36
37
    /**
38
     * Catch all callbacks
39
     * @param $name
40
     * @param $arguments
41
     * @return null|string
42
     */
43
    public function __call($name, $arguments)
44
    {
45
        $content = null;
46
        $properties = null;
47
        // get closure anonymous function and call it
48
        if (isset($arguments[0]) && $arguments[0] instanceof \Closure) {
49
            $closure = array_shift($arguments);
50
            $content = call_user_func_array($closure, $arguments);
51
        }
52
        // get properties for current lvl
53
        if (isset($arguments[0]) && is_array($arguments[0])) {
54
            $properties = $arguments[0];
55
        }
56
57
        // build tag output html
58
        return $this->buildTag($name, $content, $properties);
59
    }
60
61
    /**
62
     * Build output content by tag name, tag content and properties
63
     * @param string $name
64
     * @param string|null $content
65
     * @param array|null $properties
66
     * @return null|string
67
     */
68
    private function buildTag($name, $content = null, array $properties = null)
69
    {
70
        // looks like a single tag, <img src="" class="" />, <hr class="" />
71
        if (Arr::in($name, self::$singleTags)) {
72
            return '<' . $name . self::applyProperties($properties) . ' />';
73
        } elseif(Arr::in($name, self::$containerTags)) { // looks like a container tag, <div class=""></div>
74
            return '<' . $name . self::applyProperties($properties) . '>' . $content . '</' . $name . '>';
75
        }
76
77
        // empty response
78
        return null;
79
    }
80
81
    /**
82
     * Parse properties from array to html string
83
     * @param array|null $properties
84
     * @return null|string
85
     */
86
    public static function applyProperties(array $properties = null)
87
    {
88
        // if looks like nothing - return
89
        if ($properties === null || count($properties) < 1) {
90
            return null;
91
        }
92
93
        // build output string
94
        $build = null;
95
        foreach ($properties as $property => $value) {
96
            if (!is_string($property)) {
97
                continue;
98
            }
99
            // sounds like single standalone property, ex required, selected etc
100
            if ($value === null || $value === false) {
101
                $build .= ' ' . htmlentities($property, ENT_QUOTES);
102
            } else { // sounds like a classic key="value" property
103
                $build .= ' ' . htmlentities($property, ENT_QUOTES) . '="' . htmlentities($value, ENT_QUOTES) . '"';
104
            }
105
        }
106
        return $build;
107
    }
108
109
    /**
110
     * Variable magic set
111
     * @param string $name
112
     * @param string $value
113
     */
114
    public function __set($name, $value)
115
    {
116
        $this->_vars[$name] = $value;
117
    }
118
119
    /**
120
     * Variable magic get
121
     * @param string $name
122
     * @return mixed
123
     */
124
    public function __get($name)
125
    {
126
        return $this->_vars[$name];
127
    }
128
}