From ecb486794b622a9ea9f563abdf8a7fa41038d4e9 Mon Sep 17 00:00:00 2001
From: Dag <me@dvikan.no>
Date: Tue, 2 Aug 2022 15:03:54 +0200
Subject: [PATCH] refactor: use static values for cache scope

This fixes a future problem when code is placed under a namespace because `get_class($bridge)` will then return e.g. `RssBridge\Bridge\TwitterBridge` instead of the the current value `TwitterBridge`.

Also a bit refactoring of `Configuration.php`.
---
 bridges/ElloBridge.php       |  2 +-
 bridges/InstagramBridge.php  |  2 +-
 bridges/SoundcloudBridge.php |  2 +-
 bridges/SpotifyBridge.php    |  2 +-
 bridges/TwitterBridge.php    |  7 ++++---
 caches/MemcachedCache.php    | 15 ++++++++-------
 caches/SQLiteCache.php       |  7 ++++---
 index.php                    |  5 +++++
 lib/BridgeAbstract.php       | 10 +++++++---
 lib/Configuration.php        | 25 ++++++++++---------------
 tests/ConfigurationTest.php  |  6 ------
 11 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/bridges/ElloBridge.php b/bridges/ElloBridge.php
index 6d9c1a70..c45e554a 100644
--- a/bridges/ElloBridge.php
+++ b/bridges/ElloBridge.php
@@ -116,7 +116,7 @@ class ElloBridge extends BridgeAbstract
         $cacheFactory = new CacheFactory();
 
         $cache = $cacheFactory->create();
-        $cache->setScope(get_called_class());
+        $cache->setScope('ElloBridge');
         $cache->setKey(['key']);
         $key = $cache->loadData();
 
diff --git a/bridges/InstagramBridge.php b/bridges/InstagramBridge.php
index 8450300c..1bfa2472 100644
--- a/bridges/InstagramBridge.php
+++ b/bridges/InstagramBridge.php
@@ -101,7 +101,7 @@ class InstagramBridge extends BridgeAbstract
         $cacheFactory = new CacheFactory();
 
         $cache = $cacheFactory->create();
-        $cache->setScope(get_called_class());
+        $cache->setScope('InstagramBridge');
         $cache->setKey([$username]);
         $key = $cache->loadData();
 
diff --git a/bridges/SoundcloudBridge.php b/bridges/SoundcloudBridge.php
index 996e9731..242402a6 100644
--- a/bridges/SoundcloudBridge.php
+++ b/bridges/SoundcloudBridge.php
@@ -125,7 +125,7 @@ HTML;
         $cacheFactory = new CacheFactory();
 
         $this->clientIDCache = $cacheFactory->create();
-        $this->clientIDCache->setScope(get_called_class());
+        $this->clientIDCache->setScope('SoundCloudBridge');
         $this->clientIDCache->setKey(['client_id']);
     }
 
diff --git a/bridges/SpotifyBridge.php b/bridges/SpotifyBridge.php
index 8af3f232..b3204dfc 100644
--- a/bridges/SpotifyBridge.php
+++ b/bridges/SpotifyBridge.php
@@ -103,7 +103,7 @@ class SpotifyBridge extends BridgeAbstract
         $cacheFactory = new CacheFactory();
 
         $cache = $cacheFactory->create();
-        $cache->setScope(get_called_class());
+        $cache->setScope('SpotifyBridge');
         $cache->setKey(['token']);
 
         if ($cache->getTime()) {
diff --git a/bridges/TwitterBridge.php b/bridges/TwitterBridge.php
index fe9f2588..cc87743a 100644
--- a/bridges/TwitterBridge.php
+++ b/bridges/TwitterBridge.php
@@ -506,7 +506,8 @@ EOD;
         $cacheFactory = new CacheFactory();
 
         $r_cache = $cacheFactory->create();
-        $r_cache->setScope(get_called_class());
+        $scope = 'TwitterBridge';
+        $r_cache->setScope($scope);
         $r_cache->setKey(['refresh']);
         $data = $r_cache->loadData();
 
@@ -521,7 +522,7 @@ EOD;
         $cacheFactory = new CacheFactory();
 
         $cache = $cacheFactory->create();
-        $cache->setScope(get_called_class());
+        $cache->setScope($scope);
         $cache->setKey(['api_key']);
         $data = $cache->loadData();
 
@@ -558,7 +559,7 @@ EOD;
         $cacheFac2 = new CacheFactory();
 
         $gt_cache = $cacheFactory->create();
-        $gt_cache->setScope(get_called_class());
+        $gt_cache->setScope($scope);
         $gt_cache->setKey(['guest_token']);
         $guestTokenUses = $gt_cache->loadData();
 
diff --git a/caches/MemcachedCache.php b/caches/MemcachedCache.php
index 8619c255..42a8ddad 100644
--- a/caches/MemcachedCache.php
+++ b/caches/MemcachedCache.php
@@ -15,22 +15,23 @@ class MemcachedCache implements CacheInterface
             returnServerError('"memcached" extension not loaded. Please check "php.ini"');
         }
 
