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

MagicMethodPointcut   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 40%

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 2
dl 0
loc 68
ccs 6
cts 15
cp 0.4
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 2014, 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\Pointcut;
14
15
use Go\Aop\Pointcut;
16
use Go\Aop\PointFilter;
17
18
/**
19
 * Magic method pointcut is a dynamic checker that verifies calls for __call and __callStatic
20
 */
21
class MagicMethodPointcut implements PointFilter, Pointcut
22
{
23
    use PointcutClassFilterTrait;
24
25
    /**
26
     * Method name to match, can contain wildcards *,?
27
     */
28
    protected string $methodName = '';
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 T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
29
30
    /**
31
     * Regular expression for matching
32
     */
33
    protected string $regexp;
34
35
    /**
36
     * Modifier filter for method
37
     */
38
    protected PointFilter $modifierFilter;
39
40
    /**
41
     * Magic method matcher constructor
42
     *
43
     * NB: only public methods can be matched as __call and __callStatic are public
44 2
     */
45
    public function __construct(string $methodName, PointFilter $modifierFilter)
46 2
    {
47 2
        $this->methodName     = $methodName;
48 2
        $this->regexp         = strtr(
49
            preg_quote($this->methodName, '/'),
50
            [
51
                '\\*' => '.*?',
52 2
                '\\?' => '.',
53 2
                '\\|' => '|'
54
            ]
55
        );
56
        $this->modifierFilter = $modifierFilter;
57
    }
58
59
    /**
60
     * Performs matching of point of code
61
     *
62
     * @param mixed              $point     Specific part of code, can be any Reflection class
63
     * @param null|mixed         $context   Related context, can be class or namespace
64
     * @param null|string|object $instance  Invocation instance or string for static calls
65
     * @param null|array         $arguments Dynamic arguments for method
66
     */
67
    public function matches($point, $context = null, $instance = null, array $arguments = null): bool
68
    {
69
        // With single parameter (statically) always matches for __call, __callStatic
70
        if ($instance === null) {
71
            return ($point->name === '__call' || $point->name === '__callStatic');
72
        }
73
74
        if (!$this->modifierFilter->matches($point)) {
75
            return false;
76
        }
77
78
        // for __call and __callStatic method name is the first argument on invocation
79
        [$methodName] = $arguments;
80
81
        return ($methodName === $this->methodName) || (bool)preg_match("/^(?:{$this->regexp})$/", $methodName);
82
    }
83
84
    /**
85
     * Returns the kind of point filter
86
     */
87
    public function getKind(): int
88
    {
89
        return PointFilter::KIND_METHOD | PointFilter::KIND_DYNAMIC;
90
    }
91
}
92