Passed
Push — feat/cache-warming ( 42d7a7...77c6b1 )
by Chema
10:00 queued 05:54
created

AbstractPhpFileCache::clearStaticCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Framework\ClassResolver\Cache;
6
7
use RuntimeException;
8
9
use function sprintf;
10
11
use const LOCK_EX;
12
13
abstract class AbstractPhpFileCache implements CacheInterface
14
{
15
    /** @var array<class-string,array<string,string>> */
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<class-string,array<string,string>> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array<class-string,array<string,string>>.
Loading history...
16
    private static array $cache = [];
17
18
    public function __construct(
19
        private readonly string $cacheDir,
20
    ) {
21
        self::$cache[static::class] = $this->getExistingCache();
22
    }
23
24
    /**
25
     * @internal
26
     *
27
     * @return array<string,string>
28
     */
29
    public static function all(): array
30
    {
31
        return self::$cache[static::class];
32
    }
33
34
    /**
35
     * Clears the static in-memory cache.
36
     * Useful for testing to ensure test isolation when tests run in the same PHP process.
37
     *
38
     * @internal
39
     */
40
    public static function clearStaticCache(): void
41
    {
42
        self::$cache[static::class] = [];
43
    }
44
45
    public function has(string $cacheKey): bool
46
    {
47
        return isset(self::$cache[static::class][$cacheKey]);
48
    }
49
50
    public function get(string $cacheKey): string
51
    {
52
        return self::$cache[static::class][$cacheKey];
53
    }
54
55
    /**
56
     * @return array<string,string>
57
     */
58
    public function getAll(): array
59
    {
60
        return self::$cache[static::class];
61
    }
62
63
    public function put(string $cacheKey, string $className): void
64
    {
65
        if (isset(self::$cache[static::class][$cacheKey])
66
            && self::$cache[static::class][$cacheKey] === $className
67
        ) {
68
            return;
69
        }
70
71
        self::$cache[static::class][$cacheKey] = $className;
72
73
        $fileContent = sprintf(
74
            '<?php return %s;',
75
            var_export(self::$cache[static::class], true),
76
        );
77
78
        file_put_contents($this->getAbsoluteCacheFilename(), $fileContent, LOCK_EX);
79
    }
80
81
    abstract protected function getCacheFilename(): string;
82
83
    /**
84
     * @return array<string,string>
85
     */
86
    private function getExistingCache(): array
87
    {
88
        $filename = $this->getAbsoluteCacheFilename();
89
90
        if (file_exists($filename)) {
91
            /** @var array<string,string> $content */
92
            $content = require $filename;
93
94
            return $content;
95
        }
96
97
        return [];
98
    }
99
100
    private function getAbsoluteCacheFilename(): string
101
    {
102
        if (!is_dir($this->cacheDir)
103
            && !mkdir($concurrentDirectory = $this->cacheDir, 0777, true)
104
            && !is_dir($concurrentDirectory)
105
        ) {
106
            throw new RuntimeException(sprintf('Directory "%s" was not created', $concurrentDirectory));
107
        }
108
109
        return $this->cacheDir . DIRECTORY_SEPARATOR . $this->getCacheFilename();
110
    }
111
}
112