Completed
Push — master ( 28615a...652b7c )
by Alexander
25s queued 11s
created

ReflectionConstructorInvocation::getStaticPart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
declare(strict_types = 1);
3
/*
4
 * Go! AOP framework
5
 *
6
 * @copyright Copyright 2011, Lisachenko Alexander <[email protected]>
7
 *
8
 * This source file is subject to the license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Go\Aop\Framework;
13
14
use Go\Aop\Intercept\ConstructorInvocation;
15
use Go\Core\AspectContainer;
16
use ReflectionClass;
17
use ReflectionMethod;
18
19
/**
20
 * Reflection constructor invocation implementation
21
 */
22
class ReflectionConstructorInvocation extends AbstractInvocation implements ConstructorInvocation
23
{
24
    /**
25
     * Reflection class
26
     *
27
     * @var ReflectionClass
28
     */
29
    protected $class;
30
31
    /**
32
     * Instance of created class, can be used for Around or After types of advices
33
     *
34
     * @var object|null
35
     */
36
    protected $instance;
37
38
    /**
39
     * Instance of reflection constructor for class
40
     *
41
     * @var null|ReflectionMethod
42
     */
43
    private $constructor;
44
45
    /**
46
     * Constructor for constructor invocation :)
47
     *
48
     * @param array $advices List of advices for this invocation
49 1
     */
50
    public function __construct(string $className, string $unusedType, array $advices)
51 1
    {
52 1
        $originalClass = $className;
53
        if (strpos($originalClass, AspectContainer::AOP_PROXIED_SUFFIX) !== false) {
54
            $originalClass = substr($originalClass, 0, -strlen(AspectContainer::AOP_PROXIED_SUFFIX));
55 1
        }
56
57
        $this->class       = new ReflectionClass($originalClass);
58
        $this->constructor = $constructor = $this->class->getConstructor();
59 1
60 1
        // Give an access to call protected/private constructors
61
        if ($constructor && !$constructor->isPublic()) {
62
            $constructor->setAccessible(true);
63
        }
64
65
        parent::__construct($advices);
66
    }
67
68
    /**
69
     * Proceed to the next interceptor in the Chain
70
     *
71
     * Typically this method is called inside previous closure, as instance of Joinpoint is passed to callback
72
     * Do not call this method directly, only inside callback closures.
73
     *
74
     * @return mixed
75
     */
76
    final public function proceed()
77
    {
78
        if (isset($this->advices[$this->current])) {
79
            $currentInterceptor = $this->advices[$this->current];
80
            $this->current++;
81
82
            return $currentInterceptor->invoke($this);
83
        }
84
85
        $this->instance = $this->class->newInstanceWithoutConstructor();
86
        $constructor    = $this->getConstructor();
87
        if ($constructor !== null) {
88
            $constructor->invoke($this->instance, ...$this->arguments);
89
        }
90
91
        return $this->instance;
92
    }
93
94
    /**
95
     * Gets the constructor being called or null if it is absent.
96
     */
97
    public function getConstructor(): ?ReflectionMethod
98
    {
99
        return $this->constructor;
100
    }
101
102
    /**
103
     * Returns the object for which current joinpoint is invoked
104
     *
105
     * @return object|null Instance of object or null for static call/unavailable context
106
     */
107
    public function getThis(): ?object
108
    {
109
        return $this->instance;
110
    }
111
112
    /**
113
     * Invokes current constructor invocation with all interceptors
114
     *
115
     * @return mixed
116
     */
117
    final public function __invoke(array $arguments = [])
118
    {
119
        $this->current   = 0;
120
        $this->arguments = $arguments;
121
122
        return $this->proceed();
123
    }
124
125
    /**
126
     * Checks if the current joinpoint is dynamic or static
127
     *
128
     * Dynamic joinpoint contains a reference to an object that can be received via getThis() method call
129
     *
130
     * @see ClassJoinpoint::getThis()
131
     */
132
    public function isDynamic(): bool
133
    {
134
        return true;
135
    }
136
137
    /**
138
     * Returns the static scope name (class name) of this joinpoint.
139
     */
140
    public function getScope(): string
141
    {
142
        return $this->class->getName();
143
    }
144
145
    /**
146
     * Returns a friendly description of current joinpoint
147
     */
148
    final public function __toString(): string
149
    {
150
        return sprintf(
151
            'initialization(%s)',
152
            $this->getScope()
153
        );
154
    }
155
}
156