]> git.mxchange.org Git - friendica.git/commitdiff
Restructure (P)Config to follow new paradigm
authorPhilipp <admin@philipp.info>
Sat, 23 Oct 2021 09:29:16 +0000 (11:29 +0200)
committerPhilipp <admin@philipp.info>
Tue, 26 Oct 2021 20:11:06 +0000 (22:11 +0200)
64 files changed:
src/App.php
src/App/Mode.php
src/Console/AutomaticInstallation.php
src/Console/DatabaseStructure.php
src/Core/BaseConfig.php [deleted file]
src/Core/BasePConfig.php [deleted file]
src/Core/Config/Cache.php [deleted file]
src/Core/Config/Cache/Cache.php [new file with mode: 0644]
src/Core/Config/Cache/ConfigFileLoader.php [new file with mode: 0644]
src/Core/Config/Factory/ConfigFactory.php [new file with mode: 0644]
src/Core/Config/IConfig.php
src/Core/Config/JitConfig.php [deleted file]
src/Core/Config/Model/Config.php [new file with mode: 0644]
src/Core/Config/Model/DbaUtils.php [new file with mode: 0644]
src/Core/Config/PreloadConfig.php [deleted file]
src/Core/Config/Type/BaseConfig.php [new file with mode: 0644]
src/Core/Config/Type/JitConfig.php [new file with mode: 0644]
src/Core/Config/Type/PreloadConfig.php [new file with mode: 0644]
src/Core/Installer.php
src/Core/PConfig/Cache.php [deleted file]
src/Core/PConfig/Cache/Cache.php [new file with mode: 0644]
src/Core/PConfig/Factory/PConfigFactory.php [new file with mode: 0644]
src/Core/PConfig/IPConfig.php
src/Core/PConfig/JitPConfig.php [deleted file]
src/Core/PConfig/Model/PConfig.php [new file with mode: 0644]
src/Core/PConfig/PreloadPConfig.php [deleted file]
src/Core/PConfig/Type/BasePConfig.php [new file with mode: 0644]
src/Core/PConfig/Type/JitPConfig.php [new file with mode: 0644]
src/Core/PConfig/Type/PreloadPConfig.php [new file with mode: 0644]
src/Database/Database.php
src/Factory/ConfigFactory.php [deleted file]
src/Model/Config/Config.php [deleted file]
src/Model/Config/DbaConfig.php [deleted file]
src/Model/Config/PConfig.php [deleted file]
src/Module/Admin/Summary.php
src/Module/Install.php
src/Util/ConfigFileLoader.php [deleted file]
src/Util/Profiler.php
static/dependencies.config.php
tests/FixtureTest.php
tests/Util/AppMockTrait.php
tests/functional/DependencyCheckTest.php
tests/src/App/ModeTest.php
tests/src/Console/AutomaticInstallationConsoleTest.php
tests/src/Core/Cache/DatabaseCacheTest.php
tests/src/Core/Config/Cache/CacheTest.php [new file with mode: 0644]
tests/src/Core/Config/Cache/ConfigFileLoaderTest.php [new file with mode: 0644]
tests/src/Core/Config/CacheTest.php [deleted file]
tests/src/Core/Config/ConfigTest.php
tests/src/Core/Config/JitConfigTest.php
tests/src/Core/Config/PreloadConfigTest.php
tests/src/Core/InstallerTest.php
tests/src/Core/Lock/DatabaseLockDriverTest.php
tests/src/Core/Lock/SemaphoreLockTest.php
tests/src/Core/PConfig/Cache/CacheTest.php [new file with mode: 0644]
tests/src/Core/PConfig/CacheTest.php [deleted file]
tests/src/Core/PConfig/JitPConfigTest.php
tests/src/Core/PConfig/PConfigTest.php
tests/src/Core/PConfig/PreloadPConfigTest.php
tests/src/Core/StorageManagerTest.php
tests/src/Model/ProcessTest.php
tests/src/Model/Storage/DatabaseStorageTest.php
tests/src/Util/Config/ConfigFileLoaderTest.php [deleted file]
tests/src/Util/ProfilerTest.php

index 3ef9bdb4ed56e326865478fba2ecbee1ea80003b..cd217c34e7ec715212962b6ed530e759b43d5a71 100644 (file)
@@ -25,10 +25,10 @@ use Exception;
 use Friendica\App\Arguments;
 use Friendica\App\BaseURL;
 use Friendica\App\Module;
-use Friendica\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Module\Maintenance;
 use Friendica\Security\Authentication;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Config\IConfig;
 use Friendica\Core\PConfig\IPConfig;
 use Friendica\Core\L10n;
@@ -39,7 +39,6 @@ use Friendica\Model\Contact;
 use Friendica\Model\Profile;
 use Friendica\Module\Special\HTTPException as ModuleHTTPException;
 use Friendica\Network\HTTPException;
-use Friendica\Util\ConfigFileLoader;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\HTTPSignature;
 use Friendica\Util\Profiler;
index 7210184a0da9dc6f50cd235885bfe54b82573f76..9f7a34a53eda466cd6c94d44cfdfed80a5cc3a56 100644 (file)
@@ -22,7 +22,7 @@
 namespace Friendica\App;
 
 use Detection\MobileDetect;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Database\Database;
 use Friendica\Util\BasePath;
 
index 5d608b00d54bbdbe4db3f86b7931611d1ee35000..9ef82524aab835f5e8a51f1e2a3c20f0eed39751 100644 (file)
@@ -25,7 +25,7 @@ use Asika\SimpleConsole\Console;
 use Friendica\App;
 use Friendica\App\BaseURL;
 use Friendica\Core\Config\IConfig;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Installer;
 use Friendica\Core\Theme;
 use Friendica\Database\Database;
