Completed
Push — master ( 43a266...382a9d )
by Cheren
07:50
created

Html::_()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 30
rs 8.5806
cc 4
eloc 19
nc 4
nop 1
1
<?php
2
/**
3
 * CakeCMS Core
4
 *
5
 * This file is part of the of the simple cms based on CakePHP 3.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @package   Core
10
 * @license   MIT
11
 * @copyright MIT License http://www.opensource.org/licenses/mit-license.php
12
 * @link      https://github.com/CakeCMS/Core".
13
 * @author    Sergey Kalistratov <[email protected]>
14
 */
15
16
namespace Core\Html;
17
18
use JBZoo\Utils\Arr;
19
use JBZoo\Utils\Str;
20
21
/**
22
 * Class Html
23
 *
24
 * @package Core\Html
25
 */
26
class Html
27
{
28
29
    /**
30
     * An array to hold namespaces.
31
     *
32
     * @var array
33
     */
34
    protected static $_namespaces = [];
35
36
    /**
37
     * An array to hold method references.
38
     *
39
     * @var array
40
     */
41
    protected static $_registry = [];
42
43
    /**
44
     * Class loader method.
45
     *
46
     * @param string $key The name of helper method to load, (prefix).(class).function.
47
     * @return mixed Result of JHtml::call($function, $args)
48
     */
49
    public static function _($key)
50
    {
51
        list($key, $prefix, $file, $func) = static::_extract($key);
52
53
        if (Arr::key($key, self::$_registry)) {
54
            $function = static::$_registry[$key];
55
            $args = func_get_args();
56
            // Remove function name from arguments
57
            array_shift($args);
58
            return static::_call($function, $args);
59
        }
60
61
        $className     = $prefix . ucfirst($file);
62
        $fullClassName = self::_classExists($className);
63
64
        if ($fullClassName === false) {
65
            throw new \InvalidArgumentException(sprintf('%s not found.', $className));
66
        }
67
68
        $toCall = [$fullClassName, $func];
69
        if (is_callable($toCall)) {
70
            static::register($key, $toCall);
0 ignored issues
show
Documentation introduced by
$toCall is of type array<integer,?,{"0":"string","1":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
71
            $args = func_get_args();
72
            // Remove function name from arguments
73
            array_shift($args);
74
            return static::_call($toCall, $args);
75
        } else {
76
            throw new \InvalidArgumentException(sprintf('%s::%s not found.', $className, $func), 500);
77
        }
78
    }
79
80
    /**
81
     * Add namespaces list.
82
     *
83
     * @param string $namespace
84
     * @return void
85
     */
86
    public static function addNameSpace($namespace)
87
    {
88
        array_push(self::$_namespaces, $namespace);
89
    }
90
91
    /**
92
     * Clean registered namespaces.
93
     *
94
     * @return void
95
     */
96
    public static function clean()
97
    {
98
        self::$_namespaces = [];
99
    }
100
101
    /**
102
     * Get namespaces list.
103
     *
104
     * @return array
105
     */
106
    public static function getNameSpaces()
107
    {
108
        return self::$_namespaces;
109
    }
110
111
    /**
112
     * Registers a function to be called with a specific key.
113
     *
114
     * @param string $key
115
     * @param string $function Function or method
116
     * @return bool
117
     */
118 View Code Duplication
    public static function register($key, $function)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
119
    {
120
        list($key) = static::_extract($key);
121
        if (is_callable($function)) {
122
            static::$_registry[$key] = $function;
123
            return true;
124
        }
125
126
        return false;
127
    }
128
129
    /**
130
     * Removes a key for a method from registry.
131
     *
132
     * @param string $key  The name of the key
133
     * @return boolean True if a set key is unset
134
     */
135 View Code Duplication
    public static function unRegister($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
136
    {
137
        list($key) = static::_extract($key);
138
        if (isset(static::$_registry[$key])) {
139
            unset(static::$_registry[$key]);
140
            return true;
141
        }
142
143
        return false;
144
    }
145
146
    /**
147
     * Function caller method.
148
     *
149
     * @param callable $function Function or method to call
150
     * @param array $args Arguments to be passed to function
151
     * @return mixed Function result or false on error.
152
     * @see https://secure.php.net/manual/en/function.call-user-func-array.php
153
     * @throws \InvalidArgumentException
154
     */
155
    protected static function _call($function, $args)
156
    {
157
        // PHP 5.3 workaround
158
        $temp = [];
159
        foreach ($args as &$arg) {
160
            $temp[] = &$arg;
161
        }
162
163
        return call_user_func_array($function, $temp);
164
    }
165
166
    /**
167
     * Check html class exists.
168
     *
169
     * @param string $className
170
     * @return bool
171
     */
172
    protected function _classExists($className)
173
    {
174
        $namespaces = self::$_namespaces;
175
        array_push($namespaces, __NAMESPACE__);
176
        foreach ($namespaces as $namespace) {
177
            $className = $namespace . '\\' . $className;
178
            if (class_exists($className)) {
179
                return $className;
180
            }
181
        }
182
183
        return false;
184
    }
185
186
    /**
187
     * Method to extract a key.
188
     *
189
     * @param string $key The name of helper method to load, (prefix).(class).function
190
     * prefix and class are optional and can be used to load custom html helpers.
191
     * @return array
192
     */
193
    protected static function _extract($key)
194
    {
195
        $key = preg_replace('#[^A-Z0-9_\.]#i', '', $key);
196
        $details = explode('.', $key);
197
198
        $prefix = (count($details) == 3 ? array_shift($details) : 'Html');
199
        $file   = (count($details) == 2 ? array_shift($details) : '');
200
        $func   = array_shift($details);
201
202
        return [Str::low($prefix . '.' . $file . '.' . $func), $prefix, $file, $func];
203
    }
204
}
205