Passed
Push — master ( 949343...ba585c )
by Jesús
03:36 queued 12s
created

AbstractClassResolver::findClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Framework\ClassResolver;
6
7
use Gacela\Framework\ClassResolver\ClassNameFinder\ClassNameFinderInterface;
8
use Gacela\Framework\ClassResolver\DependencyResolver\DependencyResolver;
9
use Gacela\Framework\ClassResolver\GlobalInstance\AnonymousGlobal;
10
use Gacela\Framework\Config;
11
use Gacela\Framework\Config\GacelaFileConfig\GacelaConfigFile;
12
use function class_exists;
13
use function is_string;
14
15
abstract class AbstractClassResolver
16
{
17
    /** @var array<string,null|object> */
18
    private static array $cachedInstances = [];
19
20
    private ?ClassNameFinderInterface $classNameFinder = null;
21
22
    private ?DependencyResolver $dependencyResolver = null;
23
24
    private ?GacelaConfigFile $gacelaFileConfig = null;
25
26
    abstract public function resolve(object $callerClass): ?object;
27
28
    abstract protected function getResolvableType(): string;
29
30 25
    public function doResolve(object $callerClass): ?object
31
    {
32 25
        $classInfo = ClassInfo::fromObject($callerClass, $this->getResolvableType());
33 25
        $cacheKey = $classInfo->getCacheKey();
34
35 25
        $resolvedClass = $this->resolveCached($cacheKey);
36 25
        if (null !== $resolvedClass) {
37 7
            return $resolvedClass;
38
        }
39
40 18
        $resolvedClassName = $this->findClassName($classInfo);
41 18
        if (null === $resolvedClassName) {
42 3
            return null;
43
        }
44
45 17
        self::$cachedInstances[$cacheKey] = $this->createInstance($resolvedClassName);
46
47 17
        return self::$cachedInstances[$cacheKey];
48
    }
49
50 25
    private function resolveCached(string $cacheKey): ?object
51
    {
52 25
        return AnonymousGlobal::getByKey($cacheKey)
53 24
            ?? self::$cachedInstances[$cacheKey]
54
            ?? null;
55
    }
56
57 18
    private function findClassName(ClassInfo $classInfo): ?string
58
    {
59 18
        return $this->getClassNameFinder()->findClassName(
60
            $classInfo,
61 18
            $this->getFinalResolvableTypes()
62
        );
63
    }
64
65 18
    private function getClassNameFinder(): ClassNameFinderInterface
66
    {
67 18
        if (null === $this->classNameFinder) {
68 18
            $this->classNameFinder = (new ClassResolverFactory())
69 18
                ->createClassNameFinder();
70
        }
71
72 18
        return $this->classNameFinder;
73
    }
74
75
    /**
76
     * Allow overriding gacela resolvable types.
77
     *
78
     * @return list<string>
79
     */
80 18
    private function getFinalResolvableTypes(): array
81
    {
82 18
        $overrideResolvableTypes = $this->getGacelaConfigFile()->getOverrideResolvableTypes();
83
84 18
        $overrideResolvable = $overrideResolvableTypes[$this->getResolvableType()] ?? $this->getResolvableType();
85
86 18
        if (is_string($overrideResolvable)) {
87 15
            $overrideResolvable = [$overrideResolvable];
88
        }
89
90 18
        return $overrideResolvable;
91
    }
92
93 17
    private function createInstance(string $resolvedClassName): ?object
94
    {
95 17
        if (class_exists($resolvedClassName)) {
96 17
            $dependencies = $this->getDependencyResolver()
97 17
                ->resolveDependencies($resolvedClassName);
98
99
            /** @psalm-suppress MixedMethodCall */
100 17
            return new $resolvedClassName(...$dependencies);
101
        }
102
103
        return null;
104
    }
105
106 17
    private function getDependencyResolver(): DependencyResolver
107
    {
108 17
        if (null === $this->dependencyResolver) {
109 17
            $this->dependencyResolver = new DependencyResolver(
110 17
                $this->getGacelaConfigFile()
111
            );
112
        }
113
114 17
        return $this->dependencyResolver;
115
    }
116
117 18
    private function getGacelaConfigFile(): GacelaConfigFile
118
    {
119 18
        if (null === $this->gacelaFileConfig) {
120 18
            $this->gacelaFileConfig = Config::getInstance()
121 18
                ->getFactory()
122 18
                ->createGacelaConfigFileFactory()
123 18
                ->createGacelaFileConfig();
124
        }
125
126 18
        return $this->gacelaFileConfig;
127
    }
128
}
129