@@ -36,7 +36,7 @@ class AutomaticInstallation extends Console
 {
        /** @var App\Mode */
        private $appMode;
-       /** @var Cache */
+       /** @var \Friendica\Core\Config\Cache\Cache */
        private $configCache;
        /** @var IConfig */
        private $config;
index b44400c01a0b710c6cb8dc8b36c6239b6c155731..1083a512d44f7a6128a600c3daaf6b59f3007bea 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Console;
 
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Update;
 use Friendica\Database\Database;
 use Friendica\Database\DBStructure;
diff --git a/src/Core/BaseConfig.php b/src/Core/BaseConfig.php
deleted file mode 100644 (file)
index f8583de..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core;
-
-use Friendica\Core\Config\Cache;
-use Friendica\Core\Config\IConfig;
-use Friendica\Model;
-
-/**
- * This class is responsible for all system-wide configuration values in Friendica
- * There are two types of storage
- * - The Config-Files    (loaded into the FileCache @see Cache\ConfigCache)
- * - The Config-DB-Table (per Config-DB-model @see Model\Config\Config)
- */
-abstract class BaseConfig implements IConfig
-{
-       /**
-        * @var Cache
-        */
-       protected $configCache;
-
-       /**
-        * @var Model\Config\Config
-        */
-       protected $configModel;
-
-       /**
-        * @param Cache $configCache The configuration cache (based on the config-files)
-        * @param Model\Config\Config          $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, Model\Config\Config $configModel)
-       {
-               $this->configCache = $configCache;
-               $this->configModel = $configModel;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function getCache()
-       {
-               return $this->configCache;
-       }
-}
diff --git a/src/Core/BasePConfig.php b/src/Core/BasePConfig.php
deleted file mode 100644 (file)
index 366a8e6..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core;
-
-use Friendica\Core\PConfig\Cache;
-use Friendica\Core\PConfig\IPConfig;
-use Friendica\Model;
-
-/**
- * This class is responsible for the user-specific configuration values in Friendica
- * The values are set through the Config-DB-Table (per Config-DB-model @see Model\Config\PConfig)
- *
- * The configuration cache (@see Cache\PConfigCache) is used for temporary caching of database calls. This will
- * increase the performance.
- */
-abstract class BasePConfig implements IPConfig
-{
-       /**
-        * @var Cache
-        */
-       protected $configCache;
-
-       /**
-        * @var Model\Config\PConfig
-        */
-       protected $configModel;
-
-       /**
-        * @param Cache $configCache The configuration cache
-        * @param Model\Config\PConfig          $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, Model\Config\PConfig $configModel)
-       {
-               $this->configCache = $configCache;
-               $this->configModel = $configModel;
-       }
-
-       /**
-        * Returns the Config Cache
-        *
-        * @return Cache
-        */
-       public function getCache()
-       {
-               return $this->configCache;
-       }
-}
diff --git a/src/Core/Config/Cache.php b/src/Core/Config/Cache.php
deleted file mode 100644 (file)
index 8d2eb1a..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config;
-
-use ParagonIE\HiddenString\HiddenString;
-
-/**
- * The Friendica config cache for the application
- * Initial, all *.config.php files are loaded into this cache with the
- * ConfigFileLoader ( @see ConfigFileLoader )
- */
-class Cache
-{
-       /** @var int Indicates that the cache entry is set by file - Low Priority */
-       const SOURCE_FILE = 0;
-       /** @var int Indicates that the cache entry is set by the DB config table - Middle Priority */
-       const SOURCE_DB = 1;
-       /** @var int Indicates that the cache entry is set by a server environment variable - High Priority */
-       const SOURCE_ENV = 3;
-       /** @var int Indicates that the cache entry is fixed and must not be changed */
-       const SOURCE_FIX = 4;
-
-       /** @var int Default value for a config source */
-       const SOURCE_DEFAULT = self::SOURCE_FILE;
-
-       /**
-        * @var array
-        */
-       private $config;
-
-       /**
-        * @var int[][]
-        */
-       private $source = [];
-
-       /**
-        * @var bool
-        */
-       private $hidePasswordOutput;
-
-       /**
-        * @param array $config             A initial config array
-        * @param bool  $hidePasswordOutput True, if cache variables should take extra care of password values
-        * @param int   $source             Sets a source of the initial config values
-        */
-       public function __construct(array $config = [], bool $hidePasswordOutput = true, $source = self::SOURCE_DEFAULT)
-       {
-               $this->hidePasswordOutput = $hidePasswordOutput;
-               $this->load($config, $source);
-       }
-
-       /**
-        * Tries to load the specified configuration array into the config array.
-        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
-        *
-        * @param array $config
-        * @param int   $source Indicates the source of the config entry
-        */
-       public function load(array $config, int $source = self::SOURCE_DEFAULT)
-       {
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (is_array($config[$category])) {
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       $value = $config[$category][$key];
-                                       if (isset($value)) {
-                                               $this->set($category, $key, $value, $source);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Gets a value from the config cache.
-        *
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return null|mixed Returns the value of the Config entry or null if not set
-        */
-       public function get(string $cat, string $key = null)
-       {
-               if (isset($this->config[$cat][$key])) {
-                       return $this->config[$cat][$key];
-               } else if (!isset($key) && isset($this->config[$cat])) {
-                       return $this->config[$cat];
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Sets a value in the config cache. Accepts raw output from the config table
-        *
-        * @param string $cat    Config category
-        * @param string $key    Config key
-        * @param mixed  $value  Value to set
-        * @param int    $source The source of the current config key
-        *
-        * @return bool True, if the value is set
-        */
-       public function set(string $cat, string $key, $value, $source = self::SOURCE_DEFAULT)
-       {
-               if (!isset($this->config[$cat])) {
-                       $this->config[$cat] = [];
-                       $this->source[$cat] = [];
-               }
-
-               if (isset($this->source[$cat][$key]) &&
-                       $source < $this->source[$cat][$key]) {
-                       return false;
-               }
-
-               if ($this->hidePasswordOutput &&
-                       $key == 'password' &&
-                       is_string($value)) {
-                       $this->config[$cat][$key] = new HiddenString((string)$value);
-               } else {
-                       $this->config[$cat][$key] = $value;
-               }
-
-               $this->source[$cat][$key] = $source;
-
-               return true;
-       }
-
-       /**
-        * Deletes a value from the config cache.
-        *
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return bool true, if deleted
-        */
-       public function delete(string $cat, string $key)
-       {
-               if (isset($this->config[$cat][$key])) {
-                       unset($this->config[$cat][$key]);
-                       unset($this->source[$cat][$key]);
-                       if (count($this->config[$cat]) == 0) {
-                               unset($this->config[$cat]);
-                               unset($this->source[$cat]);
-                       }
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Returns the whole configuration
-        *
-        * @return array The configuration
-        */
-       public function getAll()
-       {
-               return $this->config;
-       }
-
-       /**
-        * Returns an array with missing categories/Keys
-        *
-        * @param array $config The array to check
-        *
-        * @return array
-        */
-       public function keyDiff(array $config)
-       {
-               $return = [];
-
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (is_array($config[$category])) {
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       if (!isset($this->config[$category][$key])) {
-                                               $return[$category][$key] = $config[$category][$key];
-                                       }
-                               }
-                       }
-               }
-
-               return $return;
-       }
-}
diff --git a/src/Core/Config/Cache/Cache.php b/src/Core/Config/Cache/Cache.php
new file mode 100644 (file)
index 0000000..77e6562
--- /dev/null
@@ -0,0 +1,210 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Cache;
+
+use ParagonIE\HiddenString\HiddenString;
+
+/**
+ * The Friendica config cache for the application
+ * Initial, all *.config.php files are loaded into this cache with the
+ * ConfigFileLoader ( @see ConfigFileLoader )
+ */
+class Cache
+{
+       /** @var int Indicates that the cache entry is set by file - Low Priority */
+       const SOURCE_FILE = 0;
+       /** @var int Indicates that the cache entry is set by the DB config table - Middle Priority */
+       const SOURCE_DB = 1;
+       /** @var int Indicates that the cache entry is set by a server environment variable - High Priority */
+       const SOURCE_ENV = 3;
+       /** @var int Indicates that the cache entry is fixed and must not be changed */
+       const SOURCE_FIX = 4;
+
+       /** @var int Default value for a config source */
+       const SOURCE_DEFAULT = self::SOURCE_FILE;
+
+       /**
+        * @var array
+        */
+       private $config;
+
+       /**
+        * @var int[][]
+        */
+       private $source = [];
+
+       /**
+        * @var bool
+        */
+       private $hidePasswordOutput;
+
+       /**
+        * @param array $config             A initial config array
+        * @param bool  $hidePasswordOutput True, if cache variables should take extra care of password values
+        * @param int   $source             Sets a source of the initial config values
+        */
+       public function __construct(array $config = [], bool $hidePasswordOutput = true, $source = self::SOURCE_DEFAULT)
+       {
+               $this->hidePasswordOutput = $hidePasswordOutput;
+               $this->load($config, $source);
+       }
+
+       /**
+        * Tries to load the specified configuration array into the config array.
+        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+        *
+        * @param array $config
+        * @param int   $source Indicates the source of the config entry
+        */
+       public function load(array $config, int $source = self::SOURCE_DEFAULT)
+       {
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       $value = $config[$category][$key];
+                                       if (isset($value)) {
+                                               $this->set($category, $key, $value, $source);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Gets a value from the config cache.
+        *
+        * @param string $cat Config category
+        * @param string $key Config key
+        *
+        * @return null|mixed Returns the value of the Config entry or null if not set
+        */
+       public function get(string $cat, string $key = null)
+       {
+               if (isset($this->config[$cat][$key])) {
+                       return $this->config[$cat][$key];
+               } else if (!isset($key) && isset($this->config[$cat])) {
+                       return $this->config[$cat];
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Sets a value in the config cache. Accepts raw output from the config table
+        *
+        * @param string $cat    Config category
+        * @param string $key    Config key
+        * @param mixed  $value  Value to set
+        * @param int    $source The source of the current config key
+        *
+        * @return bool True, if the value is set
+        */
+       public function set(string $cat, string $key, $value, $source = self::SOURCE_DEFAULT)
+       {
+               if (!isset($this->config[$cat])) {
+                       $this->config[$cat] = [];
+                       $this->source[$cat] = [];
+               }
+
+               if (isset($this->source[$cat][$key]) &&
+                       $source < $this->source[$cat][$key]) {
+                       return false;
+               }
+
+               if ($this->hidePasswordOutput &&
+                       $key == 'password' &&
+                       is_string($value)) {
+                       $this->config[$cat][$key] = new HiddenString((string)$value);
+               } else {
+                       $this->config[$cat][$key] = $value;
+               }
+
+               $this->source[$cat][$key] = $source;
+
+               return true;
+       }
+
+       /**
+        * Deletes a value from the config cache.
+        *
+        * @param string $cat Config category
+        * @param string $key Config key
+        *
+        * @return bool true, if deleted
+        */
+       public function delete(string $cat, string $key)
+       {
+               if (isset($this->config[$cat][$key])) {
+                       unset($this->config[$cat][$key]);
+                       unset($this->source[$cat][$key]);
+                       if (count($this->config[$cat]) == 0) {
+                               unset($this->config[$cat]);
+                               unset($this->source[$cat]);
+                       }
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns the whole configuration
+        *
+        * @return array The configuration
+        */
+       public function getAll()
+       {
+               return $this->config;
+       }
+
+       /**
+        * Returns an array with missing categories/Keys
+        *
+        * @param array $config The array to check
+        *
+        * @return array
+        */
+       public function keyDiff(array $config)
+       {
+               $return = [];
+
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       if (!isset($this->config[$category][$key])) {
+                                               $return[$category][$key] = $config[$category][$key];
+                                       }
+                               }
+                       }
+               }
+
+               return $return;
+       }
+}
diff --git a/src/Core/Config/Cache/ConfigFileLoader.php b/src/Core/Config/Cache/ConfigFileLoader.php
new file mode 100644 (file)
index 0000000..4b1a09c
--- /dev/null
@@ -0,0 +1,368 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Cache;
+
+use Exception;
+use Friendica\Core\Addon;
+use Friendica\Core\Config\Cache\Cache;
+
+/**
+ * The ConfigFileLoader loads config-files and stores them in a ConfigCache ( @see Cache )
+ *
+ * It is capable of loading the following config files:
+ * - *.config.php   (current)
+ * - *.ini.php      (deprecated)
+ * - *.htconfig.php (deprecated)
+ */
+class ConfigFileLoader
+{
+       /**
+        * The default name of the user defined ini file
+        *
+        * @var string
+        */
+       const CONFIG_INI = 'local';
+
+       /**
+        * The default name of the user defined legacy config file
+        *
+        * @var string
+        */
+       const CONFIG_HTCONFIG = 'htconfig';
+
+       /**
+        * The sample string inside the configs, which shouldn't get loaded
+        *
+        * @var string
+        */
+       const SAMPLE_END = '-sample';
+
+       /**
+        * @var string
+        */
+       private $baseDir;
+       /**
+        * @var string
+        */
+       private $configDir;
+       /**
+        * @var string
+        */
+       private $staticDir;
+
+       /**
+        * @param string $baseDir   The base
+        * @param string $configDir
+        * @param string $staticDir
+        */
+       public function __construct(string $baseDir, string $configDir, string $staticDir)
+       {
+               $this->baseDir   = $baseDir;
+               $this->configDir = $configDir;
+               $this->staticDir = $staticDir;
+       }
+
+       /**
+        * Load the configuration files into an configuration cache
+        *
+        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
+        * expected local.config.php
+        *
+        * @param Cache $config The config cache to load to
+        * @param array $server The $_SERVER array
+        * @param bool  $raw    Setup the raw config format
+        *
+        * @throws Exception
+        */
+       public function setupCache(Cache $config, array $server = [], bool $raw = false)
+       {
+               // Load static config files first, the order is important
+               $config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_FILE);
+               $config->load($this->loadStaticConfig('settings'), Cache::SOURCE_FILE);
+
+               // try to load the legacy config first
+               $config->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
+               $config->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
+
+               // Now load every other config you find inside the 'config/' directory
+               $this->loadCoreConfig($config);
+
+               $config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV);
+
+               // In case of install mode, add the found basepath (because there isn't a basepath set yet
+               if (!$raw && empty($config->get('system', 'basepath'))) {
+                       // Setting at least the basepath we know
+                       $config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
+               }
+       }
+
+       /**
+        * Tries to load the static core-configuration and returns the config array.
+        *
+        * @param string $name The name of the configuration
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws Exception if the configuration file isn't readable
+        */
+       private function loadStaticConfig($name)
+       {
+               $configName = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.config.php';
+               $iniName    = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
+
+               if (file_exists($configName)) {
+                       return $this->loadConfigFile($configName);
+               } elseif (file_exists($iniName)) {
+                       return $this->loadINIConfigFile($iniName);
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the specified core-configuration into the config cache.
+        *
+        * @param Cache $config The Config cache
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws Exception if the configuration file isn't readable
+        */
+       private function loadCoreConfig(Cache $config)
+       {
+               // try to load legacy ini-files first
+               foreach ($this->getConfigFiles(true) as $configFile) {
+                       $config->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
+               }
+
+               // try to load supported config at last to overwrite it
+               foreach ($this->getConfigFiles() as $configFile) {
+                       $config->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
+               }
+
+               return [];
+       }
+
+       /**
+        * Tries to load the specified addon-configuration and returns the config array.
+        *
+        * @param string $name The name of the configuration
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws Exception if the configuration file isn't readable
+        */
+       public function loadAddonConfig($name)
+       {
+               $filepath = $this->baseDir . DIRECTORY_SEPARATOR .   // /var/www/html/
+                           Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
+                           $name . DIRECTORY_SEPARATOR .            // openstreetmap/
+                           'config'. DIRECTORY_SEPARATOR .              // config/
+                           $name . ".config.php";                   // openstreetmap.config.php
+
+               if (file_exists($filepath)) {
+                       return $this->loadConfigFile($filepath);
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load environment specific variables, based on the `env.config.php` mapping table
+        *
+        * @param array $server The $_SERVER variable
+        *
+        * @return array The config array (empty if no config was found)
+        *
+        * @throws Exception if the configuration file isn't readable
+        */
+       public function loadEnvConfig(array $server)
+       {
+               $filepath = $this->staticDir . DIRECTORY_SEPARATOR .   // /var/www/html/static/
+                                       "env.config.php";                          // env.config.php
+
+               if (!file_exists($filepath)) {
+                       return [];
+               }
+
+               $envConfig = $this->loadConfigFile($filepath);
+
+               $return = [];
+
+               foreach ($envConfig as $envKey => $configStructure) {
+                       if (isset($server[$envKey])) {
+                               $return[$configStructure[0]][$configStructure[1]] = $server[$envKey];
+                       }
+               }
+
+               return $return;
+       }
+
+       /**
+        * Get the config files of the config-directory
+        *
+        * @param bool $ini True, if scan for ini-files instead of config files
+        *
+        * @return array
+        */
+       private function getConfigFiles(bool $ini = false)
+       {
+               $files = scandir($this->configDir);
+               $found = array();
+
+               $filePattern = ($ini ? '*.ini.php' : '*.config.php');
+
+               // Don't load sample files
+               $sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
+
+               foreach ($files as $filename) {
+                       if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
+                               $found[] = $this->configDir . '/' . $filename;
+                       }
+               }
+
+               return $found;
+       }
+
+       /**
+        * Tries to load the legacy config files (.htconfig.php, .htpreconfig.php) and returns the config array.
+        *
+        * @param string $name The name of the config file (default is empty, which means .htconfig.php)
+        *
+        * @return array The configuration array (empty if no config found)
+        *
+        * @deprecated since version 2018.09
+        */
+       private function loadLegacyConfig($name = '')
+       {
+               $name     = !empty($name) ? $name : self::CONFIG_HTCONFIG;
+               $fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
+
+               $config = [];
+               if (file_exists($fullName)) {
+                       $a         = new \stdClass();
+                       $a->config = [];
+                       include $fullName;
+
+                       $htConfigCategories = array_keys($a->config);
+
+                       // map the legacy configuration structure to the current structure
+                       foreach ($htConfigCategories as $htConfigCategory) {
+                               if (is_array($a->config[$htConfigCategory])) {
+                                       $keys = array_keys($a->config[$htConfigCategory]);
+
+                                       foreach ($keys as $key) {
+                                               $config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
+                                       }
+                               } else {
+                                       $config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
+                               }
+                       }
+
+                       unset($a);
+
+                       if (isset($db_host)) {
+                               $config['database']['hostname'] = $db_host;
+                               unset($db_host);
+                       }
+                       if (isset($db_user)) {
+                               $config['database']['username'] = $db_user;
+                               unset($db_user);
+                       }
+                       if (isset($db_pass)) {
+                               $config['database']['password'] = $db_pass;
+                               unset($db_pass);
+                       }
+                       if (isset($db_data)) {
+                               $config['database']['database'] = $db_data;
+                               unset($db_data);
+                       }
+                       if (isset($config['system']['db_charset'])) {
+                               $config['database']['charset'] = $config['system']['db_charset'];
+                       }
+                       if (isset($pidfile)) {
+                               $config['system']['pidfile'] = $pidfile;
+                               unset($pidfile);
+                       }
+                       if (isset($default_timezone)) {
+                               $config['system']['default_timezone'] = $default_timezone;
+                               unset($default_timezone);
+                       }
+                       if (isset($lang)) {
+                               $config['system']['language'] = $lang;
+                               unset($lang);
+                       }
+               }
+
+               return $config;
+       }
+
+       /**
+        * Tries to load the specified legacy configuration file and returns the config array.
+        *
+        * @param string $filepath
+        *
+        * @return array The configuration array
+        * @throws Exception
+        * @deprecated since version 2018.12
+        */
+       private function loadINIConfigFile($filepath)
+       {
+               $contents = include($filepath);
+
+               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
+
+               if ($config === false) {
+                       throw new Exception('Error parsing INI config file ' . $filepath);
+               }
+
+               return $config;
+       }
+
+       /**
+        * Tries to load the specified configuration file and returns the config array.
+        *
+        * The config format is PHP array and the template for configuration files is the following:
+        *
+        * <?php return [
+        *      'section' => [
+        *          'key' => 'value',
+        *      ],
+        * ];
+        *
+        * @param string $filepath The filepath of the
+        *
+        * @return array The config array0
+        *
+        * @throws Exception if the config cannot get loaded.
+        */
+       private function loadConfigFile($filepath)
+       {
+               $config = include($filepath);
+
+               if (!is_array($config)) {
+                       throw new Exception('Error loading config file ' . $filepath);
+               }
+
+               return $config;
+       }
+}
diff --git a/src/Core/Config/Factory/ConfigFactory.php b/src/Core/Config/Factory/ConfigFactory.php
new file mode 100644 (file)
index 0000000..9546a02
--- /dev/null
@@ -0,0 +1,103 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Factory;
+
+use Exception;
+use Friendica\Core\Config;
+use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\Model\Config as ConfigModel;
+use Friendica\Core\Config\Cache\ConfigFileLoader;
+
+class ConfigFactory
+{
+       /**
+        * The key of the $_SERVER variable to override the config directory
+        *
+        * @var string
+        */
+       const CONFIG_DIR_ENV = 'FRIENDICA_CONFIG_DIR';
+
+       /**
+        * The Sub directory of the config-files
+        *
+        * @var string
+        */
+       const CONFIG_DIR = 'config';
+
+       /**
+        * The Sub directory of the static config-files
+        *
+        * @var string
+        */
+       const STATIC_DIR = 'static';
+
+       /**
+        * @param string $basePath The basepath of FRIENDICA
+        * @param array $serer the $_SERVER array
+        *
+        * @return \Friendica\Core\Config\Cache\ConfigFileLoader
+        */
+       public function createConfigFileLoader(string $basePath, array $server = [])
+       {
+               if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
+                       $configDir = $server[self::CONFIG_DIR_ENV];
+               } else {
+                       $configDir = $basePath . DIRECTORY_SEPARATOR . self::CONFIG_DIR;
+               }
+               $staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
+
+               return new ConfigFileLoader($basePath, $configDir, $staticDir);
+       }
+
+       /**
+        * @param \Friendica\Core\Config\Cache\ConfigFileLoader $loader The Config Cache loader (INI/config/.htconfig)
+        *
+        * @return Cache
+        *
+        * @throws Exception
+        */
+       public function createCache(ConfigFileLoader $loader, array $server = [])
+       {
+               $configCache = new Cache();
+               $loader->setupCache($configCache, $server);
+
+               return $configCache;
+       }
+
+       /**
+        * @param \Friendica\Core\Config\Cache\Cache $configCache The config cache of this adapter
+        * @param ConfigModel                        $configModel The configuration model
+        *
+        * @return Config\IConfig
+        */
+       public function create(Cache $configCache, ConfigModel $configModel)
+       {
+               if ($configCache->get('system', 'config_adapter') === 'preload') {
+                       $configuration = new Config\Type\PreloadConfig($configCache, $configModel);
+               } else {
+                       $configuration = new Config\Type\JitConfig($configCache, $configModel);
+               }
+
+
+               return $configuration;
+       }
+}
index 81ea1afd7680d31ae05b7c5efb7832d273956fbe..21cee2e92445d78b7aeba7a265c77fcb3114f98a 100644 (file)
@@ -21,6 +21,8 @@
 
 namespace Friendica\Core\Config;
 
+use Friendica\Core\Config\Cache\Cache;
+
 /**
  * Interface for accessing system wide configurations
  */
diff --git a/src/Core/Config/JitConfig.php b/src/Core/Config/JitConfig.php
deleted file mode 100644 (file)
index 8eb4ace..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config;
-
-use Friendica\Core\BaseConfig;
-use Friendica\Model;
-
-/**
- * This class implements the Just-In-Time configuration, which will cache
- * config values in a cache, once they are retrieved.
- *
- * Default Configuration type.
- * Provides the best performance for pages loading few configuration variables.
- */
-class JitConfig extends BaseConfig
-{
-       /**
-        * @var array Array of already loaded db values (even if there was no value)
-        */
-       private $db_loaded;
-
-       /**
-        * @param Cache               $configCache The configuration cache (based on the config-files)
-        * @param Model\Config\Config $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, Model\Config\Config $configModel)
-       {
-               parent::__construct($configCache, $configModel);
-               $this->db_loaded = [];
-
-               $this->load();
-       }
-
-       /**
-        * {@inheritDoc}
-        *
-        */
-       public function load(string $cat = 'config')
-       {
-               // If not connected, do nothing
-               if (!$this->configModel->isConnected()) {
-                       return;
-               }
-
-               $config = $this->configModel->load($cat);
-
-               if (!empty($config[$cat])) {
-                       foreach ($config[$cat] as $key => $value) {
-                               $this->db_loaded[$cat][$key] = true;
-                       }
-               }
-
-               // load the whole category out of the DB into the cache
-               $this->configCache->load($config, Cache::SOURCE_DB);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function get(string $cat, string $key, $default_value = null, bool $refresh = false)
-       {
-               // if the value isn't loaded or refresh is needed, load it to the cache
-               if ($this->configModel->isConnected() &&
-                   (empty($this->db_loaded[$cat][$key]) ||
-                    $refresh)) {
-
-                       $dbvalue = $this->configModel->get($cat, $key);
-
-                       if (isset($dbvalue)) {
-                               $this->configCache->set($cat, $key, $dbvalue, Cache::SOURCE_DB);
-                               unset($dbvalue);
-                       }
-
-                       $this->db_loaded[$cat][$key] = true;
-               }
-
-               // use the config cache for return
-               $result = $this->configCache->get($cat, $key);
-
-               return (isset($result)) ? $result : $default_value;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function set(string $cat, string $key, $value)
-       {
-               // set the cache first
-               $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB);
-
-               // If there is no connected adapter, we're finished
-               if (!$this->configModel->isConnected()) {
-                       return $cached;
-               }
-
-               $stored = $this->configModel->set($cat, $key, $value);
-
-               $this->db_loaded[$cat][$key] = $stored;
-
-               return $cached && $stored;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function delete(string $cat, string $key)
-       {
-               $cacheRemoved = $this->configCache->delete($cat, $key);
-
-               if (isset($this->db_loaded[$cat][$key])) {
-                       unset($this->db_loaded[$cat][$key]);
-               }
-
-               if (!$this->configModel->isConnected()) {
-                       return $cacheRemoved;
-               }
-
-               $storeRemoved = $this->configModel->delete($cat, $key);
-
-               return $cacheRemoved || $storeRemoved;
-       }
-}
diff --git a/src/Core/Config/Model/Config.php b/src/Core/Config/Model/Config.php
new file mode 100644 (file)
index 0000000..bca2145
--- /dev/null
@@ -0,0 +1,172 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Model;
+
+use Friendica\Database\Database;
+
+/**
+ * The Config model backend, which is using the general DB-model backend for configs
+ */
+class Config
+{
+       /** @var Database */
+       protected $dba;
+
+       /**
+        * @param Database $dba The database connection of this model
+        */
+       public function __construct(Database $dba)
+       {
+               $this->dba = $dba;
+       }
+
+       /**
+        * Checks if the model is currently connected
+        *
+        * @return bool
+        */
+       public function isConnected()
+       {
+               return $this->dba->isConnected();
+       }
+
+       /**
+        * Loads all configuration values and returns the loaded category as an array.
+        *
+        * @param string|null $cat The category of the configuration values to load
+        *
+        * @return array The config array
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function load(string $cat = null)
+       {
+               $return = [];
+
+               if (empty($cat)) {
+                       $configs = $this->dba->select('config', ['cat', 'v', 'k']);
+               } else {
+                       $configs = $this->dba->select('config', ['cat', 'v', 'k'], ['cat' => $cat]);
+               }
+
+               while ($config = $this->dba->fetch($configs)) {
+
+                       $key   = $config['k'];
+                       $value = DbaUtils::toConfigValue($config['v']);
+
+                       // just save it in case it is set
+                       if (isset($value)) {
+                               $return[$config['cat']][$key] = $value;
+                       }
+               }
+               $this->dba->close($configs);
+
+               return $return;
+       }
+
+       /**
+        * Get a particular, system-wide config variable out of the DB with the
+        * given category name ($cat) and a key ($key).
+        *
+        * Note: Boolean variables are defined as 0/1 in the database
+        *
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to query
+        *
+        * @return array|string|null Stored value or null if it does not exist
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function get(string $cat, string $key)
+       {
+               if (!$this->isConnected()) {
+                       return null;
+               }
+
+               $config = $this->dba->selectFirst('config', ['v'], ['cat' => $cat, 'k' => $key]);
+               if ($this->dba->isResult($config)) {
+                       $value = DbaUtils::toConfigValue($config['v']);
+
+                       // just return it in case it is set
+                       if (isset($value)) {
+                               return $value;
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Stores a config value ($value) in the category ($cat) under the key ($key).
+        *
+        * Note: Please do not store booleans - convert to 0/1 integer values!
+        *
+        * @param string $cat   The category of the configuration value
+        * @param string $key   The configuration key to set
+        * @param mixed  $value The value to store
+        *
+        * @return bool Operation success
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function set(string $cat, string $key, $value)
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               // We store our setting values in a string variable.
+               // So we have to do the conversion here so that the compare below works.
+               // The exception are array values.
+               $compare_value = (!is_array($value) ? (string)$value : $value);
+               $stored_value  = $this->get($cat, $key);
+
+               if (isset($stored_value) && ($stored_value === $compare_value)) {
+                       return true;
+               }
+
+               $dbvalue = DbaUtils::toDbValue($value);
+
+               $result = $this->dba->update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
+
+               return $result;
+       }
+
+       /**
+        * Removes the configured value from the database.
+        *
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to delete
+        *
+        * @return bool Operation success
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function delete(string $cat, string $key)
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               return $this->dba->delete('config', ['cat' => $cat, 'k' => $key]);
+       }
+}
diff --git a/src/Core/Config/Model/DbaUtils.php b/src/Core/Config/Model/DbaUtils.php
new file mode 100644 (file)
index 0000000..da2b897
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+
+namespace Friendica\Core\Config\Model;
+
+class DbaUtils
+{
+       /**
+        * Formats a DB value to a config value
+        * - null   = The db-value isn't set
+        * - bool   = The db-value is either '0' or '1'
+        * - array  = The db-value is a serialized array
+        * - string = The db-value is a string
+        *
+        * Keep in mind that there aren't any numeric/integer config values in the database
+        *
+        * @param null|string $value
+        *
+        * @return null|array|string
+        */
+       public static function toConfigValue($value)
+       {
+               if (!isset($value)) {
+                       return null;
+               }
+
+               switch (true) {
+                       // manage array value
+                       case preg_match("|^a:[0-9]+:{.*}$|s", $value):
+                               return unserialize($value);
+
+                       default:
+                               return $value;
+               }
+       }
+
+       /**
+        * Formats a config value to a DB value (string)
+        *
+        * @param mixed $value
+        *
+        * @return string
+        */
+       public static function toDbValue($value): string
+       {
+               // if not set, save an empty string
+               if (!isset($value)) {
+                       return '';
+               }
+
+               switch (true) {
+                       // manage arrays
+                       case is_array($value):
+                               return serialize($value);
+
+                       default:
+                               return (string)$value;
+               }
+       }
+}
diff --git a/src/Core/Config/PreloadConfig.php b/src/Core/Config/PreloadConfig.php
deleted file mode 100644 (file)
index a72fd16..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\Config;
-
-use Friendica\Core\BaseConfig;
-use Friendica\Model;
-
-/**
- * This class implements the preload configuration, which will cache
- * all config values per call in a cache.
- *
- * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
- */
-class PreloadConfig extends BaseConfig
-{
-       /** @var bool */
-       private $config_loaded;
-
-       /**
-        * @param Cache               $configCache The configuration cache (based on the config-files)
-        * @param Model\Config\Config $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, Model\Config\Config $configModel)
-       {
-               parent::__construct($configCache, $configModel);
-               $this->config_loaded = false;
-
-               $this->load();
-       }
-
-       /**
-        * {@inheritDoc}
-        *
-        * This loads all config values everytime load is called
-        *
-        */
-       public function load(string $cat = 'config')
-       {
-               // Don't load the whole configuration twice
-               if ($this->config_loaded) {
-                       return;
-               }
-
-               // If not connected, do nothing
-               if (!$this->configModel->isConnected()) {
-                       return;
-               }
-
-               $config              = $this->configModel->load();
-               $this->config_loaded = true;
-
-               // load the whole category out of the DB into the cache
-               $this->configCache->load($config, Cache::SOURCE_DB);
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function get(string $cat, string $key, $default_value = null, bool $refresh = false)
-       {
-               if ($refresh) {
-                       if ($this->configModel->isConnected()) {
-                               $config = $this->configModel->get($cat, $key);
-                               if (isset($config)) {
-                                       $this->configCache->set($cat, $key, $config, Cache::SOURCE_DB);
-                               }
-                       }
-               }
-
-               // use the config cache for return
-               $result = $this->configCache->get($cat, $key);
-
-               return (isset($result)) ? $result : $default_value;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function set(string $cat, string $key, $value)
-       {
-               if (!$this->config_loaded) {
-                       $this->load();
-               }
-
-               // set the cache first
-               $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB);
-
-               // If there is no connected adapter, we're finished
-               if (!$this->configModel->isConnected()) {
-                       return $cached;
-               }
-
-               $stored = $this->configModel->set($cat, $key, $value);
-
-               return $cached && $stored;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function delete(string $cat, string $key)
-       {
-               if ($this->config_loaded) {
-                       $this->load();
-               }
-
-               $cacheRemoved = $this->configCache->delete($cat, $key);
-
-               if (!$this->configModel->isConnected()) {
-                       return $cacheRemoved;
-               }
-
-               $storeRemoved = $this->configModel->delete($cat, $key);
-
-               return $cacheRemoved || $storeRemoved;
-       }
-
-       public function testSetDouble()
-       {
-               $this->configModel->shouldReceive('isConnected')
-                                                 ->andReturn(true);
-
-               // constructor loading
-               $this->configModel->shouldReceive('load')
-                                                 ->with('config')
-                                                 ->andReturn(['config' => ['test' => 'it']])
-                                                 ->once();
-
-               parent::testSetDouble();
-       }
-}
diff --git a/src/Core/Config/Type/BaseConfig.php b/src/Core/Config/Type/BaseConfig.php
new file mode 100644 (file)
index 0000000..86a847a
--- /dev/null
@@ -0,0 +1,63 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Type;
+
+use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\IConfig;
+use Friendica\Model;
+
+/**
+ * This class is responsible for all system-wide configuration values in Friendica
+ * There are two types of storage
+ * - The Config-Files    (loaded into the FileCache @see ConfigCache)
+ * - The Config-DB-Table (per Config-DB-model @see Model\Config\Config)
+ */
+abstract class BaseConfig implements IConfig
+{
+       /**
+        * @var Cache
+        */
+       protected $configCache;
+
+       /**
+        * @var \Friendica\Core\Config\Model\Config
+        */
+       protected $configModel;
+
+       /**
+        * @param Cache                               $configCache The configuration cache (based on the config-files)
+        * @param \Friendica\Core\Config\Model\Config $configModel The configuration model
+        */
+       public function __construct(Cache $configCache, \Friendica\Core\Config\Model\Config $configModel)
+       {
+               $this->configCache = $configCache;
+               $this->configModel = $configModel;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function getCache()
+       {
+               return $this->configCache;
+       }
+}
diff --git a/src/Core/Config/Type/JitConfig.php b/src/Core/Config/Type/JitConfig.php
new file mode 100644 (file)
index 0000000..5e1fe24
--- /dev/null
@@ -0,0 +1,141 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Type;
+
+use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\Model\Config;
+
+/**
+ * This class implements the Just-In-Time configuration, which will cache
+ * config values in a cache, once they are retrieved.
+ *
+ * Default Configuration type.
+ * Provides the best performance for pages loading few configuration variables.
+ */
+class JitConfig extends BaseConfig
+{
+       /**
+        * @var array Array of already loaded db values (even if there was no value)
+        */
+       private $db_loaded;
+
+       /**
+        * @param Cache                               $configCache The configuration cache (based on the config-files)
+        * @param Config $configModel The configuration model
+        */
+       public function __construct(Cache $configCache, Config $configModel)
+       {
+               parent::__construct($configCache, $configModel);
+               $this->db_loaded = [];
+
+               $this->load();
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        */
+       public function load(string $cat = 'config')
+       {
+               // If not connected, do nothing
+               if (!$this->configModel->isConnected()) {
+                       return;
+               }
+
+               $config = $this->configModel->load($cat);
+
+               if (!empty($config[$cat])) {
+                       foreach ($config[$cat] as $key => $value) {
+                               $this->db_loaded[$cat][$key] = true;
+                       }
+               }
+
+               // load the whole category out of the DB into the cache
+               $this->configCache->load($config, Cache::SOURCE_DB);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function get(string $cat, string $key, $default_value = null, bool $refresh = false)
+       {
+               // if the value isn't loaded or refresh is needed, load it to the cache
+               if ($this->configModel->isConnected() &&
+                   (empty($this->db_loaded[$cat][$key]) ||
+                    $refresh)) {
+
+                       $dbvalue = $this->configModel->get($cat, $key);
+
+                       if (isset($dbvalue)) {
+                               $this->configCache->set($cat, $key, $dbvalue, Cache::SOURCE_DB);
+                               unset($dbvalue);
+                       }
+
+                       $this->db_loaded[$cat][$key] = true;
+               }
+
+               // use the config cache for return
+               $result = $this->configCache->get($cat, $key);
+
+               return (isset($result)) ? $result : $default_value;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function set(string $cat, string $key, $value)
+       {
+               // set the cache first
+               $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB);
+
+               // If there is no connected adapter, we're finished
+               if (!$this->configModel->isConnected()) {
+                       return $cached;
+               }
+
+               $stored = $this->configModel->set($cat, $key, $value);
+
+               $this->db_loaded[$cat][$key] = $stored;
+
+               return $cached && $stored;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function delete(string $cat, string $key)
+       {
+               $cacheRemoved = $this->configCache->delete($cat, $key);
+
+               if (isset($this->db_loaded[$cat][$key])) {
+                       unset($this->db_loaded[$cat][$key]);
+               }
+
+               if (!$this->configModel->isConnected()) {
+                       return $cacheRemoved;
+               }
+
+               $storeRemoved = $this->configModel->delete($cat, $key);
+
+               return $cacheRemoved || $storeRemoved;
+       }
+}
diff --git a/src/Core/Config/Type/PreloadConfig.php b/src/Core/Config/Type/PreloadConfig.php
new file mode 100644 (file)
index 0000000..c6abfcd
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\Config\Type;
+
+use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\Config\Model\Config;
+
+/**
+ * This class implements the preload configuration, which will cache
+ * all config values per call in a cache.
+ *
+ * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
+ */
+class PreloadConfig extends BaseConfig
+{
+       /** @var bool */
+       private $config_loaded;
+
+       /**
+        * @param Cache                               $configCache The configuration cache (based on the config-files)
+        * @param Config $configModel The configuration model
+        */
+       public function __construct(Cache $configCache, Config $configModel)
+       {
+               parent::__construct($configCache, $configModel);
+               $this->config_loaded = false;
+
+               $this->load();
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * This loads all config values everytime load is called
+        *
+        */
+       public function load(string $cat = 'config')
+       {
+               // Don't load the whole configuration twice
+               if ($this->config_loaded) {
+                       return;
+               }
+
+               // If not connected, do nothing
+               if (!$this->configModel->isConnected()) {
+                       return;
+               }
+
+               $config              = $this->configModel->load();
+               $this->config_loaded = true;
+
+               // load the whole category out of the DB into the cache
+               $this->configCache->load($config, Cache::SOURCE_DB);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function get(string $cat, string $key, $default_value = null, bool $refresh = false)
+       {
+               if ($refresh) {
+                       if ($this->configModel->isConnected()) {
+                               $config = $this->configModel->get($cat, $key);
+                               if (isset($config)) {
+                                       $this->configCache->set($cat, $key, $config, Cache::SOURCE_DB);
+                               }
+                       }
+               }
+
+               // use the config cache for return
+               $result = $this->configCache->get($cat, $key);
+
+               return (isset($result)) ? $result : $default_value;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function set(string $cat, string $key, $value)
+       {
+               if (!$this->config_loaded) {
+                       $this->load();
+               }
+
+               // set the cache first
+               $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB);
+
+               // If there is no connected adapter, we're finished
+               if (!$this->configModel->isConnected()) {
+                       return $cached;
+               }
+
+               $stored = $this->configModel->set($cat, $key, $value);
+
+               return $cached && $stored;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function delete(string $cat, string $key)
+       {
+               if ($this->config_loaded) {
+                       $this->load();
+               }
+
+               $cacheRemoved = $this->configCache->delete($cat, $key);
+
+               if (!$this->configModel->isConnected()) {
+                       return $cacheRemoved;
+               }
+
+               $storeRemoved = $this->configModel->delete($cat, $key);
+
+               return $cacheRemoved || $storeRemoved;
+       }
+
+       public function testSetDouble()
+       {
+               $this->configModel->shouldReceive('isConnected')
+                                                 ->andReturn(true);
+
+               // constructor loading
+               $this->configModel->shouldReceive('load')
+                                                 ->with('config')
+                                                 ->andReturn(['config' => ['test' => 'it']])
+                                                 ->once();
+
+               parent::testSetDouble();
+       }
+}
index 96fe941564b915f0d2e12b631ac53680bcd38007..fc0da6cbeda750c622dd4fc3876c6ec11b513cd0 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Core;
 
 use DOMDocument;
 use Exception;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Database\Database;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
@@ -278,7 +278,7 @@ class Installer
                        $cmd = "$phppath -v";
                        $result = trim(shell_exec($cmd));
                        $passed2 = (strpos($result, "(cli)") !== false);
-                       list($result) = explode("\n", $result);
+                       [$result] = explode("\n", $result);
                        $help = "";
                        if (!$passed2) {
                                $help .= DI::l10n()->t("PHP executable is not the php cli binary \x28could be cgi-fgci version\x29") . EOL;
@@ -678,8 +678,8 @@ class Installer
        /**
         * Setup the default cache for a new installation
         *
-        * @param Cache  $configCache The configuration cache
-        * @param string $basePath    The determined basepath
+        * @param \Friendica\Core\Config\Cache\Cache $configCache The configuration cache
+        * @param string                             $basePath    The determined basepath
         *
         * @throws \Friendica\Network\HTTPException\InternalServerErrorException
         */
diff --git a/src/Core/PConfig/Cache.php b/src/Core/PConfig/Cache.php
deleted file mode 100644 (file)
index d19c34d..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig;
-
-use ParagonIE\HiddenString\HiddenString;
-
-/**
- * The Friendica config cache for users
- */
-class Cache
-{
-       /**
-        * @var array
-        */
-       private $config;
-
-       /**
-        * @var bool
-        */
-       private $hidePasswordOutput;
-
-       /**
-        * @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
-        */
-       public function __construct(bool $hidePasswordOutput = true)
-       {
-               $this->hidePasswordOutput = $hidePasswordOutput;
-       }
-
-       /**
-        * Tries to load the specified configuration array into the user specific config array.
-        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
-        *
-        * @param int   $uid
-        * @param array $config
-        */
-       public function load($uid, array $config)
-       {
-               if (!is_int($uid)) {
-                       return;
-               }
-
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (isset($config[$category]) && is_array($config[$category])) {
-
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       $value = $config[$category][$key];
-                                       if (isset($value)) {
-                                               $this->set($uid, $category, $key, $value);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /**
-        * Retrieves a value from the user config cache
-        *
-        * @param int    $uid User Id
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return null|string The value of the config entry or null if not set
-        */
-       public function get($uid, string $cat, string $key = null)
-       {
-               if (!is_int($uid)) {
-                       return null;
-               }
-
-               if (isset($this->config[$uid][$cat][$key])) {
-                       return $this->config[$uid][$cat][$key];
-               } elseif (!isset($key) && isset($this->config[$uid][$cat])) {
-                       return $this->config[$uid][$cat];
-               } else {
-                       return null;
-               }
-       }
-
-       /**
-        * Sets a value in the user config cache
-        *
-        * Accepts raw output from the pconfig table
-        *
-        * @param int    $uid   User Id
-        * @param string $cat   Config category
-        * @param string $key   Config key
-        * @param mixed  $value Value to set
-        *
-        * @return bool Set successful
-        */
-       public function set($uid, string $cat, string $key, $value)
-       {
-               if (!is_int($uid)) {
-                       return false;
-               }
-
-               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
-                       $this->config[$uid] = [];
-               }
-
-               if (!isset($this->config[$uid][$cat])) {
-                       $this->config[$uid][$cat] = [];
-               }
-
-               if ($this->hidePasswordOutput &&
-                   $key == 'password' &&
-                   !empty($value) && is_string($value)) {
-                       $this->config[$uid][$cat][$key] = new HiddenString((string)$value);
-               } else {
-                       $this->config[$uid][$cat][$key] = $value;
-               }
-
-
-               return true;
-       }
-
-       /**
-        * Deletes a value from the user config cache
-        *
-        * @param int    $uid User Id
-        * @param string $cat Config category
-        * @param string $key Config key
-        *
-        * @return bool true, if deleted
-        */
-       public function delete($uid, string $cat, string $key)
-       {
-               if (!is_int($uid)) {
-                       return false;
-               }
-
-               if (isset($this->config[$uid][$cat][$key])) {
-                       unset($this->config[$uid][$cat][$key]);
-                       if (count($this->config[$uid][$cat]) == 0) {
-                               unset($this->config[$uid][$cat]);
-                               if (count($this->config[$uid]) == 0) {
-                                       unset($this->config[$uid]);
-                               }
-                       }
-
-                       return true;
-               } else {
-                       return false;
-               }
-       }
-
-       /**
-        * Returns the whole configuration
-        *
-        * @return array The configuration
-        */
-       public function getAll()
-       {
-               return $this->config;
-       }
-
-       /**
-        * Returns an array with missing categories/Keys
-        *
-        * @param array $config The array to check
-        *
-        * @return array
-        */
-       public function keyDiff(array $config)
-       {
-               $return = [];
-
-               $categories = array_keys($config);
-
-               foreach ($categories as $category) {
-                       if (is_array($config[$category])) {
-                               $keys = array_keys($config[$category]);
-
-                               foreach ($keys as $key) {
-                                       if (!isset($this->config[$category][$key])) {
-                                               $return[$category][$key] = $config[$category][$key];
-                                       }
-                               }
-                       }
-               }
-
-               return $return;
-       }
-}
diff --git a/src/Core/PConfig/Cache/Cache.php b/src/Core/PConfig/Cache/Cache.php
new file mode 100644 (file)
index 0000000..97554b2
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Cache;
+
+use ParagonIE\HiddenString\HiddenString;
+
+/**
+ * The Friendica config cache for users
+ */
+class Cache
+{
+       /**
+        * @var array
+        */
+       private $config;
+
+       /**
+        * @var bool
+        */
+       private $hidePasswordOutput;
+
+       /**
+        * @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
+        */
+       public function __construct(bool $hidePasswordOutput = true)
+       {
+               $this->hidePasswordOutput = $hidePasswordOutput;
+       }
+
+       /**
+        * Tries to load the specified configuration array into the user specific config array.
+        * Doesn't overwrite previously set values by default to prevent default config files to supersede DB Config.
+        *
+        * @param int   $uid
+        * @param array $config
+        */
+       public function load($uid, array $config)
+       {
+               if (!is_int($uid)) {
+                       return;
+               }
+
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (isset($config[$category]) && is_array($config[$category])) {
+
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       $value = $config[$category][$key];
+                                       if (isset($value)) {
+                                               $this->set($uid, $category, $key, $value);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       /**
+        * Retrieves a value from the user config cache
+        *
+        * @param int    $uid User Id
+        * @param string $cat Config category
+        * @param string $key Config key
+        *
+        * @return null|string The value of the config entry or null if not set
+        */
+       public function get($uid, string $cat, string $key = null)
+       {
+               if (!is_int($uid)) {
+                       return null;
+               }
+
+               if (isset($this->config[$uid][$cat][$key])) {
+                       return $this->config[$uid][$cat][$key];
+               } elseif (!isset($key) && isset($this->config[$uid][$cat])) {
+                       return $this->config[$uid][$cat];
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Sets a value in the user config cache
+        *
+        * Accepts raw output from the pconfig table
+        *
+        * @param int    $uid   User Id
+        * @param string $cat   Config category
+        * @param string $key   Config key
+        * @param mixed  $value Value to set
+        *
+        * @return bool Set successful
+        */
+       public function set($uid, string $cat, string $key, $value)
+       {
+               if (!is_int($uid)) {
+                       return false;
+               }
+
+               if (!isset($this->config[$uid]) || !is_array($this->config[$uid])) {
+                       $this->config[$uid] = [];
+               }
+
+               if (!isset($this->config[$uid][$cat])) {
+                       $this->config[$uid][$cat] = [];
+               }
+
+               if ($this->hidePasswordOutput &&
+                   $key == 'password' &&
+                   !empty($value) && is_string($value)) {
+                       $this->config[$uid][$cat][$key] = new HiddenString((string)$value);
+               } else {
+                       $this->config[$uid][$cat][$key] = $value;
+               }
+
+
+               return true;
+       }
+
+       /**
+        * Deletes a value from the user config cache
+        *
+        * @param int    $uid User Id
+        * @param string $cat Config category
+        * @param string $key Config key
+        *
+        * @return bool true, if deleted
+        */
+       public function delete($uid, string $cat, string $key)
+       {
+               if (!is_int($uid)) {
+                       return false;
+               }
+
+               if (isset($this->config[$uid][$cat][$key])) {
+                       unset($this->config[$uid][$cat][$key]);
+                       if (count($this->config[$uid][$cat]) == 0) {
+                               unset($this->config[$uid][$cat]);
+                               if (count($this->config[$uid]) == 0) {
+                                       unset($this->config[$uid]);
+                               }
+                       }
+
+                       return true;
+               } else {
+                       return false;
+               }
+       }
+
+       /**
+        * Returns the whole configuration
+        *
+        * @return array The configuration
+        */
+       public function getAll()
+       {
+               return $this->config;
+       }
+
+       /**
+        * Returns an array with missing categories/Keys
+        *
+        * @param array $config The array to check
+        *
+        * @return array
+        */
+       public function keyDiff(array $config)
+       {
+               $return = [];
+
+               $categories = array_keys($config);
+
+               foreach ($categories as $category) {
+                       if (is_array($config[$category])) {
+                               $keys = array_keys($config[$category]);
+
+                               foreach ($keys as $key) {
+                                       if (!isset($this->config[$category][$key])) {
+                                               $return[$category][$key] = $config[$category][$key];
+                                       }
+                               }
+                       }
+               }
+
+               return $return;
+       }
+}
diff --git a/src/Core/PConfig/Factory/PConfigFactory.php b/src/Core/PConfig/Factory/PConfigFactory.php
new file mode 100644 (file)
index 0000000..eb248f1
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Factory;
+
+use Friendica\Core\Config\Cache\Cache;
+use Friendica\Core\PConfig\IPConfig;
+use Friendica\Core\PConfig\Model\PConfig as PConfigModel;
+use Friendica\Core\PConfig\Type;
+
+class PConfigFactory
+{
+       /**
+        * @param Cache                               $configCache  The config cache
+        * @param \Friendica\Core\PConfig\Cache\Cache $pConfigCache The personal config cache
+        * @param PConfigModel                        $configModel  The configuration model
+        *
+        * @return IPConfig
+        */
+       public function create(Cache $configCache, \Friendica\Core\PConfig\Cache\Cache $pConfigCache, PConfigModel $configModel)
+       {
+               if ($configCache->get('system', 'config_adapter') === 'preload') {
+                       $configuration = new Type\PreloadPConfig($pConfigCache, $configModel);
+               } else {
+                       $configuration = new Type\JitPConfig($pConfigCache, $configModel);
+               }
+
+               return $configuration;
+       }
+}
index 25d81bd7e9f50a48390df0efc3bdd3aea19a6fdb..1795a603921f98d0ae8bbddb2fed045a4c1e7934 100644 (file)
@@ -21,6 +21,8 @@
 
 namespace Friendica\Core\PConfig;
 
+use Friendica\Core\Config\Cache\Cache;
+
 /**
  * Interface for accessing user specific configurations
  */
@@ -95,7 +97,7 @@ interface IPConfig
        /**
         * Returns the Config Cache
         *
-        * @return Cache
+        * @return \Friendica\Core\PConfig\Cache\Cache
         */
        function getCache();
 }
diff --git a/src/Core/PConfig/JitPConfig.php b/src/Core/PConfig/JitPConfig.php
deleted file mode 100644 (file)
index 251f1bd..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig;
-
-use Friendica\Core\BasePConfig;
-use Friendica\Model;
-
-/**
- * This class implements the Just-In-Time configuration, which will cache
- * user config values in a cache, once they are retrieved.
- *
- * Default Configuration type.
- * Provides the best performance for pages loading few configuration variables.
- */
-class JitPConfig extends BasePConfig
-{
-       /**
-        * @var array Array of already loaded db values (even if there was no value)
-        */
-       private $db_loaded;
-
-       /**
-        * @param Cache                $configCache The configuration cache
-        * @param Model\Config\PConfig $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, Model\Config\PConfig $configModel)
-       {
-               parent::__construct($configCache, $configModel);
-               $this->db_loaded = [];
-       }
-
-       /**
-        * {@inheritDoc}
-        *
-        */
-       public function load(int $uid, string $cat = 'config')
-       {
-               // If not connected or no uid, do nothing
-               if (!$uid || !$this->configModel->isConnected()) {
-                       return;
-               }
-
-               $config = $this->configModel->load($uid, $cat);
-
-               if (!empty($config[$cat])) {
-                       foreach ($config[$cat] as $key => $value) {
-                               $this->db_loaded[$uid][$cat][$key] = true;
-                       }
-               }
-
-               // load the whole category out of the DB into the cache
-               $this->configCache->load($uid, $config);
-
-               return $config;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function get(int $uid, string $cat, string $key, $default_value = null, bool $refresh = false)
-       {
-               if (!$uid) {
-                       return $default_value;
-               }
-
-               // if the value isn't loaded or refresh is needed, load it to the cache
-               if ($this->configModel->isConnected() &&
-                   (empty($this->db_loaded[$uid][$cat][$key]) ||
-                    $refresh)) {
-
-                       $dbvalue = $this->configModel->get($uid, $cat, $key);
-
-                       if (isset($dbvalue)) {
-                               $this->configCache->set($uid, $cat, $key, $dbvalue);
-                               unset($dbvalue);
-                       }
-
-                       $this->db_loaded[$uid][$cat][$key] = true;
-               }
-
-               // use the config cache for return
-               $result = $this->configCache->get($uid, $cat, $key);
-
-               return (isset($result)) ? $result : $default_value;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function set(int $uid, string $cat, string $key, $value)
-       {
-               if (!$uid) {
-                       return false;
-               }
-
-               // set the cache first
-               $cached = $this->configCache->set($uid, $cat, $key, $value);
-
-               // If there is no connected adapter, we're finished
-               if (!$this->configModel->isConnected()) {
-                       return $cached;
-               }
-
-               $stored = $this->configModel->set($uid, $cat, $key, $value);
-
-               $this->db_loaded[$uid][$cat][$key] = $stored;
-
-               return $cached && $stored;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function delete(int $uid, string $cat, string $key)
-       {
-               if (!$uid) {
-                       return false;
-               }
-
-               $cacheRemoved = $this->configCache->delete($uid, $cat, $key);
-
-               if (isset($this->db_loaded[$uid][$cat][$key])) {
-                       unset($this->db_loaded[$uid][$cat][$key]);
-               }
-
-               if (!$this->configModel->isConnected()) {
-                       return $cacheRemoved;
-               }
-
-               $storeRemoved = $this->configModel->delete($uid, $cat, $key);
-
-               return $cacheRemoved || $storeRemoved;
-       }
-}
diff --git a/src/Core/PConfig/Model/PConfig.php b/src/Core/PConfig/Model/PConfig.php
new file mode 100644 (file)
index 0000000..35ff34a
--- /dev/null
@@ -0,0 +1,177 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Model;
+
+use Friendica\Core\Config\Model\DbaUtils;
+use Friendica\Database\Database;
+
+/**
+ * The Config model backend for users, which is using the general DB-model backend for user-configs
+ */
+class PConfig
+{
+       /** @var Database */
+       protected $dba;
+
+       /**
+        * @param Database $dba The database connection of this model
+        */
+       public function __construct(Database $dba)
+       {
+               $this->dba = $dba;
+       }
+
+       /**
+        * Checks if the model is currently connected
+        *
+        * @return bool
+        */
+       public function isConnected()
+       {
+               return $this->dba->isConnected();
+       }
+
+       /**
+        * Loads all configuration values and returns the loaded category as an array.
+        *
+        * @param int         $uid The id of the user to load
+        * @param string|null $cat The category of the configuration values to load
+        *
+        * @return array The config array
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function load(int $uid, string $cat = null)
+       {
+               $return = [];
+
+               if (empty($cat)) {
+                       $configs = $this->dba->select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]);
+               } else {
+                       $configs = $this->dba->select('pconfig', ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]);
+               }
+
+               while ($config = $this->dba->fetch($configs)) {
+                       $key   = $config['k'];
+                       $value = DbaUtils::toConfigValue($config['v']);
+
+                       // just save it in case it is set
+                       if (isset($value)) {
+                               $return[$config['cat']][$key] = $value;
+                       }
+               }
+               $this->dba->close($configs);
+
+               return $return;
+       }
+
+       /**
+        * Get a particular user config variable out of the DB with the
+        * given category name ($cat) and a key ($key).
+        *
+        * Note: Boolean variables are defined as 0/1 in the database
+        *
+        * @param int         $uid The id of the user to load
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to query
+        *
+        * @return array|string|null Stored value or null if it does not exist
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function get(int $uid, string $cat, string $key)
+       {
+               if (!$this->isConnected()) {
+                       return null;
+               }
+
+               $config = $this->dba->selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
+               if ($this->dba->isResult($config)) {
+                       $value = DbaUtils::toConfigValue($config['v']);
+
+                       // just return it in case it is set
+                       if (isset($value)) {
+                               return $value;
+                       }
+               }
+
+               return null;
+       }
+
+       /**
+        * Stores a config value ($value) in the category ($cat) under the key ($key) for a
+        * given user ($uid).
+        *
+        * Note: Please do not store booleans - convert to 0/1 integer values!
+        *
+        * @param int    $uid   The id of the user to load
+        * @param string $cat   The category of the configuration value
+        * @param string $key   The configuration key to set
+        * @param mixed  $value The value to store
+        *
+        * @return bool Operation success
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function set(int $uid, string $cat, string $key, $value)
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               // We store our setting values in a string variable.
+               // So we have to do the conversion here so that the compare below works.
+               // The exception are array values.
+               $compare_value = (!is_array($value) ? (string)$value : $value);
+               $stored_value  = $this->get($uid, $cat, $key);
+
+               if (isset($stored_value) && ($stored_value === $compare_value)) {
+                       return true;
+               }
+
+               $dbvalue = DbaUtils::toDbValue($value);
+
+               $result = $this->dba->update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
+
+               return $result;
+       }
+
+       /**
+        * Removes the configured value of the given user.
+        *
+        * @param int    $uid The id of the user to load
+        * @param string $cat The category of the configuration value
+        * @param string $key The configuration key to delete
+        *
+        * @return bool Operation success
+        *
+        * @throws \Exception In case DB calls are invalid
+        */
+       public function delete(int $uid, string $cat, string $key)
+       {
+               if (!$this->isConnected()) {
+                       return false;
+               }
+
+               return $this->dba->delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
+       }
+}
diff --git a/src/Core/PConfig/PreloadPConfig.php b/src/Core/PConfig/PreloadPConfig.php
deleted file mode 100644 (file)
index abdc18b..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Core\PConfig;
-
-use Friendica\Core\BasePConfig;
-use Friendica\Model;
-
-/**
- * This class implements the preload configuration, which will cache
- * all user config values per call in a cache.
- *
- * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
- */
-class PreloadPConfig extends BasePConfig
-{
-       /** @var array */
-       private $config_loaded;
-
-       /**
-        * @param Cache                $configCache The configuration cache
-        * @param Model\Config\PConfig $configModel The configuration model
-        */
-       public function __construct(Cache $configCache, Model\Config\PConfig $configModel)
-       {
-               parent::__construct($configCache, $configModel);
-               $this->config_loaded = [];
-       }
-
-       /**
-        * {@inheritDoc}
-        *
-        * This loads all config values everytime load is called
-        *
-        */
-       public function load(int $uid, string $cat = 'config')
-       {
-               // Don't load the whole configuration twice or with invalid uid
-               if (!$uid || !empty($this->config_loaded[$uid])) {
-                       return;
-               }
-
-               // If not connected, do nothing
-               if (!$this->configModel->isConnected()) {
-                       return;
-               }
-
-               $config                    = $this->configModel->load($uid);
-               $this->config_loaded[$uid] = true;
-
-               // load the whole category out of the DB into the cache
-               $this->configCache->load($uid, $config);
-
-               return $config;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function get(int $uid, string $cat, string $key, $default_value = null, bool $refresh = false)
-       {
-               if (!$uid) {
-                       return $default_value;
-               }
-
-               if (empty($this->config_loaded[$uid])) {
-                       $this->load($uid);
-               } elseif ($refresh) {
-                       if ($this->configModel->isConnected()) {
-                               $config = $this->configModel->get($uid, $cat, $key);
-                               if (isset($config)) {
-                                       $this->configCache->set($uid, $cat, $key, $config);
-                               }
-                       }
-               }
-
-               // use the config cache for return
-               $result = $this->configCache->get($uid, $cat, $key);
-
-               return (isset($result)) ? $result : $default_value;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function set(int $uid, string $cat, string $key, $value)
-       {
-               if (!$uid) {
-                       return false;
-               }
-
-               if (empty($this->config_loaded[$uid])) {
-                       $this->load($uid);
-               }
-
-               // set the cache first
-               $cached = $this->configCache->set($uid, $cat, $key, $value);
-
-               // If there is no connected adapter, we're finished
-               if (!$this->configModel->isConnected()) {
-                       return $cached;
-               }
-
-               $stored = $this->configModel->set($uid, $cat, $key, $value);
-
-               return $cached && $stored;
-       }
-
-       /**
-        * {@inheritDoc}
-        */
-       public function delete(int $uid, string $cat, string $key)
-       {
-               if (!$uid) {
-                       return false;
-               }
-
-               if (empty($this->config_loaded[$uid])) {
-                       $this->load($uid);
-               }
-
-               $cacheRemoved = $this->configCache->delete($uid, $cat, $key);
-
-               if (!$this->configModel->isConnected()) {
-                       return $cacheRemoved;
-               }
-
-               $storeRemoved = $this->configModel->delete($uid, $cat, $key);
-
-               return $cacheRemoved || $storeRemoved;
-       }
-}
diff --git a/src/Core/PConfig/Type/BasePConfig.php b/src/Core/PConfig/Type/BasePConfig.php
new file mode 100644 (file)
index 0000000..9ae374f
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Type;
+
+use Friendica\Core\PConfig\Cache\Cache;
+use Friendica\Core\PConfig\IPConfig;
+use Friendica\Model;
+
+/**
+ * This class is responsible for the user-specific configuration values in Friendica
+ * The values are set through the Config-DB-Table (per Config-DB-model @see Model\Config\PConfig)
+ *
+ * The configuration cache (@see Cache\PConfigCache) is used for temporary caching of database calls. This will
+ * increase the performance.
+ */
+abstract class BasePConfig implements IPConfig
+{
+       /**
+        * @var \Friendica\Core\PConfig\Cache\Cache
+        */
+       protected $configCache;
+
+       /**
+        * @var \Friendica\Core\PConfig\Model\PConfig
+        */
+       protected $configModel;
+
+       /**
+        * @param \Friendica\Core\PConfig\Cache\Cache   $configCache The configuration cache
+        * @param \Friendica\Core\PConfig\Model\PConfig $configModel The configuration model
+        */
+       public function __construct(Cache $configCache, \Friendica\Core\PConfig\Model\PConfig $configModel)
+       {
+               $this->configCache = $configCache;
+               $this->configModel = $configModel;
+       }
+
+       /**
+        * Returns the Config Cache
+        *
+        * @return \Friendica\Core\PConfig\Cache\Cache
+        */
+       public function getCache()
+       {
+               return $this->configCache;
+       }
+}
diff --git a/src/Core/PConfig/Type/JitPConfig.php b/src/Core/PConfig/Type/JitPConfig.php
new file mode 100644 (file)
index 0000000..99c3b58
--- /dev/null
@@ -0,0 +1,153 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Type;
+
+use Friendica\Core\PConfig\Cache\Cache;
+use Friendica\Model;
+
+/**
+ * This class implements the Just-In-Time configuration, which will cache
+ * user config values in a cache, once they are retrieved.
+ *
+ * Default Configuration type.
+ * Provides the best performance for pages loading few configuration variables.
+ */
+class JitPConfig extends BasePConfig
+{
+       /**
+        * @var array Array of already loaded db values (even if there was no value)
+        */
+       private $db_loaded;
+
+       /**
+        * @param Cache                                 $configCache The configuration cache
+        * @param \Friendica\Core\PConfig\Model\PConfig $configModel The configuration model
+        */
+       public function __construct(Cache $configCache, \Friendica\Core\PConfig\Model\PConfig $configModel)
+       {
+               parent::__construct($configCache, $configModel);
+               $this->db_loaded = [];
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        */
+       public function load(int $uid, string $cat = 'config')
+       {
+               // If not connected or no uid, do nothing
+               if (!$uid || !$this->configModel->isConnected()) {
+                       return;
+               }
+
+               $config = $this->configModel->load($uid, $cat);
+
+               if (!empty($config[$cat])) {
+                       foreach ($config[$cat] as $key => $value) {
+                               $this->db_loaded[$uid][$cat][$key] = true;
+                       }
+               }
+
+               // load the whole category out of the DB into the cache
+               $this->configCache->load($uid, $config);
+
+               return $config;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function get(int $uid, string $cat, string $key, $default_value = null, bool $refresh = false)
+       {
+               if (!$uid) {
+                       return $default_value;
+               }
+
+               // if the value isn't loaded or refresh is needed, load it to the cache
+               if ($this->configModel->isConnected() &&
+                   (empty($this->db_loaded[$uid][$cat][$key]) ||
+                    $refresh)) {
+
+                       $dbvalue = $this->configModel->get($uid, $cat, $key);
+
+                       if (isset($dbvalue)) {
+                               $this->configCache->set($uid, $cat, $key, $dbvalue);
+                               unset($dbvalue);
+                       }
+
+                       $this->db_loaded[$uid][$cat][$key] = true;
+               }
+
+               // use the config cache for return
+               $result = $this->configCache->get($uid, $cat, $key);
+
+               return (isset($result)) ? $result : $default_value;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function set(int $uid, string $cat, string $key, $value)
+       {
+               if (!$uid) {
+                       return false;
+               }
+
+               // set the cache first
+               $cached = $this->configCache->set($uid, $cat, $key, $value);
+
+               // If there is no connected adapter, we're finished
+               if (!$this->configModel->isConnected()) {
+                       return $cached;
+               }
+
+               $stored = $this->configModel->set($uid, $cat, $key, $value);
+
+               $this->db_loaded[$uid][$cat][$key] = $stored;
+
+               return $cached && $stored;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function delete(int $uid, string $cat, string $key)
+       {
+               if (!$uid) {
+                       return false;
+               }
+
+               $cacheRemoved = $this->configCache->delete($uid, $cat, $key);
+
+               if (isset($this->db_loaded[$uid][$cat][$key])) {
+                       unset($this->db_loaded[$uid][$cat][$key]);
+               }
+
+               if (!$this->configModel->isConnected()) {
+                       return $cacheRemoved;
+               }
+
+               $storeRemoved = $this->configModel->delete($uid, $cat, $key);
+
+               return $cacheRemoved || $storeRemoved;
+       }
+}
diff --git a/src/Core/PConfig/Type/PreloadPConfig.php b/src/Core/PConfig/Type/PreloadPConfig.php
new file mode 100644 (file)
index 0000000..4498bb4
--- /dev/null
@@ -0,0 +1,150 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Core\PConfig\Type;
+
+use Friendica\Core\PConfig\Cache\Cache;
+use Friendica\Model;
+
+/**
+ * This class implements the preload configuration, which will cache
+ * all user config values per call in a cache.
+ *
+ * Minimizes the number of database queries to retrieve configuration values at the cost of memory.
+ */
+class PreloadPConfig extends BasePConfig
+{
+       /** @var array */
+       private $config_loaded;
+
+       /**
+        * @param \Friendica\Core\PConfig\Cache\Cache   $configCache The configuration cache
+        * @param \Friendica\Core\PConfig\Model\PConfig $configModel The configuration model
+        */
+       public function __construct(Cache $configCache, \Friendica\Core\PConfig\Model\PConfig $configModel)
+       {
+               parent::__construct($configCache, $configModel);
+               $this->config_loaded = [];
+       }
+
+       /**
+        * {@inheritDoc}
+        *
+        * This loads all config values everytime load is called
+        *
+        */
+       public function load(int $uid, string $cat = 'config')
+       {
+               // Don't load the whole configuration twice or with invalid uid
+               if (!$uid || !empty($this->config_loaded[$uid])) {
+                       return;
+               }
+
+               // If not connected, do nothing
+               if (!$this->configModel->isConnected()) {
+                       return;
+               }
+
+               $config                    = $this->configModel->load($uid);
+               $this->config_loaded[$uid] = true;
+
+               // load the whole category out of the DB into the cache
+               $this->configCache->load($uid, $config);
+
+               return $config;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function get(int $uid, string $cat, string $key, $default_value = null, bool $refresh = false)
+       {
+               if (!$uid) {
+                       return $default_value;
+               }
+
+               if (empty($this->config_loaded[$uid])) {
+                       $this->load($uid);
+               } elseif ($refresh) {
+                       if ($this->configModel->isConnected()) {
+                               $config = $this->configModel->get($uid, $cat, $key);
+                               if (isset($config)) {
+                                       $this->configCache->set($uid, $cat, $key, $config);
+                               }
+                       }
+               }
+
+               // use the config cache for return
+               $result = $this->configCache->get($uid, $cat, $key);
+
+               return (isset($result)) ? $result : $default_value;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function set(int $uid, string $cat, string $key, $value)
+       {
+               if (!$uid) {
+                       return false;
+               }
+
+               if (empty($this->config_loaded[$uid])) {
+                       $this->load($uid);
+               }
+
+               // set the cache first
+               $cached = $this->configCache->set($uid, $cat, $key, $value);
+
+               // If there is no connected adapter, we're finished
+               if (!$this->configModel->isConnected()) {
+                       return $cached;
+               }
+
+               $stored = $this->configModel->set($uid, $cat, $key, $value);
+
+               return $cached && $stored;
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       public function delete(int $uid, string $cat, string $key)
+       {
+               if (!$uid) {
+                       return false;
+               }
+
+               if (empty($this->config_loaded[$uid])) {
+                       $this->load($uid);
+               }
+
+               $cacheRemoved = $this->configCache->delete($uid, $cat, $key);
+
+               if (!$this->configModel->isConnected()) {
+                       return $cacheRemoved;
+               }
+
+               $storeRemoved = $this->configModel->delete($uid, $cat, $key);
+
+               return $cacheRemoved || $storeRemoved;
+       }
+}
index a654cccc5b8df02730e22022e23cb3d8ee804455..4a8d5d36e7746f92e6e894cf96662dfd2688e0e4 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Database;
 
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\System;
 use Friendica\Network\HTTPException\InternalServerErrorException;
 use Friendica\Util\DateTimeFormat;
diff --git a/src/Factory/ConfigFactory.php b/src/Factory/ConfigFactory.php
deleted file mode 100644 (file)
index cf55640..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Factory;
-
-use Exception;
-use Friendica\Core\Config;
-use Friendica\Core\Config\Cache;
-use Friendica\Model\Config\Config as ConfigModel;
-use Friendica\Model\Config\PConfig as PConfigModel;
-use Friendica\Util\ConfigFileLoader;
-
-class ConfigFactory
-{
-       /**
-        * The key of the $_SERVER variable to override the config directory
-        *
-        * @var string
-        */
-       const CONFIG_DIR_ENV = 'FRIENDICA_CONFIG_DIR';
-
-       /**
-        * The Sub directory of the config-files
-        *
-        * @var string
-        */
-       const CONFIG_DIR = 'config';
-
-       /**
-        * The Sub directory of the static config-files
-        *
-        * @var string
-        */
-       const STATIC_DIR = 'static';
-
-       /**
-        * @param string $basePath The basepath of FRIENDICA
-        * @param array $serer the $_SERVER array
-        *
-        * @return ConfigFileLoader
-        */
-       public function createConfigFileLoader(string $basePath, array $server = [])
-       {
-               if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
-                       $configDir = $server[self::CONFIG_DIR_ENV];
-               } else {
-                       $configDir = $basePath . DIRECTORY_SEPARATOR . self::CONFIG_DIR;
-               }
-               $staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
-
-               return new ConfigFileLoader($basePath, $configDir, $staticDir);
-       }
-
-       /**
-        * @param ConfigFileLoader $loader The Config Cache loader (INI/config/.htconfig)
-        *
-        * @return Cache
-        *
-        * @throws Exception
-        */
-       public function createCache(ConfigFileLoader $loader, array $server = [])
-       {
-               $configCache = new Cache();
-               $loader->setupCache($configCache, $server);
-
-               return $configCache;
-       }
-
-       /**
-        * @param Cache       $configCache The config cache of this adapter
-        * @param ConfigModel $configModel The configuration model
-        *
-        * @return Config\IConfig
-        */
-       public function createConfig(Cache $configCache, ConfigModel $configModel)
-       {
-               if ($configCache->get('system', 'config_adapter') === 'preload') {
-                       $configuration = new Config\PreloadConfig($configCache, $configModel);
-               } else {
-                       $configuration = new Config\JitConfig($configCache, $configModel);
-               }
-
-
-               return $configuration;
-       }
-
-       /**
-        * @param Cache                         $configCache  The config cache
-        * @param \Friendica\Core\PConfig\Cache $pConfigCache The personal config cache
-        * @param PConfigModel                  $configModel  The configuration model
-        *
-        * @return \Friendica\Core\PConfig\IPConfig
-        */
-       public function createPConfig(Cache $configCache, \Friendica\Core\PConfig\Cache $pConfigCache, PConfigModel $configModel)
-       {
-               if ($configCache->get('system', 'config_adapter') === 'preload') {
-                       $configuration = new \Friendica\Core\PConfig\PreloadPConfig($pConfigCache, $configModel);
-               } else {
-                       $configuration = new \Friendica\Core\PConfig\JitPConfig($pConfigCache, $configModel);
-               }
-
-               return $configuration;
-       }
-}
diff --git a/src/Model/Config/Config.php b/src/Model/Config/Config.php
deleted file mode 100644 (file)
index ecc6b6f..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Model\Config;
-
-
-/**
- * The Config model backend, which is using the general DB-model backend for configs
- */
-class Config extends DbaConfig
-{
-       /**
-        * Loads all configuration values and returns the loaded category as an array.
-        *
-        * @param string|null $cat The category of the configuration values to load
-        *
-        * @return array The config array
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function load(string $cat = null)
-       {
-               $return = [];
-
-               if (empty($cat)) {
-                       $configs = $this->dba->select('config', ['cat', 'v', 'k']);
-               } else {
-                       $configs = $this->dba->select('config', ['cat', 'v', 'k'], ['cat' => $cat]);
-               }
-
-               while ($config = $this->dba->fetch($configs)) {
-
-                       $key   = $config['k'];
-                       $value = $this->toConfigValue($config['v']);
-
-                       // just save it in case it is set
-                       if (isset($value)) {
-                               $return[$config['cat']][$key] = $value;
-                       }
-               }
-               $this->dba->close($configs);
-
-               return $return;
-       }
-
-       /**
-        * Get a particular, system-wide config variable out of the DB with the
-        * given category name ($cat) and a key ($key).
-        *
-        * Note: Boolean variables are defined as 0/1 in the database
-        *
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to query
-        *
-        * @return array|string|null Stored value or null if it does not exist
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function get(string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return null;
-               }
-
-               $config = $this->dba->selectFirst('config', ['v'], ['cat' => $cat, 'k' => $key]);
-               if ($this->dba->isResult($config)) {
-                       $value = $this->toConfigValue($config['v']);
-
-                       // just return it in case it is set
-                       if (isset($value)) {
-                               return $value;
-                       }
-               }
-
-               return null;
-       }
-
-       /**
-        * Stores a config value ($value) in the category ($cat) under the key ($key).
-        *
-        * Note: Please do not store booleans - convert to 0/1 integer values!
-        *
-        * @param string $cat   The category of the configuration value
-        * @param string $key   The configuration key to set
-        * @param mixed  $value The value to store
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function set(string $cat, string $key, $value)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               // We store our setting values in a string variable.
-               // So we have to do the conversion here so that the compare below works.
-               // The exception are array values.
-               $compare_value = (!is_array($value) ? (string)$value : $value);
-               $stored_value  = $this->get($cat, $key);
-
-               if (isset($stored_value) && ($stored_value === $compare_value)) {
-                       return true;
-               }
-
-               $dbvalue = $this->toDbValue($value);
-
-               $result = $this->dba->update('config', ['v' => $dbvalue], ['cat' => $cat, 'k' => $key], true);
-
-               return $result;
-       }
-
-       /**
-        * Removes the configured value from the database.
-        *
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to delete
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function delete(string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               return $this->dba->delete('config', ['cat' => $cat, 'k' => $key]);
-       }
-}
diff --git a/src/Model/Config/DbaConfig.php b/src/Model/Config/DbaConfig.php
deleted file mode 100644 (file)
index 4ef96f6..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Model\Config;
-
-use Friendica\Database\Database;
-
-/**
- * The DB-based model of (P-)Config values
- * Encapsulates db-calls in case of config queries
- */
-abstract class DbaConfig
-{
-       /** @var Database */
-       protected $dba;
-
-       /**
-        * @param Database $dba The database connection of this model
-        */
-       public function __construct(Database $dba)
-       {
-               $this->dba = $dba;
-       }
-
-       /**
-        * Checks if the model is currently connected
-        *
-        * @return bool
-        */
-       public function isConnected()
-       {
-               return $this->dba->isConnected();
-       }
-
-       /**
-        * Formats a DB value to a config value
-        * - null   = The db-value isn't set
-        * - bool   = The db-value is either '0' or '1'
-        * - array  = The db-value is a serialized array
-        * - string = The db-value is a string
-        *
-        * Keep in mind that there aren't any numeric/integer config values in the database
-        *
-        * @param null|string $value
-        *
-        * @return null|array|string
-        */
-       protected function toConfigValue($value)
-       {
-               if (!isset($value)) {
-                       return null;
-               }
-
-               switch (true) {
-                       // manage array value
-                       case preg_match("|^a:[0-9]+:{.*}$|s", $value):
-                               return unserialize($value);
-
-                       default:
-                               return $value;
-               }
-       }
-
-       /**
-        * Formats a config value to a DB value (string)
-        *
-        * @param mixed $value
-        *
-        * @return string
-        */
-       protected function toDbValue($value)
-       {
-               // if not set, save an empty string
-               if (!isset($value)) {
-                       return '';
-               }
-
-               switch (true) {
-                       // manage arrays
-                       case is_array($value):
-                               return serialize($value);
-
-                       default:
-                               return (string)$value;
-               }
-       }
-}
diff --git a/src/Model/Config/PConfig.php b/src/Model/Config/PConfig.php
deleted file mode 100644 (file)
index 0aeb0df..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Model\Config;
-
-
-/**
- * The Config model backend for users, which is using the general DB-model backend for user-configs
- */
-class PConfig extends DbaConfig
-{
-       /**
-        * Loads all configuration values and returns the loaded category as an array.
-        *
-        * @param int         $uid The id of the user to load
-        * @param string|null $cat The category of the configuration values to load
-        *
-        * @return array The config array
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function load(int $uid, string $cat = null)
-       {
-               $return = [];
-
-               if (empty($cat)) {
-                       $configs = $this->dba->select('pconfig', ['cat', 'v', 'k'], ['uid' => $uid]);
-               } else {
-                       $configs = $this->dba->select('pconfig', ['cat', 'v', 'k'], ['cat' => $cat, 'uid' => $uid]);
-               }
-
-               while ($config = $this->dba->fetch($configs)) {
-                       $key   = $config['k'];
-                       $value = $this->toConfigValue($config['v']);
-
-                       // just save it in case it is set
-                       if (isset($value)) {
-                               $return[$config['cat']][$key] = $value;
-                       }
-               }
-               $this->dba->close($configs);
-
-               return $return;
-       }
-
-       /**
-        * Get a particular user config variable out of the DB with the
-        * given category name ($cat) and a key ($key).
-        *
-        * Note: Boolean variables are defined as 0/1 in the database
-        *
-        * @param int         $uid The id of the user to load
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to query
-        *
-        * @return array|string|null Stored value or null if it does not exist
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function get(int $uid, string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return null;
-               }
-
-               $config = $this->dba->selectFirst('pconfig', ['v'], ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
-               if ($this->dba->isResult($config)) {
-                       $value = $this->toConfigValue($config['v']);
-
-                       // just return it in case it is set
-                       if (isset($value)) {
-                               return $value;
-                       }
-               }
-
-               return null;
-       }
-
-       /**
-        * Stores a config value ($value) in the category ($cat) under the key ($key) for a
-        * given user ($uid).
-        *
-        * Note: Please do not store booleans - convert to 0/1 integer values!
-        *
-        * @param int    $uid   The id of the user to load
-        * @param string $cat   The category of the configuration value
-        * @param string $key   The configuration key to set
-        * @param mixed  $value The value to store
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function set(int $uid, string $cat, string $key, $value)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               // We store our setting values in a string variable.
-               // So we have to do the conversion here so that the compare below works.
-               // The exception are array values.
-               $compare_value = (!is_array($value) ? (string)$value : $value);
-               $stored_value  = $this->get($uid, $cat, $key);
-
-               if (isset($stored_value) && ($stored_value === $compare_value)) {
-                       return true;
-               }
-
-               $dbvalue = $this->toDbValue($value);
-
-               $result = $this->dba->update('pconfig', ['v' => $dbvalue], ['uid' => $uid, 'cat' => $cat, 'k' => $key], true);
-
-               return $result;
-       }
-
-       /**
-        * Removes the configured value of the given user.
-        *
-        * @param int    $uid The id of the user to load
-        * @param string $cat The category of the configuration value
-        * @param string $key The configuration key to delete
-        *
-        * @return bool Operation success
-        *
-        * @throws \Exception In case DB calls are invalid
-        */
-       public function delete(int $uid, string $cat, string $key)
-       {
-               if (!$this->isConnected()) {
-                       return false;
-               }
-
-               return $this->dba->delete('pconfig', ['uid' => $uid, 'cat' => $cat, 'k' => $key]);
-       }
-}
index 2d081f407752b0c9ef0fa8f83fe92526ad252679..5077d3b5db3ecdf23df08b488177a124a5f32046 100644 (file)
 namespace Friendica\Module\Admin;
 
 use Friendica\Core\Addon;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
 use Friendica\Core\Update;
 use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
-use Friendica\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Model\Register;
 use Friendica\Module\BaseAdmin;
 use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\ConfigFileLoader;
+use Friendica\Core\Config\Cache\ConfigFileLoader;
 use Friendica\Util\DateTimeFormat;
 
 class Summary extends BaseAdmin
index c61f162338f7b04b5e146e0b51ce24cabaccf0b8..b9ae763b72174a937c8650f52bcb1ac954cc9516 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Module;
 use Friendica\App;
 use Friendica\BaseModule;
 use Friendica\Core;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Renderer;
 use Friendica\Core\Theme;
 use Friendica\DI;
diff --git a/src/Util/ConfigFileLoader.php b/src/Util/ConfigFileLoader.php
deleted file mode 100644 (file)
index aabefc1..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Util;
-
-use Exception;
-use Friendica\Core\Addon;
-use Friendica\Core\Config\Cache;
-
-/**
- * The ConfigFileLoader loads config-files and stores them in a ConfigCache ( @see Cache )
- *
- * It is capable of loading the following config files:
- * - *.config.php   (current)
- * - *.ini.php      (deprecated)
- * - *.htconfig.php (deprecated)
- */
-class ConfigFileLoader
-{
-       /**
-        * The default name of the user defined ini file
-        *
-        * @var string
-        */
-       const CONFIG_INI = 'local';
-
-       /**
-        * The default name of the user defined legacy config file
-        *
-        * @var string
-        */
-       const CONFIG_HTCONFIG = 'htconfig';
-
-       /**
-        * The sample string inside the configs, which shouldn't get loaded
-        *
-        * @var string
-        */
-       const SAMPLE_END = '-sample';
-
-       /**
-        * @var string
-        */
-       private $baseDir;
-       /**
-        * @var string
-        */
-       private $configDir;
-       /**
-        * @var string
-        */
-       private $staticDir;
-
-       /**
-        * @param string $baseDir   The base
-        * @param string $configDir
-        * @param string $staticDir
-        */
-       public function __construct(string $baseDir, string $configDir, string $staticDir)
-       {
-               $this->baseDir   = $baseDir;
-               $this->configDir = $configDir;
-               $this->staticDir = $staticDir;
-       }
-
-       /**
-        * Load the configuration files into an configuration cache
-        *
-        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
-        * expected local.config.php
-        *
-        * @param Cache $config The config cache to load to
-        * @param array $server The $_SERVER array
-        * @param bool  $raw    Setup the raw config format
-        *
-        * @throws Exception
-        */
-       public function setupCache(Cache $config, array $server = [], bool $raw = false)
-       {
-               // Load static config files first, the order is important
-               $config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_FILE);
-               $config->load($this->loadStaticConfig('settings'), Cache::SOURCE_FILE);
-
-               // try to load the legacy config first
-               $config->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
-               $config->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
-
-               // Now load every other config you find inside the 'config/' directory
-               $this->loadCoreConfig($config);
-
-               $config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV);
-
-               // In case of install mode, add the found basepath (because there isn't a basepath set yet
-               if (!$raw && empty($config->get('system', 'basepath'))) {
-                       // Setting at least the basepath we know
-                       $config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
-               }
-       }
-
-       /**
-        * Tries to load the static core-configuration and returns the config array.
-        *
-        * @param string $name The name of the configuration
-        *
-        * @return array The config array (empty if no config found)
-        *
-        * @throws Exception if the configuration file isn't readable
-        */
-       private function loadStaticConfig($name)
-       {
-               $configName = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.config.php';
-               $iniName    = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
-
-               if (file_exists($configName)) {
-                       return $this->loadConfigFile($configName);
-               } elseif (file_exists($iniName)) {
-                       return $this->loadINIConfigFile($iniName);
-               } else {
-                       return [];
-               }
-       }
-
-       /**
-        * Tries to load the specified core-configuration into the config cache.
-        *
-        * @param Cache $config The Config cache
-        *
-        * @return array The config array (empty if no config found)
-        *
-        * @throws Exception if the configuration file isn't readable
-        */
-       private function loadCoreConfig(Cache $config)
-       {
-               // try to load legacy ini-files first
-               foreach ($this->getConfigFiles(true) as $configFile) {
-                       $config->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
-               }
-
-               // try to load supported config at last to overwrite it
-               foreach ($this->getConfigFiles() as $configFile) {
-                       $config->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
-               }
-
-               return [];
-       }
-
-       /**
-        * Tries to load the specified addon-configuration and returns the config array.
-        *
-        * @param string $name The name of the configuration
-        *
-        * @return array The config array (empty if no config found)
-        *
-        * @throws Exception if the configuration file isn't readable
-        */
-       public function loadAddonConfig($name)
-       {
-               $filepath = $this->baseDir . DIRECTORY_SEPARATOR .   // /var/www/html/
-                           Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
-                           $name . DIRECTORY_SEPARATOR .            // openstreetmap/
-                           'config'. DIRECTORY_SEPARATOR .              // config/
-                           $name . ".config.php";                   // openstreetmap.config.php
-
-               if (file_exists($filepath)) {
-                       return $this->loadConfigFile($filepath);
-               } else {
-                       return [];
-               }
-       }
-
-       /**
-        * Tries to load environment specific variables, based on the `env.config.php` mapping table
-        *
-        * @param array $server The $_SERVER variable
-        *
-        * @return array The config array (empty if no config was found)
-        *
-        * @throws Exception if the configuration file isn't readable
-        */
-       public function loadEnvConfig(array $server)
-       {
-               $filepath = $this->staticDir . DIRECTORY_SEPARATOR .   // /var/www/html/static/
-                                       "env.config.php";                          // env.config.php
-
-               if (!file_exists($filepath)) {
-                       return [];
-               }
-
-               $envConfig = $this->loadConfigFile($filepath);
-
-               $return = [];
-
-               foreach ($envConfig as $envKey => $configStructure) {
-                       if (isset($server[$envKey])) {
-                               $return[$configStructure[0]][$configStructure[1]] = $server[$envKey];
-                       }
-               }
-
-               return $return;
-       }
-
-       /**
-        * Get the config files of the config-directory
-        *
-        * @param bool $ini True, if scan for ini-files instead of config files
-        *
-        * @return array
-        */
-       private function getConfigFiles(bool $ini = false)
-       {
-               $files = scandir($this->configDir);
-               $found = array();
-
-               $filePattern = ($ini ? '*.ini.php' : '*.config.php');
-
-               // Don't load sample files
-               $sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
-
-               foreach ($files as $filename) {
-                       if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
-                               $found[] = $this->configDir . '/' . $filename;
-                       }
-               }
-
-               return $found;
-       }
-
-       /**
-        * Tries to load the legacy config files (.htconfig.php, .htpreconfig.php) and returns the config array.
-        *
-        * @param string $name The name of the config file (default is empty, which means .htconfig.php)
-        *
-        * @return array The configuration array (empty if no config found)
-        *
-        * @deprecated since version 2018.09
-        */
-       private function loadLegacyConfig($name = '')
-       {
-               $name     = !empty($name) ? $name : self::CONFIG_HTCONFIG;
-               $fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
-
-               $config = [];
-               if (file_exists($fullName)) {
-                       $a         = new \stdClass();
-                       $a->config = [];
-                       include $fullName;
-
-                       $htConfigCategories = array_keys($a->config);
-
-                       // map the legacy configuration structure to the current structure
-                       foreach ($htConfigCategories as $htConfigCategory) {
-                               if (is_array($a->config[$htConfigCategory])) {
-                                       $keys = array_keys($a->config[$htConfigCategory]);
-
-                                       foreach ($keys as $key) {
-                                               $config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
-                                       }
-                               } else {
-                                       $config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
-                               }
-                       }
-
-                       unset($a);
-
-                       if (isset($db_host)) {
-                               $config['database']['hostname'] = $db_host;
-                               unset($db_host);
-                       }
-                       if (isset($db_user)) {
-                               $config['database']['username'] = $db_user;
-                               unset($db_user);
-                       }
-                       if (isset($db_pass)) {
-                               $config['database']['password'] = $db_pass;
-                               unset($db_pass);
-                       }
-                       if (isset($db_data)) {
-                               $config['database']['database'] = $db_data;
-                               unset($db_data);
-                       }
-                       if (isset($config['system']['db_charset'])) {
-                               $config['database']['charset'] = $config['system']['db_charset'];
-                       }
-                       if (isset($pidfile)) {
-                               $config['system']['pidfile'] = $pidfile;
-                               unset($pidfile);
-                       }
-                       if (isset($default_timezone)) {
-                               $config['system']['default_timezone'] = $default_timezone;
-                               unset($default_timezone);
-                       }
-                       if (isset($lang)) {
-                               $config['system']['language'] = $lang;
-                               unset($lang);
-                       }
-               }
-
-               return $config;
-       }
-
-       /**
-        * Tries to load the specified legacy configuration file and returns the config array.
-        *
-        * @param string $filepath
-        *
-        * @return array The configuration array
-        * @throws Exception
-        * @deprecated since version 2018.12
-        */
-       private function loadINIConfigFile($filepath)
-       {
-               $contents = include($filepath);
-
-               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
-
-               if ($config === false) {
-                       throw new Exception('Error parsing INI config file ' . $filepath);
-               }
-
-               return $config;
-       }
-
-       /**
-        * Tries to load the specified configuration file and returns the config array.
-        *
-        * The config format is PHP array and the template for configuration files is the following:
-        *
-        * <?php return [
-        *      'section' => [
-        *          'key' => 'value',
-        *      ],
-        * ];
-        *
-        * @param string $filepath The filepath of the
-        *
-        * @return array The config array0
-        *
-        * @throws Exception if the config cannot get loaded.
-        */
-       private function loadConfigFile($filepath)
-       {
-               $config = include($filepath);
-
-               if (!is_array($config)) {
-                       throw new Exception('Error loading config file ' . $filepath);
-               }
-
-               return $config;
-       }
-}
index fb499d815613f4ff40f2e5cd12a9e0456e94a8df..0ff338353eb51533d3d546eb52428e9e1e97c8c8 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Util;
 
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Config\IConfig;
 use Friendica\Core\System;
 use Psr\Container\ContainerExceptionInterface;
@@ -78,7 +78,7 @@ class Profiler implements ContainerInterface
        }
 
        /**
-        * @param Cache $configCache The configuration cache
+        * @param \Friendica\Core\Config\Cache\Cache $configCache The configuration cache
         */
        public function __construct(Cache $configCache)
        {
index 39aae97fd188e99fd033e199538f6bf5a0207be5..fe063c0463b049d310bcd601e95da1f9567fa17e 100644 (file)
@@ -37,6 +37,7 @@ use Dice\Dice;
 use Friendica\App;
 use Friendica\Core\Cache;
 use Friendica\Core\Config;
+use Friendica\Core\PConfig;
 use Friendica\Core\L10n;
 use Friendica\Core\Lock\ILock;
 use Friendica\Core\Process;
@@ -73,8 +74,8 @@ return [
                        $_SERVER
                ]
        ],
-       Util\ConfigFileLoader::class => [
-               'instanceOf' => Factory\ConfigFactory::class,
+       Config\Cache\ConfigFileLoader::class => [
+               'instanceOf' => Config\Factory\ConfigFactory::class,
                'call'       => [
                        ['createConfigFileLoader', [
                                [Dice::INSTANCE => '$basepath'],
@@ -82,8 +83,8 @@ return [
                        ], Dice::CHAIN_CALL],
                ],
        ],
-       Config\Cache::class          => [
-               'instanceOf' => Factory\ConfigFactory::class,
+       Config\Cache\Cache::class => [
+               'instanceOf' => Config\Factory\ConfigFactory::class,
                'call'       => [
                        ['createCache', [$_SERVER], Dice::CHAIN_CALL],
                ],
@@ -95,15 +96,15 @@ return [
                ],
        ],
        Config\IConfig::class                   => [
-               'instanceOf' => Factory\ConfigFactory::class,
+               'instanceOf' => Config\Factory\ConfigFactory::class,
                'call'       => [
-                       ['createConfig', [], Dice::CHAIN_CALL],
+                       ['create', [], Dice::CHAIN_CALL],
                ],
        ],
        \Friendica\Core\PConfig\IPConfig::class => [
-               'instanceOf' => Factory\ConfigFactory::class,
+               'instanceOf' => PConfig\Factory\PConfigFactory::class,
                'call'       => [
-                       ['createPConfig', [], Dice::CHAIN_CALL],
+                       ['create', [], Dice::CHAIN_CALL],
                ]
        ],
        Database::class                         => [
index f30b50878b7e40825e599851206a140c4d6d5aac..fdeda1febc22c83c5b3bd6e9809c569bdaaeb800 100644 (file)
@@ -6,7 +6,7 @@
 namespace Friendica\Test;
 
 use Dice\Dice;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Config\IConfig;
 use Friendica\Core\Session;
 use Friendica\Core\Session\ISession;
index 4266a4a0238c9fafea32882a102bafa15443a148..cca9bd37e80c379925ed35cafbc9721aa15925c2 100644 (file)
@@ -74,19 +74,19 @@ trait AppMockTrait
                $this->dice = \Mockery::mock(Dice::class)->makePartial();
                $this->dice = $this->dice->addRules(include __DIR__ . '/../../static/dependencies.config.php');
 
-               $this->configMock = \Mockery::mock(Config\Cache::class);
+               $this->configMock = \Mockery::mock(Config\Cache\Cache::class);
                $this->dice->shouldReceive('create')
-                          ->with(Config\Cache::class)
+                          ->with(Config\Cache\Cache::class)
                           ->andReturn($this->configMock);
                $this->mode = \Mockery::mock(App\Mode::class);
                $this->dice->shouldReceive('create')
                           ->with(App\Mode::class)
                           ->andReturn($this->mode);
-               $configModel= \Mockery::mock(\Friendica\Model\Config\Config::class);
+               $configModel= \Mockery::mock(Config\Model\Config::class);
                // Disable the adapter
                $configModel->shouldReceive('isConnected')->andReturn(false);
 
-               $config = new Config\JitConfig($this->configMock, $configModel);
+               $config = new Config\Type\JitConfig($this->configMock, $configModel);
                $this->dice->shouldReceive('create')
                           ->with(Config\IConfig::class)
                           ->andReturn($config);
index a7b45ccebeffa9ce1362436e524a77fbeb9bc5aa..3d207d07d157beaefd5fd294fe3535103e56d1cb 100644 (file)
@@ -25,13 +25,13 @@ use Dice\Dice;
 use Friendica\App;
 use Friendica\Core\Cache\ICache;
 use Friendica\Core\Cache\IMemoryCache;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Config\IConfig;
 use Friendica\Core\Lock\ILock;
 use Friendica\Database\Database;
 use Friendica\Test\Util\VFSTrait;
 use Friendica\Util\BasePath;
-use Friendica\Util\ConfigFileLoader;
+use Friendica\Core\Config\Cache\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use PHPUnit\Framework\TestCase;
 use Psr\Log\LoggerInterface;
index 36ca6b21d6f7dca1950441bd0c5da01e1b00af3d..c3a5c5e72b4f99f0c10edf3f573a9b1bcfcf890e 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\App;
 use Detection\MobileDetect;
 use Friendica\App\Mode;
 use Friendica\App\Module;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Database\Database;
 use Friendica\Test\MockedTest;
 use Friendica\Test\Util\VFSTrait;
index 01a57b57e9489d94633a0749efa2f9c397647d92..f11d38365887dd195c6ddc70aa6d4c17e4cc8979 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Console;
 use Dice\Dice;
 use Friendica\App;
 use Friendica\Console\AutomaticInstallation;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Installer;
 use Friendica\Core\L10n;
 use Friendica\Core\Logger;
@@ -53,7 +53,7 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
        private $assertFileDb;
 
        /**
-        * @var Cache The configuration cache to check after each test
+        * @var \Friendica\Core\Config\Cache\Cache The configuration cache to check after each test
         */
        private $configCache;
 
index 8d404b3552be0754df5dd7f584309b8b12f9becf..55011f87cfea2e686cbf4dca1b700b9b6e28616a 100644 (file)
 namespace Friendica\Test\src\Core\Cache;
 
 use Friendica\Core\Cache;
-use Friendica\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use Mockery;
 use Psr\Log\NullLogger;
diff --git a/tests/src/Core/Config/Cache/CacheTest.php b/tests/src/Core/Config/Cache/CacheTest.php
new file mode 100644 (file)
index 0000000..530b5b4
--- /dev/null
@@ -0,0 +1,345 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Test\src\Core\Config\Cache;
+
+use Friendica\Core\Config\Cache;
+use Friendica\Test\MockedTest;
+use ParagonIE\HiddenString\HiddenString;
+use stdClass;
+
+class CacheTest extends MockedTest
+{
+       public function dataTests()
+       {
+               return [
+                       'normal' => [
+                               'data' => [
+                                       'system' => [
+                                               'test' => 'it',
+                                               'boolTrue' => true,
+                                               'boolFalse' => false,
+                                               'int' => 235,
+                                               'dec' => 2.456,
+                                               'array' => ['1', 2, '3', true, false],
+                                       ],
+                                       'config' => [
+                                               'a' => 'value',
+                                       ],
+                               ]
+                       ]
+               ];
+       }
+
+       private function assertConfigValues($data, Cache\Cache $configCache)
+       {
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               self::assertEquals($data[$cat][$key], $configCache->get($cat, $key));
+                       }
+               }
+       }
+
+       /**
+        * Test the loadConfigArray() method without override
+        * @dataProvider dataTests
+        */
+       public function testLoadConfigArray($data)
+       {
+               $configCache = new Cache\Cache();
+               $configCache->load($data);
+
+               self::assertConfigValues($data, $configCache);
+       }
+
+       /**
+        * Test the loadConfigArray() method with overrides
+        * @dataProvider dataTests
+        */
+       public function testLoadConfigArrayOverride($data)
+       {
+               $override = [
+                       'system' => [
+                               'test' => 'not',
+                               'boolTrue' => false,
+                       ]
+               ];
+
+               $configCache = new Cache\Cache();
+               $configCache->load($data, Cache\Cache::SOURCE_DB);
+               // doesn't override - Low Priority due Config file
+               $configCache->load($override, Cache\Cache::SOURCE_FILE);
+
+               self::assertConfigValues($data, $configCache);
+
+               // override the value - High Prio due Server Env
+               $configCache->load($override, Cache\Cache::SOURCE_ENV);
+
+               self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
+               self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
+
+               // Don't overwrite server ENV variables - even in load mode
+               $configCache->load($data, Cache\Cache::SOURCE_DB);
+
+               self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
+               self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
+
+               // Overwrite ENV variables with ENV variables
+               $configCache->load($data, Cache\Cache::SOURCE_ENV);
+
+               self::assertConfigValues($data, $configCache);
+               self::assertNotEquals($override['system']['test'], $configCache->get('system', 'test'));
+               self::assertNotEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
+       }
+
+       /**
+        * Test the loadConfigArray() method with wrong/empty datasets
+        */
+       public function testLoadConfigArrayWrong()
+       {
+               $configCache = new Cache\Cache();
+
+               // empty dataset
+               $configCache->load([]);
+               self::assertEmpty($configCache->getAll());
+
+               // wrong dataset
+               $configCache->load(['system' => 'not_array']);
+               self::assertEmpty($configCache->getAll());
+
+               // incomplete dataset (key is integer ID of the array)
+               $configCache->load(['system' => ['value']]);
+               self::assertEquals('value', $configCache->get('system', 0));
+       }
+
+       /**
+        * Test the getAll() method
+        * @dataProvider dataTests
+        */
+       public function testGetAll($data)
+       {
+               $configCache = new Cache\Cache();
+               $configCache->load($data);
+
+               $all = $configCache->getAll();
+
+               self::assertContains($data['system'], $all);
+               self::assertContains($data['config'], $all);
+       }
+
+       /**
+        * Test the set() and get() method
+        * @dataProvider dataTests
+        */
+       public function testSetGet($data)
+       {
+               $configCache = new Cache\Cache();
+
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               $configCache->set($cat, $key, $value);
+                       }
+               }
+
+               self::assertConfigValues($data, $configCache);
+       }
+
+       /**
+        * Test the get() method without a value
+        */
+       public function testGetEmpty()
+       {
+               $configCache = new Cache\Cache();
+
+               self::assertNull($configCache->get('something', 'value'));
+       }
+
+       /**
+        * Test the get() method with a category
+        */
+       public function testGetCat()
+       {
+               $configCache = new Cache\Cache([
+                       'system' => [
+                               'key1' => 'value1',
+                               'key2' => 'value2',
+                       ],
+                       'config' => [
+                               'key3' => 'value3',
+                       ],
+               ]);
+
+               self::assertEquals([
+                       'key1' => 'value1',
+                       'key2' => 'value2',
+               ], $configCache->get('system'));
+
+               // explicit null as key
+               self::assertEquals([
+                       'key1' => 'value1',
+                       'key2' => 'value2',
+               ], $configCache->get('system', null));
+       }
+
+       /**
+        * Test the delete() method
+        * @dataProvider dataTests
+        */
+       public function testDelete($data)
+       {
+               $configCache = new Cache\Cache($data);
+
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               $configCache->delete($cat, $key);
+                       }
+               }
+
+               self::assertEmpty($configCache->getAll());
+       }
+
+       /**
+        * Test the keyDiff() method with result
+        * @dataProvider dataTests
+        */
+       public function testKeyDiffWithResult($data)
+       {
+               $configCache = new Cache\Cache($data);
+
+               $diffConfig = [
+                       'fakeCat' => [
+                               'fakeKey' => 'value',
+                       ]
+               ];
+
+               self::assertEquals($diffConfig, $configCache->keyDiff($diffConfig));
+       }
+
+       /**
+        * Test the keyDiff() method without result
+        * @dataProvider dataTests
+        */
+       public function testKeyDiffWithoutResult($data)
+       {
+               $configCache = new Cache\Cache($data);
+
+               $diffConfig = $configCache->getAll();
+
+               self::assertEmpty($configCache->keyDiff($diffConfig));
+       }
+
+       /**
+        * Test the default hiding of passwords inside the cache
+        */
+       public function testPasswordHide()
+       {
+               $configCache = new Cache\Cache([
+                       'database' => [
+                               'password' => 'supersecure',
+                               'username' => 'notsecured',
+                       ],
+               ]);
+
+               self::assertEquals('supersecure', $configCache->get('database', 'password'));
+               self::assertNotEquals('supersecure', print_r($configCache->get('database', 'password'), true));
+               self::assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
+       }
+
+       /**
+        * Test disabling the hiding of passwords inside the cache
+        */
+       public function testPasswordShow()
+       {
+               $configCache = new Cache\Cache([
+                       'database' => [
+                               'password' => 'supersecure',
+                               'username' => 'notsecured',
+                       ],
+               ], false);
+
+               self::assertEquals('supersecure', $configCache->get('database', 'password'));
+               self::assertEquals('supersecure', print_r($configCache->get('database', 'password'), true));
+               self::assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
+       }
+
+       /**
+        * Test a empty password
+        */
+       public function testEmptyPassword()
+       {
+               $configCache = new Cache\Cache([
+                       'database' => [
+                               'password' => '',
+                               'username' => '',
+                       ]
+               ]);
+
+               self::assertNotEmpty($configCache->get('database', 'password'));
+               self::assertInstanceOf(HiddenString::class, $configCache->get('database', 'password'));
+               self::assertEmpty($configCache->get('database', 'username'));
+       }
+
+       public function testWrongTypePassword()
+       {
+               $configCache = new Cache\Cache([
+                       'database' => [
+                               'password' => new stdClass(),
+                               'username' => '',
+                       ]
+               ]);
+
+               self::assertNotEmpty($configCache->get('database', 'password'));
+               self::assertEmpty($configCache->get('database', 'username'));
+
+               $configCache = new Cache\Cache([
+                       'database' => [
+                               'password' => 23,
+                               'username' => '',
+                       ]
+               ]);
+
+               self::assertEquals(23, $configCache->get('database', 'password'));
+               self::assertEmpty($configCache->get('database', 'username'));
+       }
+
+       /**
+        * Test the set() method with overrides
+        * @dataProvider dataTests
+        */
+       public function testSetOverrides($data)
+       {
+
+               $configCache = new Cache\Cache();
+               $configCache->load($data, Cache\Cache::SOURCE_DB);
+
+               // test with wrong override
+               self::assertFalse($configCache->set('system', 'test', '1234567', Cache\Cache::SOURCE_FILE));
+               self::assertEquals($data['system']['test'], $configCache->get('system', 'test'));
+
+               // test with override (equal)
+               self::assertTrue($configCache->set('system', 'test', '8910', Cache\Cache::SOURCE_DB));
+               self::assertEquals('8910', $configCache->get('system', 'test'));
+
+               // test with override (over)
+               self::assertTrue($configCache->set('system', 'test', '111213', Cache\Cache::SOURCE_ENV));
+               self::assertEquals('111213', $configCache->get('system', 'test'));
+       }
+}
diff --git a/tests/src/Core/Config/Cache/ConfigFileLoaderTest.php b/tests/src/Core/Config/Cache/ConfigFileLoaderTest.php
new file mode 100644 (file)
index 0000000..ed5cfa1
--- /dev/null
@@ -0,0 +1,389 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Test\src\Core\Config\Cache;
+
+use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Test\MockedTest;
+use Friendica\Test\Util\VFSTrait;
+use Friendica\Core\Config\Cache\ConfigFileLoader;
+use org\bovigo\vfs\vfsStream;
+
+class ConfigFileLoaderTest extends MockedTest
+{
+       use VFSTrait;
+
+       protected function setUp(): void
+       {
+               parent::setUp();
+
+               $this->setUpVfsDir();
+       }
+
+       /**
+        * Test the loadConfigFiles() method with default values
+        */
+       public function testLoadConfigFiles()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
+       }
+
+       /**
+        * Test the loadConfigFiles() method with a wrong local.config.php
+        *
+        */
+       public function testLoadConfigWrong()
+       {
+               $this->expectExceptionMessageMatches("/Error loading config file \w+/");
+               $this->expectException(\Exception::class);
+               $this->delConfigFile('local.config.php');
+
+               vfsStream::newFile('local.config.php')
+                       ->at($this->root->getChild('config'))
+                       ->setContent('<?php return true;');
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+       }
+
+       /**
+        * Test the loadConfigFiles() method with a local.config.php file
+        */
+       public function testLoadConfigFilesLocal()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       'A.config.php';
+
+               vfsStream::newFile('local.config.php')
+                       ->at($this->root->getChild('config'))
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('testhost', $configCache->get('database', 'hostname'));
+               self::assertEquals('testuser', $configCache->get('database', 'username'));
+               self::assertEquals('testpw', $configCache->get('database', 'password'));
+               self::assertEquals('testdb', $configCache->get('database', 'database'));
+
+               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+               self::assertEquals('Friendica Social Network', $configCache->get('config', 'sitename'));
+       }
+
+       /**
+        * Test the loadConfigFile() method with a local.ini.php file
+        */
+       public function testLoadConfigFilesINI()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       'A.ini.php';
+
+               vfsStream::newFile('local.ini.php')
+                       ->at($this->root->getChild('config'))
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('testhost', $configCache->get('database', 'hostname'));
+               self::assertEquals('testuser', $configCache->get('database', 'username'));
+               self::assertEquals('testpw', $configCache->get('database', 'password'));
+               self::assertEquals('testdb', $configCache->get('database', 'database'));
+
+               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+       }
+
+       /**
+        * Test the loadConfigFile() method with a .htconfig.php file
+        */
+       public function testLoadConfigFilesHtconfig()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       '.htconfig.php';
+
+               vfsStream::newFile('.htconfig.php')
+                       ->at($this->root)
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('testhost', $configCache->get('database', 'hostname'));
+               self::assertEquals('testuser', $configCache->get('database', 'username'));
+               self::assertEquals('testpw', $configCache->get('database', 'password'));
+               self::assertEquals('testdb', $configCache->get('database', 'database'));
+               self::assertEquals('anotherCharset', $configCache->get('database', 'charset'));
+
+               self::assertEquals('/var/run/friendica.pid', $configCache->get('system', 'pidfile'));
+               self::assertEquals('Europe/Berlin', $configCache->get('system', 'default_timezone'));
+               self::assertEquals('fr', $configCache->get('system', 'language'));
+
+               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+               self::assertEquals('Friendly admin', $configCache->get('config', 'admin_nickname'));
+
+               self::assertEquals('/another/php', $configCache->get('config', 'php_path'));
+               self::assertEquals('999', $configCache->get('config', 'max_import_size'));
+               self::assertEquals('666', $configCache->get('system', 'maximagesize'));
+
+               self::assertEquals('frio,quattro,vier,duepuntozero', $configCache->get('system', 'allowed_themes'));
+               self::assertEquals('1', $configCache->get('system', 'no_regfullname'));
+       }
+
+       public function testLoadAddonConfig()
+       {
+               $structure = [
+                       'addon' => [
+                               'test' => [
+                                       'config' => [],
+                               ],
+                       ],
+               ];
+
+               vfsStream::create($structure, $this->root);
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       'A.config.php';
+
+               vfsStream::newFile('test.config.php')
+                       ->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+
+               $conf = $configFileLoader->loadAddonConfig('test');
+
+               self::assertEquals('testhost', $conf['database']['hostname']);
+               self::assertEquals('testuser', $conf['database']['username']);
+               self::assertEquals('testpw', $conf['database']['password']);
+               self::assertEquals('testdb', $conf['database']['database']);
+
+               self::assertEquals('admin@test.it', $conf['config']['admin_email']);
+       }
+
+       /**
+        * test loading multiple config files - the last config should work
+        */
+       public function testLoadMultipleConfigs()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                          '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR;
+
+               vfsStream::newFile('A.config.php')
+                        ->at($this->root->getChild('config'))
+                        ->setContent(file_get_contents($fileDir . 'A.config.php'));
+               vfsStream::newFile('B.config.php')
+                               ->at($this->root->getChild('config'))
+                        ->setContent(file_get_contents($fileDir . 'B.config.php'));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('admin@overwritten.local', $configCache->get('config', 'admin_email'));
+               self::assertEquals('newValue', $configCache->get('system', 'newKey'));
+       }
+
+       /**
+        * test loading multiple config files - the last config should work (INI-version)
+        */
+       public function testLoadMultipleInis()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                          '..' . DIRECTORY_SEPARATOR .
+                          '..' . DIRECTORY_SEPARATOR .
+                                  '..' . DIRECTORY_SEPARATOR .
+                          'datasets' . DIRECTORY_SEPARATOR .
+                          'config' . DIRECTORY_SEPARATOR;
+
+               vfsStream::newFile('A.ini.php')
+                        ->at($this->root->getChild('config'))
+                        ->setContent(file_get_contents($fileDir . 'A.ini.php'));
+               vfsStream::newFile('B.ini.php')
+                        ->at($this->root->getChild('config'))
+                        ->setContent(file_get_contents($fileDir . 'B.ini.php'));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('admin@overwritten.local', $configCache->get('config', 'admin_email'));
+               self::assertEquals('newValue', $configCache->get('system', 'newKey'));
+       }
+
+       /**
+        * Test that sample-files (e.g. local-sample.config.php) is never loaded
+        */
+       public function testNotLoadingSamples()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                          '..' . DIRECTORY_SEPARATOR .
+                                  '..' . DIRECTORY_SEPARATOR .
+                          '..' . DIRECTORY_SEPARATOR .
+                          'datasets' . DIRECTORY_SEPARATOR .
+                          'config' . DIRECTORY_SEPARATOR;
+
+               vfsStream::newFile('A.ini.php')
+                        ->at($this->root->getChild('config'))
+                        ->setContent(file_get_contents($fileDir . 'A.ini.php'));
+               vfsStream::newFile('B-sample.ini.php')
+                        ->at($this->root->getChild('config'))
+                        ->setContent(file_get_contents($fileDir . 'B.ini.php'));
+
+               $configFileLoader = new ConfigFileLoader(
+                       $this->root->url(),
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
+                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
+               );
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+               self::assertEmpty($configCache->get('system', 'NewKey'));
+       }
+
+       /**
+        * Test that using a wrong configuration directory leads to the "normal" config path
+        */
+       public function testWrongEnvDir()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $configFileLoader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
+       }
+
+       /**
+        * Test that a different location of the configuration directory produces the expected output
+        */
+       public function testRightEnvDir()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                                  '..' . DIRECTORY_SEPARATOR .
+                                  '..' . DIRECTORY_SEPARATOR .
+                                  '..' . DIRECTORY_SEPARATOR .
+                                  'datasets' . DIRECTORY_SEPARATOR .
+                                  'config' . DIRECTORY_SEPARATOR;
+
+               vfsStream::newFile('B.config.php')
+                                ->at($this->root->getChild('config2'))
+                                ->setContent(file_get_contents($fileDir . 'B.config.php'));
+
+               $configFileLoader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()]);
+               $configCache = new Cache\Cache();
+
+               $configFileLoader->setupCache($configCache);
+
+               self::assertEquals('newValue', $configCache->get('system', 'newKey'));
+       }
+}
diff --git a/tests/src/Core/Config/CacheTest.php b/tests/src/Core/Config/CacheTest.php
deleted file mode 100644 (file)
index 79cca7c..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Test\src\Core\Config;
-
-use Friendica\Core\Config\Cache;
-use Friendica\Test\MockedTest;
-use ParagonIE\HiddenString\HiddenString;
-use stdClass;
-
-class CacheTest extends MockedTest
-{
-       public function dataTests()
-       {
-               return [
-                       'normal' => [
-                               'data' => [
-                                       'system' => [
-                                               'test' => 'it',
-                                               'boolTrue' => true,
-                                               'boolFalse' => false,
-                                               'int' => 235,
-                                               'dec' => 2.456,
-                                               'array' => ['1', 2, '3', true, false],
-                                       ],
-                                       'config' => [
-                                               'a' => 'value',
-                                       ],
-                               ]
-                       ]
-               ];
-       }
-
-       private function assertConfigValues($data, Cache $configCache)
-       {
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               self::assertEquals($data[$cat][$key], $configCache->get($cat, $key));
-                       }
-               }
-       }
-
-       /**
-        * Test the loadConfigArray() method without override
-        * @dataProvider dataTests
-        */
-       public function testLoadConfigArray($data)
-       {
-               $configCache = new Cache();
-               $configCache->load($data);
-
-               self::assertConfigValues($data, $configCache);
-       }
-
-       /**
-        * Test the loadConfigArray() method with overrides
-        * @dataProvider dataTests
-        */
-       public function testLoadConfigArrayOverride($data)
-       {
-               $override = [
-                       'system' => [
-                               'test' => 'not',
-                               'boolTrue' => false,
-                       ]
-               ];
-
-               $configCache = new Cache();
-               $configCache->load($data, Cache::SOURCE_DB);
-               // doesn't override - Low Priority due Config file
-               $configCache->load($override, Cache::SOURCE_FILE);
-
-               self::assertConfigValues($data, $configCache);
-
-               // override the value - High Prio due Server Env
-               $configCache->load($override, Cache::SOURCE_ENV);
-
-               self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
-               self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
-
-               // Don't overwrite server ENV variables - even in load mode
-               $configCache->load($data, Cache::SOURCE_DB);
-
-               self::assertEquals($override['system']['test'], $configCache->get('system', 'test'));
-               self::assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
-
-               // Overwrite ENV variables with ENV variables
-               $configCache->load($data, Cache::SOURCE_ENV);
-
-               self::assertConfigValues($data, $configCache);
-               self::assertNotEquals($override['system']['test'], $configCache->get('system', 'test'));
-               self::assertNotEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue'));
-       }
-
-       /**
-        * Test the loadConfigArray() method with wrong/empty datasets
-        */
-       public function testLoadConfigArrayWrong()
-       {
-               $configCache = new Cache();
-
-               // empty dataset
-               $configCache->load([]);
-               self::assertEmpty($configCache->getAll());
-
-               // wrong dataset
-               $configCache->load(['system' => 'not_array']);
-               self::assertEmpty($configCache->getAll());
-
-               // incomplete dataset (key is integer ID of the array)
-               $configCache->load(['system' => ['value']]);
-               self::assertEquals('value', $configCache->get('system', 0));
-       }
-
-       /**
-        * Test the getAll() method
-        * @dataProvider dataTests
-        */
-       public function testGetAll($data)
-       {
-               $configCache = new Cache();
-               $configCache->load($data);
-
-               $all = $configCache->getAll();
-
-               self::assertContains($data['system'], $all);
-               self::assertContains($data['config'], $all);
-       }
-
-       /**
-        * Test the set() and get() method
-        * @dataProvider dataTests
-        */
-       public function testSetGet($data)
-       {
-               $configCache = new Cache();
-
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               $configCache->set($cat, $key, $value);
-                       }
-               }
-
-               self::assertConfigValues($data, $configCache);
-       }
-
-       /**
-        * Test the get() method without a value
-        */
-       public function testGetEmpty()
-       {
-               $configCache = new Cache();
-
-               self::assertNull($configCache->get('something', 'value'));
-       }
-
-       /**
-        * Test the get() method with a category
-        */
-       public function testGetCat()
-       {
-               $configCache = new Cache([
-                       'system' => [
-                               'key1' => 'value1',
-                               'key2' => 'value2',
-                       ],
-                       'config' => [
-                               'key3' => 'value3',
-                       ],
-               ]);
-
-               self::assertEquals([
-                       'key1' => 'value1',
-                       'key2' => 'value2',
-               ], $configCache->get('system'));
-
-               // explicit null as key
-               self::assertEquals([
-                       'key1' => 'value1',
-                       'key2' => 'value2',
-               ], $configCache->get('system', null));
-       }
-
-       /**
-        * Test the delete() method
-        * @dataProvider dataTests
-        */
-       public function testDelete($data)
-       {
-               $configCache = new Cache($data);
-
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               $configCache->delete($cat, $key);
-                       }
-               }
-
-               self::assertEmpty($configCache->getAll());
-       }
-
-       /**
-        * Test the keyDiff() method with result
-        * @dataProvider dataTests
-        */
-       public function testKeyDiffWithResult($data)
-       {
-               $configCache = new Cache($data);
-
-               $diffConfig = [
-                       'fakeCat' => [
-                               'fakeKey' => 'value',
-                       ]
-               ];
-
-               self::assertEquals($diffConfig, $configCache->keyDiff($diffConfig));
-       }
-
-       /**
-        * Test the keyDiff() method without result
-        * @dataProvider dataTests
-        */
-       public function testKeyDiffWithoutResult($data)
-       {
-               $configCache = new Cache($data);
-
-               $diffConfig = $configCache->getAll();
-
-               self::assertEmpty($configCache->keyDiff($diffConfig));
-       }
-
-       /**
-        * Test the default hiding of passwords inside the cache
-        */
-       public function testPasswordHide()
-       {
-               $configCache = new Cache([
-                       'database' => [
-                               'password' => 'supersecure',
-                               'username' => 'notsecured',
-                       ],
-               ]);
-
-               self::assertEquals('supersecure', $configCache->get('database', 'password'));
-               self::assertNotEquals('supersecure', print_r($configCache->get('database', 'password'), true));
-               self::assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
-       }
-
-       /**
-        * Test disabling the hiding of passwords inside the cache
-        */
-       public function testPasswordShow()
-       {
-               $configCache = new Cache([
-                       'database' => [
-                               'password' => 'supersecure',
-                               'username' => 'notsecured',
-                       ],
-               ], false);
-
-               self::assertEquals('supersecure', $configCache->get('database', 'password'));
-               self::assertEquals('supersecure', print_r($configCache->get('database', 'password'), true));
-               self::assertEquals('notsecured', print_r($configCache->get('database', 'username'), true));
-       }
-
-       /**
-        * Test a empty password
-        */
-       public function testEmptyPassword()
-       {
-               $configCache = new Cache([
-                       'database' => [
-                               'password' => '',
-                               'username' => '',
-                       ]
-               ]);
-
-               self::assertNotEmpty($configCache->get('database', 'password'));
-               self::assertInstanceOf(HiddenString::class, $configCache->get('database', 'password'));
-               self::assertEmpty($configCache->get('database', 'username'));
-       }
-
-       public function testWrongTypePassword()
-       {
-               $configCache = new Cache([
-                       'database' => [
-                               'password' => new stdClass(),
-                               'username' => '',
-                       ]
-               ]);
-
-               self::assertNotEmpty($configCache->get('database', 'password'));
-               self::assertEmpty($configCache->get('database', 'username'));
-
-               $configCache = new Cache([
-                       'database' => [
-                               'password' => 23,
-                               'username' => '',
-                       ]
-               ]);
-
-               self::assertEquals(23, $configCache->get('database', 'password'));
-               self::assertEmpty($configCache->get('database', 'username'));
-       }
-
-       /**
-        * Test the set() method with overrides
-        * @dataProvider dataTests
-        */
-       public function testSetOverrides($data)
-       {
-
-               $configCache = new Cache();
-               $configCache->load($data, Cache::SOURCE_DB);
-
-               // test with wrong override
-               self::assertFalse($configCache->set('system', 'test', '1234567', Cache::SOURCE_FILE));
-               self::assertEquals($data['system']['test'], $configCache->get('system', 'test'));
-
-               // test with override (equal)
-               self::assertTrue($configCache->set('system', 'test', '8910', Cache::SOURCE_DB));
-               self::assertEquals('8910', $configCache->get('system', 'test'));
-
-               // test with override (over)
-               self::assertTrue($configCache->set('system', 'test', '111213', Cache::SOURCE_ENV));
-               self::assertEquals('111213', $configCache->get('system', 'test'));
-       }
-}
index 734f6bff7935fecaf54ce9894c73a0de0beac7ef..e7708598758ec0d55d113e3beaae1b96df420054 100644 (file)
@@ -23,7 +23,7 @@ namespace Friendica\Test\src\Core\Config;
 
 use Friendica\Core\Config\Cache;
 use Friendica\Core\Config\IConfig;
-use Friendica\Model\Config\Config as ConfigModel;
+use Friendica\Core\Config\Model\Config as ConfigModel;
 use Friendica\Test\MockedTest;
 use Mockery\MockInterface;
 use Mockery;
@@ -33,7 +33,7 @@ abstract class ConfigTest extends MockedTest
        /** @var ConfigModel|MockInterface */
        protected $configModel;
 
-       /** @var Cache */
+       /** @var Cache\Cache */
        protected $configCache;
 
        /** @var IConfig */
@@ -61,7 +61,7 @@ abstract class ConfigTest extends MockedTest
 
                // Create the config model
                $this->configModel = Mockery::mock(ConfigModel::class);
-               $this->configCache = new Cache();
+               $this->configCache = new Cache\Cache();
        }
 
        /**
@@ -161,7 +161,7 @@ abstract class ConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // assert config is loaded everytime
                self::assertConfig('config', $data['config']);
@@ -176,7 +176,7 @@ abstract class ConfigTest extends MockedTest
        public function testLoad(array $data, array $load)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                foreach ($load as $loadedCats) {
                        $this->testedConfig->load($loadedCats);
@@ -257,7 +257,7 @@ abstract class ConfigTest extends MockedTest
        public function testCacheLoadDouble(array $data1, array $data2, array $expect = [])
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                foreach ($data1 as $cat => $data) {
                        $this->testedConfig->load($cat);
@@ -282,7 +282,7 @@ abstract class ConfigTest extends MockedTest
                $this->configModel->shouldReceive('load')->withAnyArgs()->andReturn([])->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertEmpty($this->testedConfig->getCache()->getAll());
        }
@@ -299,7 +299,7 @@ abstract class ConfigTest extends MockedTest
                                  ->times(3);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set('test', 'it', $data));
 
@@ -317,7 +317,7 @@ abstract class ConfigTest extends MockedTest
                $this->configModel->shouldReceive('set')->with('test', 'it', $data)->andReturn(true)->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set('test', 'it', $data));
 
@@ -331,7 +331,7 @@ abstract class ConfigTest extends MockedTest
        public function testGetWrongWithoutDB()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertNull($this->testedConfig->get('test', 'it'));
@@ -353,10 +353,10 @@ abstract class ConfigTest extends MockedTest
         */
        public function testGetWithRefresh($data)
        {
-               $this->configCache->load(['test' => ['it' => 'now']], Cache::SOURCE_FILE);
+               $this->configCache->load(['test' => ['it' => 'now']], Cache\Cache::SOURCE_FILE);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertEquals('now', $this->testedConfig->get('test', 'it'));
@@ -378,10 +378,10 @@ abstract class ConfigTest extends MockedTest
         */
        public function testDeleteWithoutDB($data)
        {
-               $this->configCache->load(['test' => ['it' => $data]], Cache::SOURCE_FILE);
+               $this->configCache->load(['test' => ['it' => $data]], Cache\Cache::SOURCE_FILE);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertEquals($data, $this->testedConfig->get('test', 'it'));
                self::assertEquals($data, $this->testedConfig->getCache()->get('test', 'it'));
@@ -398,7 +398,7 @@ abstract class ConfigTest extends MockedTest
         */
        public function testDeleteWithDB()
        {
-               $this->configCache->load(['test' => ['it' => 'now', 'quarter' => 'true']], Cache::SOURCE_FILE);
+               $this->configCache->load(['test' => ['it' => 'now', 'quarter' => 'true']], Cache\Cache::SOURCE_FILE);
 
                $this->configModel->shouldReceive('delete')
                                  ->with('test', 'it')
@@ -418,7 +418,7 @@ abstract class ConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // directly set the value to the cache
                $this->testedConfig->getCache()->set('test', 'it', 'now');
@@ -444,9 +444,9 @@ abstract class ConfigTest extends MockedTest
        public function testSetGetHighPrio()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
-               $this->testedConfig->getCache()->set('config', 'test', 'prio', Cache::SOURCE_FILE);
+               $this->testedConfig->getCache()->set('config', 'test', 'prio', Cache\Cache::SOURCE_FILE);
                self::assertEquals('prio', $this->testedConfig->get('config', 'test'));
 
                // now you have to get the new variable entry because of the new set the get refresh succeed as well
@@ -460,10 +460,10 @@ abstract class ConfigTest extends MockedTest
        public function testSetGetLowPrio()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
                self::assertEquals('it', $this->testedConfig->get('config', 'test'));
 
-               $this->testedConfig->getCache()->set('config', 'test', 'prio', Cache::SOURCE_ENV);
+               $this->testedConfig->getCache()->set('config', 'test', 'prio', Cache\Cache::SOURCE_ENV);
                // now you have to get the env variable entry as output, even with a new set (which failed) and a get refresh
                self::assertFalse($this->testedConfig->set('config', 'test', '123'));
                self::assertEquals('prio', $this->testedConfig->get('config', 'test', '', true));
index 62c5effda6e9d74635f08a8f37f238ac58034586..5c923beec753e4ccbdba0658a9ffbb0cf1cfa804 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Core\Config;
 
-use Friendica\Core\Config\JitConfig;
+use Friendica\Core\Config\Type\JitConfig;
 
 class JitConfigTest extends ConfigTest
 {
index d12f2dcd597c9737420469504ea630476b8eee2b..9ce6f4e1ba0a06a5374ccc9456b6cecd7ac50bd4 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Core\Config;
 
-use Friendica\Core\Config\PreloadConfig;
+use Friendica\Core\Config\Type\PreloadConfig;
 
 class PreloadConfigTest extends ConfigTest
 {
index 1263fe7e67b73f0f7e72c0ed3f3af80287ec87a3..bdb1d53c0b112d500b98feb17a9faf803a4ba698 100644 (file)
@@ -23,7 +23,7 @@
 namespace Friendica\Core;
 
 use Dice\Dice;
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\DI;
 use Friendica\Network\IHTTPResult;
 use Friendica\Network\IHTTPClient;
index c51d153efce13da26fdab419995b02449f07fba6..86209d5c7d70c0bf23e292fbc3be684b9b55d850 100644 (file)
 namespace Friendica\Test\src\Core\Lock;
 
 use Friendica\Core\Lock\DatabaseLock;
-use Friendica\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use Mockery;
 use Psr\Log\NullLogger;
index 87d8b2cd2f59595eeed51422037e92a2f5caa01a..89a3ec633cb8adfb04c4346d97b274b597736d2f 100644 (file)
@@ -24,7 +24,7 @@ namespace Friendica\Test\src\Core\Lock;
 use Dice\Dice;
 use Friendica\App;
 use Friendica\Core\Config\IConfig;
-use Friendica\Core\Config\JitConfig;
+use Friendica\Core\Config\Type\JitConfig;
 use Friendica\Core\Lock\SemaphoreLock;
 use Friendica\DI;
 use Mockery;
diff --git a/tests/src/Core/PConfig/Cache/CacheTest.php b/tests/src/Core/PConfig/Cache/CacheTest.php
new file mode 100644 (file)
index 0000000..99e0e91
--- /dev/null
@@ -0,0 +1,292 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2021, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace Friendica\Test\src\Core\PConfig\Cache;
+
+use Friendica\Core\PConfig\Cache;
+use Friendica\Test\MockedTest;
+
+class CacheTest extends MockedTest
+{
+       public function dataTests()
+       {
+               return [
+                       'normal' => [
+                               'data' => [
+                                       'system' => [
+                                               'test'      => 'it',
+                                               'boolTrue'  => true,
+                                               'boolFalse' => false,
+                                               'int'       => 235,
+                                               'dec'       => 2.456,
+                                               'array'     => ['1', 2, '3', true, false],
+                                       ],
+                                       'config' => [
+                                               'a' => 'value',
+                                       ],
+                               ]
+                       ]
+               ];
+       }
+
+       private function assertConfigValues($data, Cache\Cache $configCache, $uid)
+       {
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               self::assertEquals($data[$cat][$key], $configCache->get($uid, $cat, $key));
+                       }
+               }
+       }
+
+       /**
+        * Test the setP() and getP() methods
+        *
+        * @dataProvider dataTests
+        */
+       public function testSetGet($data)
+       {
+               $configCache = new Cache\Cache();
+               $uid         = 345;
+
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               $configCache->set($uid, $cat, $key, $value);
+                       }
+               }
+
+               self::assertConfigValues($data, $configCache, $uid);
+       }
+
+
+       /**
+        * Test the getP() method with a category
+        */
+       public function testGetCat()
+       {
+               $configCache = new Cache\Cache();
+               $uid         = 345;
+
+               $configCache->load($uid, [
+                       'system' => [
+                               'key1' => 'value1',
+                               'key2' => 'value2',
+                       ],
+                       'config' => [
+                               'key3' => 'value3',
+                       ],
+               ]);
+
+               self::assertEquals([
+                       'key1' => 'value1',
+                       'key2' => 'value2',
+               ], $configCache->get($uid, 'system'));
+
+               // test explicit cat with null as key
+               self::assertEquals([
+                       'key1' => 'value1',
+                       'key2' => 'value2',
+               ], $configCache->get($uid, 'system', null));
+       }
+
+       /**
+        * Test the deleteP() method
+        *
+        * @dataProvider dataTests
+        */
+       public function testDelete($data)
+       {
+               $configCache = new Cache\Cache();
+               $uid         = 345;
+
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               $configCache->set($uid, $cat, $key, $value);
+                       }
+               }
+
+               foreach ($data as $cat => $values) {
+                       foreach ($values as $key => $value) {
+                               $configCache->delete($uid, $cat, $key);
+                       }
+               }
+
+               self::assertEmpty($configCache->getAll());
+       }
+
+       /**
+        * Test the keyDiff() method with result
+        */
+       public function testKeyDiffWithResult()
+       {
+               $configCache = new Cache\Cache();
+
+               $diffConfig = [
+                       'fakeCat' => [
+                               'fakeKey' => 'value',
+                       ]
+               ];
+
+               self::assertEquals($diffConfig, $configCache->keyDiff($diffConfig));
+       }
+
+       /**
+        * Test the keyDiff() method without result
+        *
+        * @dataProvider dataTests
+        */
+       public function testKeyDiffWithoutResult($data)
+       {
+               $configCache = new Cache\Cache();
+
+               $configCache->load(1, $data);
+
+               $diffConfig = $configCache->getAll();
+
+               self::assertEmpty($configCache->keyDiff($diffConfig));
+       }
+
+       /**
+        * Test the default hiding of passwords inside the cache
+        */
+       public function testPasswordHide()
+       {
+               $configCache = new Cache\Cache();
+
+               $configCache->load(1, [
+                       'database' => [
+                               'password' => 'supersecure',
+                               'username' => 'notsecured',
+                       ]
+               ]);
+
+               self::assertEquals('supersecure', $configCache->get(1, 'database', 'password'));
+               self::assertNotEquals('supersecure', print_r($configCache->get(1, 'database', 'password'), true));
+               self::assertEquals('notsecured', print_r($configCache->get(1, 'database', 'username'), true));
+       }
+
+       /**
+        * Test disabling the hiding of passwords inside the cache
+        */
+       public function testPasswordShow()
+       {
+               $configCache = new Cache\Cache(false);
+
+               $configCache->load(1, [
+                       'database' => [
+                               'password' => 'supersecure',
+                               'username' => 'notsecured',
+                       ]
+               ]);
+
+               self::assertEquals('supersecure', $configCache->get(1, 'database', 'password'));
+               self::assertEquals('supersecure', print_r($configCache->get(1, 'database', 'password'), true));
+               self::assertEquals('notsecured', print_r($configCache->get(1, 'database', 'username'), true));
+       }
+
+       /**
+        * Test a empty password
+        */
+       public function testEmptyPassword()
+       {
+               $configCache = new Cache\Cache();
+
+               $configCache->load(1, [
+                       'database' => [
+                               'password' => '',
+                               'username' => '',
+                       ]
+               ]);
+
+               self::assertEmpty($configCache->get(1, 'database', 'password'));
+               self::assertEmpty($configCache->get(1, 'database', 'username'));
+       }
+
+       public function testWrongTypePassword()
+       {
+               $configCache = new Cache\Cache();
+
+               $configCache->load(1, [
+                       'database' => [
+                               'password' => new \stdClass(),
+                               'username' => '',
+                       ]
+               ]);
+
+               self::assertNotEmpty($configCache->get(1, 'database', 'password'));
+               self::assertEmpty($configCache->get(1, 'database', 'username'));
+
+               $configCache = new Cache\Cache();
+
+               $configCache->load(1, [
+                       'database' => [
+                               'password' => 23,
+                               'username' => '',
+                       ],
+               ]);
+
+               self::assertEquals(23, $configCache->get(1, 'database', 'password'));
+               self::assertEmpty($configCache->get(1, 'database', 'username'));
+       }
+
+       /**
+        * Test two different UID configs and make sure that there is no overlapping possible
+        */
+       public function testTwoUid()
+       {
+               $configCache = new Cache\Cache();
+
+               $configCache->load(1, [
+                       'cat1' => [
+                               'key1' => 'value1',
+                       ],
+               ]);
+
+
+               $configCache->load(2, [
+                       'cat2' => [
+                               'key2' => 'value2',
+                       ],
+               ]);
+
+               self::assertEquals('value1', $configCache->get(1, 'cat1', 'key1'));
+               self::assertEquals('value2', $configCache->get(2, 'cat2', 'key2'));
+
+               self::assertNull($configCache->get(1, 'cat2', 'key2'));
+               self::assertNull($configCache->get(2, 'cat1', 'key1'));
+       }
+
+       /**
+        * Test when using an invalid UID
+        * @todo check it the clean way before using the config class
+        */
+       public function testInvalidUid()
+       {
+               // bad UID!
+               $uid = null;
+
+               $configCache = new Cache\Cache();
+
+               self::assertNull($configCache->get($uid, 'cat1', 'cat2'));
+
+               self::assertFalse($configCache->set($uid, 'cat1', 'key1', 'doesn\'t matter!'));
+               self::assertFalse($configCache->delete($uid, 'cat1', 'key1'));
+       }
+}
diff --git a/tests/src/Core/PConfig/CacheTest.php b/tests/src/Core/PConfig/CacheTest.php
deleted file mode 100644 (file)
index 77f6140..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Test\src\Core\PConfig;
-
-use Friendica\Core\PConfig\Cache;
-use Friendica\Test\MockedTest;
-
-class CacheTest extends MockedTest
-{
-       public function dataTests()
-       {
-               return [
-                       'normal' => [
-                               'data' => [
-                                       'system' => [
-                                               'test'      => 'it',
-                                               'boolTrue'  => true,
-                                               'boolFalse' => false,
-                                               'int'       => 235,
-                                               'dec'       => 2.456,
-                                               'array'     => ['1', 2, '3', true, false],
-                                       ],
-                                       'config' => [
-                                               'a' => 'value',
-                                       ],
-                               ]
-                       ]
-               ];
-       }
-
-       private function assertConfigValues($data, Cache $configCache, $uid)
-       {
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               self::assertEquals($data[$cat][$key], $configCache->get($uid, $cat, $key));
-                       }
-               }
-       }
-
-       /**
-        * Test the setP() and getP() methods
-        *
-        * @dataProvider dataTests
-        */
-       public function testSetGet($data)
-       {
-               $configCache = new Cache();
-               $uid         = 345;
-
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               $configCache->set($uid, $cat, $key, $value);
-                       }
-               }
-
-               self::assertConfigValues($data, $configCache, $uid);
-       }
-
-
-       /**
-        * Test the getP() method with a category
-        */
-       public function testGetCat()
-       {
-               $configCache = new Cache();
-               $uid         = 345;
-
-               $configCache->load($uid, [
-                       'system' => [
-                               'key1' => 'value1',
-                               'key2' => 'value2',
-                       ],
-                       'config' => [
-                               'key3' => 'value3',
-                       ],
-               ]);
-
-               self::assertEquals([
-                       'key1' => 'value1',
-                       'key2' => 'value2',
-               ], $configCache->get($uid, 'system'));
-
-               // test explicit cat with null as key
-               self::assertEquals([
-                       'key1' => 'value1',
-                       'key2' => 'value2',
-               ], $configCache->get($uid, 'system', null));
-       }
-
-       /**
-        * Test the deleteP() method
-        *
-        * @dataProvider dataTests
-        */
-       public function testDelete($data)
-       {
-               $configCache = new Cache();
-               $uid         = 345;
-
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               $configCache->set($uid, $cat, $key, $value);
-                       }
-               }
-
-               foreach ($data as $cat => $values) {
-                       foreach ($values as $key => $value) {
-                               $configCache->delete($uid, $cat, $key);
-                       }
-               }
-
-               self::assertEmpty($configCache->getAll());
-       }
-
-       /**
-        * Test the keyDiff() method with result
-        */
-       public function testKeyDiffWithResult()
-       {
-               $configCache = new Cache();
-
-               $diffConfig = [
-                       'fakeCat' => [
-                               'fakeKey' => 'value',
-                       ]
-               ];
-
-               self::assertEquals($diffConfig, $configCache->keyDiff($diffConfig));
-       }
-
-       /**
-        * Test the keyDiff() method without result
-        *
-        * @dataProvider dataTests
-        */
-       public function testKeyDiffWithoutResult($data)
-       {
-               $configCache = new Cache();
-
-               $configCache->load(1, $data);
-
-               $diffConfig = $configCache->getAll();
-
-               self::assertEmpty($configCache->keyDiff($diffConfig));
-       }
-
-       /**
-        * Test the default hiding of passwords inside the cache
-        */
-       public function testPasswordHide()
-       {
-               $configCache = new Cache();
-
-               $configCache->load(1, [
-                       'database' => [
-                               'password' => 'supersecure',
-                               'username' => 'notsecured',
-                       ]
-               ]);
-
-               self::assertEquals('supersecure', $configCache->get(1, 'database', 'password'));
-               self::assertNotEquals('supersecure', print_r($configCache->get(1, 'database', 'password'), true));
-               self::assertEquals('notsecured', print_r($configCache->get(1, 'database', 'username'), true));
-       }
-
-       /**
-        * Test disabling the hiding of passwords inside the cache
-        */
-       public function testPasswordShow()
-       {
-               $configCache = new Cache(false);
-
-               $configCache->load(1, [
-                       'database' => [
-                               'password' => 'supersecure',
-                               'username' => 'notsecured',
-                       ]
-               ]);
-
-               self::assertEquals('supersecure', $configCache->get(1, 'database', 'password'));
-               self::assertEquals('supersecure', print_r($configCache->get(1, 'database', 'password'), true));
-               self::assertEquals('notsecured', print_r($configCache->get(1, 'database', 'username'), true));
-       }
-
-       /**
-        * Test a empty password
-        */
-       public function testEmptyPassword()
-       {
-               $configCache = new Cache();
-
-               $configCache->load(1, [
-                       'database' => [
-                               'password' => '',
-                               'username' => '',
-                       ]
-               ]);
-
-               self::assertEmpty($configCache->get(1, 'database', 'password'));
-               self::assertEmpty($configCache->get(1, 'database', 'username'));
-       }
-
-       public function testWrongTypePassword()
-       {
-               $configCache = new Cache();
-
-               $configCache->load(1, [
-                       'database' => [
-                               'password' => new \stdClass(),
-                               'username' => '',
-                       ]
-               ]);
-
-               self::assertNotEmpty($configCache->get(1, 'database', 'password'));
-               self::assertEmpty($configCache->get(1, 'database', 'username'));
-
-               $configCache = new Cache();
-
-               $configCache->load(1, [
-                       'database' => [
-                               'password' => 23,
-                               'username' => '',
-                       ],
-               ]);
-
-               self::assertEquals(23, $configCache->get(1, 'database', 'password'));
-               self::assertEmpty($configCache->get(1, 'database', 'username'));
-       }
-
-       /**
-        * Test two different UID configs and make sure that there is no overlapping possible
-        */
-       public function testTwoUid()
-       {
-               $configCache = new Cache();
-
-               $configCache->load(1, [
-                       'cat1' => [
-                               'key1' => 'value1',
-                       ],
-               ]);
-
-
-               $configCache->load(2, [
-                       'cat2' => [
-                               'key2' => 'value2',
-                       ],
-               ]);
-
-               self::assertEquals('value1', $configCache->get(1, 'cat1', 'key1'));
-               self::assertEquals('value2', $configCache->get(2, 'cat2', 'key2'));
-
-               self::assertNull($configCache->get(1, 'cat2', 'key2'));
-               self::assertNull($configCache->get(2, 'cat1', 'key1'));
-       }
-
-       /**
-        * Test when using an invalid UID
-        * @todo check it the clean way before using the config class
-        */
-       public function testInvalidUid()
-       {
-               // bad UID!
-               $uid = null;
-
-               $configCache = new Cache();
-
-               self::assertNull($configCache->get($uid, 'cat1', 'cat2'));
-
-               self::assertFalse($configCache->set($uid, 'cat1', 'key1', 'doesn\'t matter!'));
-               self::assertFalse($configCache->delete($uid, 'cat1', 'key1'));
-       }
-}
index f43b9cd762ab61168a30eff5cf8e4dfb5f9ad646..34428cb317d784d5c8e9e3097e3903eeb450adff 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Core\PConfig;
 
-use Friendica\Core\PConfig\JitPConfig;
+use Friendica\Core\PConfig\Type\JitPConfig;
 
 class JitPConfigTest extends PConfigTest
 {
index f35aa10d98acce29b41bf9017e47e62a80d66a54..9288b10585a0c20ecb82c40895105dbdd5fe021d 100644 (file)
@@ -22,8 +22,8 @@
 namespace Friendica\Test\src\Core\PConfig;
 
 use Friendica\Core\PConfig\Cache;
-use Friendica\Core\BasePConfig;
-use Friendica\Model\Config\PConfig as PConfigModel;
+use Friendica\Core\PConfig\Type\BasePConfig;
+use Friendica\Core\PConfig\Model\PConfig as PConfigModel;
 use Friendica\Test\MockedTest;
 use Mockery;
 use Mockery\MockInterface;
@@ -33,7 +33,7 @@ abstract class PConfigTest extends MockedTest
        /** @var PConfigModel|MockInterface */
        protected $configModel;
 
-       /** @var Cache */
+       /** @var Cache\Cache */
        protected $configCache;
 
        /** @var BasePConfig */
@@ -63,11 +63,11 @@ abstract class PConfigTest extends MockedTest
 
                // Create the config model
                $this->configModel = Mockery::mock(PConfigModel::class);
-               $this->configCache = new Cache();
+               $this->configCache = new Cache\Cache();
        }
 
        /**
-        * @return BasePConfig
+        * @return \Friendica\Core\PConfig\Type\BasePConfig
         */
        abstract public function getInstance();
 
@@ -163,7 +163,7 @@ abstract class PConfigTest extends MockedTest
        public function testSetUp()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertEmpty($this->testedConfig->getCache()->getAll());
        }
@@ -174,7 +174,7 @@ abstract class PConfigTest extends MockedTest
        public function testLoad(int $uid, array $data, array $possibleCats, array $load)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                foreach ($load as $loadedCats) {
                        $this->testedConfig->load($uid, $loadedCats);
@@ -257,7 +257,7 @@ abstract class PConfigTest extends MockedTest
        public function testCacheLoadDouble(int $uid, array $data1, array $data2, array $expect)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                foreach ($data1 as $cat => $data) {
                        $this->testedConfig->load($uid, $cat);
@@ -281,7 +281,7 @@ abstract class PConfigTest extends MockedTest
        public function testSetGetWithoutDB(int $uid, $data)
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set($uid, 'test', 'it', $data));
 
@@ -302,7 +302,7 @@ abstract class PConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertTrue($this->testedConfig->set($uid, 'test', 'it', $data));
 
@@ -316,7 +316,7 @@ abstract class PConfigTest extends MockedTest
        public function testGetWrongWithoutDB()
        {
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertNull($this->testedConfig->get(0, 'test', 'it'));
@@ -341,7 +341,7 @@ abstract class PConfigTest extends MockedTest
                $this->configCache->load($uid, ['test' => ['it' => 'now']]);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // without refresh
                self::assertEquals('now', $this->testedConfig->get($uid, 'test', 'it'));
@@ -366,7 +366,7 @@ abstract class PConfigTest extends MockedTest
                $this->configCache->load($uid, ['test' => ['it' => $data]]);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertEquals($data, $this->testedConfig->get($uid, 'test', 'it'));
                self::assertEquals($data, $this->testedConfig->getCache()->get($uid, 'test', 'it'));
@@ -405,7 +405,7 @@ abstract class PConfigTest extends MockedTest
                                  ->once();
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                // directly set the value to the cache
                $this->testedConfig->getCache()->set($uid, 'test', 'it', 'now');
@@ -465,7 +465,7 @@ abstract class PConfigTest extends MockedTest
                $this->configCache->load($data2['uid'], $data2['data']);
 
                $this->testedConfig = $this->getInstance();
-               self::assertInstanceOf(Cache::class, $this->testedConfig->getCache());
+               self::assertInstanceOf(Cache\Cache::class, $this->testedConfig->getCache());
 
                self::assertConfig($data1['uid'], 'cat1', $data1['data']['cat1']);
                self::assertConfig($data1['uid'], 'cat2', $data1['data']['cat2']);
index aa4c2f70b19cffa34469e440a63066dbadf4281d..6ffee63f76026ffdd0e10d4688363011c648e520 100644 (file)
 
 namespace Friendica\Test\src\Core\PConfig;
 
-use Friendica\Core\PConfig\PreloadPConfig;
+use Friendica\Core\PConfig\Type\PreloadPConfig;
 
 class PreloadPConfigTest extends PConfigTest
 {
        public function getInstance()
        {
-               return new PreloadPConfig($this->configCache, $this->configModel);
+               return new \Friendica\Core\PConfig\Type\PreloadPConfig($this->configCache, $this->configModel);
        }
 
        /**
index 77e4946bdf02bf4335aa2a315f2ef3565995107f..acab50ce42390f6f58f2de05a54c919f536d3835 100644 (file)
@@ -23,22 +23,22 @@ namespace Friendica\Test\src\Core;
 
 use Dice\Dice;
 use Friendica\Core\Config\IConfig;
-use Friendica\Core\Config\PreloadConfig;
+use Friendica\Core\Config\Type\PreloadConfig;
 use Friendica\Core\Hook;
 use Friendica\Core\L10n;
 use Friendica\Core\Session\ISession;
 use Friendica\Core\StorageManager;
 use Friendica\Database\Database;
 use Friendica\DI;
-use Friendica\Factory\ConfigFactory;
-use Friendica\Model\Config\Config;
+use Friendica\Core\Config\Factory\ConfigFactory;
+use Friendica\Core\Config\Model\Config;
 use Friendica\Model\Storage;
 use Friendica\Core\Session;
 use Friendica\Network\HTTPClient;
 use Friendica\Test\DatabaseTest;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
+use Friendica\Core\Config\Cache\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use org\bovigo\vfs\vfsStream;
 use Psr\Log\LoggerInterface;
index a4739d7f5b1495652bcb6f6124f6af8dce764873..ecb4d52d490d4d9f052ff09deaf5d3ec3bdd3d7a 100644 (file)
@@ -2,12 +2,11 @@
 
 namespace Friendica\Test\src\Model;
 
-use Friendica\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Model\Process;
 use Friendica\Test\DatabaseTest;
 use Friendica\Test\Util\Database\StaticDatabase;
 use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use Psr\Log\NullLogger;
 
index e1dfef9a18a4f114aabeedb1a3ea6ed0c2fe8edd..e92dd213521d7d6b5fd64cce716b3eb334159419 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Model\Storage;
 
-use Friendica\Factory\ConfigFactory;
+use Friendica\Core\Config\Factory\ConfigFactory;
 use Friendica\Model\Storage\Database;
 use Friendica\Test\DatabaseTestTrait;
 use Friendica\Test\Util\Database\StaticDatabase;
diff --git a/tests/src/Util/Config/ConfigFileLoaderTest.php b/tests/src/Util/Config/ConfigFileLoaderTest.php
deleted file mode 100644 (file)
index cb3ae84..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2010-2021, the Friendica project
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Test\src\Util\Config;
-
-use Friendica\Core\Config\Cache;
-use Friendica\Factory\ConfigFactory;
-use Friendica\Test\MockedTest;
-use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\ConfigFileLoader;
-use org\bovigo\vfs\vfsStream;
-
-class ConfigFileLoaderTest extends MockedTest
-{
-       use VFSTrait;
-
-       protected function setUp(): void
-       {
-               parent::setUp();
-
-               $this->setUpVfsDir();
-       }
-
-       /**
-        * Test the loadConfigFiles() method with default values
-        */
-       public function testLoadConfigFiles()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
-       }
-
-       /**
-        * Test the loadConfigFiles() method with a wrong local.config.php
-        *
-        */
-       public function testLoadConfigWrong()
-       {
-               $this->expectExceptionMessageMatches("/Error loading config file \w+/");
-               $this->expectException(\Exception::class);
-               $this->delConfigFile('local.config.php');
-
-               vfsStream::newFile('local.config.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent('<?php return true;');
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-       }
-
-       /**
-        * Test the loadConfigFiles() method with a local.config.php file
-        */
-       public function testLoadConfigFilesLocal()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'A.config.php';
-
-               vfsStream::newFile('local.config.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('testhost', $configCache->get('database', 'hostname'));
-               self::assertEquals('testuser', $configCache->get('database', 'username'));
-               self::assertEquals('testpw', $configCache->get('database', 'password'));
-               self::assertEquals('testdb', $configCache->get('database', 'database'));
-
-               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               self::assertEquals('Friendica Social Network', $configCache->get('config', 'sitename'));
-       }
-
-       /**
-        * Test the loadConfigFile() method with a local.ini.php file
-        */
-       public function testLoadConfigFilesINI()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'A.ini.php';
-
-               vfsStream::newFile('local.ini.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('testhost', $configCache->get('database', 'hostname'));
-               self::assertEquals('testuser', $configCache->get('database', 'username'));
-               self::assertEquals('testpw', $configCache->get('database', 'password'));
-               self::assertEquals('testdb', $configCache->get('database', 'database'));
-
-               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-       }
-
-       /**
-        * Test the loadConfigFile() method with a .htconfig.php file
-        */
-       public function testLoadConfigFilesHtconfig()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       '.htconfig.php';
-
-               vfsStream::newFile('.htconfig.php')
-                       ->at($this->root)
-                       ->setContent(file_get_contents($file));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('testhost', $configCache->get('database', 'hostname'));
-               self::assertEquals('testuser', $configCache->get('database', 'username'));
-               self::assertEquals('testpw', $configCache->get('database', 'password'));
-               self::assertEquals('testdb', $configCache->get('database', 'database'));
-               self::assertEquals('anotherCharset', $configCache->get('database', 'charset'));
-
-               self::assertEquals('/var/run/friendica.pid', $configCache->get('system', 'pidfile'));
-               self::assertEquals('Europe/Berlin', $configCache->get('system', 'default_timezone'));
-               self::assertEquals('fr', $configCache->get('system', 'language'));
-
-               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               self::assertEquals('Friendly admin', $configCache->get('config', 'admin_nickname'));
-
-               self::assertEquals('/another/php', $configCache->get('config', 'php_path'));
-               self::assertEquals('999', $configCache->get('config', 'max_import_size'));
-               self::assertEquals('666', $configCache->get('system', 'maximagesize'));
-
-               self::assertEquals('frio,quattro,vier,duepuntozero', $configCache->get('system', 'allowed_themes'));
-               self::assertEquals('1', $configCache->get('system', 'no_regfullname'));
-       }
-
-       public function testLoadAddonConfig()
-       {
-               $structure = [
-                       'addon' => [
-                               'test' => [
-                                       'config' => [],
-                               ],
-                       ],
-               ];
-
-               vfsStream::create($structure, $this->root);
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'A.config.php';
-
-               vfsStream::newFile('test.config.php')
-                       ->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-
-               $conf = $configFileLoader->loadAddonConfig('test');
-
-               self::assertEquals('testhost', $conf['database']['hostname']);
-               self::assertEquals('testuser', $conf['database']['username']);
-               self::assertEquals('testpw', $conf['database']['password']);
-               self::assertEquals('testdb', $conf['database']['database']);
-
-               self::assertEquals('admin@test.it', $conf['config']['admin_email']);
-       }
-
-       /**
-        * test loading multiple config files - the last config should work
-        */
-       public function testLoadMultipleConfigs()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR;
-
-               vfsStream::newFile('A.config.php')
-                        ->at($this->root->getChild('config'))
-                        ->setContent(file_get_contents($fileDir . 'A.config.php'));
-               vfsStream::newFile('B.config.php')
-                               ->at($this->root->getChild('config'))
-                        ->setContent(file_get_contents($fileDir . 'B.config.php'));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('admin@overwritten.local', $configCache->get('config', 'admin_email'));
-               self::assertEquals('newValue', $configCache->get('system', 'newKey'));
-       }
-
-       /**
-        * test loading multiple config files - the last config should work (INI-version)
-        */
-       public function testLoadMultipleInis()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                          '..' . DIRECTORY_SEPARATOR .
-                          '..' . DIRECTORY_SEPARATOR .
-                          'datasets' . DIRECTORY_SEPARATOR .
-                          'config' . DIRECTORY_SEPARATOR;
-
-               vfsStream::newFile('A.ini.php')
-                        ->at($this->root->getChild('config'))
-                        ->setContent(file_get_contents($fileDir . 'A.ini.php'));
-               vfsStream::newFile('B.ini.php')
-                        ->at($this->root->getChild('config'))
-                        ->setContent(file_get_contents($fileDir . 'B.ini.php'));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('admin@overwritten.local', $configCache->get('config', 'admin_email'));
-               self::assertEquals('newValue', $configCache->get('system', 'newKey'));
-       }
-
-       /**
-        * Test that sample-files (e.g. local-sample.config.php) is never loaded
-        */
-       public function testNotLoadingSamples()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                          '..' . DIRECTORY_SEPARATOR .
-                          '..' . DIRECTORY_SEPARATOR .
-                          'datasets' . DIRECTORY_SEPARATOR .
-                          'config' . DIRECTORY_SEPARATOR;
-
-               vfsStream::newFile('A.ini.php')
-                        ->at($this->root->getChild('config'))
-                        ->setContent(file_get_contents($fileDir . 'A.ini.php'));
-               vfsStream::newFile('B-sample.ini.php')
-                        ->at($this->root->getChild('config'))
-                        ->setContent(file_get_contents($fileDir . 'B.ini.php'));
-
-               $configFileLoader = new ConfigFileLoader(
-                       $this->root->url(),
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::CONFIG_DIR,
-                       $this->root->url() . DIRECTORY_SEPARATOR . ConfigFactory::STATIC_DIR
-               );
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               self::assertEmpty($configCache->get('system', 'NewKey'));
-       }
-
-       /**
-        * Test that using a wrong configuration directory leads to the "normal" config path
-        */
-       public function testWrongEnvDir()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $configFileLoader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
-       }
-
-       /**
-        * Test that a different location of the configuration directory produces the expected output
-        */
-       public function testRightEnvDir()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                                  '..' . DIRECTORY_SEPARATOR .
-                                  '..' . DIRECTORY_SEPARATOR .
-                                  'datasets' . DIRECTORY_SEPARATOR .
-                                  'config' . DIRECTORY_SEPARATOR;
-
-               vfsStream::newFile('B.config.php')
-                                ->at($this->root->getChild('config2'))
-                                ->setContent(file_get_contents($fileDir . 'B.config.php'));
-
-               $configFileLoader = (new ConfigFactory())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()]);
-               $configCache = new Cache();
-
-               $configFileLoader->setupCache($configCache);
-
-               self::assertEquals('newValue', $configCache->get('system', 'newKey'));
-       }
-}
index 3178f7d17af913563f387eb15b914b170fe5b49a..4c55c419b8909484823db69a4b6b00553ade42b3 100644 (file)
@@ -21,7 +21,7 @@
 
 namespace Friendica\Test\src\Util;
 
-use Friendica\Core\Config\Cache;
+use Friendica\Core\Config\Cache\Cache;
 use Friendica\Core\Config\IConfig;
 use Friendica\Test\MockedTest;
 use Friendica\Util\Profiler;