-        $host = Configuration::getConfig(get_called_class(), 'host');
-        $port = Configuration::getConfig(get_called_class(), 'port');
+        $section = 'MemcachedCache';
+        $host = Configuration::getConfig($section, 'host');
+        $port = Configuration::getConfig($section, 'port');
         if (empty($host) && empty($port)) {
-            returnServerError('Configuration for ' . get_called_class() . ' missing. Please check your ' . FILE_CONFIG);
+            returnServerError('Configuration for ' . $section . ' missing. Please check your ' . FILE_CONFIG);
         } elseif (empty($host)) {
-            returnServerError('"host" param is not set for ' . get_called_class() . '. Please check your ' . FILE_CONFIG);
+            returnServerError('"host" param is not set for ' . $section . '. Please check your ' . FILE_CONFIG);
         } elseif (empty($port)) {
-            returnServerError('"port" param is not set for ' . get_called_class() . '. Please check your ' . FILE_CONFIG);
+            returnServerError('"port" param is not set for ' . $section . '. Please check your ' . FILE_CONFIG);
         } elseif (!ctype_digit($port)) {
-            returnServerError('"port" param is invalid for ' . get_called_class() . '. Please check your ' . FILE_CONFIG);
+            returnServerError('"port" param is invalid for ' . $section . '. Please check your ' . FILE_CONFIG);
         }
 
         $port = intval($port);
 
         if ($port < 1 || $port > 65535) {
-            returnServerError('"port" param is invalid for ' . get_called_class() . '. Please check your ' . FILE_CONFIG);
+            returnServerError('"port" param is invalid for ' . $section . '. Please check your ' . FILE_CONFIG);
         }
 
         $conn = new Memcached();
diff --git a/caches/SQLiteCache.php b/caches/SQLiteCache.php
index 6a2273e9..2f798714 100644
--- a/caches/SQLiteCache.php
+++ b/caches/SQLiteCache.php
@@ -24,16 +24,17 @@ class SQLiteCache implements CacheInterface
             );
         }
 
-        $file = Configuration::getConfig(get_called_class(), 'file');
+        $section = 'SQLiteCache';
+        $file = Configuration::getConfig($section, 'file');
         if (empty($file)) {
-            $message = sprintf('Configuration for %s missing. Please check your %s', get_called_class(), FILE_CONFIG);
+            $message = sprintf('Configuration for %s missing. Please check your %s', $section, FILE_CONFIG);
             print render('error.html.php', ['message' => $message]);
             exit;
         }
         if (dirname($file) == '.') {
             $file = PATH_CACHE . $file;
         } elseif (!is_dir(dirname($file))) {
-            $message = sprintf('Invalid configuration for %s. Please check your %s', get_called_class(), FILE_CONFIG);
+            $message = sprintf('Invalid configuration for %s. Please check your %s', $section, FILE_CONFIG);
             print render('error.html.php', ['message' => $message]);
             exit;
         }
diff --git a/index.php b/index.php
index 9eaa17a6..60ece16a 100644
--- a/index.php
+++ b/index.php
@@ -4,6 +4,11 @@ require_once __DIR__ . '/lib/rssbridge.php';
 
 Configuration::verifyInstallation();
 Configuration::loadConfiguration();
