Completed
Push — 2.x ( 4c102d...e762e8 )
by Akihito
02:20
created

MethodMatch   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 4
dl 0
loc 83
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A __invoke() 0 17 4
A annotatedMethodMatchBind() 0 14 3
A onionOrderMatch() 0 17 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\Aop;
6
7
use Doctrine\Common\Annotations\AnnotationReader;
8
9
final class MethodMatch
10
{
11
    /**
12
     * @var AnnotationReader
13
     */
14
    private $reader;
15
16
    /**
17
     * @var BindInterface
18
     */
19
    private $bind;
20
21
    public function __construct(BindInterface $bind)
22
    {
23
        $this->bind = $bind;
24
        $this->reader = new AnnotationReader;
25
    }
26
27
    /**
28
     * @param \ReflectionClass<object> $class
0 ignored issues
show
Documentation introduced by
The doc-type \ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 16. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
29
     * @param Pointcut[]               $pointcuts
30
     */
31
    public function __invoke(\ReflectionClass $class, \ReflectionMethod $method, array $pointcuts) : void
32
    {
33
        $annotations = $this->reader->getMethodAnnotations($method);
34
        // priority bind
35
        foreach ($pointcuts as $key => $pointcut) {
36
            if ($pointcut instanceof PriorityPointcut) {
37
                $this->annotatedMethodMatchBind($class, $method, $pointcut);
38
                unset($pointcuts[$key]);
39
            }
40
        }
41
        $onion = $this->onionOrderMatch($class, $method, $pointcuts, $annotations);
42
43
        // default binding
44
        foreach ($onion as $pointcut) {
45
            $this->annotatedMethodMatchBind($class, $method, $pointcut);
46
        }
47
    }
48
49
    /**
50
     * @param \ReflectionClass<object> $class
0 ignored issues
show
Documentation introduced by
The doc-type \ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 16. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
51
     */
52
    private function annotatedMethodMatchBind(\ReflectionClass $class, \ReflectionMethod $method, Pointcut $pointCut) : void
53
    {
54
        $isMethodMatch = $pointCut->methodMatcher->matchesMethod($method, $pointCut->methodMatcher->getArguments());
55
        if (! $isMethodMatch) {
56
            return;
57
        }
58
        $isClassMatch = $pointCut->classMatcher->matchesClass($class, $pointCut->classMatcher->getArguments());
59
        if (! $isClassMatch) {
60
            return;
61
        }
62
        /** @var MethodInterceptor[] $interceptors */
63
        $interceptors = $pointCut->interceptors;
64
        $this->bind->bindInterceptors($method->name, $interceptors);
65
    }
66
67
    /**
68
     * @param \ReflectionClass<object> $class
0 ignored issues
show
Documentation introduced by
The doc-type \ReflectionClass<object> could not be parsed: Expected "|" or "end of type", but got "<" at position 16. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
69
     * @param Pointcut[]               $pointcuts
70
     * @param object[]                 $annotations
71
     *
72
     * @return Pointcut[]
73
     */
74
    private function onionOrderMatch(
75
        \ReflectionClass $class,
76
        \ReflectionMethod $method,
77
        array $pointcuts,
78
        array $annotations
79
    ) : array {
80
        // method bind in annotation order
81
        foreach ($annotations as $annotation) {
82
            $annotationIndex = get_class($annotation);
83
            if (array_key_exists($annotationIndex, $pointcuts)) {
84
                $this->annotatedMethodMatchBind($class, $method, $pointcuts[$annotationIndex]);
85
                unset($pointcuts[$annotationIndex]);
86
            }
87
        }
88
89
        return $pointcuts;
90
    }
91
}
92