Passed
Push — main ( 4e1019...30af20 )
by Daniel
05:38
created

AnnotationReader::resolveClassName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.0218

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 16
ccs 8
cts 9
cp 0.8889
crap 4.0218
rs 10
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Silverback\ApiComponentsBundle\AnnotationReader;
15
16
use Doctrine\Common\Annotations\Reader;
17
use Doctrine\Persistence\ManagerRegistry;
18
use Silverback\ApiComponentsBundle\Exception\InvalidArgumentException;
19
use Silverback\ApiComponentsBundle\Utility\ClassMetadataTrait;
20
21
/**
22
 * @author Vincent Chalamon <[email protected]>
23
 * @author Daniel West <[email protected]>
24
 */
25
abstract class AnnotationReader implements AnnotationReaderInterface
26
{
27
    use ClassMetadataTrait;
28
29
    protected Reader $reader;
30
31
    private array $configurationCache = [];
32
33 19
    public function __construct(Reader $reader, ManagerRegistry $managerRegistry)
34
    {
35 19
        $this->reader = $reader;
36 19
        $this->initRegistry($managerRegistry);
37 19
    }
38
39
    abstract public function getConfiguration($class);
40
41
    /**
42
     * @param object|string $class
43
     */
44 19
    public function isConfigured($class): bool
45
    {
46
        try {
47 19
            $this->getConfiguration($class);
48 19
        } catch (InvalidArgumentException $e) {
49 19
            return false;
50
        }
51
52 19
        return true;
53
    }
54
55 19
    private function resolveClassName(object|string|null $class): string
56
    {
57 19
        $error = sprintf('$class passed to %s must be a valid class FQN or object.', __CLASS__);
58 19
        if (null === $class) {
59
            throw new InvalidArgumentException($error . ' It is null.');
60
        }
61
62 19
        if (\is_string($class)) {
63 19
            if (!class_exists($class)) {
64 2
                throw new InvalidArgumentException(sprintf('%s %s is not a class.', $error, $class));
65
            }
66
67 19
            return $class;
68
        }
69
70 2
        return \get_class($class);
71
    }
72
73
    /**
74
     * @throws \ReflectionException
75
     */
76 19
    protected function getClassAnnotationConfiguration(object|string|null $class, string $annotationClass): ?object
77
    {
78 19
        $className = $this->resolveClassName($class);
79 19
        if (\array_key_exists($className, $this->configurationCache)) {
80 19
            return $this->configurationCache[$className];
81
        }
82
83 19
        $annotation = $this->findAnnotationConfiguration($class, $annotationClass);
84
85 19
        $this->configurationCache[$className] = $annotation;
86
87 19
        return $annotation;
88
    }
89
90
    /**
91
     * @param string|object $class
92
     *
93
     * @throws \ReflectionException
94
     */
95 19
    private function findAnnotationConfiguration($class, string $annotationClass): ?object
96
    {
97 19
        $reflection = new \ReflectionClass($class);
98 19
        $annotation = $this->reader->getClassAnnotation($reflection, $annotationClass);
99 19
        if (!$annotation) {
100 19
            $annotation = $this->getConfigurationFromParentClasses($reflection, $annotationClass);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $annotation is correct as $this->getConfigurationF...tion, $annotationClass) targeting Silverback\ApiComponents...tionFromParentClasses() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
101 19
            if (!$annotation) {
0 ignored issues
show
introduced by
$annotation is of type null, thus it always evaluated to false.
Loading history...
102 19
                $annotation = $this->getConfigurationFromTraits($reflection, $annotationClass);
103 19
                if (!$annotation) {
104 19
                    throw new InvalidArgumentException(sprintf('%s does not have %s annotation', \is_object($class) ? \get_class($class) : $class, $annotationClass));
105
                }
106
            }
107
        }
108
109 19
        return $annotation;
110
    }
111
112 19
    private function getConfigurationFromParentClasses(\ReflectionClass $reflection, string $annotationClass): ?object
113
    {
114 19
        $annotation = null;
115
116 19
        $parentReflection = $reflection->getParentClass();
117
        while (
118 19
            $parentReflection &&
119 19
            !$annotation = $this->reader->getClassAnnotation($parentReflection, $annotationClass)
120
        ) {
121 19
            $parentReflection = $parentReflection->getParentClass();
122
        }
123
124 19
        return $annotation;
125
    }
126
127 19
    private function getConfigurationFromTraits(\ReflectionClass $reflection, string $annotationClass): ?object
128
    {
129 19
        $annotation = null;
130 19
        $traits = $reflection->getTraits();
131 19
        foreach ($traits as $trait) {
132 19
            $annotation = $this->reader->getClassAnnotation($trait, $annotationClass);
133 19
            if ($annotation) {
134
                break;
135
            }
136
        }
137
138 19
        return $annotation;
139
    }
140
}
141