+
+date_default_timezone_set(Configuration::getConfig('system', 'timezone'));
+
+define('CUSTOM_CACHE_TIMEOUT', Configuration::getConfig('cache', 'custom_timeout'));
+
 Authentication::showPromptIfNeeded();
 
 try {
diff --git a/lib/BridgeAbstract.php b/lib/BridgeAbstract.php
index fea5fe09..16e057c7 100644
--- a/lib/BridgeAbstract.php
+++ b/lib/BridgeAbstract.php
@@ -280,7 +280,8 @@ abstract class BridgeAbstract implements BridgeInterface
     public function loadConfiguration()
     {
         foreach (static::CONFIGURATION as $optionName => $optionValue) {
-            $configurationOption = Configuration::getConfig(get_class($this), $optionName);
+            $section = (new ReflectionClass($this))->getShortName();
+            $configurationOption = Configuration::getConfig($section, $optionName);
 
             if ($configurationOption !== null) {
                 $this->configuration[$optionName] = $configurationOption;
@@ -408,7 +409,9 @@ abstract class BridgeAbstract implements BridgeInterface
         $cacheFactory = new CacheFactory();
 
         $cache = $cacheFactory->create();
-        $cache->setScope(get_called_class());
+        // Create class name without the namespace part
+        $scope = (new ReflectionClass($this))->getShortName();
+        $cache->setScope($scope);
         $cache->setKey($key);
         if ($cache->getTime() < time() - $duration) {
             return null;
@@ -427,7 +430,8 @@ abstract class BridgeAbstract implements BridgeInterface
         $cacheFactory = new CacheFactory();
 
         $cache = $cacheFactory->create();
-        $cache->setScope(get_called_class());
+        $scope = (new ReflectionClass($this))->getShortName();
+        $cache->setScope($scope);
         $cache->setKey($key);
         $cache->saveData($value);
     }
diff --git a/lib/Configuration.php b/lib/Configuration.php
index 7311c351..141f3d88 100644
--- a/lib/Configuration.php
+++ b/lib/Configuration.php
@@ -131,8 +131,8 @@ final class Configuration
             self::reportError('The default configuration file is missing at ' . FILE_CONFIG_DEFAULT);
         }
 
-        Configuration::$config = parse_ini_file(FILE_CONFIG_DEFAULT, true, INI_SCANNER_TYPED);
-        if (!Configuration::$config) {
+        $config = parse_ini_file(FILE_CONFIG_DEFAULT, true, INI_SCANNER_TYPED);
+        if (!$config) {
             self::reportError('Error parsing ' . FILE_CONFIG_DEFAULT);
         }
 
@@ -140,24 +140,26 @@ final class Configuration
             // Replace default configuration with custom settings
             foreach (parse_ini_file(FILE_CONFIG, true, INI_SCANNER_TYPED) as $header => $section) {
                 foreach ($section as $key => $value) {
-                    Configuration::$config[$header][$key] = $value;
+                    $config[$header][$key] = $value;
                 }
             }
         }
 
-        foreach (getenv() as $envkey => $value) {
+        foreach (getenv() as $envName => $envValue) {
             // Replace all settings with their respective environment variable if available
-            $keyArray = explode('_', $envkey);
+            $keyArray = explode('_', $envName);
             if ($keyArray[0] === 'RSSBRIDGE') {
                 $header = strtolower($keyArray[1]);
                 $key = strtolower($keyArray[2]);
-                if ($value === 'true' || $value === 'false') {
-                    $value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
+                if ($envValue === 'true' || $envValue === 'false') {
+                    $envValue = filter_var($envValue, FILTER_VALIDATE_BOOLEAN);
                 }
-                Configuration::$config[$header][$key] = $value;
+                $config[$header][$key] = $envValue;
             }
         }
 
+        self::$config = $config;
+
         if (
             !is_string(self::getConfig('system', 'timezone'))
             || !in_array(self::getConfig('system', 'timezone'), timezone_identifiers_list(DateTimeZone::ALL_WITH_BC))
@@ -165,14 +167,10 @@ final class Configuration
             self::reportConfigurationError('system', 'timezone');
         }
 
-        date_default_timezone_set(self::getConfig('system', 'timezone'));
-
         if (!is_string(self::getConfig('proxy', 'url'))) {
-            /** URL of the proxy server */
             self::reportConfigurationError('proxy', 'url', 'Is not a valid string');
         }
 
-        /** True if proxy usage can be enabled selectively for each bridge */
         if (!is_bool(self::getConfig('proxy', 'by_bridge'))) {
             self::reportConfigurationError('proxy', 'by_bridge', 'Is not a valid Boolean');
         }
@@ -190,9 +188,6 @@ final class Configuration
             self::reportConfigurationError('cache', 'custom_timeout', 'Is not a valid Boolean');
         }
 
-        /** True if the cache timeout can be specified by the user */
-        define('CUSTOM_CACHE_TIMEOUT', self::getConfig('cache', 'custom_timeout'));
-
         if (!is_bool(self::getConfig('authentication', 'enable'))) {
             self::reportConfigurationError('authentication', 'enable', 'Is not a valid Boolean');
         }
diff --git a/tests/ConfigurationTest.php b/tests/ConfigurationTest.php
index 6a5dce26..43ae64a3 100644
--- a/tests/ConfigurationTest.php
+++ b/tests/ConfigurationTest.php
@@ -21,11 +21,5 @@ final class ConfigurationTest extends TestCase
 
         // test value from env
         $this->assertSame('Europe/Berlin', Configuration::getConfig('system', 'timezone'));
-
-        // test real values
-        $this->assertSame('file', Configuration::getConfig('cache', 'type'));
-        $this->assertSame(false, Configuration::getConfig('authentication', 'enable'));
-        $this->assertSame(true, Configuration::getConfig('admin', 'donations'));
-        $this->assertSame(1, Configuration::getConfig('error', 'report_limit'));
     }
 }