Passed
Pull Request — master (#215)
by Jesús
06:56 queued 03:36
created

ClassInfo::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 4
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Framework\ClassResolver;
6
7
use function array_slice;
8
use function count;
9
use function get_class;
10
use function is_object;
11
use function is_string;
12
13
final class ClassInfo implements ClassInfoInterface
14
{
15
    public const MODULE_NAME_ANONYMOUS = 'module-name@anonymous';
16
17
    /** @var array<string,array<string,self>> */
18
    private static array $callerClassCache;
19
20
    private string $callerModuleNamespace;
21
    private string $callerModuleName;
22
    private string $cacheKey;
23
    private string $resolvableType;
24
25 40
    public function __construct(
26
        string $callerModuleNamespace,
27
        string $callerModuleName,
28
        string $cacheKey,
29
        string $resolvableType = ''
30
    ) {
31 40
        $this->callerModuleNamespace = $callerModuleNamespace;
32 40
        $this->callerModuleName = $callerModuleName;
33 40
        $this->cacheKey = $cacheKey;
34 40
        $this->resolvableType = $resolvableType;
35
    }
36
37
    /**
38
     * @param object|class-string $caller
0 ignored issues
show
Documentation Bug introduced by
The doc comment object|class-string at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in object|class-string.
Loading history...
39
     */
40 66
    public static function from($caller, string $resolvableType = ''): self
41
    {
42 66
        if (is_object($caller)) {
43 49
            return self::fromObject($caller, $resolvableType);
44
        }
45
46 32
        return self::fromString($caller, $resolvableType);
47
    }
48
49 43
    public function getModuleNamespace(): string
50
    {
51 43
        return $this->callerModuleNamespace;
52
    }
53
54 44
    public function getModuleName(): string
55
    {
56 44
        return $this->callerModuleName;
57
    }
58
59 65
    public function getCacheKey(): string
60
    {
61 65
        return $this->cacheKey;
62
    }
63
64
    public function getResolvableType(): string
65
    {
66
        return $this->resolvableType;
67
    }
68
69
    public function toString(): string
70
    {
71
        return sprintf(
72
            'ClassInfo{callerModuleNamespace:"%s", callerModuleName:"%s", resolvableType:"%s", cacheKey:"%s"}',
73
            $this->callerModuleNamespace,
74
            $this->callerModuleName,
75
            $this->resolvableType,
76
            $this->cacheKey,
77
        );
78
    }
79
80 49
    private static function fromObject(object $callerObject, string $resolvableType): self
81
    {
82 49
        $callerClass = get_class($callerObject);
83
84 49
        return self::fromString($callerClass, $resolvableType);
85
    }
86
87 66
    private static function fromString(string $callerClass, string $resolvableType): self
88
    {
89 66
        if (isset(self::$callerClassCache[$callerClass][$resolvableType])) {
90 38
            return self::$callerClassCache[$callerClass][$resolvableType];
91
        }
92
        /** @var list<string> $callerClassParts */
93 35
        $callerClassParts = explode('\\', ltrim($callerClass, '\\'));
94 35
        $lastCallerClassPart = end($callerClassParts);
95 35
        $filepath = is_string($lastCallerClassPart) ? $lastCallerClassPart : '';
96 35
        $filename = self::normalizeFilename($filepath);
97
98 35
        if (strpos($filepath, 'anonymous') !== false) {
99
            $callerClassParts = [
100
                self::MODULE_NAME_ANONYMOUS . '\\' . $filename,
101
                $filepath,
102
            ];
103
        }
104
105 35
        $callerFullNamespace = implode('\\', array_slice($callerClassParts, 0, count($callerClassParts) - 1));
106
107 35
        $callerModuleNamespace = substr($callerFullNamespace, 0, (int)strrpos($callerFullNamespace, '\\'));
108 35
        $callerModuleName = $callerClassParts[count($callerClassParts) - 2] ?? '';
109 35
        $cacheKey = GlobalKey::fromClassName(sprintf('\\%s\\%s', $callerFullNamespace, $resolvableType));
110
111 35
        $self = new self($callerModuleNamespace, $callerModuleName, $cacheKey, $resolvableType);
112 35
        self::$callerClassCache[$callerClass][$resolvableType] = $self;
113
114 35
        return $self;
115
    }
116
117 35
    private static function normalizeFilename(string $filepath): string
118
    {
119 35
        $filename = basename($filepath);
120 35
        $filename = substr($filename, 0, (int)strpos($filename, ':'));
121
122 35
        if (false === ($pos = strpos($filename, '.'))) {
123 33
            return $filename;
124
        }
125
126 4
        return substr($filename, 0, $pos);
127
    }
128
}
129