Completed
Push — 1.x ( fd0c91...cdd807 )
by Akihito
03:35
created

CompileClassMetaInfo::__invoke()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.1768
c 0
b 0
f 0
cc 5
nc 5
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\Package\Compiler;
6
7
use BEAR\Resource\Exception\ParameterException;
8
use BEAR\Resource\NamedParameterInterface;
9
use Doctrine\Common\Annotations\Reader;
10
use ReflectionClass;
11
12
use function in_array;
13
use function is_callable;
14
use function sprintf;
15
use function substr;
16
17
final class CompileClassMetaInfo
18
{
19
    /**
20
     * Save annotation and method meta information
21
     *
22
     * @param class-string<T> $className
0 ignored issues
show
Documentation introduced by
The doc-type class-string<T> could not be parsed: Unknown type name "class-string" at position 0. (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...
23
     *
24
     * @template T
25
     */
26
    public function __invoke(Reader $reader, NamedParameterInterface $namedParams, string $className): void
27
    {
28
        $class = new ReflectionClass($className);
29
        $instance = $class->newInstanceWithoutConstructor();
30
        if (! $instance instanceof $className) {
31
            return; // @codeCoverageIgnore
32
        }
33
34
        $reader->getClassAnnotations($class);
35
        $methods = $class->getMethods();
36
        $log = sprintf('M %s:', $className);
37
        foreach ($methods as $method) {
38
            $methodName = $method->getName();
0 ignored issues
show
Bug introduced by
Consider using $method->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
39
            if ($this->isMagicMethod($methodName)) {
40
                continue;
41
            }
42
43
            if (substr($methodName, 0, 2) === 'on') {
44
                $log .= sprintf(' %s', $methodName);
45
                $this->saveNamedParam($namedParams, $instance, $methodName);
46
            }
47
48
            // method annotation
49
            $reader->getMethodAnnotations($method);
50
            $log .= sprintf('@ %s', $methodName);
51
        }
52
    }
53
54
    private function isMagicMethod(string $method): bool
55
    {
56
        return in_array($method, ['__sleep', '__wakeup', 'offsetGet', 'offsetSet', 'offsetExists', 'offsetUnset', 'count', 'ksort', 'asort', 'jsonSerialize'], true);
57
    }
58
59
    private function saveNamedParam(NamedParameterInterface $namedParameter, object $instance, string $method): void
60
    {
61
        // named parameter
62
        if (! in_array($method, ['onGet', 'onPost', 'onPut', 'onPatch', 'onDelete', 'onHead'], true)) {
63
            return;  // @codeCoverageIgnore
64
        }
65
66
        $callable = [$instance, $method];
67
        if (! is_callable($callable)) {
68
            return;  // @codeCoverageIgnore
69
        }
70
71
        try {
72
            $namedParameter->getParameters($callable, []);
73
        } catch (ParameterException $e) {
74
            return;
75
        }
76
    }
77
}
78