Completed
Push — 2.x ( 1d2844...e1ee47 )
by Akihito
02:02 queued 22s
created

MethodMatch::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 1
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
    public function __invoke(\ReflectionClass $class, \ReflectionMethod $method, array $pointcuts) : void
28
    {
29
        $annotations = $this->reader->getMethodAnnotations($method);
30
        // priority bind
31
        foreach ($pointcuts as $key => $pointcut) {
32
            if ($pointcut instanceof PriorityPointcut) {
33
                $this->annotatedMethodMatchBind($class, $method, $pointcut);
34
                unset($pointcuts[$key]);
35
            }
36
        }
37
        $onion = $this->onionOrderMatch($class, $method, $pointcuts, $annotations);
38
39
        // default binding
40
        foreach ($onion as $pointcut) {
41
            $this->annotatedMethodMatchBind($class, $method, $pointcut);
42
        }
43
    }
44
45
    private function annotatedMethodMatchBind(\ReflectionClass $class, \ReflectionMethod $method, Pointcut $pointCut) : void
46
    {
47
        $isMethodMatch = $pointCut->methodMatcher->matchesMethod($method, $pointCut->methodMatcher->getArguments());
48
        if (! $isMethodMatch) {
49
            return;
50
        }
51
        $isClassMatch = $pointCut->classMatcher->matchesClass($class, $pointCut->classMatcher->getArguments());
52
        if (! $isClassMatch) {
53
            return;
54
        }
55
        $this->bind->bindInterceptors($method->name, $pointCut->interceptors);
56
    }
57
58
    private function onionOrderMatch(
59
        \ReflectionClass $class,
60
        \ReflectionMethod $method,
61
        array $pointcuts,
62
        array $annotations
63
    ) : array {
64
        // method bind in annotation order
65
        foreach ($annotations as $annotation) {
66
            $annotationIndex = get_class($annotation);
67
            if (array_key_exists($annotationIndex, $pointcuts)) {
68
                $this->annotatedMethodMatchBind($class, $method, $pointcuts[$annotationIndex]);
69
                unset($pointcuts[$annotationIndex]);
70
            }
71
        }
72
73
        return $pointcuts;
74
    }
75
}
76