Completed
Push — 2.x ( ef6a56...c04ee5 )
by Akihito
09:29 queued 06:55
created

src/ReflectiveMethodInvocation.php (1 issue)

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
namespace Ray\Aop;
6
7
use ArrayObject;
8
use ReflectionClass;
9
use ReflectionObject;
10
11
use function array_shift;
12
use function assert;
13
use function call_user_func_array;
14
use function class_exists;
15
use function is_callable;
16
17
final class ReflectiveMethodInvocation implements MethodInvocation
18
{
19
    /** @var object */
20
    private $object;
21
22
    /** @var ArrayObject<int, mixed> */
23
    private $arguments;
24
25
    /** @var string */
26
    private $method;
27
28
    /** @var MethodInterceptor[] */
29
    private $interceptors;
30
31
    /** @var callable */
32
    private $callable;
33
34
    /**
35
     * @param array<MethodInterceptor> $interceptors
36
     * @param array<int, mixed>        $arguments
37
     */
38
    public function __construct(
39
        object $object,
40
        string $method,
41
        array $arguments,
42
        array $interceptors = []
43
    ) {
44 17
        $this->object = $object;
45
        $this->method = $method;
46
        $callable = [$object, $method];
47
        assert(is_callable($callable));
48
        $this->callable = $callable;
49
        $this->arguments = new ArrayObject($arguments);
50 17
        $this->interceptors = $interceptors;
51 17
    }
52 17
53 17
    /**
54 17
     * {@inheritdoc}
55 17
     */
56
    public function getMethod(): ReflectionMethod
57
    {
58
        if ($this->object instanceof WeavedInterface) {
59
            $class = (new ReflectionObject($this->object))->getParentClass();
60 6
            assert($class instanceof ReflectionClass);
61
            assert(class_exists($class->name));
62 6
            $method = new ReflectionMethod($class->name, $this->method);
63 3
            $method->setObject($this->object, $method);
64 3
65
            return $method;
66
        }
67 3
68 3
        return new ReflectionMethod($this->object, $this->method);
69
    }
70 3
71
    /**
72
     * {@inheritdoc}
73 3
     */
74
    public function getArguments(): ArrayObject
75
    {
76
        return $this->arguments;
77
    }
78
79 3
    /**
80
     * {@inheritdoc}
81 3
     */
82
    public function getNamedArguments(): ArrayObject
83 3
    {
84
        $args = $this->getArguments();
85
        $params = $this->getMethod()->getParameters();
86
        $namedParams = [];
87
        foreach ($params as $param) {
88
            $pos = $param->getPosition();
89 1
            if (isset($args[$pos])) {
90
                /** @psalm-suppress MixedAssignment */
91 1
                $namedParams[$param->getName()] = $args[$pos];
0 ignored issues
show
Consider using $param->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
92 1
            }
93 1
        }
94 1
95 1
        return new ArrayObject($namedParams);
96
    }
97
98 1
    /**
99
     * {@inheritdoc}
100
     */
101
    public function proceed()
102
    {
103
        $interceptor = array_shift($this->interceptors);
104 11
        if ($interceptor instanceof MethodInterceptor) {
105
            return $interceptor->invoke($this);
106 11
        }
107 9
108
        return call_user_func_array($this->callable, (array) $this->arguments);
109 9
    }
110 9
111 8
    /**
112
     * {@inheritdoc}
113 1
     */
114
    public function getThis()
115
    {
116
        return $this->object;
117
    }
118
}
119