Introduce ConfigFileManager for config files

This commit is contained in:
Philipp 2023-01-01 21:10:37 +01:00
parent fea4b202c1
commit 0f91d1cbde
No known key found for this signature in database
GPG key ID: 24A7501396EB5432
21 changed files with 343 additions and 302 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2023.03-dev (Giant Rhubarb) -- Friendica 2023.03-dev (Giant Rhubarb)
-- DB_UPDATE_VERSION 1507 -- DB_UPDATE_VERSION 1508
-- ------------------------------------------ -- ------------------------------------------
@ -494,18 +494,6 @@ CREATE TABLE IF NOT EXISTS `cache` (
INDEX `k_expires` (`k`,`expires`) INDEX `k_expires` (`k`,`expires`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Stores temporary data'; ) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Stores temporary data';
--
-- TABLE config
--
CREATE TABLE IF NOT EXISTS `config` (
`id` int unsigned NOT NULL auto_increment COMMENT '',
`cat` varbinary(50) NOT NULL DEFAULT '' COMMENT '',
`k` varbinary(50) NOT NULL DEFAULT '' COMMENT '',
`v` mediumtext COMMENT '',
PRIMARY KEY(`id`),
UNIQUE INDEX `cat_k` (`cat`,`k`)
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='main configuration storage';
-- --
-- TABLE contact-relation -- TABLE contact-relation
-- --

View file

@ -18,7 +18,6 @@ Database Tables
| [arrived-activity](help/database/db_arrived-activity) | Id of arrived activities | | [arrived-activity](help/database/db_arrived-activity) | Id of arrived activities |
| [attach](help/database/db_attach) | file attachments | | [attach](help/database/db_attach) | file attachments |
| [cache](help/database/db_cache) | Stores temporary data | | [cache](help/database/db_cache) | Stores temporary data |
| [config](help/database/db_config) | main configuration storage |
| [contact](help/database/db_contact) | contact table | | [contact](help/database/db_contact) | contact table |
| [contact-relation](help/database/db_contact-relation) | Contact relations | | [contact-relation](help/database/db_contact-relation) | Contact relations |
| [conv](help/database/db_conv) | private messages | | [conv](help/database/db_conv) | private messages |

View file

@ -1,25 +0,0 @@
Table config
===========
main configuration storage
Fields
------
| Field | Description | Type | Null | Key | Default | Extra |
| ----- | ----------- | ------------- | ---- | --- | ------- | -------------- |
| id | | int unsigned | NO | PRI | NULL | auto_increment |
| cat | | varbinary(50) | NO | | | |
| k | | varbinary(50) | NO | | | |
| v | | mediumtext | YES | | NULL | |
Indexes
------------
| Name | Fields |
| ------- | -------------- |
| PRIMARY | id |
| cat_k | UNIQUE, cat, k |
Return to [database documentation](help/database)

View file

@ -177,7 +177,7 @@ class BaseURL
$currURLPath = $this->urlPath; $currURLPath = $this->urlPath;
if (!empty($hostname) && $hostname !== $this->hostname) { if (!empty($hostname) && $hostname !== $this->hostname) {
if ($this->config->set('config', 'hostname', $hostname)) { if ($this->config->set('config', 'hostname', $hostname, false)) {
$this->hostname = $hostname; $this->hostname = $hostname;
} else { } else {
return false; return false;
@ -185,40 +185,45 @@ class BaseURL
} }
if (isset($sslPolicy) && $sslPolicy !== $this->sslPolicy) { if (isset($sslPolicy) && $sslPolicy !== $this->sslPolicy) {
if ($this->config->set('system', 'ssl_policy', $sslPolicy)) { if ($this->config->set('system', 'ssl_policy', $sslPolicy, false)) {
$this->sslPolicy = $sslPolicy; $this->sslPolicy = $sslPolicy;
} else { } else {
$this->hostname = $currHostname; $this->hostname = $currHostname;
$this->config->set('config', 'hostname', $this->hostname); $this->config->set('config', 'hostname', $this->hostname, false);
$this->config->save();
return false; return false;
} }
} }
if (isset($urlPath) && $urlPath !== $this->urlPath) { if (isset($urlPath) && $urlPath !== $this->urlPath) {
if ($this->config->set('system', 'urlpath', $urlPath)) { if ($this->config->set('system', 'urlpath', $urlPath, false)) {
$this->urlPath = $urlPath; $this->urlPath = $urlPath;
} else { } else {
$this->hostname = $currHostname; $this->hostname = $currHostname;
$this->sslPolicy = $currSSLPolicy; $this->sslPolicy = $currSSLPolicy;
$this->config->set('config', 'hostname', $this->hostname); $this->config->set('config', 'hostname', $this->hostname, false);
$this->config->set('system', 'ssl_policy', $this->sslPolicy); $this->config->set('system', 'ssl_policy', $this->sslPolicy, false);
$this->config->save();
return false; return false;
} }
} }
$this->determineBaseUrl(); $this->determineBaseUrl();
if (!$this->config->set('system', 'url', $this->url)) { if (!$this->config->set('system', 'url', $this->url, false)) {
$this->hostname = $currHostname; $this->hostname = $currHostname;
$this->sslPolicy = $currSSLPolicy; $this->sslPolicy = $currSSLPolicy;
$this->urlPath = $currURLPath; $this->urlPath = $currURLPath;
$this->determineBaseUrl(); $this->determineBaseUrl();
$this->config->set('config', 'hostname', $this->hostname); $this->config->set('config', 'hostname', $this->hostname, false);
$this->config->set('system', 'ssl_policy', $this->sslPolicy); $this->config->set('system', 'ssl_policy', $this->sslPolicy, false);
$this->config->set('system', 'urlpath', $this->urlPath); $this->config->set('system', 'urlpath', $this->urlPath, false);
$this->config->save();
return false; return false;
} }
$this->config->save();
return true; return true;
} }
@ -295,17 +300,21 @@ class BaseURL
$this->sslPolicy = $this->config->get('system', 'ssl_policy'); $this->sslPolicy = $this->config->get('system', 'ssl_policy');
$this->url = $this->config->get('system', 'url'); $this->url = $this->config->get('system', 'url');
$savable = false;
if (empty($this->hostname)) { if (empty($this->hostname)) {
$this->determineHostname(); $this->determineHostname();
if (!empty($this->hostname)) { if (!empty($this->hostname)) {
$this->config->set('config', 'hostname', $this->hostname); $this->config->set('config', 'hostname', $this->hostname, false);
$savable = true;
} }
} }
if (!isset($this->urlPath)) { if (!isset($this->urlPath)) {
$this->determineURLPath(); $this->determineURLPath();
$this->config->set('system', 'urlpath', $this->urlPath); $this->config->set('system', 'urlpath', $this->urlPath, false);
$savable = true;
} }
if (!isset($this->sslPolicy)) { if (!isset($this->sslPolicy)) {
@ -314,16 +323,22 @@ class BaseURL
} else { } else {
$this->sslPolicy = self::DEFAULT_SSL_SCHEME; $this->sslPolicy = self::DEFAULT_SSL_SCHEME;
} }
$this->config->set('system', 'ssl_policy', $this->sslPolicy); $this->config->set('system', 'ssl_policy', $this->sslPolicy, false);
$savable = true;
} }
if (empty($this->url)) { if (empty($this->url)) {
$this->determineBaseUrl(); $this->determineBaseUrl();
if (!empty($this->url)) { if (!empty($this->url)) {
$this->config->set('system', 'url', $this->url); $this->config->set('system', 'url', $this->url, false);
$savable = true;
} }
} }
if ($savable) {
$this->config->save();
}
} }
/** /**

View file

@ -100,16 +100,18 @@ HELP;
$enabled = intval($this->getArgument(0)); $enabled = intval($this->getArgument(0));
$this->config->set('system', 'maintenance', $enabled); $this->config->set('system', 'maintenance', $enabled, false);
$reason = $this->getArgument(1); $reason = $this->getArgument(1);
if ($enabled && $this->getArgument(1)) { if ($enabled && $this->getArgument(1)) {
$this->config->set('system', 'maintenance_reason', $this->getArgument(1)); $this->config->set('system', 'maintenance_reason', $this->getArgument(1), false);
} else { } else {
$this->config->set('system', 'maintenance_reason', ''); $this->config->set('system', 'maintenance_reason', '', false);
} }
$this->config->save();
if ($enabled) { if ($enabled) {
$mode_str = "maintenance mode"; $mode_str = "maintenance mode";
} else { } else {

View file

@ -101,8 +101,8 @@ HELP;
$old_host = str_replace('http://', '@', Strings::normaliseLink($old_url)); $old_host = str_replace('http://', '@', Strings::normaliseLink($old_url));
$this->out('Entering maintenance mode'); $this->out('Entering maintenance mode');
$this->config->set('system', 'maintenance', true); $this->config->set('system', 'maintenance', true, false);
$this->config->set('system', 'maintenance_reason', 'Relocating node to ' . $new_url); $this->config->set('system', 'maintenance_reason', 'Relocating node to ' . $new_url, false);
try { try {
if (!$this->database->transaction()) { if (!$this->database->transaction()) {
@ -189,8 +189,9 @@ HELP;
return 1; return 1;
} finally { } finally {
$this->out('Leaving maintenance mode'); $this->out('Leaving maintenance mode');
$this->config->set('system', 'maintenance', false); $this->config->set('system', 'maintenance', false, false);
$this->config->set('system', 'maintenance_reason', ''); $this->config->set('system', 'maintenance_reason', '', false);
$this->config->save();
} }
// send relocate // send relocate

View file

@ -71,12 +71,18 @@ interface IManageConfigValues
* @param string $cat The category of the configuration value * @param string $cat The category of the configuration value
* @param string $key The configuration key to set * @param string $key The configuration key to set
* @param mixed $value The value to store * @param mixed $value The value to store
* @param bool $autosave If true, implicit save the value
* *
* @return bool Operation success * @return bool Operation success
* *
* @throws ConfigPersistenceException In case the persistence layer throws errors * @throws ConfigPersistenceException In case the persistence layer throws errors
*/ */
public function set(string $cat, string $key, $value): bool; public function set(string $cat, string $key, $value, bool $autosave = true): bool;
/**
* Save back the overridden values of the config cache
*/
public function save();
/** /**
* Deletes the given key from the system configuration. * Deletes the given key from the system configuration.
@ -85,13 +91,14 @@ interface IManageConfigValues
* *
* @param string $cat The category of the configuration value * @param string $cat The category of the configuration value
* @param string $key The configuration key to delete * @param string $key The configuration key to delete
* @param bool $autosave If true, implicit save the value
* *
* @return bool * @return bool
* *
* @throws ConfigPersistenceException In case the persistence layer throws errors * @throws ConfigPersistenceException In case the persistence layer throws errors
* *
*/ */
public function delete(string $cat, string $key): bool; public function delete(string $cat, string $key, bool $autosave = true): bool;
/** /**
* Returns the Config Cache * Returns the Config Cache

View file

@ -21,12 +21,12 @@
namespace Friendica\Core\Config\Factory; namespace Friendica\Core\Config\Factory;
use Friendica\Core\Config\Capability;
use Friendica\Core\Config\Repository;
use Friendica\Core\Config\Type;
use Friendica\Core\Config\Util; use Friendica\Core\Config\Util;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
/**
* The config factory for creating either the cache or the whole model
*/
class Config class Config
{ {
/** /**
@ -54,9 +54,9 @@ class Config
* @param string $basePath The basepath of FRIENDICA * @param string $basePath The basepath of FRIENDICA
* @param array $server The $_SERVER array * @param array $server The $_SERVER array
* *
* @return Util\ConfigFileLoader * @return Util\ConfigFileManager
*/ */
public function createConfigFileLoader(string $basePath, array $server = []): Util\ConfigFileLoader public function createConfigFileLoader(string $basePath, array $server = []): Util\ConfigFileManager
{ {
if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) { if (!empty($server[self::CONFIG_DIR_ENV]) && is_dir($server[self::CONFIG_DIR_ENV])) {
$configDir = $server[self::CONFIG_DIR_ENV]; $configDir = $server[self::CONFIG_DIR_ENV];
@ -65,19 +65,19 @@ class Config
} }
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR; $staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
return new Util\ConfigFileLoader($basePath, $configDir, $staticDir); return new Util\ConfigFileManager($basePath, $configDir, $staticDir, new Util\ConfigFileTransformer());
} }
/** /**
* @param Util\ConfigFileLoader $loader The Config Cache loader (INI/config/.htconfig) * @param Util\ConfigFileManager $configFileManager The Config Cache manager (INI/config/.htconfig)
* @param array $server * @param array $server
* *
* @return Cache * @return Cache
*/ */
public function createCache(Util\ConfigFileLoader $loader, array $server = []): Cache public function createCache(Util\ConfigFileManager $configFileManager, array $server = []): Cache
{ {
$configCache = new Cache(); $configCache = new Cache();
$loader->setupCache($configCache, $server); $configFileManager->setupCache($configCache, $server);
return $configCache; return $configCache;
} }
@ -88,12 +88,12 @@ class Config
* *
* @return Capability\IManageConfigValues * @return Capability\IManageConfigValues
*/ */
public function create(Cache $configCache, Repository\Config $configRepo) public function create(Util\ConfigFileManager $loader, Cache $configCache, Repository\Config $configRepo)
{ {
if ($configCache->get('system', 'config_adapter') === 'preload') { if ($configCache->get('system', 'config_adapter') === 'preload') {
$configuration = new Type\PreloadConfig($configCache, $configRepo); $configuration = new Type\PreloadConfig($loader, $configCache, $configRepo);
} else { } else {
$configuration = new Type\JitConfig($configCache, $configRepo); $configuration = new Type\JitConfig($loader, $configCache, $configRepo);
} }
return $configuration; return $configuration;

View file

@ -51,7 +51,7 @@ class Config
*/ */
public function isConnected(): bool public function isConnected(): bool
{ {
return $this->db->isConnected() && !$this->mode->isInstall(); return true;
} }
/** /**
@ -65,31 +65,7 @@ class Config
*/ */
public function load(?string $cat = null): array public function load(?string $cat = null): array
{ {
$return = []; return [];
try {
if (empty($cat)) {
$configs = $this->db->select(static::$table_name, ['cat', 'v', 'k']);
} else {
$configs = $this->db->select(static::$table_name, ['cat', 'v', 'k'], ['cat' => $cat]);
}
while ($config = $this->db->fetch($configs)) {
$key = $config['k'];
$value = ValueConversion::toConfigValue($config['v']);
// just save it in case it is set
if (isset($value)) {
$return[$config['cat']][$key] = $value;
}
}
} catch (\Exception $exception) {
throw new ConfigPersistenceException(sprintf('Cannot load config category %s', $cat), $exception);
} finally {
$this->db->close($configs);
}
return $return;
} }
/** /**
@ -107,24 +83,6 @@ class Config
*/ */
public function get(string $cat, string $key) public function get(string $cat, string $key)
{ {
if (!$this->isConnected()) {
return null;
}
try {
$config = $this->db->selectFirst(static::$table_name, ['v'], ['cat' => $cat, 'k' => $key]);
if ($this->db->isResult($config)) {
$value = ValueConversion::toConfigValue($config['v']);
// just return it in case it is set
if (isset($value)) {
return $value;
}
}
} catch (\Exception $exception) {
throw new ConfigPersistenceException(sprintf('Cannot get config with category %s and key %s', $cat, $key), $exception);
}
return null; return null;
} }
@ -143,27 +101,7 @@ class Config
*/ */
public function set(string $cat, string $key, $value): bool public function set(string $cat, string $key, $value): bool
{ {
if (!$this->isConnected()) { return true;
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 = ValueConversion::toDbValue($value);
try {
return $this->db->update(static::$table_name, ['v' => $dbValue], ['cat' => $cat, 'k' => $key], true);
} catch (\Exception $exception) {
throw new ConfigPersistenceException(sprintf('Cannot set config with category %s and key %s', $cat, $key), $exception);
}
} }
/** /**
@ -178,14 +116,6 @@ class Config
*/ */
public function delete(string $cat, string $key): bool public function delete(string $cat, string $key): bool
{ {
if (!$this->isConnected()) { return true;
return false;
}
try {
return $this->db->delete(static::$table_name, ['cat' => $cat, 'k' => $key]);
} catch (\Exception $exception) {
throw new ConfigPersistenceException(sprintf('Cannot delete config with category %s and key %s', $cat, $key), $exception);
}
} }
} }

View file

@ -22,8 +22,10 @@
namespace Friendica\Core\Config\Type; namespace Friendica\Core\Config\Type;
use Friendica\Core\Config\Repository\Config; use Friendica\Core\Config\Repository\Config;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\DI;
/** /**
* This class is responsible for all system-wide configuration values in Friendica * This class is responsible for all system-wide configuration values in Friendica
@ -43,14 +45,19 @@ abstract class AbstractConfig implements IManageConfigValues
*/ */
protected $configRepo; protected $configRepo;
/** @var ConfigFileManager */
protected $configFileManager;
/** /**
* @param ConfigFileManager $configFileManager The configuration file manager to save back configs
* @param Cache $configCache The configuration cache (based on the config-files) * @param Cache $configCache The configuration cache (based on the config-files)
* @param Config $configRepo The configuration repository * @param Config $configRepo The configuration repository
*/ */
public function __construct(Cache $configCache, Config $configRepo) public function __construct(ConfigFileManager $configFileManager, Cache $configCache, Config $configRepo)
{ {
$this->configCache = $configCache; $this->configFileManager = $configFileManager;
$this->configRepo = $configRepo; $this->configCache = $configCache;
$this->configRepo = $configRepo;
} }
/** /**
@ -60,4 +67,9 @@ abstract class AbstractConfig implements IManageConfigValues
{ {
return $this->configCache; return $this->configCache;
} }
public function save()
{
$this->configFileManager->saveData($this->configCache);
}
} }

View file

@ -21,6 +21,7 @@
namespace Friendica\Core\Config\Type; namespace Friendica\Core\Config\Type;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Config\Repository\Config; use Friendica\Core\Config\Repository\Config;
@ -39,12 +40,13 @@ class JitConfig extends AbstractConfig
private $db_loaded; private $db_loaded;
/** /**
* @param Cache $configCache The configuration cache (based on the config-files) * @param ConfigFileManager $configFileManager The configuration file manager to save back configs
* @param Config $configRepo The configuration model * @param Cache $configCache The configuration cache (based on the config-files)
* @param Config $configRepo The configuration model
*/ */
public function __construct(Cache $configCache, Config $configRepo) public function __construct(ConfigFileManager $configFileManager, Cache $configCache, Config $configRepo)
{ {
parent::__construct($configCache, $configRepo); parent::__construct($configFileManager, $configCache, $configRepo);
$this->db_loaded = []; $this->db_loaded = [];
$this->load(); $this->load();
@ -69,7 +71,7 @@ class JitConfig extends AbstractConfig
} }
// load the whole category out of the DB into the cache // load the whole category out of the DB into the cache
$this->configCache->load($config, Cache::SOURCE_DB); $this->configCache->load($config, Cache::SOURCE_DATA);
} }
/** /**
@ -84,7 +86,7 @@ class JitConfig extends AbstractConfig
$dbValue = $this->configRepo->get($cat, $key); $dbValue = $this->configRepo->get($cat, $key);
if (isset($dbValue)) { if (isset($dbValue)) {
$this->configCache->set($cat, $key, $dbValue, Cache::SOURCE_DB); $this->configCache->set($cat, $key, $dbValue, Cache::SOURCE_DATA);
unset($dbValue); unset($dbValue);
} }
@ -100,10 +102,10 @@ class JitConfig extends AbstractConfig
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function set(string $cat, string $key, $value): bool public function set(string $cat, string $key, $value, bool $autosave = true): bool
{ {
// set the cache first // set the cache first
$cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB); $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DATA);
// If there is no connected adapter, we're finished // If there is no connected adapter, we're finished
if (!$this->configRepo->isConnected()) { if (!$this->configRepo->isConnected()) {
@ -114,13 +116,17 @@ class JitConfig extends AbstractConfig
$this->db_loaded[$cat][$key] = $stored; $this->db_loaded[$cat][$key] = $stored;
if ($autosave) {
$this->save();
}
return $cached && $stored; return $cached && $stored;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function delete(string $cat, string $key): bool public function delete(string $cat, string $key, bool $autosave = true): bool
{ {
$cacheRemoved = $this->configCache->delete($cat, $key); $cacheRemoved = $this->configCache->delete($cat, $key);
@ -134,6 +140,10 @@ class JitConfig extends AbstractConfig
$storeRemoved = $this->configRepo->delete($cat, $key); $storeRemoved = $this->configRepo->delete($cat, $key);
if ($autosave) {
$this->save();
}
return $cacheRemoved || $storeRemoved; return $cacheRemoved || $storeRemoved;
} }
} }

View file

@ -21,6 +21,7 @@
namespace Friendica\Core\Config\Type; namespace Friendica\Core\Config\Type;
use Friendica\Core\Config\Util\ConfigFileManager;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
use Friendica\Core\Config\Repository\Config; use Friendica\Core\Config\Repository\Config;
@ -36,12 +37,13 @@ class PreloadConfig extends AbstractConfig
private $config_loaded; private $config_loaded;
/** /**
* @param Cache $configCache The configuration cache (based on the config-files) * @param ConfigFileManager $configFileManager The configuration file manager to save back configs
* @param Config $configRepo The configuration model * @param Cache $configCache The configuration cache (based on the config-files)
* @param Config $configRepo The configuration model
*/ */
public function __construct(Cache $configCache, Config $configRepo) public function __construct(ConfigFileManager $configFileManager, Cache $configCache, Config $configRepo)
{ {
parent::__construct($configCache, $configRepo); parent::__construct($configFileManager, $configCache, $configRepo);
$this->config_loaded = false; $this->config_loaded = false;
$this->load(); $this->load();
@ -68,7 +70,7 @@ class PreloadConfig extends AbstractConfig
$this->config_loaded = true; $this->config_loaded = true;
// load the whole category out of the DB into the cache // load the whole category out of the DB into the cache
$this->configCache->load($config, Cache::SOURCE_DB); $this->configCache->load($config, Cache::SOURCE_DATA);
} }
/** /**
@ -80,7 +82,7 @@ class PreloadConfig extends AbstractConfig
if ($this->configRepo->isConnected()) { if ($this->configRepo->isConnected()) {
$config = $this->configRepo->get($cat, $key); $config = $this->configRepo->get($cat, $key);
if (isset($config)) { if (isset($config)) {
$this->configCache->set($cat, $key, $config, Cache::SOURCE_DB); $this->configCache->set($cat, $key, $config, Cache::SOURCE_DATA);
} }
} }
} }
@ -94,14 +96,14 @@ class PreloadConfig extends AbstractConfig
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function set(string $cat, string $key, $value): bool public function set(string $cat, string $key, $value, bool $autosave = true): bool
{ {
if (!$this->config_loaded) { if (!$this->config_loaded) {
$this->load(); $this->load();
} }
// set the cache first // set the cache first
$cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DB); $cached = $this->configCache->set($cat, $key, $value, Cache::SOURCE_DATA);
// If there is no connected adapter, we're finished // If there is no connected adapter, we're finished
if (!$this->configRepo->isConnected()) { if (!$this->configRepo->isConnected()) {
@ -110,13 +112,17 @@ class PreloadConfig extends AbstractConfig
$stored = $this->configRepo->set($cat, $key, $value); $stored = $this->configRepo->set($cat, $key, $value);
if ($autosave) {
$this->save();
}
return $cached && $stored; return $cached && $stored;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
public function delete(string $cat, string $key): bool public function delete(string $cat, string $key, bool $autosave = true): bool
{ {
if ($this->config_loaded) { if ($this->config_loaded) {
$this->load(); $this->load();
@ -130,6 +136,10 @@ class PreloadConfig extends AbstractConfig
$storeRemoved = $this->configRepo->delete($cat, $key); $storeRemoved = $this->configRepo->delete($cat, $key);
if ($autosave) {
$this->save();
}
return $cacheRemoved || $storeRemoved; return $cacheRemoved || $storeRemoved;
} }
} }

View file

@ -26,22 +26,15 @@ use Friendica\Core\Config\Exception\ConfigFileException;
use Friendica\Core\Config\ValueObject\Cache; use Friendica\Core\Config\ValueObject\Cache;
/** /**
* The ConfigFileLoader loads config-files and stores them in a ConfigCache ( @see Cache ) * The ConfigFileLoader loads and saves config-files and stores them in a ConfigCache ( @see Cache )
* *
* It is capable of loading the following config files: * It is capable of loading the following config files:
* - *.config.php (current) * - *.config.php (current)
* - *.ini.php (deprecated) * - *.ini.php (deprecated)
* - *.htconfig.php (deprecated) * - *.htconfig.php (deprecated)
*/ */
class ConfigFileLoader class ConfigFileManager
{ {
/**
* 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 * The default name of the user defined legacy config file
* *
@ -49,6 +42,13 @@ class ConfigFileLoader
*/ */
const CONFIG_HTCONFIG = 'htconfig'; const CONFIG_HTCONFIG = 'htconfig';
/**
* The config file, where overrides per admin page/console are saved at
*
* @var string
*/
const CONFIG_DATA_FILE = 'node.config.php';
/** /**
* The sample string inside the configs, which shouldn't get loaded * The sample string inside the configs, which shouldn't get loaded
* *
@ -89,7 +89,7 @@ class ConfigFileLoader
* *
* @param Cache $config The config cache to load to * @param Cache $config The config cache to load to
* @param array $server The $_SERVER array * @param array $server The $_SERVER array
* @param bool $raw Setup the raw config format * @param bool $raw Set up the raw config format
* *
* @throws ConfigFileException * @throws ConfigFileException
*/ */
@ -106,6 +106,9 @@ class ConfigFileLoader
// Now load every other config you find inside the 'config/' directory // Now load every other config you find inside the 'config/' directory
$this->loadCoreConfig($config); $this->loadCoreConfig($config);
// Now load the node.config.php file with the node specific config values (based on admin gui/console actions)
$this->loadDataConfig($config);
$config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV); $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 // In case of install mode, add the found basepath (because there isn't a basepath set yet
@ -158,6 +161,50 @@ class ConfigFileLoader
} }
} }
/**
* Tries to load the data config file with the overridden data
*
* @param Cache $config The Config cache
*
* @throws ConfigFileException In case the config file isn't loadable
*/
private function loadDataConfig(Cache $config)
{
$filename = $this->configDir . '/' . self::CONFIG_DATA_FILE;
if (file_exists($filename)) {
$dataArray = include $filename;
if (!is_array($dataArray)) {
throw new ConfigFileException(sprintf('Error loading config file %s', $filename));
}
$config->load($dataArray, Cache::SOURCE_DATA);
}
}
/**
* Saves overridden config entries back into the data.config.phpR
*
* @param Cache $config The config cache
*
* @throws ConfigFileException In case the config file isn't writeable or the data is invalid
*/
public function saveData(Cache $config)
{
$data = $config->getDataBySource(Cache::SOURCE_DATA);
$encodedData = ConfigFileTransformer::encode($data);
if (!$encodedData) {
throw new ConfigFileException('config source cannot get encoded');
}
if (!file_put_contents($this->configDir . '/' . self::CONFIG_DATA_FILE, $encodedData)) {
throw new ConfigFileException(sprintf('Cannot save data to file %s/%s', $this->configDir, self::CONFIG_DATA_FILE));
}
}
/** /**
* Tries to load the specified addon-configuration and returns the config array. * Tries to load the specified addon-configuration and returns the config array.
* *
@ -353,12 +400,16 @@ class ConfigFileLoader
*/ */
private function loadConfigFile(string $filepath): array private function loadConfigFile(string $filepath): array
{ {
$config = include($filepath); if (file_exists($filepath)) {
$config = include($filepath);
if (!is_array($config)) { if (!is_array($config)) {
throw new ConfigFileException('Error loading config file ' . $filepath); throw new ConfigFileException('Error loading config file ' . $filepath);
}
return $config;
} else {
return [];
} }
return $config;
} }
} }

