Completed
Push — master ( bd6513...1812e2 )
by Vitaly
05:41
created

Container::buildDependenciesTree()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 35
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 6.0038

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 35
ccs 20
cts 21
cp 0.9524
rs 8.439
cc 6
eloc 16
nc 4
nop 2
crap 6.0038
1
<?php
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 22.01.16 at 23:53
5
 */
6
namespace samsonframework\di;
7
8
use samsonframework\di\exception\ContainerException;
9
use samsonframework\di\exception\NotFoundException;
10
11
//TODO: caching
12
//TODO: Interface & abstract class resolving
13
//TODO: Other parameter types(not hintable) resolving
14
//TODO: Lazy creation by default
15
16
/**
17
 * Class Container
18
 * @package samsonframework\di
19
 */
20
class Container implements ContainerInterface
21
{
22
    /** @var array[string] Collection of loaded services */
23
    protected $services = array();
24
25
    /** @var array[string] Collection of alias => class name for alias resolving*/
26
    protected $aliases = array();
27
28 1
    protected function getClassName(\ReflectionParameter $param) {
29 1
        preg_match('/\[\s\<\w+?>\s([\w\\\\]+)/s', $param->__toString(), $matches);
30 1
        return isset($matches[1]) ? $matches[1] : null;
31
    }
32
33
    /**
34
     * Recursively build class constructor dependencies tree.
35
     *
36
     * @param string $className Current class name for analyzing
37
     * @param array  $dependencies Reference to tree for filling up
38
     *
39
     * @return array[string] Multidimensional array as dependency tree
0 ignored issues
show
Documentation introduced by
The doc-type array[string] could not be parsed: Expected "]" at position 2, but found "string". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
40
     */
41 1
    protected function buildDependenciesTree($className, array &$dependencies = array())
42
    {
43
        // We need this class to exists to use reflections
44 1
        if (class_exists($className)) {
45 1
            $class = new \ReflectionClass($className);
46
            // We can build dependency tree only from constructor dependencies
47 1
            $constructor = $class->getConstructor();
48 1
            if (null !== $constructor) {
49
                // Iterate all dependencies
50 1
                foreach ($constructor->getParameters() as $parameter) {
51
                    // Ignore optional parameters
52 1
                    if (!$parameter->isOptional()) {
53
                        // Read dependency class name
54 1
                        $dependencyClass = $this->getClassName($parameter);
55
56
                        // If we have found dependency class
57 1
                        if ($dependencyClass !== null) {
58
                            // Store new inner dependency branch
59 1
                            $dependencies[$className][$parameter->getName()] = array($dependencyClass => array());
60
                            // Go deeper in recursion and pass new branch there
61 1
                            $this->buildDependenciesTree(
62 1
                                $dependencyClass,
63 1
                                $dependencies[$className][$parameter->getName()]
64 1
                            );
65 1
                        }
66
67 1
                    } else { // Stop iterating as first optional parameter is met
68
                        break;
69
                    }
70 1
                }
71 1
            }
72 1
        }
73
74 1
        return $dependencies;
75
    }
76
77
    /**
78
     * Finds an entry of the container by its identifier and returns it.
79
     *
80
     * @param string $id Identifier of the entry to look for.
81
     *
82
     * @throws NotFoundException  No entry was found for this identifier.
83
     * @throws ContainerException Error while retrieving the entry.
84
     *
85
     * @return mixed Entry.
86
     */
87
    public function get($id)
88
    {
89
        // Set pointer to module
90
        $module = &$this->services[$id];
91
92
        if (null === $module) {
93
            throw new NotFoundException($id);
94
        } else {
95
            if (!is_object($module)) {
96
                throw new ContainerException($id);
97
            } else {
98
                return $module;
99
            }
100
        }
101
    }
102
103
    /**
104
     * Returns true if the container can return an entry for the given identifier.
105
     * Returns false otherwise.
106
     *
107
     * @param string $id Identifier of the entry to look for.
108
     *
109
     * @return boolean
110
     */
111
    public function has($id)
112
    {
113
        return isset($this->services[$id]) || isset($this->aliases[$id]);
114
    }
115
116
    /**
117
     * Set dependency alias with callback function.
118
     *
119
     * @param callable $callable Callable to return dependency
120
     * @param string   $alias    Dependency name
121
     *
122
     * @return self Chaining
123
     */
124
    public function callback($callable, $alias = null)
125
    {
126
        // TODO: Implement callback() method.
127
    }
128
129
    /**
130
     * Set service dependency. Upon first creation of this class instance
131
     * it would be used everywhere where this dependency is needed.
132
     *
133
     * @param string $className  Fully qualified class name
134
     * @param string $alias      Dependency name
135
     * @param array  $parameters Collection of parameters needed for dependency creation
136
     *
137
     * @return self Chaining
138
     */
139
    public function service($className, $alias = null, array $parameters = array())
140
    {
141
        // TODO: Implement service() method.
142
    }
143
144
    /**
145
     * Set service dependency by passing object instance.
146
     *
147
     * @param mixed  $instance   Instance that needs to be return by this dependency
148
     * @param string $alias      Dependency name
149
     * @param array  $parameters Collection of parameters needed for dependency creation
150
     *
151
     * @return self Chaining
152
     */
153
    public function instance(&$instance, $alias = null, array $parameters = array())
154
    {
155
156
        // TODO: Implement instance() method.
157
    }
158
159
    /**
160
     * Set dependency.
161
     *
162
     * @param string $className  Fully qualified class name
163
     * @param string $alias      Dependency name
164
     * @param array  $parameters Collection of parameters needed for dependency creation
165
     *
166
     * @return ContainerInterface Chaining
167
     */
168 1
    public function set($className, $alias = null, array $parameters = array())
169
    {
170 1
        $tree = $this->buildDependenciesTree($className);
171
172 1
        var_dump($tree);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($tree); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
173 1
    }
174
}
175