Completed
Pull Request — master (#463)
by Alexander
30:17 queued 05:15
created

AbstractMethodInvocation   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 112
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 79.31%

Importance

Changes 0
Metric Value
wmc 9
lcom 0
cbo 2
dl 0
loc 112
ccs 23
cts 29
cp 0.7931
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
/*
5
 * Go! AOP framework
6
 *
7
 * @copyright Copyright 2011, Lisachenko Alexander <[email protected]>
8
 *
9
 * This source file is subject to the license that is bundled
10
 * with this source code in the file LICENSE.
11
 */
12
13
namespace Go\Aop\Framework;
14
15
use Go\Aop\Intercept\MethodInvocation;
16
use Go\Aop\Support\AnnotatedReflectionMethod;
17
18
use function array_merge;
19
use function array_pop;
20
use function count;
21
22
/**
23
 * Abstract method invocation implementation
24
 */
25
abstract class AbstractMethodInvocation extends AbstractInvocation implements MethodInvocation
26
{
27
    /**
28
     * Instance of object for invoking
29
     */
30
    protected ?object $instance;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected '?', expecting T_FUNCTION or T_CONST
Loading history...
31
32
    /**
33
     * Instance of reflection method for invocation
34
     */
35
    protected AnnotatedReflectionMethod $reflectionMethod;
36
37
    /**
38
     * Class name scope for static invocation
39
     */
40
    protected string $scope = '';
41
42
    /**
43
     * This static string variable holds the name of field to use to avoid extra "if" section in the __invoke method
44
     *
45
     * Overridden in children classes and initialized via LSB
46
     */
47
    protected static string $propertyName;
48
49
    /**
50
     * Constructor for method invocation
51 24
     *
52
     * @param array $advices List of advices for this invocation
53 24
     */
54 24
    public function __construct(array $advices, string $className, string $methodName)
55 24
    {
56
        parent::__construct($advices);
57
        $this->reflectionMethod = $method = new AnnotatedReflectionMethod($className, $methodName);
58 24
59 4
        // Give an access to call protected method
60
        if ($method->isProtected()) {
61 24
            $method->setAccessible(true);
62
        }
63
    }
64
65
    /**
66
     * Invokes current method invocation with all interceptors
67
     *
68
     * @param null|object|string $instance          Invocation instance (class name for static methods)
69
     * @param array              $arguments         List of arguments for method invocation
70
     * @param array              $variadicArguments Additional list of variadic arguments
71
     *
72 20
     * @return mixed Result of invocation
73
     */
74 20
    final public function __invoke($instance = null, array $arguments = [], array $variadicArguments = [])
75 2
    {
76
        if ($this->level > 0) {
77
            $this->stackFrames[] = [$this->arguments, $this->scope, $this->instance, $this->current];
78 20
        }
79
80
        if (count($variadicArguments) > 0) {
81
            $arguments = array_merge($arguments, $variadicArguments);
82
        }
83 20
84
        try {
85 20
            ++$this->level;
86 20
87 20
            $this->current   = 0;
88
            $this->arguments = $arguments;
89 20
90
            $this->{static::$propertyName} = $instance;
91 20
92
            return $this->proceed();
93 20
        } finally {
94 20
            --$this->level;
95
96
            if ($this->level > 0) {
97
                [$this->arguments, $this->scope, $this->instance, $this->current] = array_pop($this->stackFrames);
98
            } else {
99
                $this->instance  = null;
100
                $this->arguments = [];
101
            }
102
        }
103
    }
104 3
105
    /**
106 3
     * Gets the method being called.
107
     *
108
     * @return AnnotatedReflectionMethod Covariant, the method being called.
109
     */
110
    public function getMethod(): AnnotatedReflectionMethod
111
    {
112
        return $this->reflectionMethod;
113
    }
114
115
    /**
116
     * Returns friendly description of this joinpoint
117
     */
118
    final public function __toString(): string
119
    {
120
        return sprintf(
121
            'execution(%s%s%s())',
122
            $this->getScope(),
123
            $this->reflectionMethod->isStatic() ? '::' : '->',
124
            $this->reflectionMethod->name
125 1
        );
126
    }
127
}
128