Passed
Branch master (f36b3c)
by Matthew
08:01
created

Registry::make()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 6
c 4
b 0
f 0
dl 0
loc 15
ccs 7
cts 7
cp 1
rs 10
cc 4
nc 6
nop 1
crap 4
1
<?php
2
namespace Fyuze\Kernel;
3
4
use Closure;
5
use ReflectionClass;
6
use ReflectionParameter;
7
8
class Registry
9
{
10
    /**
11
     * Singleton instance
12
     *
13
     * @var static
14
     */
15
    protected static $instance = null;
16
17
    /**
18
     * Registered services
19
     *
20
     * @var array
21
     */
22
    protected $members = [];
23
24
    /**
25
     * Initialize object
26
     *
27
     * @return static
28
     */
29 14
    public static function init()
30
    {
31 14
        if (self::$instance === null) {
32 1
            return static::$instance = new static;
33
        }
34 13
        return static::$instance;
35
    }
36
37
    /**
38
     * @param string $alias
39
     * @param mixed $member
40
     */
41 8
    public function add($alias, $member)
42
    {
43 8
        $this->members[$alias] = $member;
44
    }
45
46
    /**
47
     * @param $alias
48
     * @return bool
49
     */
50 1
    public function has($alias)
51
    {
52 1
        return array_key_exists($alias, $this->members);
53
    }
54
55
    /**
56
     * @param string $member
57
     * @return mixed|void
58
     */
59 12
    public function make($member)
60
    {
61 12
        $key = is_object($member) ? get_class($member) : $member;
0 ignored issues
show
introduced by
The condition is_object($member) is always false.
Loading history...
62
63 12
        if (array_key_exists($key, $this->members)) {
64
65 6
            return $this->build($this->members[$member]);
66
        }
67
68 7
        if (is_object($member)) {
0 ignored issues
show
introduced by
The condition is_object($member) is always false.
Loading history...
69
70 1
            return $this->members[$key] = $member;
71
        }
72
73 6
        return $this->locate($key, $member);
74
    }
75
76
    /**
77
     *
78
     */
79 11
    public static function dump()
80
    {
81 11
        static::$instance->members = [];
82
    }
83
84
    /**
85
     * @param $class
86
     * @return object
87
     */
88 6
    protected function resolve($class)
89
    {
90 6
        $reflection = new ReflectionClass($class);
91
92 5
        if (!$constructor = $reflection->getConstructor()) {
93
94 3
            return new $class;
95
        }
96
97 4
        $params = array_filter($constructor->getParameters(), $this->getParams());
98
99
        /** @var \ReflectionParameter $param */
100 4
        foreach ($params as &$param) {
101 4
            $param = $this->make($param->getClass()->getName());
102
        }
103
104 4
        return $reflection->newInstanceArgs($params);
105
    }
106
107
    /**
108
     * @param $member
109
     * @return mixed
110
     */
111 6
    protected function build(&$member)
112
    {
113 6
        if ($member instanceof Closure) {
114 6
            return $member = $member($this);
115
        }
116
117 5
        return $member;
118
    }
119
120
    /**
121
     * @param $key
122
     * @param $member
123
     * @return mixed|object
124
     */
125 6
    protected function locate($key, $member)
126
    {
127 6
        $aliases = array_filter($this->members, function ($n) use ($member) {
128 3
            if ($n instanceof Closure) {
129 2
                return $n($this) instanceof $member;
130
            }
131 2
            return $n instanceof $member;
132 6
        });
133
134 6
        if (count($aliases)) {
135 2
            $alias = reset($aliases);
136 2
            if ($alias instanceof Closure) {
137 1
                return $alias($this);
138
            }
139 1
            return $alias;
140
        }
141
142 6
        return $this->members[$key] = $this->resolve($key);
143
    }
144
145
    /**
146
     * @return Closure
147
     */
148 4
    protected function getParams()
149
    {
150 4
        return function (ReflectionParameter $param) {
151 4
            return $param->getClass();
152 4
        };
153
    }
154
}
155