View file

@ -21,13 +21,13 @@
namespace Friendica\Core\Config\ValueObject; namespace Friendica\Core\Config\ValueObject;
use Friendica\Core\Config\Util\ConfigFileLoader; use Friendica\Core\Config\Util\ConfigFileManager;
use ParagonIE\HiddenString\HiddenString; use ParagonIE\HiddenString\HiddenString;
/** /**
* The Friendica config cache for the application * The Friendica config cache for the application
* Initial, all *.config.php files are loaded into this cache with the * Initial, all *.config.php files are loaded into this cache with the
* ConfigFileLoader ( @see ConfigFileLoader ) * ConfigFileManager ( @see ConfigFileManager )
*/ */
class Cache class Cache
{ {
@ -35,8 +35,8 @@ class Cache
const SOURCE_STATIC = 0; const SOURCE_STATIC = 0;
/** @var int Indicates that the cache entry is set by file - Low Priority */ /** @var int Indicates that the cache entry is set by file - Low Priority */
const SOURCE_FILE = 1; const SOURCE_FILE = 1;
/** @var int Indicates that the cache entry is set by the DB config table - Middle Priority */ /** @var int Indicates that the cache entry is manually set by the application (per admin page/console) - Middle Priority */
const SOURCE_DB = 2; const SOURCE_DATA = 2;
/** @var int Indicates that the cache entry is set by a server environment variable - High Priority */ /** @var int Indicates that the cache entry is set by a server environment variable - High Priority */
const SOURCE_ENV = 3; const SOURCE_ENV = 3;
/** @var int Indicates that the cache entry is fixed and must not be changed */ /** @var int Indicates that the cache entry is fixed and must not be changed */
@ -128,6 +128,34 @@ class Cache
return $this->source[$cat][$key] ?? -1; return $this->source[$cat][$key] ?? -1;
} }
/**
* Returns the whole config array based on the given source type
*
* @param int $source Indicates the source of the config entry
*
* @return array The config array part of the given source
*/
public function getDataBySource(int $source): array
{
$data = [];
$categories = array_keys($this->source);
foreach ($categories as $category) {
if (is_array($this->source[$category])) {
$keys = array_keys($this->source[$category]);
foreach ($keys as $key) {
if ($this->source[$category][$key] === $source) {
$data[$category][$key] = $this->config[$category][$key];
}
}
}
}
return $data;
}
/** /**
* Sets a value in the config cache. Accepts raw output from the config table * Sets a value in the config cache. Accepts raw output from the config table
* *

View file

@ -21,7 +21,7 @@
namespace Friendica\Core\KeyValueStorage\Type; namespace Friendica\Core\KeyValueStorage\Type;
use Friendica\Core\Config\Util\ValueConversion; use Friendica\Core\PConfig\Util\ValueConversion;
use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException; use Friendica\Core\KeyValueStorage\Exceptions\KeyValueStoragePersistenceException;
use Friendica\Database\Database; use Friendica\Database\Database;

View file

@ -160,8 +160,9 @@ class Update
Logger::warning('Pre update failed', ['version' => $version]); Logger::warning('Pre update failed', ['version' => $version]);
DI::config()->set('system', 'update', Update::FAILED); DI::config()->set('system', 'update', Update::FAILED);
DI::lock()->release('dbupdate'); DI::lock()->release('dbupdate');
DI::config()->set('system', 'maintenance', 0); DI::config()->set('system', 'maintenance', false, false);
DI::config()->set('system', 'maintenance_reason', ''); DI::config()->delete('system', 'maintenance_reason', false);
DI::config()->save();
return $r; return $r;
} else { } else {
Logger::notice('Pre update executed.', ['version' => $version]); Logger::notice('Pre update executed.', ['version' => $version]);
@ -181,8 +182,9 @@ class Update
Logger::error('Update ERROR.', ['from' => $stored, 'to' => $current, 'retval' => $retval]); Logger::error('Update ERROR.', ['from' => $stored, 'to' => $current, 'retval' => $retval]);
DI::config()->set('system', 'update', Update::FAILED); DI::config()->set('system', 'update', Update::FAILED);
DI::lock()->release('dbupdate'); DI::lock()->release('dbupdate');
DI::config()->set('system', 'maintenance', 0); DI::config()->set('system', 'maintenance', false, false);
DI::config()->set('system', 'maintenance_reason', ''); DI::config()->delete('system', 'maintenance_reason', false);
DI::config()->save();
return $retval; return $retval;
} else { } else {
Logger::notice('Database structure update finished.', ['from' => $stored, 'to' => $current]); Logger::notice('Database structure update finished.', ['from' => $stored, 'to' => $current]);
@ -198,8 +200,9 @@ class Update
Logger::warning('Post update failed', ['version' => $version]); Logger::warning('Post update failed', ['version' => $version]);
DI::config()->set('system', 'update', Update::FAILED); DI::config()->set('system', 'update', Update::FAILED);
DI::lock()->release('dbupdate'); DI::lock()->release('dbupdate');
DI::config()->set('system', 'maintenance', 0); DI::config()->set('system', 'maintenance', false, false);
DI::config()->set('system', 'maintenance_reason', ''); DI::config()->delete('system', 'maintenance_reason', false);
DI::config()->save();
return $r; return $r;
} else { } else {
DI::config()->set('system', 'build', $version); DI::config()->set('system', 'build', $version);
@ -210,8 +213,9 @@ class Update
DI::config()->set('system', 'build', $current); DI::config()->set('system', 'build', $current);
DI::config()->set('system', 'update', Update::SUCCESS); DI::config()->set('system', 'update', Update::SUCCESS);
DI::lock()->release('dbupdate'); DI::lock()->release('dbupdate');
DI::config()->set('system', 'maintenance', 0); DI::config()->set('system', 'maintenance', false, false);
DI::config()->set('system', 'maintenance_reason', ''); DI::config()->delete('system', 'maintenance_reason', false);
DI::config()->save();
Logger::notice('Update success.', ['from' => $stored, 'to' => $current]); Logger::notice('Update success.', ['from' => $stored, 'to' => $current]);
if ($sendMail) { if ($sendMail) {

View file

@ -74,7 +74,7 @@ class DBStructure
$old_tables = ['fserver', 'gcign', 'gcontact', 'gcontact-relation', 'gfollower' ,'glink', 'item-delivery-data', $old_tables = ['fserver', 'gcign', 'gcontact', 'gcontact-relation', 'gfollower' ,'glink', 'item-delivery-data',
'item-activity', 'item-content', 'item_id', 'participation', 'poll', 'poll_result', 'queue', 'retriever_rule', 'item-activity', 'item-content', 'item_id', 'participation', 'poll', 'poll_result', 'queue', 'retriever_rule',
'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge', 'deliverq', 'dsprphotoq', 'ffinder', 'sign', 'spam', 'term', 'user-item', 'thread', 'item', 'challenge',
'auth_codes', 'tokens', 'clients', 'profile_check', 'host', 'conversation', 'fcontact']; 'auth_codes', 'tokens', 'clients', 'profile_check', 'host', 'conversation', 'fcontact', 'config'];
$tables = DBA::selectToArray('INFORMATION_SCHEMA.TABLES', ['TABLE_NAME'], $tables = DBA::selectToArray('INFORMATION_SCHEMA.TABLES', ['TABLE_NAME'],
['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']); ['TABLE_SCHEMA' => DBA::databaseName(), 'TABLE_TYPE' => 'BASE TABLE']);
@ -176,14 +176,15 @@ class DBStructure
public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false): string public static function performUpdate(bool $enable_maintenance_mode = true, bool $verbose = false): string
{ {
if ($enable_maintenance_mode) { if ($enable_maintenance_mode) {
DI::config()->set('system', 'maintenance', 1); DI::config()->set('system', 'maintenance', true);
} }
$status = self::update($verbose, true); $status = self::update($verbose, true);
if ($enable_maintenance_mode) { if ($enable_maintenance_mode) {
DI::config()->set('system', 'maintenance', 0); DI::config()->set('system', 'maintenance', false, false);
DI::config()->set('system', 'maintenance_reason', ''); DI::config()->delete('system', 'maintenance_reason', false);
DI::config()->save();
} }
return $status; return $status;

View file

@ -148,7 +148,7 @@ class Site extends BaseAdmin
// Has the directory url changed? If yes, then resubmit the existing profiles there // Has the directory url changed? If yes, then resubmit the existing profiles there
if ($global_directory != DI::config()->get('system', 'directory') && ($global_directory != '')) { if ($global_directory != DI::config()->get('system', 'directory') && ($global_directory != '')) {
DI::config()->set('system', 'directory', $global_directory); DI::config()->set('system', 'directory', $global_directory, false);
Worker::add(Worker::PRIORITY_LOW, 'Directory'); Worker::add(Worker::PRIORITY_LOW, 'Directory');
} }
@ -194,131 +194,133 @@ class Site extends BaseAdmin
); );
} }
} }
DI::config()->set('system', 'ssl_policy' , $ssl_policy); DI::config()->set('system', 'ssl_policy' , $ssl_policy, false);
DI::config()->set('system', 'maxloadavg' , $maxloadavg); DI::config()->set('system', 'maxloadavg' , $maxloadavg, false);
DI::config()->set('system', 'min_memory' , $min_memory); DI::config()->set('system', 'min_memory' , $min_memory, false);
DI::config()->set('system', 'optimize_tables' , $optimize_tables); DI::config()->set('system', 'optimize_tables' , $optimize_tables, false);
DI::config()->set('system', 'contact_discovery' , $contact_discovery); DI::config()->set('system', 'contact_discovery' , $contact_discovery, false);
DI::config()->set('system', 'synchronize_directory' , $synchronize_directory); DI::config()->set('system', 'synchronize_directory' , $synchronize_directory, false);
DI::config()->set('system', 'poco_requery_days' , $poco_requery_days); DI::config()->set('system', 'poco_requery_days' , $poco_requery_days, false);
DI::config()->set('system', 'poco_discovery' , $poco_discovery); DI::config()->set('system', 'poco_discovery' , $poco_discovery, false);
DI::config()->set('system', 'poco_local_search' , $poco_local_search); DI::config()->set('system', 'poco_local_search' , $poco_local_search, false);
DI::config()->set('system', 'nodeinfo' , $nodeinfo); DI::config()->set('system', 'nodeinfo' , $nodeinfo, false);
DI::config()->set('config', 'sitename' , $sitename); DI::config()->set('config', 'sitename' , $sitename, false);
DI::config()->set('config', 'sender_email' , $sender_email); DI::config()->set('config', 'sender_email' , $sender_email, false);
DI::config()->set('system', 'suppress_tags' , $suppress_tags); DI::config()->set('system', 'suppress_tags' , $suppress_tags, false);
DI::config()->set('system', 'shortcut_icon' , $shortcut_icon); DI::config()->set('system', 'shortcut_icon' , $shortcut_icon, false);
DI::config()->set('system', 'touch_icon' , $touch_icon); DI::config()->set('system', 'touch_icon' , $touch_icon, false);
if ($banner == "") { if ($banner == "") {
DI::config()->delete('system', 'banner'); DI::config()->set('system', 'banner', false);
} else { } else {
DI::config()->set('system', 'banner', $banner); DI::config()->set('system', 'banner', $banner, false);
} }
if (empty($email_banner)) { if (empty($email_banner)) {
DI::config()->delete('system', 'email_banner'); DI::config()->set('system', 'email_banner', false);
} else { } else {
DI::config()->set('system', 'email_banner', $email_banner); DI::config()->set('system', 'email_banner', $email_banner, false);
} }
if (empty($additional_info)) { if (empty($additional_info)) {
DI::config()->delete('config', 'info'); DI::config()->set('config', 'info', false);
} else { } else {
DI::config()->set('config', 'info', $additional_info); DI::config()->set('config', 'info', $additional_info, false);
} }
DI::config()->set('system', 'language', $language); DI::config()->set('system', 'language', $language, false);
DI::config()->set('system', 'theme', $theme); DI::config()->set('system', 'theme', $theme, false);
Theme::install($theme); Theme::install($theme);
if ($theme_mobile == '---') { if ($theme_mobile == '---') {
DI::config()->delete('system', 'mobile-theme'); DI::config()->set('system', 'mobile-theme', false);
} else { } else {
DI::config()->set('system', 'mobile-theme', $theme_mobile); DI::config()->set('system', 'mobile-theme', $theme_mobile, false);
} }
if ($singleuser == '---') { if ($singleuser == '---') {
DI::config()->delete('system', 'singleuser'); DI::config()->set('system', 'singleuser', false);
} else { } else {
DI::config()->set('system', 'singleuser', $singleuser); DI::config()->set('system', 'singleuser', $singleuser, false);
} }
if (preg_match('/\d+(?:\s*[kmg])?/i', $maximagesize)) { if (preg_match('/\d+(?:\s*[kmg])?/i', $maximagesize)) {
DI::config()->set('system', 'maximagesize', $maximagesize); DI::config()->set('system', 'maximagesize', $maximagesize, false);
} else { } else {
DI::sysmsg()->addNotice(DI::l10n()->t('%s is no valid input for maximum image size', $maximagesize)); DI::sysmsg()->addNotice(DI::l10n()->t('%s is no valid input for maximum image size', $maximagesize));
} }
DI::config()->set('system', 'max_image_length' , $maximagelength); DI::config()->set('system', 'max_image_length' , $maximagelength, false);
DI::config()->set('system', 'jpeg_quality' , $jpegimagequality); DI::config()->set('system', 'jpeg_quality' , $jpegimagequality, false);
DI::config()->set('config', 'register_policy' , $register_policy); DI::config()->set('config', 'register_policy' , $register_policy, false);
DI::config()->set('system', 'max_daily_registrations', $daily_registrations); DI::config()->set('system', 'max_daily_registrations', $daily_registrations, false);
DI::config()->set('system', 'account_abandon_days' , $abandon_days); DI::config()->set('system', 'account_abandon_days' , $abandon_days, false);
DI::config()->set('config', 'register_text' , $register_text); DI::config()->set('config', 'register_text' , $register_text, false);
DI::config()->set('system', 'allowed_sites' , $allowed_sites); DI::config()->set('system', 'allowed_sites' , $allowed_sites, false);
DI::config()->set('system', 'allowed_email' , $allowed_email); DI::config()->set('system', 'allowed_email' , $allowed_email, false);
DI::config()->set('system', 'forbidden_nicknames' , $forbidden_nicknames); DI::config()->set('system', 'forbidden_nicknames' , $forbidden_nicknames, false);
DI::config()->set('system', 'system_actor_name' , $system_actor_name); DI::config()->set('system', 'system_actor_name' , $system_actor_name, false);
DI::config()->set('system', 'no_oembed_rich_content' , $no_oembed_rich_content); DI::config()->set('system', 'no_oembed_rich_content' , $no_oembed_rich_content, false);
DI::config()->set('system', 'allowed_oembed' , $allowed_oembed); DI::config()->set('system', 'allowed_oembed' , $allowed_oembed, false);
DI::config()->set('system', 'block_public' , $block_public); DI::config()->set('system', 'block_public' , $block_public, false);
DI::config()->set('system', 'publish_all' , $force_publish); DI::config()->set('system', 'publish_all' , $force_publish, false);
DI::config()->set('system', 'newuser_private' , $newuser_private); DI::config()->set('system', 'newuser_private' , $newuser_private, false);
DI::config()->set('system', 'enotify_no_content' , $enotify_no_content); DI::config()->set('system', 'enotify_no_content' , $enotify_no_content, false);
DI::config()->set('system', 'disable_embedded' , $disable_embedded); DI::config()->set('system', 'disable_embedded' , $disable_embedded, false);
DI::config()->set('system', 'allow_users_remote_self', $allow_users_remote_self); DI::config()->set('system', 'allow_users_remote_self', $allow_users_remote_self, false);
DI::config()->set('system', 'explicit_content' , $explicit_content); DI::config()->set('system', 'explicit_content' , $explicit_content, false);
DI::config()->set('system', 'proxify_content' , $proxify_content); DI::config()->set('system', 'proxify_content' , $proxify_content, false);
DI::config()->set('system', 'cache_contact_avatar' , $cache_contact_avatar); DI::config()->set('system', 'cache_contact_avatar' , $cache_contact_avatar, false);
DI::config()->set('system', 'check_new_version_url' , $check_new_version_url); DI::config()->set('system', 'check_new_version_url' , $check_new_version_url, false);
DI::config()->set('system', 'block_extended_register', !$enable_multi_reg); DI::config()->set('system', 'block_extended_register', !$enable_multi_reg, false);
DI::config()->set('system', 'no_openid' , !$enable_openid); DI::config()->set('system', 'no_openid' , !$enable_openid, false);
DI::config()->set('system', 'no_regfullname' , !$enable_regfullname); DI::config()->set('system', 'no_regfullname' , !$enable_regfullname, false);
DI::config()->set('system', 'register_notification' , $register_notification); DI::config()->set('system', 'register_notification' , $register_notification, false);
DI::config()->set('system', 'community_page_style' , $community_page_style); DI::config()->set('system', 'community_page_style' , $community_page_style, false);
DI::config()->set('system', 'max_author_posts_community_page', $max_author_posts_community_page); DI::config()->set('system', 'max_author_posts_community_page', $max_author_posts_community_page, false);
DI::config()->set('system', 'verifyssl' , $verifyssl); DI::config()->set('system', 'verifyssl' , $verifyssl, false);
DI::config()->set('system', 'proxyuser' , $proxyuser); DI::config()->set('system', 'proxyuser' , $proxyuser, false);
DI::config()->set('system', 'proxy' , $proxy); DI::config()->set('system', 'proxy' , $proxy, false);
DI::config()->set('system', 'curl_timeout' , $timeout); DI::config()->set('system', 'curl_timeout' , $timeout, false);
DI::config()->set('system', 'imap_disabled' , !$mail_enabled && function_exists('imap_open')); DI::config()->set('system', 'imap_disabled' , !$mail_enabled && function_exists('imap_open'), false);
DI::config()->set('system', 'ostatus_disabled' , !$ostatus_enabled); DI::config()->set('system', 'ostatus_disabled' , !$ostatus_enabled, false);
DI::config()->set('system', 'diaspora_enabled' , $diaspora_enabled); DI::config()->set('system', 'diaspora_enabled' , $diaspora_enabled, false);
DI::config()->set('config', 'private_addons' , $private_addons); DI::config()->set('config', 'private_addons' , $private_addons, false);
DI::config()->set('system', 'force_ssl' , $force_ssl); DI::config()->set('system', 'force_ssl' , $force_ssl, false);
DI::config()->set('system', 'hide_help' , !$show_help); DI::config()->set('system', 'hide_help' , !$show_help, false);
DI::config()->set('system', 'dbclean' , $dbclean); DI::config()->set('system', 'dbclean' , $dbclean, false);
DI::config()->set('system', 'dbclean-expire-days' , $dbclean_expire_days); DI::config()->set('system', 'dbclean-expire-days' , $dbclean_expire_days, false);
DI::config()->set('system', 'dbclean_expire_conversation', $dbclean_expire_conv); DI::config()->set('system', 'dbclean_expire_conversation', $dbclean_expire_conv, false);
if ($dbclean_unclaimed == 0) { if ($dbclean_unclaimed == 0) {
$dbclean_unclaimed = $dbclean_expire_days; $dbclean_unclaimed = $dbclean_expire_days;
} }
DI::config()->set('system', 'dbclean-expire-unclaimed', $dbclean_unclaimed); DI::config()->set('system', 'dbclean-expire-unclaimed', $dbclean_unclaimed, false);
DI::config()->set('system', 'max_comments', $max_comments); DI::config()->set('system', 'max_comments', $max_comments, false);
DI::config()->set('system', 'max_display_comments', $max_display_comments); DI::config()->set('system', 'max_display_comments', $max_display_comments, false);
if ($temppath != '') { if ($temppath != '') {
$temppath = BasePath::getRealPath($temppath); $temppath = BasePath::getRealPath($temppath);
} }
DI::config()->set('system', 'temppath', $temppath); DI::config()->set('system', 'temppath', $temppath, false);
DI::config()->set('system', 'only_tag_search' , $only_tag_search); DI::config()->set('system', 'only_tag_search' , $only_tag_search, false);
DI::config()->set('system', 'compute_group_counts', $compute_group_counts); DI::config()->set('system', 'compute_group_counts', $compute_group_counts, false);
DI::config()->set('system', 'worker_queues' , $worker_queues); DI::config()->set('system', 'worker_queues' , $worker_queues, false);
DI::config()->set('system', 'worker_fastlane' , $worker_fastlane); DI::config()->set('system', 'worker_fastlane' , $worker_fastlane, false);
DI::config()->set('system', 'relay_directly' , $relay_directly); DI::config()->set('system', 'relay_directly' , $relay_directly, false);
DI::config()->set('system', 'relay_scope' , $relay_scope); DI::config()->set('system', 'relay_scope' , $relay_scope, false);
DI::config()->set('system', 'relay_server_tags', $relay_server_tags); DI::config()->set('system', 'relay_server_tags', $relay_server_tags, false);
DI::config()->set('system', 'relay_deny_tags' , $relay_deny_tags); DI::config()->set('system', 'relay_deny_tags' , $relay_deny_tags, false);
DI::config()->set('system', 'relay_user_tags' , $relay_user_tags); DI::config()->set('system', 'relay_user_tags' , $relay_user_tags, false);
DI::config()->save();
DI::baseUrl()->redirect('admin/site' . $active_panel); DI::baseUrl()->redirect('admin/site' . $active_panel);
} }
@ -332,8 +334,8 @@ class Site extends BaseAdmin
if (DI::config()->get('system', 'directory_submit_url') && if (DI::config()->get('system', 'directory_submit_url') &&
!DI::config()->get('system', 'directory')) { !DI::config()->get('system', 'directory')) {
DI::config()->set('system', 'directory', dirname(DI::config()->get('system', 'directory_submit_url'))); DI::config()->set('system', 'directory', dirname(DI::config()->get('system', 'directory_submit_url')), false);
DI::config()->delete('system', 'directory_submit_url'); DI::config()->delete('system', 'directory_submit_url', false);
} }
/* Installed themes */ /* Installed themes */

