From 556a417dd6bf39b1a4892bc2c935f32b0d710f28 Mon Sep 17 00:00:00 2001 From: logmanoriginal Date: Wed, 6 Feb 2019 18:52:44 +0100 Subject: [PATCH] core: Add support for custom cache types via config.ini.php This commit adds support for a new parameter which specifies the type of cache to use for caching. It is specified in config.ini.php: [cache] type = "..." Currently only one type of cache is supported (see /caches). All uses of 'FileCache' were replaced by this configuration option. Note: Caching currently depends on files and folders (due to FileCache). Experience may vary depending on the selected cache type. For now always check if FileCache is working before testing alternative types. References #1000 --- actions/DisplayAction.php | 2 +- bridges/ElloBridge.php | 2 +- bridges/WordPressPluginUpdateBridge.php | 2 +- config.default.ini.php | 4 ++ lib/Cache.php | 73 +++++++++++++++++++++++++ lib/Configuration.php | 3 + lib/contents.php | 4 +- 7 files changed, 85 insertions(+), 5 deletions(-) diff --git a/actions/DisplayAction.php b/actions/DisplayAction.php index 6b599329..b223b757 100644 --- a/actions/DisplayAction.php +++ b/actions/DisplayAction.php @@ -85,7 +85,7 @@ class DisplayAction extends ActionAbstract { ); // Initialize cache - $cache = Cache::create('FileCache'); + $cache = Cache::create(Configuration::getConfig('cache', 'type')); $cache->setPath(PATH_CACHE); $cache->purgeCache(86400); // 24 hours $cache->setParameters($cache_params); diff --git a/bridges/ElloBridge.php b/bridges/ElloBridge.php index 22f5d309..45d33a53 100644 --- a/bridges/ElloBridge.php +++ b/bridges/ElloBridge.php @@ -120,7 +120,7 @@ class ElloBridge extends BridgeAbstract { } private function getAPIKey() { - $cache = Cache::create('FileCache'); + $cache = Cache::create(Configuration::getConfig('cache', 'type')); $cache->setPath(PATH_CACHE); $cache->setParameters(['key']); $key = $cache->loadData(); diff --git a/bridges/WordPressPluginUpdateBridge.php b/bridges/WordPressPluginUpdateBridge.php index 80b53eac..51ddd5b7 100644 --- a/bridges/WordPressPluginUpdateBridge.php +++ b/bridges/WordPressPluginUpdateBridge.php @@ -75,7 +75,7 @@ class WordPressPluginUpdateBridge extends BridgeAbstract { private function getCachedDate($url){ Debug::log('getting pubdate from url ' . $url . ''); // Initialize cache - $cache = Cache::create('FileCache'); + $cache = Cache::create(Configuration::getConfig('cache', 'type')); $cache->setPath(PATH_CACHE . 'pages/'); $params = [$url]; $cache->setParameters($params); diff --git a/config.default.ini.php b/config.default.ini.php index 2d6fca12..394658d6 100644 --- a/config.default.ini.php +++ b/config.default.ini.php @@ -6,6 +6,10 @@ [cache] +; Defines the cache type used by RSS-Bridge +; "file" = FileCache (default) +type = "file" + ; Allow users to specify custom timeout for specific requests. ; true = enabled ; false = disabled (default) diff --git a/lib/Cache.php b/lib/Cache.php index a0d2ac77..6826d4cc 100644 --- a/lib/Cache.php +++ b/lib/Cache.php @@ -64,6 +64,8 @@ class Cache { * @return object|bool The cache object or false if the class is not instantiable. */ public static function create($name){ + $name = self::sanitizeCacheName($name) . 'Cache'; + if(!self::isCacheName($name)) { throw new \InvalidArgumentException('Cache name invalid!'); } @@ -137,4 +139,75 @@ class Cache { public static function isCacheName($name){ return is_string($name) && preg_match('/^[A-Z][a-zA-Z0-9-]*$/', $name) === 1; } + + /** + * Returns a list of cache names from the working directory. + * + * The list is cached internally to allow for successive calls. + * + * @return array List of cache names + */ + public static function getCacheNames(){ + + static $cacheNames = array(); // Initialized on first call + + if(empty($cacheNames)) { + $files = scandir(self::getWorkingDir()); + + if($files !== false) { + foreach($files as $file) { + if(preg_match('/^([^.]+)Cache\.php$/U', $file, $out)) { + $cacheNames[] = $out[1]; + } + } + } + } + + return $cacheNames; + } + + /** + * Returns the sanitized cache name. + * + * The cache name can be specified in various ways: + * * The PHP file name (i.e. `FileCache.php`) + * * The PHP file name without file extension (i.e. `FileCache`) + * * The cache name (i.e. `file`) + * + * Casing is ignored (i.e. `FILE` and `fIlE` are the same). + * + * A cache file matching the given cache name must exist in the working + * directory! + * + * @param string $name The cache name + * @return string|null The sanitized cache name if the provided name is + * valid, null otherwise. + */ + protected static function sanitizeCacheName($name) { + + if(is_string($name)) { + + // Trim trailing '.php' if exists + if(preg_match('/(.+)(?:\.php)/', $name, $matches)) { + $name = $matches[1]; + } + + // Trim trailing 'Cache' if exists + if(preg_match('/(.+)(?:Cache)/i', $name, $matches)) { + $name = $matches[1]; + } + + // The name is valid if a corresponding file is found on disk + if(in_array(strtolower($name), array_map('strtolower', self::getCacheNames()))) { + $index = array_search(strtolower($name), array_map('strtolower', self::getCacheNames())); + return self::getCacheNames()[$index]; + } + + Debug::log('Invalid cache name specified: "' . $name . '"!'); + + } + + return null; // Bad parameter + + } } diff --git a/lib/Configuration.php b/lib/Configuration.php index 63144d26..3a2a7bf3 100644 --- a/lib/Configuration.php +++ b/lib/Configuration.php @@ -179,6 +179,9 @@ final class Configuration { /** Name of the proxy server */ define('PROXY_NAME', self::getConfig('proxy', 'name')); + if(!is_string(self::getConfig('cache', 'type'))) + die('Parameter [cache] => "type" is not a valid string! Please check "config.ini.php"!'); + if(!is_bool(self::getConfig('cache', 'custom_timeout'))) die('Parameter [cache] => "custom_timeout" is not a valid Boolean! Please check "config.ini.php"!'); diff --git a/lib/contents.php b/lib/contents.php index dc0ca517..976ecbee 100644 --- a/lib/contents.php +++ b/lib/contents.php @@ -45,7 +45,7 @@ function getContents($url, $header = array(), $opts = array()){ Debug::log('Reading contents from "' . $url . '"'); // Initialize cache - $cache = Cache::create('FileCache'); + $cache = Cache::create(Configuration::getConfig('cache', 'type')); $cache->setPath(PATH_CACHE . 'server/'); $cache->purgeCache(86400); // 24 hours (forced) @@ -268,7 +268,7 @@ $defaultSpanText = DEFAULT_SPAN_TEXT){ Debug::log('Caching url ' . $url . ', duration ' . $duration); // Initialize cache - $cache = Cache::create('FileCache'); + $cache = Cache::create(Configuration::getConfig('cache', 'type')); $cache->setPath(PATH_CACHE . 'pages/'); $cache->purgeCache(86400); // 24 hours (forced)