Skip to content

Commit 5422c9b

Browse files
committed
Add simplified CacheStorage implementation
To be able to use PHPStan's caching mechanism for generating factory & proxy classes, a simplified version of a file cache storage is added.
1 parent c8faa1e commit 5422c9b

File tree

2 files changed

+202
-0
lines changed

2 files changed

+202
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the phpstan-magento package.
5+
*
6+
* (c) bitExpert AG
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
declare(strict_types=1);
12+
13+
namespace bitExpert\PHPStan\Magento\Autoload\Cache;
14+
15+
use PHPStan\Cache\CacheStorage;
16+
17+
class FileCacheStorage implements CacheStorage
18+
{
19+
/**
20+
* @var string
21+
*/
22+
private $directory;
23+
24+
/**
25+
* FileCacheStorage constructor.
26+
*
27+
* @param string $directory
28+
*/
29+
public function __construct(string $directory)
30+
{
31+
$this->directory = $directory;
32+
}
33+
34+
/**
35+
* @param string $key
36+
* @param string $variableKey
37+
* @return mixed|string|null
38+
*/
39+
public function load(string $key, string $variableKey)
40+
{
41+
return (function (string $key) {
42+
$cacheDir = $this->getCacheDir($key);
43+
$cacheFile = $this->getCacheFile($key);
44+
if (!is_file($cacheDir . '/' . $cacheFile)) {
45+
return null;
46+
}
47+
48+
return $cacheDir . '/' . $cacheFile;
49+
})($key);
50+
}
51+
52+
/**
53+
* @param string $key
54+
* @param string $variableKey
55+
* @param mixed $data
56+
*/
57+
public function save(string $key, string $variableKey, $data): void
58+
{
59+
$cacheDir = $this->getCacheDir($key);
60+
$cacheFile = $this->getCacheFile($key);
61+
$this->makeDir($cacheDir);
62+
$tmpSuccess = @file_put_contents($cacheDir . '/' . $cacheFile, $data);
63+
if ($tmpSuccess === false) {
64+
throw new \InvalidArgumentException(
65+
sprintf('Could not write data to cache file %s.', $cacheDir . '/' . $cacheFile)
66+
);
67+
}
68+
}
69+
70+
/**
71+
* @param string $key
72+
* @return string
73+
*/
74+
private function getCacheDir(string $key): string
75+
{
76+
$keyHash = sha1($key);
77+
$firstDirectory = sprintf('%s/%s', $this->directory, substr($keyHash, 0, 2));
78+
return sprintf('%s/%s', $firstDirectory, substr($keyHash, 2, 2));
79+
}
80+
81+
/**
82+
* @param string $key
83+
* @return string
84+
*/
85+
private function getCacheFile(string $key): string
86+
{
87+
return sprintf('%s.php', sha1($key));
88+
}
89+
90+
/**
91+
* @param string $directory
92+
*/
93+
private function makeDir(string $directory): void
94+
{
95+
if (is_dir($directory)) {
96+
return;
97+
}
98+
99+
$result = @mkdir($directory, 0777, true);
100+
if ($result === \false) {
101+
clearstatcache();
102+
if (is_dir($directory)) {
103+
return;
104+
}
105+
106+
$error = error_get_last();
107+
throw new \InvalidArgumentException(
108+
sprintf(
109+
'Failed to create directory "%s" (%s).',
110+
$this->directory,
111+
$error !== null ? $error['message'] : 'unknown cause'
112+
)
113+
);
114+
}
115+
}
116+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the phpstan-magento package.
5+
*
6+
* (c) bitExpert AG
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
declare(strict_types=1);
12+
13+
namespace bitExpert\PHPStan\Magento\Autoload\Cache;
14+
15+
use InvalidArgumentException;
16+
use org\bovigo\vfs\vfsStream;
17+
use org\bovigo\vfs\vfsStreamDirectory;
18+
use PHPUnit\Framework\TestCase;
19+
20+
class FileCacheStorageUnitTest extends TestCase
21+
{
22+
/**
23+
* @var vfsStreamDirectory
24+
*/
25+
private $root;
26+
/**
27+
* @var FileCacheStorage
28+
*/
29+
private $storage;
30+
31+
public function setUp(): void
32+
{
33+
$this->root = vfsStream::setup('tmp');
34+
$this->storage = new FileCacheStorage($this->root->url());
35+
}
36+
37+
/**
38+
* @test
39+
*/
40+
public function nullReturnedWhenLookingUpNonExistentFileInCache()
41+
{
42+
$absFilename = $this->storage->load('test.txt', '');
43+
44+
self::assertNull($absFilename);
45+
}
46+
47+
/**
48+
* @test
49+
*/
50+
public function absoluteFilenameReturnedWhenLookingUpExistentFileInCache()
51+
{
52+
vfsStream::create(
53+
['4b' => ['6f' => ['4b6fcb2d521ef0fd442a5301e7932d16cc9f375a.php' => 'Lorem ipsum']]],
54+
$this->root
55+
);
56+
57+
$absFilename = $this->storage->load('test.txt', '');
58+
59+
self::assertSame($absFilename, vfsStream::url('tmp/4b/6f/4b6fcb2d521ef0fd442a5301e7932d16cc9f375a.php'));
60+
}
61+
62+
/**
63+
* @test
64+
*/
65+
public function addingFileToCacheSucceeds()
66+
{
67+
$this->storage->save('test.txt', '', 'Lorem ipsum');
68+
$absFilename = $this->storage->load('test.txt', '');
69+
70+
self::assertSame($absFilename, vfsStream::url('tmp/4b/6f/4b6fcb2d521ef0fd442a5301e7932d16cc9f375a.php'));
71+
}
72+
73+
/**
74+
* @test
75+
*/
76+
public function addingFileToCacheFails()
77+
{
78+
$this->expectException(InvalidArgumentException::class);
79+
80+
// simulate full disk
81+
vfsStream::setQuota(1);
82+
83+
$this->storage->save('test.txt', '', 'Lorem ipsum');
84+
$this->storage->load('test.txt', '');
85+
}
86+
}

0 commit comments

Comments
 (0)