View file

@ -55,7 +55,7 @@
use Friendica\Database\DBA; use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1507); define('DB_UPDATE_VERSION', 1508);
} }
return [ return [
@ -553,19 +553,6 @@ return [
"k_expires" => ["k", "expires"], "k_expires" => ["k", "expires"],
] ]
], ],
"config" => [
"comment" => "main configuration storage",
"fields" => [
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => ""],
"cat" => ["type" => "varbinary(50)", "not null" => "1", "default" => "", "comment" => ""],
"k" => ["type" => "varbinary(50)", "not null" => "1", "default" => "", "comment" => ""],
"v" => ["type" => "mediumtext", "comment" => ""],
],
"indexes" => [
"PRIMARY" => ["id"],
"cat_k" => ["UNIQUE", "cat", "k"],
]
],
"contact-relation" => [ "contact-relation" => [
"comment" => "Contact relations", "comment" => "Contact relations",
"fields" => [ "fields" => [

View file

@ -76,7 +76,7 @@ return [
$_SERVER $_SERVER
] ]
], ],
Config\Util\ConfigFileLoader::class => [ Config\Util\ConfigFileManager::class => [
'instanceOf' => Config\Factory\Config::class, 'instanceOf' => Config\Factory\Config::class,
'call' => [ 'call' => [
['createConfigFileLoader', [ ['createConfigFileLoader', [

View file

@ -1175,3 +1175,22 @@ function update_1505()
return DBA::delete('config', $conditions) ? Update::SUCCESS : Update::FAILED; return DBA::delete('config', $conditions) ? Update::SUCCESS : Update::FAILED;
} }
function update_1508()
{
$categories = DBA::toArray(DBA::p("SELECT DISTINCT `cat` AS 'cat' FROM `config`"));
foreach ($categories as $category) {
DI::config()->load($category['cat']);
}
$config = DBA::selectToArray('config');
foreach ($config as $entry) {
DI::config()->set($entry['cat'], $entry['k'], $entry['v'], false);
}
DI::config()->save();
DBA::e("DELETE FROM `config`");
}