Completed
Push — master ( 7b06bd...eed05d )
by James Ekow Abaka
01:23
created

Container::getConstructorArguments()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 17
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6.0208

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 11
cts 12
cp 0.9167
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 13
nc 9
nop 2
crap 6.0208
1
<?php
2
3
namespace ntentan\panie;
4
5
/**
6
 * Description of Container
7
 *
8
 * @author ekow
9
 */
10
class Container
11
{
12
13
    private $bindings;
14
    private $singletons = [];
0 ignored issues
show
Unused Code introduced by
The property $singletons is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
15
16 6
    public function __construct()
17
    {
18 6
        $this->bindings = new Bindings();
19 6
    }
20
21
    /**
22
     * 
23
     * @param string|\ReflectionClass $class
24
     * @return \ReflectionClass
25
     */
26 6
    public function getResolvedClassName($class)
27
    {
28 6
        $bound = null;
29 6
        if ($this->bindings->has($class)) {
30 4
            $bound = $this->bindings->get($class);
31 5
        } else if (is_string($class) && class_exists($class)) {
32 4
            $bound = ['binding' => $class];
33
        }
34 6
        return $bound;
35
    }
36
37 4
    public function bind($type)
38
    {
39 4
        return $this->bindings->setActiveKey($type);
40
    }
41
42
    public function has($type)
43
    {
44
        return $this->bindings->has($type);
45
    }
46
47
    public function setup($bindings, $replace = true)
48
    {
49
        $this->bindings->merge($bindings, $replace);
50
    }
51
52 6
    public function resolve($type, $constructorArguments = [])
53
    {
54 6
        if ($type === null) {
55
            throw new exceptions\ResolutionException("Cannot resolve an empty type");
56
        }
57 6
        $resolvedClass = $this->getResolvedClassName($type);
58 6
        if ($resolvedClass['binding'] === null) {
59 1
            throw new exceptions\ResolutionException("Could not resolve dependency $type");
60
        }
61 5
        $instance = $this->getInstance($resolvedClass['binding'], $constructorArguments);
62 4
        return $instance;
63
    }
64
65 3
    private function getConstructorArguments($constructor, $constructorArguments)
66
    {
67 3
        $argumentValues = [];
68 3
        $parameters = $constructor->getParameters();
69 3
        foreach ($parameters as $parameter) {
70 3
            $class = $parameter->getClass();
71 3
            $className = $class ? $class->getName() : null;
72 3
            if (isset($constructorArguments[$parameter->getName()])) {
73 1
                $argumentValues[] = $constructorArguments[$parameter->getName()];
74 3
            } else if ($className == self::class) {
75
                $argumentValues[] = $this;
76
            } else {
77 3
                $argumentValues[] = $className ? $this->resolve($className) : null;
78
            }
79
        }
80 3
        return $argumentValues;
81
    }
82
83 5
    public function getInstance($className, $constructorArguments = [])
84
    {
85 5
        if (is_callable($className)) {
86
            return $className($this);
87
        }
88 5
        if (is_object($className)) {
89
            return $className;
90
        }
91 5
        $reflection = new \ReflectionClass($className);
92 5
        if ($reflection->isAbstract()) {
93 1
            throw new exceptions\ResolutionException(
94 1
            "Abstract class {$reflection->getName()} cannot be instantiated. "
1 ignored issue
show
Bug introduced by
Consider using $reflection->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
95 1
            . "Please provide a binding to an implementation."
96
            );
97
        }
98 4
        $constructor = $reflection->getConstructor();
99 4
        return $reflection->newInstanceArgs($constructor ? $this->getConstructorArguments($constructor, $constructorArguments) : []);
100
    }
101
}
102