Completed
Pull Request — master (#422)
by Anton
04:34
created

Helper::setHelpersPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 2
rs 9.4285
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 path
36
     *
37
     * @param  string $path
38
     *
39
     * @return void
40
     * @throws CommonException
41
     */
42 714
    public function addHelperPath(string $path)
43
    {
44 714
        $class = static::class;
45 714
        $realPath = realpath($path);
46
47 714
        if (false === $realPath) {
48
            throw new CommonException("Invalid Helper path `$path` for class `$class`");
49
        }
50
51
        // create store of helpers
52 714
        if (!isset(static::$helpersPath[$class])) {
53 5
            static::$helpersPath[$class] = [];
54
        }
55
56 714
        if (!in_array($realPath, static::$helpersPath[$class])) {
57 6
            static::$helpersPath[$class][] = $realPath;
58
        }
59 714
    }
60
61
    /**
62
     * Call magic helper
63
     *
64
     * @param  string $method
65
     * @param  array  $arguments
66
     *
67
     * @return mixed
68
     * @throws CommonException
69
     */
70 76
    public function __call($method, $arguments)
71
    {
72 76
        $class = static::class;
73
74
        // Call callable helper structure (function or class)
75 76
        if (!isset(static::$helpers[$class], static::$helpers[$class][$method])) {
76 42
            $this->loadHelper($method);
77
        }
78
79
        /** @var \Closure $helper */
80 74
        $helper = static::$helpers[$class][$method];
81 74
        return $helper->call($this, ...$arguments);
82
    }
83
84
    /**
85
     * Call helper
86
     *
87
     * @param string $name
88
     *
89
     * @return void
90
     * @throws CommonException
91
     */
92 42
    private function loadHelper(string $name)
93
    {
94 42
        $class = static::class;
95
96
        // Somebody forgot to call `addHelperPath`
97 42
        if (!isset(static::$helpersPath[$class])) {
98 1
            throw new CommonException("Helper path not found for class `$class`");
99
        }
100
101
        // Try to find helper file
102 41
        foreach (static::$helpersPath[$class] as $path) {
103 41
            if ($helperPath = realpath($path . '/' . ucfirst($name) . '.php')) {
104 41
                $this->addHelper($name, $helperPath);
105 40
                return;
106
            }
107
        }
108
109
        throw new CommonException("Helper `$name` not found for class `$class`");
110
    }
111
112
    /**
113
     * Add helper callable
114
     *
115
     * @param  string $name
116
     * @param  string $path
117
     *
118
     * @return void
119
     * @throws CommonException
120
     */
121 41
    private function addHelper(string $name, string $path)
122
    {
123 41
        $class = static::class;
124
125
        // create store of helpers for this class
126 41
        if (!isset(static::$helpers[$class])) {
127 7
            static::$helpers[$class] = [];
128
        }
129
130 41
        $helper = include $path;
131
132 41
        if (is_callable($helper)) {
133 40
            static::$helpers[$class][$name] = $helper;
134
        } else {
135 1
            throw new CommonException("Helper `$name` not found in file `$path`");
136
        }
137 40
    }
138
}
139