Skip to content

Commit fb433c0

Browse files
committed
Refactored caching system
1 parent 816b036 commit fb433c0

File tree

8 files changed

+542
-236
lines changed

8 files changed

+542
-236
lines changed

src/Service/Cache/CachePaths.php renamed to src/Core/Cache/CachePaths.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
<?php
22
/** @noinspection PhpPropertyOnlyWrittenInspection */
3-
namespace Okapi\CodeTransformer\Service\Cache;
3+
namespace Okapi\CodeTransformer\Core\Cache;
44

55
use DI\Attribute\Inject;
6-
use Okapi\CodeTransformer\Service\Options;
6+
use Okapi\CodeTransformer\Core\Options;
77
use Okapi\Path\Path;
88

99
/**
1010
* # Cache Paths
1111
*
12-
* The `CachePaths` class is responsible for generating the cache paths for
13-
* the different types of files that are generated by the Code Transformer.
12+
* This class is responsible for generating the cache paths for the different
13+
* types of files that are generated by the Code Transformer.
1414
*/
1515
class CachePaths
1616
{
17+
// region DI
18+
19+
#[Inject]
20+
private Options $options;
21+
22+
// endregion
23+
1724
/**
1825
* # Directory of the transformed classes.
1926
*
@@ -32,13 +39,6 @@ class CachePaths
3239
*/
3340
private string $cacheFileName = 'cache_states.php';
3441

35-
// region DI
36-
37-
#[Inject]
38-
private Options $options;
39-
40-
// endregion
41-
4242
/**
4343
* Get the file path for a transformed file.
4444
*

src/Core/Cache/CacheState.php

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
<?php
2+
/** @noinspection PhpPropertyOnlyWrittenInspection */
3+
namespace Okapi\CodeTransformer\Core\Cache;
4+
5+
/**
6+
* # Cache State
7+
*
8+
* This class is responsible for storing the state of the cache.
9+
*/
10+
abstract class CacheState
11+
{
12+
public const TYPE = 'type';
13+
14+
public const ORIGINAL_FILE_PATH_KEY = 'originalFilePath';
15+
public const MODIFICATION_TIME_KEY = 'modificationTime';
16+
17+
public string $originalFilePath;
18+
public int $modificationTime;
19+
20+
/**
21+
* CacheState constructor.
22+
*
23+
* @param array<string, (string|int|string[])> $data
24+
*/
25+
public function __construct(
26+
array $data = [],
27+
) {
28+
$this->setData($data);
29+
}
30+
31+
/**
32+
* Get the cache state as an array.
33+
*
34+
* @return array<string, (string|int|string[])>
35+
*/
36+
public function toArray(): array
37+
{
38+
return [
39+
static::TYPE => $this->getType(),
40+
...$this->getAllData(),
41+
];
42+
}
43+
44+
/**
45+
* Get the cache state as an array.
46+
*
47+
* @return array<string, (string|int|string[])>
48+
*/
49+
private function getAllData(): array
50+
{
51+
$data = [];
52+
53+
foreach ($this->getRequiredKeys() as $key) {
54+
$data[$key] = $this->{$key};
55+
}
56+
57+
return $data;
58+
}
59+
60+
/**
61+
* Get the cache state type.
62+
*
63+
* @return string
64+
*/
65+
protected function getType(): string
66+
{
67+
// Return the class name without the namespace
68+
return substr(
69+
static::class,
70+
strrpos(static::class, '\\') + 1,
71+
);
72+
}
73+
74+
/**
75+
* Get the required keys for the cache state.
76+
*
77+
* @return string[]
78+
*/
79+
public function getRequiredKeys(): array
80+
{
81+
return [
82+
static::ORIGINAL_FILE_PATH_KEY,
83+
static::MODIFICATION_TIME_KEY,
84+
];
85+
}
86+
87+
/**
88+
* Validate the cache state.
89+
*
90+
* @param array<string, (string|int|string[])> $cacheStateArray
91+
*
92+
* @return bool
93+
*/
94+
public function valid(array $cacheStateArray): bool
95+
{
96+
// Check if all required keys are present
97+
foreach ($this->getRequiredKeys() as $requiredKey) {
98+
if (!isset($cacheStateArray[$requiredKey])) {
99+
// @codeCoverageIgnoreStart
100+
return false;
101+
// @codeCoverageIgnoreEnd
102+
}
103+
}
104+
105+
return true;
106+
}
107+
108+
/**
109+
* Set the cache state data.
110+
*
111+
* @param array<string, (string|int|string[])> $cacheStateArray
112+
*/
113+
public function setData(array $cacheStateArray): void
114+
{
115+
foreach ($cacheStateArray as $key => $value) {
116+
$this->{$key} = $value;
117+
}
118+
}
119+
120+
/**
121+
* Check if the cache state is fresh (not outdated).
122+
*
123+
* @return bool
124+
*/
125+
public function isFresh(): bool
126+
{
127+
if (filemtime($this->originalFilePath) > $this->modificationTime) {
128+
return false;
129+
}
130+
131+
return true;
132+
}
133+
134+
/**
135+
* Get the file path.
136+
*
137+
* @return string|null
138+
*/
139+
abstract public function getFilePath(): ?string;
140+
141+
// /**
142+
// * CacheState constructor.
143+
// *
144+
// * @param string $originalFilePath
145+
// * @param string $className
146+
// * @param string|null $cachedFilePath
147+
// * @param int|null $transformedTime
148+
// * @param string[]|null $transformerFilePaths
149+
// */
150+
// public function __construct(
151+
// public string $originalFilePath,
152+
// public string $className,
153+
// public ?string $cachedFilePath,
154+
// public ?int $transformedTime,
155+
// public ?array $transformerFilePaths,
156+
// ) {}
157+
//
158+
// /**
159+
// * Use the cached file path if aspects have been applied.
160+
// * Otherwise, use the original file path if no aspects have been applied.
161+
// *
162+
// * @return string
163+
// */
164+
// public function getFilePath(): string
165+
// {
166+
// return $this->cachedFilePath ?? $this->originalFilePath;
167+
// }
168+
//
169+
//
170+
//
171+
//
172+
// /**
173+
// * Get the cache state as an array.
174+
// *
175+
// * @return array
176+
// */
177+
// public function toArray(): array
178+
// {
179+
// return [
180+
// $this->originalFilePath,
181+
// $this->className,
182+
// $this->cachedFilePath,
183+
// $this->transformedTime,
184+
// $this->transformerFilePaths,
185+
// ];
186+
// }
187+
//
188+
// /**
189+
// * Check if the cache is not outdated.
190+
// *
191+
// * @return bool
192+
// */
193+
// public function isFresh(): bool
194+
// {
195+
// // @codeCoverageIgnoreStart
196+
// // This should only happen if the project is misconfigured
197+
// if ($this->checkInfiniteLoop()) {
198+
// return false;
199+
// }
200+
// // @codeCoverageIgnoreEnd
201+
//
202+
// $allFiles = array_merge(
203+
// [$this->originalFilePath],
204+
// $this->transformerFilePaths,
205+
// );
206+
//
207+
// if ($this->checkFilesModified($allFiles)) {
208+
// return false;
209+
// }
210+
//
211+
// if ($this->cachedFilePath) {
212+
// $allFiles[] = $this->cachedFilePath;
213+
// }
214+
//
215+
// if (!$this->checkFilesExist($allFiles)) {
216+
// return false;
217+
// }
218+
//
219+
// if (!$this->checkTransformerCount()) {
220+
// return false;
221+
// }
222+
//
223+
// return true;
224+
// }
225+
//
226+
// /**
227+
// * Check if the cache is in an infinite loop.
228+
// *
229+
// * @return bool True if the cache is in an infinite loop
230+
// */
231+
// protected function checkInfiniteLoop(): bool
232+
// {
233+
// if ($this->cachedFilePath !== null) {
234+
// // Same original file and cached file
235+
// if ($this->originalFilePath === $this->cachedFilePath) {
236+
// return true;
237+
// }
238+
// }
239+
//
240+
// return false;
241+
// }
242+
//
243+
// /**
244+
// * Check if the files have been modified.
245+
// *
246+
// * @param string[] $files
247+
// *
248+
// * @return bool True if any file has been modified
249+
// */
250+
// protected function checkFilesModified(array $files): bool
251+
// {
252+
// $lastModified = max(array_map('filemtime', $files));
253+
// if ($lastModified >= $this->transformedTime) {
254+
// return true;
255+
// }
256+
//
257+
// return false;
258+
// }
259+
//
260+
// /**
261+
// * Check if the files exist.
262+
// *
263+
// * @param string[] $files
264+
// *
265+
// * @return bool True if all files exist
266+
// */
267+
// protected function checkFilesExist(array $files): bool
268+
// {
269+
// // Check if the cache file exists
270+
// foreach ($files as $file) {
271+
// if (!file_exists($file)) {
272+
// return false;
273+
// }
274+
// }
275+
//
276+
// return true;
277+
// }
278+
//
279+
// /**
280+
// * Check if the transformer count is the same.
281+
// *
282+
// * @return bool True if the count is the same
283+
// */
284+
// protected function checkTransformerCount(): bool
285+
// {
286+
// // Checking the count alone should be enough
287+
// $cachedTransformerCount = count($this->transformerFilePaths);
288+
// $currentTransformerCount = count(
289+
// $this->transformerMatcher->match($this->className),
290+
// );
291+
// if ($cachedTransformerCount !== $currentTransformerCount) {
292+
// return false;
293+
// }
294+
//
295+
// return true;
296+
// }
297+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Okapi\CodeTransformer\Core\Cache\CacheState;
4+
5+
use Okapi\CodeTransformer\Core\Cache\CacheState;
6+
7+
/**
8+
* TODO: docs
9+
*/
10+
class EmptyResultCacheState extends CacheState
11+
{
12+
/**
13+
* @inheritDoc
14+
*/
15+
public function getFilePath(): ?string
16+
{
17+
return null;
18+
}
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Okapi\CodeTransformer\Core\Cache\CacheState;
4+
5+
use Okapi\CodeTransformer\Core\Cache\CacheState;
6+
7+
// TODO: docs
8+
class NoTransformationsCacheState extends CacheState
9+
{
10+
/**
11+
* @inheritDoc
12+
*/
13+
public function getFilePath(): ?string
14+
{
15+
return null;
16+
}
17+
}

0 commit comments

Comments
 (0)