Completed
Pull Request — master (#393)
by Anton
04:44
created

Helper::addHelper()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4.0092

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 5
nop 2
dl 0
loc 22
ccs 11
cts 12
cp 0.9167
crap 4.0092
rs 8.9197
c 0
b 0
f 0
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link https://github.com/bluzphp/framework
7
 */
8
9
declare(strict_types=1);
10
11
namespace Bluz\Common;
12
13
use Bluz\Common\Exception\CommonException;
14
15
/**
16
 * Helper trait
17
 *
18
 * @package  Bluz\Common
19
 * @author   Anton Shevchuk
20
 * @link     https://github.com/bluzphp/framework/wiki/Trait-Helper
21
 */
22
trait Helper
23
{
24
    /**
25
     * @var array[] list of helpers
26
     */
27
    protected static $helpers = [];
28
29
    /**
30
     * @var array[] list of helpers paths
31
     */
32
    protected static $helpersPath = [];
33
34
    /**
35
     * Add helper callable
36
     *
37
     * @param  string $name
38
     * @param  string $path
39
     * @return void
40
     * @throws CommonException
41
     */
42 40
    private function addHelper(string $name, string $path)
43
    {
44 40
        $class = static::class;
45 40
        $path = realpath($path);
46
47 40
        if (false === $path) {
48
            throw new CommonException("Helper `$name` not found for class `$class`");
49
        }
50
51
        // create store of helpers
52 40
        if (!isset(static::$helpers[$class])) {
53 8
            static::$helpers[$class] = [];
54
        }
55
56 40
        $helper = include $path;
57
58 40
        if (is_callable($helper)) {
59 39
            static::$helpers[$class][$name] = $helper;
60
        } else {
61 1
            throw new CommonException("Helper `$name` not found in file `$path`");
62
        }
63 39
    }
64
65
    /**
66
     * Call helper
67
     *
68
     * @param string $name
69
     * @param array $arguments
70
     * @return mixed
71
     * @throws CommonException
72
     */
73 68
    private function callHelper(string $name, array $arguments)
74
    {
75 68
        $class = static::class;
76 68
        if (isset(static::$helpers[$class], static::$helpers[$class][$name])) {
77
            /** @var \Closure $helper */
78 68
            $helper = static::$helpers[$class][$name];
79 68
            return $helper->call($this, ...$arguments);
80
        } else {
81
            throw new CommonException("Helper `$name` not registered for class `$class`");
82
        }
83
    }
84
85
    /**
86
     * Add helper path
87
     *
88
     * @param  string $path
89
     * @return void
90
     * @throws CommonException
91
     */
92 635
    public function addHelperPath(string $path)
93
    {
94 635
        $class = static::class;
95 635
        $realPath = realpath($path);
96
97 635
        if (false === $realPath) {
98 7
            throw new CommonException("Invalid Helper path `$path` for class `$class`");
99
        }
100
101
        // create store of helpers
102 635
        if (!isset(static::$helpersPath[$class])) {
103 6
            static::$helpersPath[$class] = [];
104
        }
105
106 635
        if (!in_array($realPath, static::$helpersPath[$class])) {
107 7
            static::$helpersPath[$class][] = $realPath;
108
        }
109 635
    }
110
111
    /**
112
     * Set helpers path
113
     *
114
     * @param  array $helpersPath
115
     * @return void
116
     */
117 7
    public function setHelpersPath(array $helpersPath)
118
    {
119 7
        foreach ($helpersPath as $path) {
120 7
            $this->addHelperPath($path);
121
        }
122 1
    }
123
124
    /**
125
     * Call magic helper
126
     *
127
     * @param  string $method
128
     * @param  array  $args
129
     * @return mixed
130
     * @throws CommonException
131
     */
132 70
    public function __call($method, $args)
133
    {
134 70
        $class = static::class;
135
136
        // Call callable helper structure (function or class)
137 70
        if (isset(static::$helpers[$class], static::$helpers[$class][$method])) {
138 50
            return $this->callHelper($method, $args);
139
        }
140
141 41
        if (!isset(static::$helpersPath[$class])) {
142 1
            throw new CommonException("Helper path not found for class `$class`");
143
        }
144
145
        // Try to find helper file
146 40
        foreach (static::$helpersPath[$class] as $path) {
147 40
            if (realpath($path . '/' . ucfirst($method) . '.php')) {
148 40
                $this->addHelper($method, $path . '/' . ucfirst($method) . '.php');
149 39
                return $this->callHelper($method, $args);
150
            }
151
        }
152
        throw new CommonException("Helper `$method` not found for `$class`");
153
    }
154
}
155