Completed
Push — 2.x ( f1079d...26569f )
by Akihito
10s
created

AssistedInterceptor::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
crap 1
1
<?php
2
/**
3
 * This file is part of the Ray.Di package.
4
 *
5
 * @license http://opensource.org/licenses/MIT MIT
6
 */
7
namespace Ray\Di;
8
9
use Ray\Aop\MethodInterceptor;
10
use Ray\Aop\MethodInvocation;
11
use Ray\Aop\ReflectionMethod;
12
use Ray\Di\Di\Assisted;
13
14
final class AssistedInterceptor implements MethodInterceptor
15
{
16
    /**
17
     * @var InjectorInterface
18
     */
19
    private $injector;
20
21
    /**
22
     * @var MethodInvocationProvider
23
     */
24
    private $methodInvocationProvider;
25
26 4
    public function __construct(InjectorInterface $injector, MethodInvocationProvider $methodInvocationProvider)
27
    {
28 4
        $this->injector = $injector;
29 4
        $this->methodInvocationProvider = $methodInvocationProvider;
30 4
    }
31
32
    /**
33
     * Intercepts any method and injects instances of the missing arguments
34
     * when they are type hinted
35
     *
36
     * @param MethodInvocation $invocation
37
     *
38
     * @return object
39
     */
40 4
    public function invoke(MethodInvocation $invocation)
41
    {
42 4
        $method = $invocation->getMethod();
43 4
        $assisted = $method->getAnnotation('Ray\Di\Di\Assisted');
44
        /* @var \Ray\Di\Di\Assisted $assisted */
45 4
        $parameters = $method->getParameters();
46 4
        $arguments = $invocation->getArguments()->getArrayCopy();
47 4
        if ($assisted instanceof Assisted && $method instanceof ReflectionMethod) {
48 4
            $this->methodInvocationProvider->set($invocation);
49 4
            $arguments = $this->injectAssistedParameters($method, $assisted, $parameters, $arguments);
50
        }
51 4
        $invocation->getArguments()->exchangeArray($arguments);
52
53 4
        return $invocation->proceed();
54
    }
55
56
    /**
57
     * @param ReflectionMethod     $method
58
     * @param \ReflectionParameter $parameter
59
     *
60
     * @return string
61
     */
62 4
    private function getName(ReflectionMethod $method, \ReflectionParameter $parameter)
63
    {
64 4
        $named = $method->getAnnotation('Ray\Di\Di\Named');
65 4
        if (! $named) {
66 2
            return Name::ANY;
67
        }
68 2
        parse_str($named->value, $names);
69 2
        $paramName = $parameter->getName();
0 ignored issues
show
Bug introduced by
Consider using $parameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
70 2
        if (isset($names[$paramName])) {
71 2
            return $names[$paramName];
72
        }
73
74 1
        return Name::ANY;
75
    }
76
77
    /**
78
     * @param ReflectionMethod       $method
79
     * @param Assisted               $assisted
80
     * @param \ReflectionParameter[] $parameters
81
     * @param array                  $arguments
82
     *
83
     * @return array
84
     *
85
     * @internal param int $cntArgs
86
     */
87 4
    public function injectAssistedParameters(ReflectionMethod $method, Assisted $assisted, array $parameters, array $arguments)
88
    {
89 4
        foreach ($parameters as $parameter) {
90 4
            if (! in_array($parameter->getName(), $assisted->values)) {
0 ignored issues
show
Bug introduced by
Consider using $parameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
91 3
                continue;
92
            }
93 4
            $hint = $parameter->getClass();
94 4
            $interface = $hint ? $hint->getName() : '';
0 ignored issues
show
Bug introduced by
Consider using $hint->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
95 4
            $name = $this->getName($method, $parameter);
96 4
            $pos = $parameter->getPosition();
97 4
            $arguments[$pos] = $this->injector->getInstance($interface, $name);
98
        }
99
100 4
        return $arguments;
101
    }
102
}
103