Completed
Push — master ( 95a6e8...b8af6d )
by Filipe
07:12
created

DependencyInspector::getDefinition()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 18
cts 18
cp 1
rs 9.2
c 0
b 0
f 0
cc 3
eloc 14
nc 4
nop 0
crap 3
1
<?php
2
3
/**
4
 * This file is part of slick/di package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Di;
11
12
use Interop\Container\ContainerInterface;
13
use Slick\Common\Base;
14
use Slick\Di\Definition\Object as ObjectDefinition;
15
use Slick\Di\Definition\ObjectDefinitionInterface;
16
use Slick\Di\DependencyInspector\ConstructorInspector;
17
use Slick\Di\DependencyInspector\MethodsInspector;
18
use Slick\Di\DependencyInspector\PropertiesInspector;
19
use Slick\Di\Exception\InvalidArgumentException;
20
21
/**
22
 * Inspects a class to determine the dependencies that can be injected
23
 *
24
 * @package Slick\Di
25
 * @author  Filipe Silva <[email protected]>
26
 *
27
 * @property string $className   The class name to inspect
28
 * @property object $instance    The instance to inspect
29
 * @property bool   $satisfiable Flag for definition resolution
30
 *
31
 * @property ContainerInterface $container Container with dependencies
32
 *
33
 * @method bool isSatisfiable() Check if definition can be resolved
34
 */
35
final class DependencyInspector extends Base
36
{
37
38
    /**
39
     * @readwrite
40
     * @var string
41
     */
42
    protected $className;
43
44
    /**
45
     * @readwrite
46
     * @var object
47
     */
48
    protected $instance;
49
50
    /**
51
     * @write
52
     * @var ContainerInterface
53
     */
54
    protected $container;
55
56
    /**
57
     * @readwrite
58
     * @var boolean
59
     */
60
    protected $satisfiable = true;
61
62
    /**
63
     * @readwrite
64
     * @var ConstructorInspector
65
     */
66
    protected $constructorInspector;
67
68
    /**
69
     * @readwrite
70
     * @var MethodsInspector
71
     */
72
    protected $methodsInspector;
73
74
    /**
75
     * @readwrite
76
     * @var PropertiesInspector
77
     */
78
    protected $propertiesInspector;
79
80
    /**
81
     * Set dependency on a container and class name or object.
82
     *
83
     * @param ContainerInterface $container The container to work with
84
     * @param object|string      $class     FQ class name or object
85
     * @param array              $options   Additional property values
86
     *
87
     * @throws InvalidArgumentException If the provided class name is from a
88
     *                                  class that does not exists.
89
     */
90 48
    public function __construct(
91
        ContainerInterface $container, $class, array $options = [])
92
    {
93 48
        $className = is_string($class) ? $class : null;
94 48
        $instance = is_object($class) ? $class : null;
95 48
        $options = array_replace(
96
            [
97 48
                'container' => $container,
98 48
                'className' => $className,
99
                'instance'  => $instance
100 48
            ],
101
            $options
102 48
        );
103 48
        parent::__construct($options);
104 48
    }
105
106
    /**
107
     * Gets the object definition with dependencies injected
108
     *
109
     * @returns ObjectDefinitionInterface
110
     */
111 46
    public function getDefinition()
112
    {
113 46
        $definition = new ObjectDefinition(
114
            [
115 46
                'className' => $this->className,
116 46
                'instance' => $this->instance,
117 46
                'container' => $this->container
118 46
            ]
119 46
        );
120 46
        if (is_null($this->instance)) {
121 8
            $definition->name = $this->className;
122 8
            $this->getConstructorInspector()->setDefinition($definition);
123 8
            $this->satisfiable = $this->getConstructorInspector()
124 8
                ->isSatisfiable();
125 8
        }
126
127 46
        if ($this->satisfiable) {
128 46
            $this->getMethodsInspector()->setDefinition($definition);
129 46
            $this->getPropertiesInspector()->setDefinition($definition);
130 46
        }
131 46
        return $definition;
132
    }
133
134
    /**
135
     * Sets the class name to be inspected
136
     *
137
     * @param string $className
138
     *
139
     * @return $this|self
140
     *
141
     * @throws InvalidArgumentException If the provided class name is from a
142
     *                                  class that does not exists.
143
     */
144 48
    public function setClassName($className)
145
    {
146 48
        if (!is_null($className) && !class_exists($className)) {
147 2
            throw new InvalidArgumentException(
148 2
                "The class '{$className}' does not exists."
149 2
            );
150
        }
151
152 48
        $this->className = $className;
153 48
        return $this;
154
    }
155
156
    /**
157
     * Gets a constructor inspector
158
     *
159
     * @return ConstructorInspector
160
     */
161 8
    protected function getConstructorInspector()
162
    {
163 8
        if (is_null($this->constructorInspector)) {
164 8
            $this->constructorInspector = new ConstructorInspector();
165 8
        }
166 8
        return $this->constructorInspector;
167
    }
168
169
    /**
170
     * Gets the methods inspector
171
     *
172
     * @return MethodsInspector
173
     */
174 46
    protected function getMethodsInspector()
175
    {
176 46
        if (is_null($this->methodsInspector)) {
177 46
            $this->methodsInspector = new MethodsInspector();
178 46
        }
179 46
        return $this->methodsInspector;
180
    }
181
182
    /**
183
     * Gets properties inspector
184
     *
185
     * @return PropertiesInspector
186
     */
187 46
    protected function getPropertiesInspector()
188
    {
189 46
        if (is_null($this->propertiesInspector)) {
190 46
            $this->propertiesInspector = new PropertiesInspector();
191 46
        }
192 46
        return $this->propertiesInspector;
193
    }
194
}
195