Completed
Push — assisted ( 544669...82d8ca )
by Akihito
11:24
created

AssistedInterceptor::invoke()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 21
ccs 16
cts 16
cp 1
rs 8.7624
cc 6
eloc 15
nc 4
nop 1
crap 6
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 Doctrine\Common\Annotations\Reader;
10
use Ray\Aop\Annotation\AbstractAssisted;
11
use Ray\Aop\MethodInterceptor;
12
use Ray\Aop\MethodInvocation;
13
14
final class AssistedInterceptor implements MethodInterceptor
15
{
16
    /**
17
     * @var InjectorInterface
18
     */
19
    private $injector;
20
21
    /**
22
     * @var Reader
23
     */
24
    private $reader;
25
26 2
    public function __construct(InjectorInterface $injector, Reader $reader)
27
    {
28 2
        $this->injector = $injector;
29 2
        $this->reader = $reader;
30 2
    }
31
32
    /**
33
     * Intercepts any method and injects instances of the missing arguments
34
     * when they are type hinted
35
     */
36 2
    public function invoke(MethodInvocation $invocation)
37
    {
38 2
        $method = $invocation->getMethod();
39 2
        $assisted = $this->reader->getMethodAnnotation($method, 'Ray\Di\Di\Assisted');
40
        /* @var \Ray\Di\Di\Assisted $assisted */
41 2
        $parameters = $method->getParameters();
42 2
        $arguments = $invocation->getArguments()->getArrayCopy();
43 2
        $cntArgs = count($arguments);
44 2
        foreach ($parameters as $pos => $parameter) {
45 2
            if ($pos < $cntArgs || ! $assisted || ! in_array($parameter->getName(), $assisted->values)) {
46 2
                continue;
47
            }
48 2
            $hint = $parameter->getClass();
49 2
            $interface = $hint ? $hint->getName() : '';
50 2
            $name = $this->getName($method, $parameter);
51 2
            $arguments[] = $this->injector->getInstance($interface, $name);
52 2
        }
53 2
        $invocation->getArguments()->exchangeArray($arguments);
54
55 2
        return $invocation->proceed();
56
    }
57
58 2
    private function getName(\ReflectionMethod $method, \ReflectionParameter $parameter)
59
    {
60 2
        $named = $this->reader->getMethodAnnotation($method, 'Ray\Di\Di\Named');
61 2
        if (! $named) {
62 1
            return Name::ANY;
63
        }
64 1
        parse_str($named->value, $names);
65 1
        $paramName = $parameter->getName();
66 1
        if (isset($names[$paramName])) {
67 1
            return $names[$paramName];
68
        }
69
70
        return Name::ANY;
71
    }
72
}