Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(FileCache): add config option "path" #3297

Merged
merged 1 commit into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions bridges/PixivBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ public function collectData()
}
}

/**
* todo: remove manual file cache
*/
private function cacheImage($url, $illustId, $isImage)
{
$illustId = preg_replace('/[^0-9]/', '', $illustId);
Expand Down
28 changes: 16 additions & 12 deletions caches/FileCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -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');
}
}

Expand All @@ -26,7 +30,7 @@ public function saveData($data)
{
$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;
}
Expand All @@ -52,7 +56,7 @@ public function purgeCache($seconds)
return;
}

$cachePath = $this->getPath();
$cachePath = $this->getScope();
if (!file_exists($cachePath)) {
return;
}
Expand All @@ -79,7 +83,7 @@ public function setScope($scope)
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;
}
Expand All @@ -96,24 +100,24 @@ public function setKey($key)
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()
Expand Down
3 changes: 3 additions & 0 deletions config.default.ini.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
; --- 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

Expand Down
2 changes: 2 additions & 0 deletions lib/CacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public function create(string $name = null): CacheInterface
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:
Expand Down
5 changes: 5 additions & 0 deletions lib/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
31 changes: 31 additions & 0 deletions tests/CacheTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace RssBridge\Tests;

use PHPUnit\Framework\TestCase;

class CacheTest extends TestCase
{
public function testFileCache()
{
$temporaryFolder = sprintf('%s/rss_bridge_%s/', sys_get_temp_dir(), create_random_string());
mkdir($temporaryFolder);

$sut = new \FileCache([
'path' => $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
}
}
22 changes: 7 additions & 15 deletions tests/UtilsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,6 @@ public function testFormatBytes()
$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'));
Expand All @@ -54,4 +39,11 @@ public function testSanitizePathNameInErrorMessage()
$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)));
}
}