Skip to content

Commit a86e405

Browse files
committed
feat: add FileLocatorCached class
1 parent edfa0b5 commit a86e405

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<?php
2+
3+
/**
4+
* This file is part of CodeIgniter 4 framework.
5+
*
6+
* (c) CodeIgniter Foundation <[email protected]>
7+
*
8+
* For the full copyright and license information, please view
9+
* the LICENSE file that was distributed with this source code.
10+
*/
11+
12+
namespace CodeIgniter\Autoloader;
13+
14+
use CodeIgniter\Cache\CacheInterface;
15+
use CodeIgniter\Cache\FactoriesCache\FileVarExportHandler;
16+
17+
/**
18+
* FileLocator with Cache
19+
*
20+
* There is no FileLocator interface, so this extends FileLocator.
21+
*/
22+
final class FileLocatorCached extends FileLocator
23+
{
24+
private FileLocator $locator;
25+
26+
/**
27+
* @var CacheInterface|FileVarExportHandler
28+
*/
29+
private $cacheHandler;
30+
31+
/**
32+
* Cache data
33+
*
34+
* [method => data]
35+
* E.g.,
36+
* [
37+
* 'search' => [$path => $foundPaths],
38+
* ]
39+
*/
40+
private array $cache = [];
41+
42+
/**
43+
* Is the cache updated?
44+
*/
45+
private bool $cacheUpdated = false;
46+
47+
private string $cacheKey = 'FileLocatorCache';
48+
49+
/**
50+
* @param CacheInterface|FileVarExportHandler|null $cache
51+
*/
52+
public function __construct(FileLocator $locator, $cache = null)
53+
{
54+
// Do not call parent constructor.
55+
56+
$this->cacheHandler = $cache ?? new FileVarExportHandler();
57+
$this->locator = $locator;
58+
59+
$this->loadCache();
60+
}
61+
62+
private function loadCache(): void
63+
{
64+
$data = $this->cacheHandler->get($this->cacheKey);
65+
66+
if (is_array($data)) {
67+
$this->cache = $data;
68+
}
69+
}
70+
71+
public function __destruct()
72+
{
73+
$this->saveCache();
74+
}
75+
76+
private function saveCache(): void
77+
{
78+
if ($this->cacheUpdated) {
79+
$this->cacheHandler->save($this->cacheKey, $this->cache, 3600 * 24);
80+
}
81+
}
82+
83+
protected function getNamespaces()
84+
{
85+
if (isset($this->cache['getNamespaces'])) {
86+
return $this->cache['getNamespaces'];
87+
}
88+
89+
$namespaces = $this->locator->getNamespaces();
90+
91+
$this->cache['getNamespaces'] = $namespaces;
92+
$this->cacheUpdated = true;
93+
94+
return $namespaces;
95+
}
96+
97+
public function findQualifiedNameFromPath(string $path): false|string
98+
{
99+
if (isset($this->cache['findQualifiedNameFromPath'][$path])) {
100+
return $this->cache['findQualifiedNameFromPath'][$path];
101+
}
102+
103+
$classname = $this->locator->findQualifiedNameFromPath($path);
104+
105+
$this->cache['findQualifiedNameFromPath'][$path] = $classname;
106+
$this->cacheUpdated = true;
107+
108+
return $classname;
109+
}
110+
111+
public function getClassname(string $file): string
112+
{
113+
if (isset($this->cache['getClassname'][$file])) {
114+
return $this->cache['getClassname'][$file];
115+
}
116+
117+
$classname = $this->locator->getClassname($file);
118+
119+
$this->cache['getClassname'][$file] = $classname;
120+
$this->cacheUpdated = true;
121+
122+
return $classname;
123+
}
124+
125+
public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array
126+
{
127+
if (isset($this->cache['search'][$path][$ext][$prioritizeApp])) {
128+
return $this->cache['search'][$path][$ext][$prioritizeApp];
129+
}
130+
131+
$foundPaths = $this->locator->search($path, $ext, $prioritizeApp);
132+
133+
$this->cache['search'][$path][$ext][$prioritizeApp] = $foundPaths;
134+
$this->cacheUpdated = true;
135+
136+
return $foundPaths;
137+
}
138+
139+
public function listFiles(string $path): array
140+
{
141+
if (isset($this->cache['listFiles'][$path])) {
142+
return $this->cache['listFiles'][$path];
143+
}
144+
145+
$files = $this->locator->listFiles($path);
146+
147+
$this->cache['listFiles'][$path] = $files;
148+
$this->cacheUpdated = true;
149+
150+
return $files;
151+
}
152+
153+
public function listNamespaceFiles(string $prefix, string $path): array
154+
{
155+
if (isset($this->cache['listNamespaceFiles'][$prefix][$path])) {
156+
return $this->cache['listNamespaceFiles'][$prefix][$path];
157+
}
158+
159+
$files = $this->locator->listNamespaceFiles($prefix, $path);
160+
161+
$this->cache['listNamespaceFiles'][$prefix][$path] = $files;
162+
$this->cacheUpdated = true;
163+
164+
return $files;
165+
}
166+
167+
public function locateFile(string $file, ?string $folder = null, string $ext = 'php')
168+
{
169+
if (isset($this->cache['locateFile'][$file][$folder][$ext])) {
170+
return $this->cache['locateFile'][$file][$folder][$ext];
171+
}
172+
173+
$files = $this->locator->locateFile($file, $folder, $ext);
174+
175+
$this->cache['locateFile'][$file][$folder][$ext] = $files;
176+
$this->cacheUpdated = true;
177+
178+
return $files;
179+
}
180+
}

0 commit comments

Comments
 (0)