diff --git a/bridges/PixivBridge.php b/bridges/PixivBridge.php index 4d885cde..cf509855 100644 --- a/bridges/PixivBridge.php +++ b/bridges/PixivBridge.php @@ -186,6 +186,9 @@ class PixivBridge extends BridgeAbstract } } + /** + * todo: remove manual file cache + */ private function cacheImage($url, $illustId, $isImage) { $illustId = preg_replace('/[^0-9]/', '', $illustId); diff --git a/caches/FileCache.php b/caches/FileCache.php index 220e6fab..8c99234d 100644 --- a/caches/FileCache.php +++ b/caches/FileCache.php @@ -3,14 +3,18 @@ class FileCache implements CacheInterface { private array $config; - protected $path; + protected $scope; protected $key; public function __construct(array $config = []) { $this->config = $config; - if (!is_writable(PATH_CACHE)) { - throw new \Exception('The cache folder is not writeable'); + + if (!is_dir($this->config['path'])) { + throw new \Exception('The cache path does not exists. You probably want: mkdir cache && chown www-data:www-data cache'); + } + if (!is_writable($this->config['path'])) { + throw new \Exception('The cache path is not writeable. You probably want: chown www-data:www-data cache'); } } @@ -26,7 +30,7 @@ class FileCache implements CacheInterface { $writeStream = file_put_contents($this->getCacheFile(), serialize($data)); if ($writeStream === false) { - throw new \Exception('Cannot write the cache... Do you have the right permissions ?'); + throw new \Exception('The cache path is not writeable. You probably want: chown www-data:www-data cache'); } return $this; } @@ -52,7 +56,7 @@ class FileCache implements CacheInterface return; } - $cachePath = $this->getPath(); + $cachePath = $this->getScope(); if (!file_exists($cachePath)) { return; } @@ -79,7 +83,7 @@ class FileCache implements CacheInterface throw new \Exception('The given scope is invalid!'); } - $this->path = PATH_CACHE . trim($scope, " \t\n\r\0\x0B\\\/") . '/'; + $this->scope = $this->config['path'] . trim($scope, " \t\n\r\0\x0B\\\/") . '/'; return $this; } @@ -96,24 +100,24 @@ class FileCache implements CacheInterface return $this; } - private function getPath() + private function getScope() { - if (is_null($this->path)) { + if (is_null($this->scope)) { throw new \Exception('Call "setScope" first!'); } - if (!is_dir($this->path)) { - if (mkdir($this->path, 0755, true) !== true) { + if (!is_dir($this->scope)) { + if (mkdir($this->scope, 0755, true) !== true) { throw new \Exception('mkdir: Unable to create file cache folder'); } } - return $this->path; + return $this->scope; } private function getCacheFile() { - return $this->getPath() . $this->getCacheName(); + return $this->getScope() . $this->getCacheName(); } private function getCacheName() diff --git a/config.default.ini.php b/config.default.ini.php index b85ec5e6..f67f315f 100644 --- a/config.default.ini.php +++ b/config.default.ini.php @@ -96,6 +96,9 @@ report_limit = 1 ; --- Cache specific configuration --------------------------------------------- [FileCache] +; The root folder to store files in. +; "" = Use the cache folder in the repository (default) +path = "" ; Whether to actually delete files when purging. Can be useful to turn off to increase performance. enable_purge = true diff --git a/lib/CacheFactory.php b/lib/CacheFactory.php index bb98fc77..4bf6342c 100644 --- a/lib/CacheFactory.php +++ b/lib/CacheFactory.php @@ -39,6 +39,8 @@ class CacheFactory return new NullCache(); case FileCache::class: return new FileCache([ + // Intentionally checking for "truthy" value + 'path' => Configuration::getConfig('FileCache', 'path') ?: PATH_CACHE, 'enable_purge' => Configuration::getConfig('FileCache', 'enable_purge'), ]); case SQLiteCache::class: diff --git a/lib/utils.php b/lib/utils.php index 9eb6f5ec..db9db0b5 100644 --- a/lib/utils.php +++ b/lib/utils.php @@ -226,3 +226,8 @@ function now(): \DateTimeImmutable { return new \DateTimeImmutable(); } + +function create_random_string(int $bytes = 16): string +{ + return bin2hex(openssl_random_pseudo_bytes($bytes)); +} diff --git a/tests/CacheTest.php b/tests/CacheTest.php new file mode 100644 index 00000000..042fc7a1 --- /dev/null +++ b/tests/CacheTest.php @@ -0,0 +1,31 @@ + $temporaryFolder, + 'enable_purge' => true, + ]); + $sut->setScope('scope'); + $sut->purgeCache(-1); + $sut->setKey(['key']); + + $this->assertNull($sut->loadData()); + + $sut->saveData('data'); + $this->assertSame('data', $sut->loadData()); + $this->assertIsNumeric($sut->getTime()); + $sut->purgeCache(-1); + + // Intentionally not deleting the temp folder + } +} diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index 451c5d5c..a7b41795 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php @@ -26,21 +26,6 @@ final class UtilsTest extends TestCase $this->assertSame('1 TB', format_bytes(1024 ** 4)); } - public function testFileCache() - { - $sut = new \FileCache(['enable_purge' => true]); - $sut->setScope('scope'); - $sut->purgeCache(-1); - $sut->setKey(['key']); - - $this->assertNull($sut->loadData()); - - $sut->saveData('data'); - $this->assertSame('data', $sut->loadData()); - $this->assertIsNumeric($sut->getTime()); - $sut->purgeCache(-1); - } - public function testSanitizePathName() { $this->assertSame('index.php', _sanitize_path_name('/home/satoshi/rss-bridge/index.php', '/home/satoshi/rss-bridge')); @@ -54,4 +39,11 @@ final class UtilsTest extends TestCase $sanitized = 'Error: Argument 1 passed to foo() must be an instance of kk, string given, called in bridges/RumbleBridge.php'; $this->assertSame($sanitized, _sanitize_path_name($raw, '/home/satoshi/rss-bridge')); } + + public function testCreateRandomString() + { + $this->assertSame(2, strlen(create_random_string(1))); + $this->assertSame(4, strlen(create_random_string(2))); + $this->assertSame(6, strlen(create_random_string(3))); + } }