Completed
Pull Request — master (#466)
by Anton
12:30 queued 10:37
created

Helper::__call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 12
ccs 6
cts 6
cp 1
crap 2
rs 10
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 604
    public function addHelperPath(string $path): void
43
    {
44 604
        $class = static::class;
45 604
        $realPath = realpath($path);
46
47 604
        if (false === $realPath) {
48
            throw new CommonException("Invalid Helper path `$path` for class `$class`");
49
        }
50
51
        // create store of helpers
52 604
        if (!isset(static::$helpersPath[$class])) {
53 5
            static::$helpersPath[$class] = [];
54
        }
55
56 604
        if (!\in_array($realPath, static::$helpersPath[$class], true)) {
57 6
            static::$helpersPath[$class][] = $realPath;
58
        }
59 604
    }
60
61
    /**
62
     * Call magic helper
63
     *
64
     * @param  string $method
65
     * @param  array  $arguments
66
     *
67
     * @return mixed
68
     * @throws CommonException
69
     */
70 107
    public function __call($method, $arguments)
71
    {
72 107
        $class = static::class;
73
74
        // Call callable helper structure (function or class)
75 107
        if (!isset(static::$helpers[$class], static::$helpers[$class][$method])) {
76 50
            $this->loadHelper($method);
77
        }
78
79
        /** @var \Closure $helper */
80 105
        $helper = static::$helpers[$class][$method];
81 105
        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 50
    private function loadHelper(string $name): void
93
    {
94 50
        $class = static::class;
95
96
        // Somebody forgot to call `addHelperPath`
97 50
        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 49
        foreach (static::$helpersPath[$class] as $path) {
103 49
            if ($helperPath = realpath($path . '/' . ucfirst($name) . '.php')) {
104 49
                $this->addHelper($name, $helperPath);
105 48
                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 49
    private function addHelper(string $name, string $path): void
122
    {
123 49
        $class = static::class;
124
125
        // create store of helpers for this class
126 49
        if (!isset(static::$helpers[$class])) {
127 7
            static::$helpers[$class] = [];
128
        }
129
130 49
        $helper = include $path;
131
132 49
        if (\is_callable($helper)) {
133 48
            static::$helpers[$class][$name] = $helper;
134
        } else {
135 1
            throw new CommonException("Helper `$name` not found in file `$path`");
136
        }
137 48
    }
138
}
139