MethodFirstParameterExtractor::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace OniBus\Handler\ClassMethod\Extractor;
5
6
use OniBus\Handler\ClassMethod\ClassMethod;
7
use OniBus\Handler\ClassMethod\ClassMethodExtractor;
8
use ReflectionClass;
9
use ReflectionException;
10
use ReflectionFunctionAbstract;
11
use ReflectionMethod;
12
use ReflectionNamedType;
13
14
class MethodFirstParameterExtractor implements ClassMethodExtractor
15
{
16
    /**
17
     * @var string
18
     */
19
    protected $method;
20
21
    /**
22
     * @var array
23
     */
24
    protected $handlersFQCN;
25
26
    public function __construct(string $method, array $handlersFQCN = [])
27
    {
28
        $this->method = $method;
29
        $this->handlersFQCN = $handlersFQCN;
30
    }
31
32
    /**
33
     * @inheritDoc
34
     */
35
    public function extractClassMethods(): array
36
    {
37
        $mapped = [];
38
        foreach ($this->handlersFQCN as $class) {
39
            $mapped = array_merge($mapped, $this->getHandlers($class));
40
        }
41
42
        return $mapped;
43
    }
44
45
    /**
46
     * @param  string $class
47
     * @return ClassMethod[]
48
     * @throws ReflectionException
49
     */
50
    protected function getHandlers(string $class): array
51
    {
52
        $handlers = [];
53
        if (!class_exists($class)) {
54
            return $handlers;
55
        }
56
57
        $reflectionClass = new ReflectionClass($class);
58
        foreach ($reflectionClass->getMethods() as $method) {
59
            if ($method->getName() !== $this->method) {
60
                continue;
61
            }
62
63
            $firstParameterTypeHint = $this->firstParameterTypeHint($method);
64
            if (!is_null($firstParameterTypeHint)) {
65
                $handlers[] = new ClassMethod($firstParameterTypeHint, $class, $method->getName());
66
            }
67
        }
68
69
        return $handlers;
70
    }
71
72
    public function firstParameterTypeHint(ReflectionFunctionAbstract $method): ?string
73
    {
74
        if (!$method->getNumberOfParameters()) {
75
            return null;
76
        }
77
78
        $parameterType = $method->getParameters()[0]->getType();
79
        if (! $parameterType instanceof ReflectionNamedType) {
80
            return null;
81
        }
82
83
        if ($parameterType->isBuiltin()) {
84
            return null;
85
        }
86
87
        return ltrim($parameterType->getName(), "?");
88
    }
89
}
90