Completed
Push — master ( 68fe25...8e1e8c )
by Woody
11s
created

Container::getContainerValue()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 18
nc 6
nop 1
dl 0
loc 25
ccs 0
cts 25
cp 0
crap 72
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace Northwoods\Config;
4
5
use ReflectionClass;
6
use Psr\Container\ContainerInterface;
7
8
class Container implements ContainerInterface
9
{
10
    /**
11
     * @var ContainerInterface
12
     */
13
    private $diContainer;
14
15
    /**
16
     * @var array
17
     */
18
    private $container = [];
19
20
    /**
21
     * @var array
22
     */
23
    private $instances = [];
24
25
    public function __construct(ContainerInterface $container)
26
    {
27
        $this->diContainer = $container;
28
    }
29
30
    public function get($id)
31
    {
32
        if (isset($this->instances[$id])) {
33
            return $this->instances[$id];
34
        }
35
36
        $className = $this->getContainerValue($id);
37
        if (is_callable($className)) {
38
            return $className($this->diContainer, $id);
39
        }
40
        $class = new $className;
41
        return $this->instances[$id] = $class($this->diContainer);
42
    }
43
44
    public function has($id)
45
    {
46
        if (isset($this->instances[$id])) {
47
            return true;
48
        }
49
        return $this->getContainerValue($id) !== null;
50
    }
51
52
    protected function getContainerValue($id)
53
    {
54
        if (isset($this->container[$id])) {
55
            return $this->container[$id];
56
        }
57
        foreach ($this->container as $alias => $concrete) {
58
            $class = new ReflectionClass($id);
59
            if (false === $class) {
60
                return null;
61
            }
62
            do {
63
                $name = $class->getName();
64
                if ($alias == $name) {
65
                    return $concrete;
66
                }
67
                $interfaces = $class->getInterfaceNames();
68
                if (is_array($interfaces) && in_array($alias, $interfaces)) {
69
                    return $concrete;
70
                }
71
                $class = $class->getParentClass();
72
            } while (false !== $class);
73
            return null;
74
        }
75
        return null;
76
    }
77
78
    public function add($alias, $className, $target = null)
79
    {
80
        if (null === $target) {
81
            $target = $className;
82
        } else {
83
            $this->container[$className] = $target;
84
        }
85
        $this->container[$alias] = $target;
86
    }
87
}
88