Completed
Push — 2.x ( bcb56c...6c548f )
by Akihito
03:06
created

AssistedInterceptor::invoke()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 9.4285
cc 3
eloc 9
nc 2
nop 1
crap 3
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 3
    public function __construct(InjectorInterface $injector)
22
    {
23 3
        $this->injector = $injector;
24 3
    }
25
26
    /**
27
     * Intercepts any method and injects instances of the missing arguments
28
     * when they are type hinted
29
     */
30 3
    public function invoke(MethodInvocation $invocation)
31
    {
32 3
        $method = $invocation->getMethod();
33 3
        $assisted = $method->getAnnotation('Ray\Di\Di\Assisted');
34
        /* @var \Ray\Di\Di\Assisted $assisted */
35 3
        $parameters = $method->getParameters();
36 3
        $arguments = $invocation->getArguments()->getArrayCopy();
37 3
        if ($assisted instanceof Assisted && $method instanceof ReflectionMethod) {
38 3
            $arguments = $this->injectAssistedParameters($method, $assisted, $parameters, $arguments);
39
        }
40 3
        $invocation->getArguments()->exchangeArray($arguments);
41
42 3
        return $invocation->proceed();
43
    }
44
45
    /**
46
     * @param ReflectionMethod     $method
47
     * @param \ReflectionParameter $parameter
48
     *
49
     * @return string
50
     */
51 3
    private function getName(ReflectionMethod $method, \ReflectionParameter $parameter)
52
    {
53 3
        $named = $method->getAnnotation('Ray\Di\Di\Named');
54 3
        if (! $named) {
55 1
            return Name::ANY;
56
        }
57 2
        parse_str($named->value, $names);
58 2
        $paramName = $parameter->getName();
59 2
        if (isset($names[$paramName])) {
60 2
            return $names[$paramName];
61
        }
62
63 1
        return Name::ANY;
64
    }
65
66
    /**
67
     * @param ReflectionMethod       $method
68
     * @param Assisted               $assisted
69
     * @param \ReflectionParameter[] $parameters
70
     * @param array                  $arguments
71
     *
72
     * @return array
73
     *
74
     * @internal param int $cntArgs
75
     */
76 3
    public function injectAssistedParameters(ReflectionMethod $method, Assisted $assisted, array $parameters, array $arguments)
77
    {
78 3
        foreach ($parameters as $parameter) {
79 3
            if (! in_array($parameter->getName(), $assisted->values)) {
80 2
                continue;
81
            }
82 3
            $hint = $parameter->getClass();
83 3
            $interface = $hint ? $hint->getName() : '';
84 3
            $name = $this->getName($method, $parameter);
85 3
            $arguments[] = $this->injector->getInstance($interface, $name);
86
        }
87
88 3
        return $arguments;
89
    }
90
}
91