Passed
Push — master ( 2c1787...c36eb2 )
by Jesús
04:16 queued 13s
created

AbstractClassResolver   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 36
c 6
b 0
f 0
dl 0
loc 93
ccs 37
cts 37
cp 1
rs 10
wmc 13

7 Methods

Rating   Name   Duplication   Size   Complexity  
A doResolve() 0 18 3
A resolveCached() 0 5 1
A createInstance() 0 7 2
A getClassNameFinder() 0 8 2
A findClassName() 0 5 1
A getPossibleResolvableTypes() 0 7 2
A getGacelaConfigFile() 0 10 2
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\GlobalInstance\AnonymousGlobal;
9
use Gacela\Framework\ClassResolver\InstanceCreator\InstanceCreator;
10
use Gacela\Framework\Config;
11
use Gacela\Framework\Config\GacelaFileConfig\GacelaConfigFileInterface;
12
use function is_array;
13
14
abstract class AbstractClassResolver
15
{
16
    /** @var array<string,null|object> */
17
    private static array $cachedInstances = [];
18
19
    private ?ClassNameFinderInterface $classNameFinder = null;
20
21
    private ?GacelaConfigFileInterface $gacelaFileConfig = null;
22
23
    private ?InstanceCreator $instanceCreator = null;
24
25
    abstract public function resolve(object $callerClass): ?object;
26
27 25
    public function doResolve(object $callerClass): ?object
28
    {
29 25
        $classInfo = ClassInfo::fromObject($callerClass, $this->getResolvableType());
30 25
        $cacheKey = $classInfo->getCacheKey();
31
32 25
        $resolvedClass = $this->resolveCached($cacheKey);
33 25
        if (null !== $resolvedClass) {
34 7
            return $resolvedClass;
35
        }
36
37 18
        $resolvedClassName = $this->findClassName($classInfo);
38 18
        if (null === $resolvedClassName) {
39 3
            return null;
40
        }
41
42 17
        self::$cachedInstances[$cacheKey] = $this->createInstance($resolvedClassName);
43
44 17
        return self::$cachedInstances[$cacheKey];
45
    }
46
47
    abstract protected function getResolvableType(): string;
48
49 25
    private function resolveCached(string $cacheKey): ?object
50
    {
51 25
        return AnonymousGlobal::getByKey($cacheKey)
52 24
            ?? self::$cachedInstances[$cacheKey]
53
            ?? null;
54
    }
55
56 18
    private function findClassName(ClassInfo $classInfo): ?string
57
    {
58 18
        return $this->getClassNameFinder()->findClassName(
59
            $classInfo,
60 18
            $this->getPossibleResolvableTypes()
61
        );
62
    }
63
64 18
    private function getClassNameFinder(): ClassNameFinderInterface
65
    {
66 18
        if (null === $this->classNameFinder) {
67 18
            $this->classNameFinder = (new ClassResolverFactory())
68 18
                ->createClassNameFinder();
69
        }
70
71 18
        return $this->classNameFinder;
72
    }
73
74
    /**
75
     * Allow overriding gacela suffixes resolvable types.
76
     *
77
     * @return list<string>
78
     */
79 18
    private function getPossibleResolvableTypes(): array
80
    {
81 18
        $suffixTypes = $this->getGacelaConfigFile()->getSuffixTypes();
82
83 18
        $resolvableTypes = $suffixTypes[$this->getResolvableType()] ?? $this->getResolvableType();
84
85 18
        return is_array($resolvableTypes) ? $resolvableTypes : [$resolvableTypes];
86
    }
87
88 17
    private function createInstance(string $resolvedClassName): ?object
89
    {
90 17
        if (null === $this->instanceCreator) {
91 17
            $this->instanceCreator = new InstanceCreator($this->getGacelaConfigFile());
92
        }
93
94 17
        return $this->instanceCreator->createByClassName($resolvedClassName);
95
    }
96
97 18
    private function getGacelaConfigFile(): GacelaConfigFileInterface
98
    {
99 18
        if (null === $this->gacelaFileConfig) {
100 18
            $this->gacelaFileConfig = Config::getInstance()
101 18
                ->getFactory()
102 18
                ->createGacelaConfigFileFactory()
103 18
                ->createGacelaFileConfig();
104
        }
105
106 18
        return $this->gacelaFileConfig;
107
    }
108
}
109