Completed
Push — 2.x ( 5c2340...e1da9c )
by Akihito
02:40
created

src/AssistedInterceptor.php (2 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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