Injector::getParameterValue()   B
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 17
rs 8.8571
cc 5
eloc 11
nc 3
nop 1
1
<?php
2
/*
3
 * This file is part of the Borobudur-DependencyInjection package.
4
 *
5
 * (c) Hexacodelabs <http://hexacodelabs.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Borobudur\DependencyInjection;
12
13
use Borobudur\DependencyInjection\ParameterBag\ParameterBagInterface;
14
use ReflectionParameter;
15
16
/**
17
 * @author      Iqbal Maulana <[email protected]>
18
 * @created     8/9/15
19
 */
20
class Injector
21
{
22
    /**
23
     * @var ContainerInterface
24
     */
25
    private $container;
26
27
    /**
28
     * @var ParameterBagInterface
29
     */
30
    private $parameter;
31
32
    /**
33
     * @var bool
34
     */
35
    private $resolveUnknownClass = false;
36
37
    /**
38
     * Constructor.
39
     *
40
     * @param ContainerInterface $container
41
     */
42
    public function __construct(ContainerInterface $container)
43
    {
44
        $this->container = $container;
45
        $this->parameter = $container->getParameterBag();
46
    }
47
48
    /**
49
     * Set resolve unknown class.
50
     *
51
     * @param bool $resolve
52
     */
53
    public function resolveUnknownClass($resolve)
54
    {
55
        $this->resolveUnknownClass = (bool) $resolve;
56
    }
57
58
    /**
59
     * Resolve parameter arguments value.
60
     *
61
     * @param array $parameters
62
     *
63
     * @return array
64
     */
65
    public function resolveParameters(array $parameters)
66
    {
67
        $args = array();
68
        foreach ($parameters as $parameter) {
69
            $args[] = $this->computeParameterValue($parameter);
70
        }
71
72
        return $args;
73
    }
74
75
    /**
76
     * Replace parameters with arguments.
77
     *
78
     * @param array $serviceParameters
79
     * @param array $parameters
80
     * @param array $arguments
81
     *
82
     * @return array
83
     */
84
    public function replaceArguments(array $serviceParameters, array $parameters, array $arguments)
85
    {
86
        if (null !== $args = $this->getNumericArguments($parameters, $arguments)) {
87
            return $args;
88
        }
89
90
        foreach ($serviceParameters as $index => $parameter) {
91
            $name = $this->getParameterName($parameter);
92
            if (isset($arguments[$name])) {
93
                $parameters[$index] = $arguments[$name];
94
            }
95
        }
96
97
        return $parameters;
98
    }
99
100
    /**
101
     * Get parameter value.
102
     *
103
     * @param mixed $value
104
     *
105
     * @return array|mixed
106
     */
107
    public function getParameterValue($value)
108
    {
109
        $value = $this->parameter->getResolver()->resolveValue($this->parameter->getResolver()->unescapeValue($value));
110
        if (is_array($value)) {
111
            foreach ($value as $index => $val) {
112
                if (is_array($val)) {
113
                    $value[$index] = array_map(array($this, 'resolveParameters'), $val);
114
                } else {
115
                    $value[$index] = $this->getParameterValue($val);
116
                }
117
            }
118
        } elseif ($value instanceof Reference) {
119
            $value = $this->container->get((string) $value);
120
        }
121
122
        return $value;
123
    }
124
125
    /**
126
     * Compute parameter value.
127
     *
128
     * @param mixed $parameter
129
     *
130
     * @return array|mixed|null
131
     */
132
    protected function computeParameterValue($parameter)
133
    {
134
        $name = $this->getParameterName($parameter);
135
        if ($this->parameter->has($name)) {
136
            $value = $this->parameter->get($name);
137
138
            return $this->getParameterValue($value);
139
        }
140
141
        if (null !== $instance = $this->computeParameterClass($parameter)) {
142
            return $instance;
143
        }
144
145
        return null;
146
    }
147
148
    /**
149
     * Compute parameter with class value.
150
     *
151
     * @param mixed $parameter
152
     *
153
     * @return mixed|object|null
154
     */
155
    protected function computeParameterClass($parameter)
156
    {
157
        $class = $this->getParameterClass($parameter);
158
159
        if (null !== $class) {
160
            if ($this->container->has($class)) {
161
                return $this->container->get($class);
162
            }
163
164
            if (false !== $this->resolveUnknownClass
165
                && null !== $instance = $this->container->getDi()->createInstance($class)) {
166
                return $instance->getOriginalInstance();
167
            }
168
        }
169
170
        return null;
171
    }
172
173
    /**
174
     * Get numeric arguments.
175
     *
176
     * @param array $parameters
177
     * @param array $arguments
178
     *
179
     * @return array|null
180
     */
181
    private function getNumericArguments(array $parameters, array $arguments)
182
    {
183
        $keys = array_keys($arguments);
184
185
        if (count($keys) > 0 && is_int($keys[0])) {
186
            return array_replace($parameters, $arguments);
187
        }
188
189
        return null;
190
    }
191
192
    /**
193
     * Get parameter name.
194
     *
195
     * @param mixed $parameter
196
     *
197
     * @return mixed
198
     */
199
    private function getParameterName($parameter)
200
    {
201
        if (is_object($parameter) && method_exists($parameter, 'getName')) {
202
            return call_user_func(array($parameter, 'getName'));
203
        }
204
205
        return $parameter;
206
    }
207
208
    /**
209
     * Get parameter class.
210
     *
211
     * @param mixed $parameter
212
     *
213
     * @return mixed|null
214
     */
215
    private function getParameterClass($parameter)
216
    {
217
        if ($parameter instanceof ReflectionParameter && null !== $class = $parameter->getClass()) {
218
            return '\\' . ltrim($class->getName(), '\\');
219
        }
220
221
        return null;
222
    }
223
}
224