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;
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;
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;
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;
{
/** @var App\Mode */
private $appMode;
- /** @var Cache */
+ /** @var \Friendica\Core\Config\Cache\Cache */
private $configCache;
/** @var IConfig */
private $config;
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;
+++ /dev/null
-<?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;
- }
-}
+++ /dev/null
-<?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;
- }
-}
+++ /dev/null
-<?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;
- }
-}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
namespace Friendica\Core\Config;
+use Friendica\Core\Config\Cache\Cache;
+
/**
* Interface for accessing system wide configurations
*/
+++ /dev/null
-<?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;
- }
-}
--- /dev/null
+<?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]);
+ }
+}
--- /dev/null
+<?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;
+ }
+ }
+}
+++ /dev/null
-<?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();
- }
-}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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();
+ }
+}
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;
$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;
/**
* 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
*/
+++ /dev/null
-<?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;
- }
-}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
namespace Friendica\Core\PConfig;
+use Friendica\Core\Config\Cache\Cache;
+
/**
* Interface for accessing user specific configurations
*/
/**
* Returns the Config Cache
*
- * @return Cache
+ * @return \Friendica\Core\PConfig\Cache\Cache
*/
function getCache();
}
+++ /dev/null
-<?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;
- }
-}
--- /dev/null
+<?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]);
+ }
+}
+++ /dev/null
-<?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;
- }
-}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
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;
+++ /dev/null
-<?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;
- }
-}
+++ /dev/null
-<?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]);
- }
-}
+++ /dev/null
-<?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;
- }
- }
-}
+++ /dev/null
-<?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]);
- }
-}
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
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;
+++ /dev/null
-<?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;
- }
-}
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;
}
/**
- * @param Cache $configCache The configuration cache
+ * @param \Friendica\Core\Config\Cache\Cache $configCache The configuration cache
*/
public function __construct(Cache $configCache)
{
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;
$_SERVER
]
],
- Util\ConfigFileLoader::class => [
- 'instanceOf' => Factory\ConfigFactory::class,
+ Config\Cache\ConfigFileLoader::class => [
+ 'instanceOf' => Config\Factory\ConfigFactory::class,
'call' => [
['createConfigFileLoader', [
[Dice::INSTANCE => '$basepath'],
], 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],
],
],
],
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 => [
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;
$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);
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;
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;
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;
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;
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;
--- /dev/null
+<?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'));
+ }
+}
--- /dev/null
+<?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'));
+ }
+}
+++ /dev/null
-<?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'));
- }
-}
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;
/** @var ConfigModel|MockInterface */
protected $configModel;
- /** @var Cache */
+ /** @var Cache\Cache */
protected $configCache;
/** @var IConfig */
// Create the config model
$this->configModel = Mockery::mock(ConfigModel::class);
- $this->configCache = new Cache();
+ $this->configCache = new Cache\Cache();
}
/**
->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']);
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);
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);
$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());
}
->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));
$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));
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'));
*/
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'));
*/
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'));
*/
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')
->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');
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
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));
namespace Friendica\Test\src\Core\Config;
-use Friendica\Core\Config\JitConfig;
+use Friendica\Core\Config\Type\JitConfig;
class JitConfigTest extends ConfigTest
{
namespace Friendica\Test\src\Core\Config;
-use Friendica\Core\Config\PreloadConfig;
+use Friendica\Core\Config\Type\PreloadConfig;
class PreloadConfigTest extends ConfigTest
{
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;
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;
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;
--- /dev/null
+<?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'));
+ }
+}
+++ /dev/null
-<?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'));
- }
-}
namespace Friendica\Test\src\Core\PConfig;
-use Friendica\Core\PConfig\JitPConfig;
+use Friendica\Core\PConfig\Type\JitPConfig;
class JitPConfigTest extends PConfigTest
{
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;
/** @var PConfigModel|MockInterface */
protected $configModel;
- /** @var Cache */
+ /** @var Cache\Cache */
protected $configCache;
/** @var BasePConfig */
// 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();
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());
}
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);
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);
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));
->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));
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'));
$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'));
$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'));
->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');
$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']);
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);
}
/**
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;
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;
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;
+++ /dev/null
-<?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'));
- }
-}
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;