Merge pull request #12622 from nupplaphil/bug/config
`node.config.php` bugfixings
This commit is contained in:
commit
308618b559
22 changed files with 457 additions and 325 deletions
|
@ -82,6 +82,10 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['auth_ejabb
|
||||||
|
|
||||||
\Friendica\DI::init($dice);
|
\Friendica\DI::init($dice);
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
||||||
|
|
||||||
|
// Check the database structure and possibly fixes it
|
||||||
|
\Friendica\Core\Update::check(\Friendica\DI::basePath(), true);
|
||||||
|
|
||||||
$appMode = $dice->create(Mode::class);
|
$appMode = $dice->create(Mode::class);
|
||||||
|
|
||||||
if ($appMode->isNormal()) {
|
if ($appMode->isNormal()) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ if (php_sapi_name() !== 'cli') {
|
||||||
use Dice\Dice;
|
use Dice\Dice;
|
||||||
use Friendica\App\Mode;
|
use Friendica\App\Mode;
|
||||||
use Friendica\Core\Logger;
|
use Friendica\Core\Logger;
|
||||||
|
use Friendica\Core\Update;
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\DI;
|
use Friendica\DI;
|
||||||
|
@ -63,7 +64,6 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['daemon']])
|
||||||
|
|
||||||
DI::init($dice);
|
DI::init($dice);
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
||||||
$a = DI::app();
|
|
||||||
|
|
||||||
if (DI::mode()->isInstall()) {
|
if (DI::mode()->isInstall()) {
|
||||||
die("Friendica isn't properly installed yet.\n");
|
die("Friendica isn't properly installed yet.\n");
|
||||||
|
@ -193,6 +193,9 @@ $last_cron = 0;
|
||||||
|
|
||||||
// Now running as a daemon.
|
// Now running as a daemon.
|
||||||
while (true) {
|
while (true) {
|
||||||
|
// Check the database structure and possibly fixes it
|
||||||
|
Update::check(DI::basePath(), true);
|
||||||
|
|
||||||
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
|
if (!$do_cron && ($last_cron + $wait_interval) < time()) {
|
||||||
Logger::info('Forcing cron worker call.', ['pid' => $pid]);
|
Logger::info('Forcing cron worker call.', ['pid' => $pid]);
|
||||||
$do_cron = true;
|
$do_cron = true;
|
||||||
|
|
|
@ -58,12 +58,11 @@ $dice = $dice->addRule(LoggerInterface::class,['constructParams' => ['worker']])
|
||||||
|
|
||||||
DI::init($dice);
|
DI::init($dice);
|
||||||
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
\Friendica\Core\Logger\Handler\ErrorHandler::register($dice->create(\Psr\Log\LoggerInterface::class));
|
||||||
$a = DI::app();
|
|
||||||
|
|
||||||
DI::mode()->setExecutor(Mode::WORKER);
|
DI::mode()->setExecutor(Mode::WORKER);
|
||||||
|
|
||||||
// Check the database structure and possibly fixes it
|
// Check the database structure and possibly fixes it
|
||||||
Update::check($a->getBasePath(), true, DI::mode());
|
Update::check(DI::basePath(), true);
|
||||||
|
|
||||||
// Quit when in maintenance
|
// Quit when in maintenance
|
||||||
if (!DI::mode()->has(App\Mode::MAINTENANCEDISABLED)) {
|
if (!DI::mode()->has(App\Mode::MAINTENANCEDISABLED)) {
|
||||||
|
|
|
@ -359,7 +359,7 @@ class App
|
||||||
$this->profiler->update($this->config);
|
$this->profiler->update($this->config);
|
||||||
|
|
||||||
Core\Hook::loadHooks();
|
Core\Hook::loadHooks();
|
||||||
$loader = (new Config())->createConfigFileLoader($this->getBasePath(), $_SERVER);
|
$loader = (new Config())->createConfigFileManager($this->getBasePath(), $_SERVER);
|
||||||
Core\Hook::callAll('load_config', $loader);
|
Core\Hook::callAll('load_config', $loader);
|
||||||
|
|
||||||
// Hooks are now working, reload the whole definitions with hook enabled
|
// Hooks are now working, reload the whole definitions with hook enabled
|
||||||
|
@ -659,7 +659,7 @@ class App
|
||||||
$this->baseURL->redirect('install');
|
$this->baseURL->redirect('install');
|
||||||
} else {
|
} else {
|
||||||
$this->checkURL();
|
$this->checkURL();
|
||||||
Core\Update::check($this->getBasePath(), false, $this->mode);
|
Core\Update::check($this->getBasePath(), false);
|
||||||
Core\Addon::loadAddons();
|
Core\Addon::loadAddons();
|
||||||
Core\Hook::loadHooks();
|
Core\Hook::loadHooks();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ class Config
|
||||||
*
|
*
|
||||||
* @return Util\ConfigFileManager
|
* @return Util\ConfigFileManager
|
||||||
*/
|
*/
|
||||||
public function createConfigFileLoader(string $basePath, array $server = []): Util\ConfigFileManager
|
public function createConfigFileManager(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,18 @@ class Config
|
||||||
}
|
}
|
||||||
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
|
$staticDir = $basePath . DIRECTORY_SEPARATOR . self::STATIC_DIR;
|
||||||
|
|
||||||
return new Util\ConfigFileManager($basePath, $configDir, $staticDir, new Util\ConfigFileTransformer());
|
return new Util\ConfigFileManager($basePath, $configDir, $staticDir, $server);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Util\ConfigFileManager $configFileManager The Config Cache manager (INI/config/.htconfig)
|
* @param Util\ConfigFileManager $configFileManager The Config Cache manager (INI/config/.htconfig)
|
||||||
* @param array $server
|
|
||||||
*
|
*
|
||||||
* @return Cache
|
* @return Cache
|
||||||
*/
|
*/
|
||||||
public function createCache(Util\ConfigFileManager $configFileManager, array $server = []): Cache
|
public function createCache(Util\ConfigFileManager $configFileManager): Cache
|
||||||
{
|
{
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
$configFileManager->setupCache($configCache, $server);
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
return $configCache;
|
return $configCache;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,19 +39,14 @@ class Config implements IManageConfigValues
|
||||||
/** @var ConfigFileManager */
|
/** @var ConfigFileManager */
|
||||||
protected $configFileManager;
|
protected $configFileManager;
|
||||||
|
|
||||||
/** @var array */
|
|
||||||
protected $server;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ConfigFileManager $configFileManager The configuration file manager to save back configs
|
* @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 array $server The $_SERVER variable
|
|
||||||
*/
|
*/
|
||||||
public function __construct(ConfigFileManager $configFileManager, Cache $configCache, array $server = [])
|
public function __construct(ConfigFileManager $configFileManager, Cache $configCache)
|
||||||
{
|
{
|
||||||
$this->configFileManager = $configFileManager;
|
$this->configFileManager = $configFileManager;
|
||||||
$this->configCache = $configCache;
|
$this->configCache = $configCache;
|
||||||
$this->server = $server;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +82,7 @@ class Config implements IManageConfigValues
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->configFileManager->setupCache($configCache, $this->server);
|
$this->configFileManager->setupCache($configCache);
|
||||||
} catch (ConfigFileException $e) {
|
} catch (ConfigFileException $e) {
|
||||||
throw new ConfigPersistenceException('Cannot reload config', $e);
|
throw new ConfigPersistenceException('Cannot reload config', $e);
|
||||||
}
|
}
|
||||||
|
@ -121,7 +116,7 @@ class Config implements IManageConfigValues
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public function delete(string $cat, string $key): bool
|
public function delete(string $cat, string $key): bool
|
||||||
{
|
{
|
||||||
if ($this->configCache->delete($cat, $key)) {
|
if ($this->configCache->delete($cat, $key, Cache::SOURCE_DATA)) {
|
||||||
$this->save();
|
$this->save();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -35,37 +35,13 @@ class ConfigTransaction implements ISetConfigValuesTransactionally
|
||||||
protected $config;
|
protected $config;
|
||||||
/** @var Cache */
|
/** @var Cache */
|
||||||
protected $cache;
|
protected $cache;
|
||||||
/** @var Cache */
|
|
||||||
protected $delCache;
|
|
||||||
/** @var bool field to check if something is to save */
|
/** @var bool field to check if something is to save */
|
||||||
protected $changedConfig = false;
|
protected $changedConfig = false;
|
||||||
|
|
||||||
public function __construct(IManageConfigValues $config)
|
public function __construct(IManageConfigValues $config)
|
||||||
{
|
{
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
$this->cache = new Cache();
|
$this->cache = clone $config->getCache();
|
||||||
$this->delCache = new Cache();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a particular user's config variable given the category name
|
|
||||||
* ($cat) and a $key from the current transaction.
|
|
||||||
*
|
|
||||||
* Isn't part of the interface because of it's rare use case
|
|
||||||
*
|
|
||||||
* @param string $cat The category of the configuration value
|
|
||||||
* @param string $key The configuration key to query
|
|
||||||
*
|
|
||||||
* @return mixed Stored value or null if it does not exist
|
|
||||||
*
|
|
||||||
* @throws ConfigPersistenceException In case the persistence layer throws errors
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function get(string $cat, string $key)
|
|
||||||
{
|
|
||||||
return !$this->delCache->get($cat, $key) ?
|
|
||||||
($this->cache->get($cat, $key) ?? $this->config->get($cat, $key)) :
|
|
||||||
null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
@ -81,8 +57,7 @@ class ConfigTransaction implements ISetConfigValuesTransactionally
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
public function delete(string $cat, string $key): ISetConfigValuesTransactionally
|
public function delete(string $cat, string $key): ISetConfigValuesTransactionally
|
||||||
{
|
{
|
||||||
$this->cache->delete($cat, $key);
|
$this->cache->delete($cat, $key, Cache::SOURCE_DATA);
|
||||||
$this->delCache->set($cat, $key, 'deleted');
|
|
||||||
$this->changedConfig = true;
|
$this->changedConfig = true;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -97,13 +72,8 @@ class ConfigTransaction implements ISetConfigValuesTransactionally
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$newCache = $this->config->getCache()->merge($this->cache);
|
$this->config->load($this->cache);
|
||||||
$newCache = $newCache->diff($this->delCache);
|
$this->cache = clone $this->config->getCache();
|
||||||
$this->config->load($newCache);
|
|
||||||
|
|
||||||
// flush current cache
|
|
||||||
$this->cache = new Cache();
|
|
||||||
$this->delCache = new Cache();
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
throw new ConfigPersistenceException('Cannot save config', $e);
|
throw new ConfigPersistenceException('Cannot save config', $e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,16 +69,22 @@ class ConfigFileManager
|
||||||
*/
|
*/
|
||||||
private $staticDir;
|
private $staticDir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $server;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $baseDir The base
|
* @param string $baseDir The base
|
||||||
* @param string $configDir
|
* @param string $configDir
|
||||||
* @param string $staticDir
|
* @param string $staticDir
|
||||||
*/
|
*/
|
||||||
public function __construct(string $baseDir, string $configDir, string $staticDir)
|
public function __construct(string $baseDir, string $configDir, string $staticDir, array $server = [])
|
||||||
{
|
{
|
||||||
$this->baseDir = $baseDir;
|
$this->baseDir = $baseDir;
|
||||||
$this->configDir = $configDir;
|
$this->configDir = $configDir;
|
||||||
$this->staticDir = $staticDir;
|
$this->staticDir = $staticDir;
|
||||||
|
$this->server = $server;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,34 +93,33 @@ class ConfigFileManager
|
||||||
* First loads the default value for all the configuration keys, then the legacy configuration files, then the
|
* First loads the default value for all the configuration keys, then the legacy configuration files, then the
|
||||||
* expected local.config.php
|
* expected local.config.php
|
||||||
*
|
*
|
||||||
* @param Cache $config The config cache to load to
|
* @param Cache $configCache The config cache to load to
|
||||||
* @param array $server The $_SERVER array
|
* @param bool $raw Set up the raw config format
|
||||||
* @param bool $raw Set up the raw config format
|
|
||||||
*
|
*
|
||||||
* @throws ConfigFileException
|
* @throws ConfigFileException
|
||||||
*/
|
*/
|
||||||
public function setupCache(Cache $config, array $server = [], bool $raw = false)
|
public function setupCache(Cache $configCache, bool $raw = false)
|
||||||
{
|
{
|
||||||
// Load static config files first, the order is important
|
// Load static config files first, the order is important
|
||||||
$config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_STATIC);
|
$configCache->load($this->loadStaticConfig('defaults'), Cache::SOURCE_STATIC);
|
||||||
$config->load($this->loadStaticConfig('settings'), Cache::SOURCE_STATIC);
|
$configCache->load($this->loadStaticConfig('settings'), Cache::SOURCE_STATIC);
|
||||||
|
|
||||||
// try to load the legacy config first
|
// try to load the legacy config first
|
||||||
$config->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
|
$configCache->load($this->loadLegacyConfig('htpreconfig'), Cache::SOURCE_FILE);
|
||||||
$config->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
|
$configCache->load($this->loadLegacyConfig('htconfig'), Cache::SOURCE_FILE);
|
||||||
|
|
||||||
// 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($configCache);
|
||||||
|
|
||||||
// Now load the node.config.php file with the node specific config values (based on admin gui/console actions)
|
// Now load the node.config.php file with the node specific config values (based on admin gui/console actions)
|
||||||
$this->loadDataConfig($config);
|
$this->loadDataConfig($configCache);
|
||||||
|
|
||||||
$config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV);
|
$configCache->load($this->loadEnvConfig(), 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
|
||||||
if (!$raw && empty($config->get('system', 'basepath'))) {
|
if (!$raw && empty($configCache->get('system', 'basepath'))) {
|
||||||
// Setting at least the basepath we know
|
// Setting at least the basepath we know
|
||||||
$config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
|
$configCache->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +139,7 @@ class ConfigFileManager
|
||||||
|
|
||||||
if (file_exists($configName)) {
|
if (file_exists($configName)) {
|
||||||
return $this->loadConfigFile($configName);
|
return $this->loadConfigFile($configName);
|
||||||
} elseif (file_exists($iniName)) {
|
} else if (file_exists($iniName)) {
|
||||||
return $this->loadINIConfigFile($iniName);
|
return $this->loadINIConfigFile($iniName);
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
|
@ -144,82 +149,154 @@ class ConfigFileManager
|
||||||
/**
|
/**
|
||||||
* Tries to load the specified core-configuration into the config cache.
|
* Tries to load the specified core-configuration into the config cache.
|
||||||
*
|
*
|
||||||
* @param Cache $config The Config cache
|
* @param Cache $configCache The Config cache
|
||||||
*
|
*
|
||||||
* @throws ConfigFileException if the configuration file isn't readable
|
* @throws ConfigFileException if the configuration file isn't readable
|
||||||
*/
|
*/
|
||||||
private function loadCoreConfig(Cache $config)
|
private function loadCoreConfig(Cache $configCache)
|
||||||
{
|
{
|
||||||
// try to load legacy ini-files first
|
// try to load legacy ini-files first
|
||||||
foreach ($this->getConfigFiles(true) as $configFile) {
|
foreach ($this->getConfigFiles(true) as $configFile) {
|
||||||
$config->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
|
$configCache->load($this->loadINIConfigFile($configFile), Cache::SOURCE_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to load supported config at last to overwrite it
|
// try to load supported config at last to overwrite it
|
||||||
foreach ($this->getConfigFiles() as $configFile) {
|
foreach ($this->getConfigFiles() as $configFile) {
|
||||||
$config->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
|
$configCache->load($this->loadConfigFile($configFile), Cache::SOURCE_FILE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to load the data config file with the overridden data
|
* Tries to load the data config file with the overridden data
|
||||||
*
|
*
|
||||||
* @param Cache $config The Config cache
|
* @param Cache $configCache The Config cache
|
||||||
*
|
*
|
||||||
* @throws ConfigFileException In case the config file isn't loadable
|
* @throws ConfigFileException In case the config file isn't loadable
|
||||||
*/
|
*/
|
||||||
private function loadDataConfig(Cache $config)
|
private function loadDataConfig(Cache $configCache)
|
||||||
{
|
{
|
||||||
$filename = $this->configDir . '/' . self::CONFIG_DATA_FILE;
|
$filename = $this->configDir . '/' . self::CONFIG_DATA_FILE;
|
||||||
|
|
||||||
if (file_exists($filename)) {
|
if (file_exists($filename)) {
|
||||||
|
|
||||||
|
// The fallback empty return content
|
||||||
$content = '<?php return [];';
|
$content = '<?php return [];';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code-block creates a readonly node.config.php content stream (fopen() with "r")
|
||||||
|
* The stream is locked shared (LOCK_SH), so not exclusively, but the OS knows that there's a lock
|
||||||
|
*
|
||||||
|
* Any exclusive locking (LOCK_EX) would need to wait until all LOCK_SHs are unlocked
|
||||||
|
*/
|
||||||
$configStream = fopen($filename, 'r');
|
$configStream = fopen($filename, 'r');
|
||||||
if (flock($configStream, LOCK_SH)) {
|
try {
|
||||||
$content = fread($configStream, filesize($filename));
|
if (flock($configStream, LOCK_SH)) {
|
||||||
if (!$content) {
|
$content = fread($configStream, filesize($filename));
|
||||||
throw new ConfigFileException(sprintf('Couldn\'t read file %s', $filename));
|
if (!$content) {
|
||||||
|
throw new ConfigFileException(sprintf('Couldn\'t read file %s', $filename));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
// unlock and close the stream for every circumstances
|
||||||
flock($configStream, LOCK_UN);
|
flock($configStream, LOCK_UN);
|
||||||
|
fclose($configStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose($configStream);
|
/**
|
||||||
|
* Evaluate the content string as PHP code
|
||||||
|
*
|
||||||
|
* @see https://www.php.net/manual/en/function.eval.php
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* To leave the PHP mode, we have to use the appropriate PHP tags '?>' as prefix.
|
||||||
|
*/
|
||||||
$dataArray = eval('?>' . $content);
|
$dataArray = eval('?>' . $content);
|
||||||
|
|
||||||
if (!is_array($dataArray)) {
|
if (is_array($dataArray)) {
|
||||||
throw new ConfigFileException(sprintf('Error loading config file %s', $filename));
|
$configCache->load($dataArray, Cache::SOURCE_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
$config->load($dataArray, Cache::SOURCE_DATA);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves overridden config entries back into the data.config.phpR
|
* Saves overridden config entries back into the data.config.php
|
||||||
*
|
*
|
||||||
* @param Cache $config The config cache
|
* @param Cache $configCache The config cache
|
||||||
*
|
*
|
||||||
* @throws ConfigFileException In case the config file isn't writeable or the data is invalid
|
* @throws ConfigFileException In case the config file isn't writeable or the data is invalid
|
||||||
*/
|
*/
|
||||||
public function saveData(Cache $config)
|
public function saveData(Cache $configCache)
|
||||||
{
|
{
|
||||||
$data = $config->getDataBySource(Cache::SOURCE_DATA);
|
$filename = $this->configDir . '/' . self::CONFIG_DATA_FILE;
|
||||||
|
|
||||||
$encodedData = ConfigFileTransformer::encode($data);
|
if (file_exists($filename)) {
|
||||||
|
$fileExists = true;
|
||||||
if (!$encodedData) {
|
} else {
|
||||||
throw new ConfigFileException('config source cannot get encoded');
|
$fileExists = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$configStream = fopen($this->configDir . '/' . self::CONFIG_DATA_FILE, 'w');
|
/**
|
||||||
|
* Creates a read-write stream
|
||||||
|
*
|
||||||
|
* @see https://www.php.net/manual/en/function.fopen.php
|
||||||
|
* @note Open the file for reading and writing. If the file does not exist, it is created.
|
||||||
|
* If it exists, it is neither truncated (as opposed to 'w'), nor the call to this function fails
|
||||||
|
* (as is the case with 'x'). The file pointer is positioned on the beginning of the file.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
$configStream = fopen($filename, 'c+');
|
||||||
|
|
||||||
if (flock($configStream, LOCK_EX)) {
|
try {
|
||||||
fwrite($configStream, $encodedData);
|
// We do want an exclusive lock, so we wait until every LOCK_SH (config reading) is unlocked
|
||||||
fflush($configStream);
|
if (flock($configStream, LOCK_EX)) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the file exists, we read the whole file again to avoid a race condition with concurrent threads that could have modified the file between the first config read of this thread and now
|
||||||
|
* Since we're currently exclusive locked, no other process can now change the config again
|
||||||
|
*/
|
||||||
|
if ($fileExists) {
|
||||||
|
// When reading the config file too fast, we get a wrong filesize, "clearstatcache" prevents that
|
||||||
|
clearstatcache(true, $filename);
|
||||||
|
$content = fread($configStream, filesize($filename));
|
||||||
|
if (!$content) {
|
||||||
|
throw new ConfigFileException(sprintf('Cannot read file %s', $filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event truncating the whole content wouldn't automatically rewind the stream,
|
||||||
|
// so we need to do it manually
|
||||||
|
rewind($configStream);
|
||||||
|
|
||||||
|
$dataArray = eval('?>' . $content);
|
||||||
|
|
||||||
|
// Merge the new content into the existing file based config cache and use it
|
||||||
|
// as the new config cache
|
||||||
|
if (is_array($dataArray)) {
|
||||||
|
$fileConfigCache = new Cache();
|
||||||
|
$fileConfigCache->load($dataArray, Cache::SOURCE_DATA);
|
||||||
|
$configCache = $fileConfigCache->merge($configCache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only SOURCE_DATA is wanted, the rest isn't part of the node.config.php file
|
||||||
|
$data = $configCache->getDataBySource(Cache::SOURCE_DATA);
|
||||||
|
|
||||||
|
$encodedData = ConfigFileTransformer::encode($data);
|
||||||
|
if (!$encodedData) {
|
||||||
|
throw new ConfigFileException('config source cannot get encoded');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once again to avoid wrong, implicit "filesize" calls during the fwrite() or ftruncate() call
|
||||||
|
clearstatcache(true, $filename);
|
||||||
|
if (!ftruncate($configStream, 0) ||
|
||||||
|
!fwrite($configStream, $encodedData) ||
|
||||||
|
!fflush($configStream)) {
|
||||||
|
throw new ConfigFileException(sprintf('Cannot modify locked file %s', $filename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
// unlock and close the stream for every circumstances
|
||||||
flock($configStream, LOCK_UN);
|
flock($configStream, LOCK_UN);
|
||||||
|
fclose($configStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +314,7 @@ class ConfigFileManager
|
||||||
$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
|
$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
|
||||||
Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
|
Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
|
||||||
$name . DIRECTORY_SEPARATOR . // openstreetmap/
|
$name . DIRECTORY_SEPARATOR . // openstreetmap/
|
||||||
'config'. DIRECTORY_SEPARATOR . // config/
|
'config' . DIRECTORY_SEPARATOR . // config/
|
||||||
$name . ".config.php"; // openstreetmap.config.php
|
$name . ".config.php"; // openstreetmap.config.php
|
||||||
|
|
||||||
if (file_exists($filepath)) {
|
if (file_exists($filepath)) {
|
||||||
|
@ -250,13 +327,11 @@ class ConfigFileManager
|
||||||
/**
|
/**
|
||||||
* Tries to load environment specific variables, based on the `env.config.php` mapping table
|
* 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)
|
* @return array The config array (empty if no config was found)
|
||||||
*
|
*
|
||||||
* @throws ConfigFileException if the configuration file isn't readable
|
* @throws ConfigFileException if the configuration file isn't readable
|
||||||
*/
|
*/
|
||||||
public function loadEnvConfig(array $server): array
|
protected function loadEnvConfig(): array
|
||||||
{
|
{
|
||||||
$filepath = $this->staticDir . DIRECTORY_SEPARATOR . // /var/www/html/static/
|
$filepath = $this->staticDir . DIRECTORY_SEPARATOR . // /var/www/html/static/
|
||||||
"env.config.php"; // env.config.php
|
"env.config.php"; // env.config.php
|
||||||
|
@ -270,8 +345,8 @@ class ConfigFileManager
|
||||||
$return = [];
|
$return = [];
|
||||||
|
|
||||||
foreach ($envConfig as $envKey => $configStructure) {
|
foreach ($envConfig as $envKey => $configStructure) {
|
||||||
if (isset($server[$envKey])) {
|
if (isset($this->server[$envKey])) {
|
||||||
$return[$configStructure[0]][$configStructure[1]] = $server[$envKey];
|
$return[$configStructure[0]][$configStructure[1]] = $this->server[$envKey];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +371,9 @@ class ConfigFileManager
|
||||||
$sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
|
$sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
|
||||||
|
|
||||||
foreach ($files as $filename) {
|
foreach ($files as $filename) {
|
||||||
if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
|
if (fnmatch($filePattern, $filename) &&
|
||||||
|
substr_compare($filename, $sampleEnd, -strlen($sampleEnd)) &&
|
||||||
|
$filename !== self::CONFIG_DATA_FILE) {
|
||||||
$found[] = $this->configDir . '/' . $filename;
|
$found[] = $this->configDir . '/' . $filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,11 @@ class ConfigFileTransformer
|
||||||
$categories = array_keys($data);
|
$categories = array_keys($data);
|
||||||
|
|
||||||
foreach ($categories as $category) {
|
foreach ($categories as $category) {
|
||||||
|
if (is_null($data[$category])) {
|
||||||
|
$dataString .= "\t'$category' => null," . PHP_EOL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$dataString .= "\t'$category' => [" . PHP_EOL;
|
$dataString .= "\t'$category' => [" . PHP_EOL;
|
||||||
|
|
||||||
if (is_array($data[$category])) {
|
if (is_array($data[$category])) {
|
||||||
|
@ -66,7 +71,9 @@ class ConfigFileTransformer
|
||||||
{
|
{
|
||||||
$string = str_repeat("\t", $level + 2) . "'$key' => ";
|
$string = str_repeat("\t", $level + 2) . "'$key' => ";
|
||||||
|
|
||||||
if (is_array($value)) {
|
if (is_null($value)) {
|
||||||
|
$string .= "null,";
|
||||||
|
} elseif (is_array($value)) {
|
||||||
$string .= "[" . PHP_EOL;
|
$string .= "[" . PHP_EOL;
|
||||||
$string .= static::extractArray($value, ++$level);
|
$string .= static::extractArray($value, ++$level);
|
||||||
$string .= str_repeat("\t", $level + 1) . '],';
|
$string .= str_repeat("\t", $level + 1) . '],';
|
||||||
|
|
|
@ -65,7 +65,7 @@ class Cache
|
||||||
* @param bool $hidePasswordOutput True, if cache variables should take extra care of password values
|
* @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
|
* @param int $source Sets a source of the initial config values
|
||||||
*/
|
*/
|
||||||
public function __construct(array $config = [], bool $hidePasswordOutput = true, $source = self::SOURCE_DEFAULT)
|
public function __construct(array $config = [], bool $hidePasswordOutput = true, int $source = self::SOURCE_DEFAULT)
|
||||||
{
|
{
|
||||||
$this->hidePasswordOutput = $hidePasswordOutput;
|
$this->hidePasswordOutput = $hidePasswordOutput;
|
||||||
$this->load($config, $source);
|
$this->load($config, $source);
|
||||||
|
@ -87,11 +87,10 @@ class Cache
|
||||||
$keys = array_keys($config[$category]);
|
$keys = array_keys($config[$category]);
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
foreach ($keys as $key) {
|
||||||
$value = $config[$category][$key];
|
$this->set($category, $key, $config[$category][$key] ?? null, $source);
|
||||||
if (isset($value)) {
|
|
||||||
$this->set($category, $key, $value, $source);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
$this->set($category, null, $config[$category], $source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,6 +149,8 @@ class Cache
|
||||||
$data[$category][$key] = $this->config[$category][$key];
|
$data[$category][$key] = $this->config[$category][$key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} elseif (is_int($this->source[$category])) {
|
||||||
|
$data[$category] = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,40 +160,49 @@ class Cache
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
*
|
*
|
||||||
* @param string $cat Config category
|
* @param string $cat Config category
|
||||||
* @param string $key Config key
|
* @param ?string $key Config key
|
||||||
* @param mixed $value Value to set
|
* @param ?mixed $value Value to set
|
||||||
* @param int $source The source of the current config key
|
* @param int $source The source of the current config key
|
||||||
*
|
*
|
||||||
* @return bool True, if the value is set
|
* @return bool True, if the value is set
|
||||||
*/
|
*/
|
||||||
public function set(string $cat, string $key, $value, int $source = self::SOURCE_DEFAULT): bool
|
public function set(string $cat, string $key = null, $value = null, int $source = self::SOURCE_DEFAULT): bool
|
||||||
{
|
{
|
||||||
if (!isset($this->config[$cat])) {
|
if (!isset($this->config[$cat]) && $key !== null) {
|
||||||
$this->config[$cat] = [];
|
$this->config[$cat] = [];
|
||||||
$this->source[$cat] = [];
|
$this->source[$cat] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->source[$cat][$key]) &&
|
if ((isset($this->source[$cat][$key]) && $source < $this->source[$cat][$key]) ||
|
||||||
$source < $this->source[$cat][$key]) {
|
(is_int($this->source[$cat] ?? null) && $source < $this->source[$cat])) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->hidePasswordOutput &&
|
if ($this->hidePasswordOutput &&
|
||||||
$key == 'password' &&
|
$key == 'password' &&
|
||||||
is_string($value)) {
|
is_string($value)) {
|
||||||
$this->config[$cat][$key] = new HiddenString((string)$value);
|
$this->setCatKeyValueSource($cat, $key, new HiddenString($value), $source);
|
||||||
} else if (is_string($value)) {
|
} else if (is_string($value)) {
|
||||||
$this->config[$cat][$key] = self::toConfigValue($value);
|
$this->setCatKeyValueSource($cat, $key, self::toConfigValue($value), $source);
|
||||||
} else {
|
} else {
|
||||||
$this->config[$cat][$key] = $value;
|
$this->setCatKeyValueSource($cat, $key, $value, $source);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->source[$cat][$key] = $source;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function setCatKeyValueSource(string $cat, string $key = null, $value = null, int $source = self::SOURCE_DEFAULT)
|
||||||
|
{
|
||||||
|
if (isset($key)) {
|
||||||
|
$this->config[$cat][$key] = $value;
|
||||||
|
$this->source[$cat][$key] = $source;
|
||||||
|
} else {
|
||||||
|
$this->config[$cat] = $value;
|
||||||
|
$this->source[$cat] = $source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a DB value to a config value
|
* Formats a DB value to a config value
|
||||||
* - null = The db-value isn't set
|
* - null = The db-value isn't set
|
||||||
|
@ -222,24 +232,27 @@ class Cache
|
||||||
/**
|
/**
|
||||||
* Deletes a value from the config cache.
|
* Deletes a value from the config cache.
|
||||||
*
|
*
|
||||||
* @param string $cat Config category
|
* @param string $cat Config category
|
||||||
* @param string $key Config key
|
* @param ?string $key Config key (if not set, the whole category will get deleted)
|
||||||
|
* @param int $source The source of the current config key
|
||||||
*
|
*
|
||||||
* @return bool true, if deleted
|
* @return bool true, if deleted
|
||||||
*/
|
*/
|
||||||
public function delete(string $cat, string $key): bool
|
public function delete(string $cat, string $key = null, int $source = self::SOURCE_DEFAULT): bool
|
||||||
{
|
{
|
||||||
if (isset($this->config[$cat][$key])) {
|
if (isset($this->config[$cat][$key])) {
|
||||||
unset($this->config[$cat][$key]);
|
$this->config[$cat][$key] = null;
|
||||||
unset($this->source[$cat][$key]);
|
$this->source[$cat][$key] = $source;
|
||||||
if (count($this->config[$cat]) == 0) {
|
if (empty(array_filter($this->config[$cat], function($value) { return !is_null($value); }))) {
|
||||||
unset($this->config[$cat]);
|
$this->config[$cat] = null;
|
||||||
unset($this->source[$cat]);
|
$this->source[$cat] = $source;
|
||||||
}
|
}
|
||||||
return true;
|
} elseif (isset($this->config[$cat])) {
|
||||||
} else {
|
$this->config[$cat] = null;
|
||||||
return false;
|
$this->source[$cat] = $source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -302,39 +315,9 @@ class Cache
|
||||||
$newConfig[$category][$key] = $cache->config[$category][$key];
|
$newConfig[$category][$key] = $cache->config[$category][$key];
|
||||||
$newSource[$category][$key] = $cache->source[$category][$key];
|
$newSource[$category][$key] = $cache->source[$category][$key];
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
$newConfig[$category] = $cache->config[$category];
|
||||||
|
$newSource[$category] = $cache->source[$category];
|
||||||
$newCache = new Cache();
|
|
||||||
$newCache->config = $newConfig;
|
|
||||||
$newCache->source = $newSource;
|
|
||||||
|
|
||||||
return $newCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Diffs a new Cache into the existing one and returns the diffed Cache
|
|
||||||
*
|
|
||||||
* @param Cache $cache The cache, which should get deleted for the current Cache
|
|
||||||
*
|
|
||||||
* @return Cache The diffed Cache
|
|
||||||
*/
|
|
||||||
public function diff(Cache $cache): Cache
|
|
||||||
{
|
|
||||||
$newConfig = $this->config;
|
|
||||||
$newSource = $this->source;
|
|
||||||
|
|
||||||
$categories = array_keys($cache->config);
|
|
||||||
|
|
||||||
foreach ($categories as $category) {
|
|
||||||
if (is_array($cache->config[$category])) {
|
|
||||||
$keys = array_keys($cache->config[$category]);
|
|
||||||
|
|
||||||
foreach ($keys as $key) {
|
|
||||||
unset($newConfig[$category][$key]);
|
|
||||||
unset($newSource[$category][$key]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Update
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function check(string $basePath, bool $via_worker, App\Mode $mode)
|
public static function check(string $basePath, bool $via_worker)
|
||||||
{
|
{
|
||||||
if (!DBA::connected()) {
|
if (!DBA::connected()) {
|
||||||
return;
|
return;
|
||||||
|
@ -61,8 +61,18 @@ class Update
|
||||||
$build = DI::config()->get('system', 'build');
|
$build = DI::config()->get('system', 'build');
|
||||||
|
|
||||||
if (empty($build)) {
|
if (empty($build)) {
|
||||||
DI::config()->set('system', 'build', DB_UPDATE_VERSION - 1);
|
// legacy option - check if there's something in the Config table
|
||||||
$build = DB_UPDATE_VERSION - 1;
|
if (DBStructure::existsTable('config')) {
|
||||||
|
$dbConfig = DBA::selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'build']);
|
||||||
|
if (!empty($dbConfig)) {
|
||||||
|
$build = $dbConfig['v'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($build)) {
|
||||||
|
DI::config()->set('system', 'build', DB_UPDATE_VERSION - 1);
|
||||||
|
$build = DB_UPDATE_VERSION - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't support upgrading from very old versions anymore
|
// We don't support upgrading from very old versions anymore
|
||||||
|
@ -119,11 +129,21 @@ class Update
|
||||||
DI::lock()->release('dbupdate', true);
|
DI::lock()->release('dbupdate', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$build = DI::config()->get('system', 'build', null);
|
$build = DI::config()->get('system', 'build');
|
||||||
|
|
||||||
if (empty($build) || ($build > DB_UPDATE_VERSION)) {
|
if (empty($build)) {
|
||||||
$build = DB_UPDATE_VERSION - 1;
|
// legacy option - check if there's something in the Config table
|
||||||
DI::config()->set('system', 'build', $build);
|
if (DBStructure::existsTable('config')) {
|
||||||
|
$dbConfig = DBA::selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'build']);
|
||||||
|
if (!empty($dbConfig)) {
|
||||||
|
$build = $dbConfig['v'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($build) || ($build > DB_UPDATE_VERSION)) {
|
||||||
|
DI::config()->set('system', 'build', DB_UPDATE_VERSION - 1);
|
||||||
|
$build = DB_UPDATE_VERSION - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($build != DB_UPDATE_VERSION || $force) {
|
if ($build != DB_UPDATE_VERSION || $force) {
|
||||||
|
@ -141,11 +161,21 @@ class Update
|
||||||
Logger::notice('Update starting.', ['from' => $stored, 'to' => $current]);
|
Logger::notice('Update starting.', ['from' => $stored, 'to' => $current]);
|
||||||
|
|
||||||
// Checks if the build changed during Lock acquiring (so no double update occurs)
|
// Checks if the build changed during Lock acquiring (so no double update occurs)
|
||||||
$retryBuild = DI::config()->get('system', 'build', null);
|
$retryBuild = DI::config()->get('system', 'build');
|
||||||
if ($retryBuild !== $build) {
|
if ($retryBuild != $build) {
|
||||||
Logger::notice('Update already done.', ['from' => $stored, 'to' => $current]);
|
// legacy option - check if there's something in the Config table
|
||||||
DI::lock()->release('dbupdate');
|
if (DBStructure::existsTable('config')) {
|
||||||
return '';
|
$dbConfig = DBA::selectFirst('config', ['v'], ['cat' => 'system', 'k' => 'build']);
|
||||||
|
if (!empty($dbConfig)) {
|
||||||
|
$retryBuild = intval($dbConfig['v']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($retryBuild != $build) {
|
||||||
|
Logger::notice('Update already done.', ['from' => $build, 'retry' => $retryBuild, 'to' => $current]);
|
||||||
|
DI::lock()->release('dbupdate');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DI::config()->set('system', 'maintenance', 1);
|
DI::config()->set('system', 'maintenance', 1);
|
||||||
|
|
|
@ -1315,8 +1315,8 @@ class Worker
|
||||||
return $added;
|
return $added;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quit on daemon mode
|
// Quit on daemon mode, except the priority is critical (like for db updates)
|
||||||
if (Worker\Daemon::isMode()) {
|
if (Worker\Daemon::isMode() && $priority !== self::PRIORITY_CRITICAL) {
|
||||||
return $added;
|
return $added;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ class Summary extends BaseAdmin
|
||||||
}
|
}
|
||||||
|
|
||||||
// check legacy basepath settings
|
// check legacy basepath settings
|
||||||
$configLoader = (new Config())->createConfigFileLoader($a->getBasePath(), $_SERVER);
|
$configLoader = (new Config())->createConfigFileManager($a->getBasePath(), $_SERVER);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
$configLoader->setupCache($configCache);
|
$configLoader->setupCache($configCache);
|
||||||
$confBasepath = $configCache->get('system', 'basepath');
|
$confBasepath = $configCache->get('system', 'basepath');
|
||||||
|
|
|
@ -79,7 +79,7 @@ return [
|
||||||
Config\Util\ConfigFileManager::class => [
|
Config\Util\ConfigFileManager::class => [
|
||||||
'instanceOf' => Config\Factory\Config::class,
|
'instanceOf' => Config\Factory\Config::class,
|
||||||
'call' => [
|
'call' => [
|
||||||
['createConfigFileLoader', [
|
['createConfigFileManager', [
|
||||||
[Dice::INSTANCE => '$basepath'],
|
[Dice::INSTANCE => '$basepath'],
|
||||||
$_SERVER,
|
$_SERVER,
|
||||||
], Dice::CHAIN_CALL],
|
], Dice::CHAIN_CALL],
|
||||||
|
@ -88,7 +88,7 @@ return [
|
||||||
Config\ValueObject\Cache::class => [
|
Config\ValueObject\Cache::class => [
|
||||||
'instanceOf' => Config\Factory\Config::class,
|
'instanceOf' => Config\Factory\Config::class,
|
||||||
'call' => [
|
'call' => [
|
||||||
['createCache', [$_SERVER], Dice::CHAIN_CALL],
|
['createCache', [], Dice::CHAIN_CALL],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
App\Mode::class => [
|
App\Mode::class => [
|
||||||
|
|
|
@ -62,7 +62,7 @@ abstract class FixtureTest extends DatabaseTest
|
||||||
->addRules(include __DIR__ . '/../static/dependencies.config.php')
|
->addRules(include __DIR__ . '/../static/dependencies.config.php')
|
||||||
->addRule(ConfigFileManager::class, [
|
->addRule(ConfigFileManager::class, [
|
||||||
'instanceOf' => Config::class,
|
'instanceOf' => Config::class,
|
||||||
'call' => [['createConfigFileLoader', [$this->root->url(), $server,],
|
'call' => [['createConfigFileManager', [$this->root->url(), $server,],
|
||||||
Dice::CHAIN_CALL]]])
|
Dice::CHAIN_CALL]]])
|
||||||
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
|
->addRule(Database::class, ['instanceOf' => StaticDatabase::class, 'shared' => true])
|
||||||
->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null])
|
->addRule(IHandleSessions::class, ['instanceOf' => Memory::class, 'shared' => true, 'call' => null])
|
||||||
|
|
|
@ -54,11 +54,11 @@ class DatabaseCacheTest extends CacheTest
|
||||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||||
|
|
||||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||||
$configFactory = new Config();
|
$configFactory = new Config();
|
||||||
$loader = (new Config())->createConfigFileLoader($this->root->url(), []);
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url(), []);
|
||||||
$configCache = $configFactory->createCache($loader);
|
$configCache = $configFactory->createCache($configFileManager);
|
||||||
|
|
||||||
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
|
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
|
||||||
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
|
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
|
||||||
|
|
||||||
$dba = new StaticDatabase($configCache, $profiler, $dbaDefinition, $viewDefinition);
|
$dba = new StaticDatabase($configCache, $profiler, $dbaDefinition, $viewDefinition);
|
||||||
|
|
|
@ -111,9 +111,9 @@ class CacheTest extends MockedTest
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the loadConfigArray() method with wrong/empty datasets
|
* Test the loadConfigArray() method with only a category
|
||||||
*/
|
*/
|
||||||
public function testLoadConfigArrayWrong()
|
public function testLoadConfigArrayWithOnlyCategory()
|
||||||
{
|
{
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
|
@ -123,9 +123,10 @@ class CacheTest extends MockedTest
|
||||||
|
|
||||||
// wrong dataset
|
// wrong dataset
|
||||||
$configCache->load(['system' => 'not_array']);
|
$configCache->load(['system' => 'not_array']);
|
||||||
self::assertEmpty($configCache->getAll());
|
self::assertEquals(['system' => 'not_array'], $configCache->getAll());
|
||||||
|
|
||||||
// incomplete dataset (key is integer ID of the array)
|
// incomplete dataset (key is integer ID of the array)
|
||||||
|
$configCache = new Cache();
|
||||||
$configCache->load(['system' => ['value']]);
|
$configCache->load(['system' => ['value']]);
|
||||||
self::assertEquals('value', $configCache->get('system', 0));
|
self::assertEquals('value', $configCache->get('system', 0));
|
||||||
}
|
}
|
||||||
|
@ -207,13 +208,16 @@ class CacheTest extends MockedTest
|
||||||
{
|
{
|
||||||
$configCache = new Cache($data);
|
$configCache = new Cache($data);
|
||||||
|
|
||||||
|
$assertion = [];
|
||||||
|
|
||||||
foreach ($data as $cat => $values) {
|
foreach ($data as $cat => $values) {
|
||||||
|
$assertion[$cat] = null;
|
||||||
foreach ($values as $key => $value) {
|
foreach ($values as $key => $value) {
|
||||||
$configCache->delete($cat, $key);
|
$configCache->delete($cat, $key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self::assertEmpty($configCache->getAll());
|
self::assertEquals($assertion, $configCache->getAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -385,32 +389,6 @@ class CacheTest extends MockedTest
|
||||||
self::assertEquals('added category', $mergedCache->get('new_category', 'test_23'));
|
self::assertEquals('added category', $mergedCache->get('new_category', 'test_23'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @dataProvider dataTests
|
|
||||||
*/
|
|
||||||
public function testDiff($data)
|
|
||||||
{
|
|
||||||
$configCache = new Cache();
|
|
||||||
$configCache->load($data, Cache::SOURCE_FILE);
|
|
||||||
|
|
||||||
$configCache->set('system', 'test_2','with_data', Cache::SOURCE_DATA);
|
|
||||||
$configCache->set('config', 'test_override','with_another_data', Cache::SOURCE_DATA);
|
|
||||||
|
|
||||||
$newCache = new Cache();
|
|
||||||
$newCache->set('config', 'test_override','override it again', Cache::SOURCE_DATA);
|
|
||||||
$newCache->set('system', 'test_3','new value', Cache::SOURCE_DATA);
|
|
||||||
|
|
||||||
$mergedCache = $configCache->diff($newCache);
|
|
||||||
|
|
||||||
print_r($mergedCache);
|
|
||||||
|
|
||||||
self::assertEquals('with_data', $mergedCache->get('system', 'test_2'));
|
|
||||||
// existing entry was dropped
|
|
||||||
self::assertNull($mergedCache->get('config', 'test_override'));
|
|
||||||
// the newCache entry wasn't set, because we Diff
|
|
||||||
self::assertNull($mergedCache->get('system', 'test_3'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function dataTestCat()
|
public function dataTestCat()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -51,6 +51,7 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
|
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
@ -69,15 +70,15 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
vfsStream::newFile('local.config.php')
|
vfsStream::newFile('local.config.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent('<?php return true;');
|
->setContent('<?php return true;');
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
}
|
}
|
||||||
|
@ -90,23 +91,23 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR .
|
'config' . DIRECTORY_SEPARATOR .
|
||||||
'A.config.php';
|
'A.config.php';
|
||||||
|
|
||||||
vfsStream::newFile('local.config.php')
|
vfsStream::newFile('local.config.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($file));
|
->setContent(file_get_contents($file));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
|
||||||
|
@ -127,23 +128,23 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR .
|
'config' . DIRECTORY_SEPARATOR .
|
||||||
'A.ini.php';
|
'A.ini.php';
|
||||||
|
|
||||||
vfsStream::newFile('local.ini.php')
|
vfsStream::newFile('local.ini.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($file));
|
->setContent(file_get_contents($file));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
|
||||||
|
@ -163,23 +164,23 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR .
|
'config' . DIRECTORY_SEPARATOR .
|
||||||
'.htconfig.php';
|
'.htconfig.php';
|
||||||
|
|
||||||
vfsStream::newFile('.htconfig.php')
|
vfsStream::newFile('.htconfig.php')
|
||||||
->at($this->root)
|
->at($this->root)
|
||||||
->setContent(file_get_contents($file));
|
->setContent(file_get_contents($file));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
|
||||||
|
@ -217,16 +218,16 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
vfsStream::create($structure, $this->root);
|
vfsStream::create($structure, $this->root);
|
||||||
|
|
||||||
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR .
|
'config' . DIRECTORY_SEPARATOR .
|
||||||
'A.config.php';
|
'A.config.php';
|
||||||
|
|
||||||
vfsStream::newFile('test.config.php')
|
vfsStream::newFile('test.config.php')
|
||||||
->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
|
->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
|
||||||
->setContent(file_get_contents($file));
|
->setContent(file_get_contents($file));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
|
@ -252,25 +253,25 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR;
|
'config' . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
vfsStream::newFile('A.config.php')
|
vfsStream::newFile('A.config.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($fileDir . 'A.config.php'));
|
->setContent(file_get_contents($fileDir . 'A.config.php'));
|
||||||
vfsStream::newFile('B.config.php')
|
vfsStream::newFile('B.config.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
|
||||||
|
@ -286,25 +287,25 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR;
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
|
'config' . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
vfsStream::newFile('A.ini.php')
|
vfsStream::newFile('A.ini.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($fileDir . 'A.ini.php'));
|
->setContent(file_get_contents($fileDir . 'A.ini.php'));
|
||||||
vfsStream::newFile('B.ini.php')
|
vfsStream::newFile('B.ini.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($fileDir . 'B.ini.php'));
|
->setContent(file_get_contents($fileDir . 'B.ini.php'));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
|
||||||
|
@ -320,24 +321,25 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'..' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'datasets' . DIRECTORY_SEPARATOR .
|
'..' . DIRECTORY_SEPARATOR .
|
||||||
'config' . DIRECTORY_SEPARATOR;
|
'datasets' . DIRECTORY_SEPARATOR .
|
||||||
|
'config' . DIRECTORY_SEPARATOR;
|
||||||
|
|
||||||
vfsStream::newFile('A.ini.php')
|
vfsStream::newFile('A.ini.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($fileDir . 'A.ini.php'));
|
->setContent(file_get_contents($fileDir . 'A.ini.php'));
|
||||||
vfsStream::newFile('B-sample.ini.php')
|
vfsStream::newFile('B-sample.ini.php')
|
||||||
->at($this->root->getChild('config'))
|
->at($this->root->getChild('config'))
|
||||||
->setContent(file_get_contents($fileDir . 'B.ini.php'));
|
->setContent(file_get_contents($fileDir . 'B.ini.php'));
|
||||||
|
|
||||||
$configFileLoader = new ConfigFileManager(
|
$configFileLoader = new ConfigFileManager(
|
||||||
$this->root->url(),
|
$this->root->url(),
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::CONFIG_DIR,
|
||||||
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
$this->root->url() . DIRECTORY_SEPARATOR . Config::STATIC_DIR
|
||||||
);
|
);
|
||||||
|
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileLoader->setupCache($configCache);
|
||||||
|
@ -353,10 +355,10 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
{
|
{
|
||||||
$this->delConfigFile('local.config.php');
|
$this->delConfigFile('local.config.php');
|
||||||
|
|
||||||
$configFileLoader = (new Config())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url(), ['FRIENDICA_CONFIG_DIR' => '/a/wrong/dir/']);
|
||||||
$configCache = new Cache();
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
self::assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
|
self::assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
|
||||||
}
|
}
|
||||||
|
@ -379,10 +381,13 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
->at($this->root->getChild('config2'))
|
->at($this->root->getChild('config2'))
|
||||||
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
||||||
|
|
||||||
$configFileLoader = (new Config())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()]);
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url(),
|
||||||
$configCache = new Cache();
|
[
|
||||||
|
'FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url(),
|
||||||
|
]);
|
||||||
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
self::assertEquals('newValue', $configCache->get('system', 'newKey'));
|
self::assertEquals('newValue', $configCache->get('system', 'newKey'));
|
||||||
}
|
}
|
||||||
|
@ -402,10 +407,13 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
->at($this->root->getChild('config2'))
|
->at($this->root->getChild('config2'))
|
||||||
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
||||||
|
|
||||||
$configFileLoader = (new Config())->createConfigFileLoader($this->root->url(), ['FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url()]);
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url(),
|
||||||
$configCache = new Cache();
|
[
|
||||||
|
'FRIENDICA_CONFIG_DIR' => $this->root->getChild('config2')->url(),
|
||||||
|
]);
|
||||||
|
$configCache = new Cache();
|
||||||
|
|
||||||
$configFileLoader->setupCache($configCache);
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
$specialChars = '!"§$%&/()(/&%$\'><?$a,;:[]}{}\\?¿¿ß';
|
$specialChars = '!"§$%&/()(/&%$\'><?$a,;:[]}{}\\?¿¿ß';
|
||||||
|
|
||||||
|
@ -414,23 +422,93 @@ class ConfigFileManagerTest extends MockedTest
|
||||||
$configCache->set('config', 'test', 'it', Cache::SOURCE_DATA);
|
$configCache->set('config', 'test', 'it', Cache::SOURCE_DATA);
|
||||||
$configCache->set('system', 'test_2', 2, Cache::SOURCE_DATA);
|
$configCache->set('system', 'test_2', 2, Cache::SOURCE_DATA);
|
||||||
$configCache->set('special_chars', 'special', $specialChars, Cache::SOURCE_DATA);
|
$configCache->set('special_chars', 'special', $specialChars, Cache::SOURCE_DATA);
|
||||||
$configFileLoader->saveData($configCache);
|
$configFileManager->saveData($configCache);
|
||||||
|
|
||||||
// Reload the configCache with the new values
|
// Reload the configCache with the new values
|
||||||
$configCache2 = new Cache();
|
$configCache2 = new Cache();
|
||||||
$configFileLoader->setupCache($configCache2);
|
$configFileManager->setupCache($configCache2);
|
||||||
|
|
||||||
self::assertEquals($configCache, $configCache2);
|
self::assertEquals($configCache, $configCache2);
|
||||||
self::assertEquals([
|
self::assertEquals([
|
||||||
'system' => [
|
'system' => [
|
||||||
'test' => 'it',
|
'test' => 'it',
|
||||||
'test_2' => 2
|
'test_2' => 2
|
||||||
],
|
],
|
||||||
'config' => [
|
'config' => [
|
||||||
'test' => 'it',
|
'test' => 'it',
|
||||||
],
|
],
|
||||||
'special_chars' => [
|
'special_chars' => [
|
||||||
'special' => $specialChars,
|
'special' => $specialChars,
|
||||||
]], $configCache2->getDataBySource(Cache::SOURCE_DATA));
|
]], $configCache2->getDataBySource(Cache::SOURCE_DATA));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we delete something with the Cache::delete() functionality, be sure to override the underlying source as well
|
||||||
|
*/
|
||||||
|
public function testDeleteKeyOverwrite()
|
||||||
|
{
|
||||||
|
$this->delConfigFile('node.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('config'))
|
||||||
|
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
||||||
|
|
||||||
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url());
|
||||||
|
$configCache = new Cache();
|
||||||
|
|
||||||
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
|
$configCache->delete('system', 'default_timezone', Cache::SOURCE_DATA);
|
||||||
|
|
||||||
|
$configFileManager->saveData($configCache);
|
||||||
|
|
||||||
|
// assert that system.default_timezone is now null, even it's set with settings.conf.php
|
||||||
|
$configCache = new Cache();
|
||||||
|
|
||||||
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
|
self::assertNull($configCache->get('system', 'default_timezone'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we delete something with the Cache::delete() functionality, be sure to override the underlying source as well
|
||||||
|
*/
|
||||||
|
public function testDeleteCategoryOverwrite()
|
||||||
|
{
|
||||||
|
$this->delConfigFile('node.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('config'))
|
||||||
|
->setContent(file_get_contents($fileDir . 'B.config.php'));
|
||||||
|
|
||||||
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url());
|
||||||
|
$configCache = new Cache();
|
||||||
|
|
||||||
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
|
$configCache->delete('system');
|
||||||
|
|
||||||
|
$configFileManager->saveData($configCache);
|
||||||
|
|
||||||
|
// assert that system.default_timezone is now null, even it's set with settings.conf.php
|
||||||
|
$configCache = new Cache();
|
||||||
|
|
||||||
|
$configFileManager->setupCache($configCache);
|
||||||
|
|
||||||
|
self::assertNull($configCache->get('system', 'default_timezone'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ class ConfigTest extends MockedTest
|
||||||
*/
|
*/
|
||||||
public function getInstance()
|
public function getInstance()
|
||||||
{
|
{
|
||||||
$this->configFileManager->setupCache($this->configCache, []);
|
$this->configFileManager->setupCache($this->configCache);
|
||||||
return new Config($this->configFileManager, $this->configCache);
|
return new Config($this->configFileManager, $this->configCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ class ConfigTest extends MockedTest
|
||||||
self::assertNull($this->testedConfig->get('test', 'it'));
|
self::assertNull($this->testedConfig->get('test', 'it'));
|
||||||
self::assertNull($this->testedConfig->getCache()->get('test', 'it'));
|
self::assertNull($this->testedConfig->getCache()->get('test', 'it'));
|
||||||
|
|
||||||
self::assertEmpty($this->testedConfig->getCache()->getAll());
|
self::assertEquals(['test' => null], $this->testedConfig->getCache()->getAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,23 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2023, 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;
|
namespace Friendica\Test\src\Core\Config;
|
||||||
|
|
||||||
|
@ -54,10 +73,6 @@ class ConfigTransactionTest extends MockedTest
|
||||||
$config->set('delete', 'keyDel', 'catDel');
|
$config->set('delete', 'keyDel', 'catDel');
|
||||||
|
|
||||||
$configTransaction = new ConfigTransaction($config);
|
$configTransaction = new ConfigTransaction($config);
|
||||||
self::assertEquals('value1', $configTransaction->get('config', 'key1'));
|
|
||||||
self::assertEquals('value2', $configTransaction->get('system', 'key2'));
|
|
||||||
self::assertEquals('valueDel', $configTransaction->get('system', 'keyDel'));
|
|
||||||
self::assertEquals('catDel', $configTransaction->get('delete', 'keyDel'));
|
|
||||||
// the config file knows it as well immediately
|
// the config file knows it as well immediately
|
||||||
$tempData = include $this->root->url() . '/config/' . ConfigFileManager::CONFIG_DATA_FILE;
|
$tempData = include $this->root->url() . '/config/' . ConfigFileManager::CONFIG_DATA_FILE;
|
||||||
self::assertEquals('value1', $tempData['config']['key1'] ?? null);
|
self::assertEquals('value1', $tempData['config']['key1'] ?? null);
|
||||||
|
@ -77,11 +92,6 @@ class ConfigTransactionTest extends MockedTest
|
||||||
self::assertEquals('value1', $config->get('config', 'key1'));
|
self::assertEquals('value1', $config->get('config', 'key1'));
|
||||||
self::assertEquals('valueDel', $config->get('system', 'keyDel'));
|
self::assertEquals('valueDel', $config->get('system', 'keyDel'));
|
||||||
self::assertEquals('catDel', $config->get('delete', 'keyDel'));
|
self::assertEquals('catDel', $config->get('delete', 'keyDel'));
|
||||||
// but the transaction config of course knows it
|
|
||||||
self::assertEquals('value3', $configTransaction->get('transaction', 'key3'));
|
|
||||||
self::assertEquals('changedValue1', $configTransaction->get('config', 'key1'));
|
|
||||||
self::assertNull($configTransaction->get('system', 'keyDel'));
|
|
||||||
self::assertNull($configTransaction->get('delete', 'keyDel'));
|
|
||||||
// The config file still doesn't know it either
|
// The config file still doesn't know it either
|
||||||
$tempData = include $this->root->url() . '/config/' . ConfigFileManager::CONFIG_DATA_FILE;
|
$tempData = include $this->root->url() . '/config/' . ConfigFileManager::CONFIG_DATA_FILE;
|
||||||
self::assertEquals('value1', $tempData['config']['key1'] ?? null);
|
self::assertEquals('value1', $tempData['config']['key1'] ?? null);
|
||||||
|
@ -97,9 +107,6 @@ class ConfigTransactionTest extends MockedTest
|
||||||
self::assertEquals('value3', $config->get('transaction', 'key3'));
|
self::assertEquals('value3', $config->get('transaction', 'key3'));
|
||||||
self::assertNull($config->get('system', 'keyDel'));
|
self::assertNull($config->get('system', 'keyDel'));
|
||||||
self::assertNull($config->get('delete', 'keyDel'));
|
self::assertNull($config->get('delete', 'keyDel'));
|
||||||
self::assertEquals('value3', $configTransaction->get('transaction', 'key3'));
|
|
||||||
self::assertEquals('changedValue1', $configTransaction->get('config', 'key1'));
|
|
||||||
self::assertNull($configTransaction->get('system', 'keyDel'));
|
|
||||||
$tempData = include $this->root->url() . '/config/' . ConfigFileManager::CONFIG_DATA_FILE;
|
$tempData = include $this->root->url() . '/config/' . ConfigFileManager::CONFIG_DATA_FILE;
|
||||||
self::assertEquals('changedValue1', $tempData['config']['key1'] ?? null);
|
self::assertEquals('changedValue1', $tempData['config']['key1'] ?? null);
|
||||||
self::assertEquals('value2', $tempData['system']['key2'] ?? null);
|
self::assertEquals('value2', $tempData['system']['key2'] ?? null);
|
||||||
|
|
|
@ -53,11 +53,11 @@ class DatabaseStorageTest extends StorageTest
|
||||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||||
|
|
||||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||||
$configFactory = new Config();
|
$configFactory = new Config();
|
||||||
$loader = (new Config())->createConfigFileLoader($this->root->url(), []);
|
$configFileManager = (new Config())->createConfigFileManager($this->root->url());
|
||||||
$configCache = $configFactory->createCache($loader);
|
$configCache = $configFactory->createCache($configFileManager);
|
||||||
|
|
||||||
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
|
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
|
||||||
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
|
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
|
||||||
|
|
||||||
$dba = new StaticDatabase($configCache, $profiler, $dbaDefinition, $viewDefinition);
|
$dba = new StaticDatabase($configCache, $profiler, $dbaDefinition, $viewDefinition);
|
||||||
|
|
|
@ -52,6 +52,7 @@ use Friendica\Test\Util\SampleStorageBackend;
|
||||||
class StorageManagerTest extends DatabaseTest
|
class StorageManagerTest extends DatabaseTest
|
||||||
{
|
{
|
||||||
use VFSTrait;
|
use VFSTrait;
|
||||||
|
|
||||||
/** @var Database */
|
/** @var Database */
|
||||||
private $dba;
|
private $dba;
|
||||||
/** @var IManageConfigValues */
|
/** @var IManageConfigValues */
|
||||||
|
@ -77,18 +78,19 @@ class StorageManagerTest extends DatabaseTest
|
||||||
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
$profiler->shouldReceive('saveTimestamp')->withAnyArgs()->andReturn(true);
|
||||||
|
|
||||||
// load real config to avoid mocking every config-entry which is related to the Database class
|
// load real config to avoid mocking every config-entry which is related to the Database class
|
||||||
$configFactory = new Config();
|
$configFactory = new Config();
|
||||||
$loader = $configFactory->createConfigFileLoader($this->root->url(), []);
|
$configFileManager = $configFactory->createConfigFileManager($this->root->url());
|
||||||
$configCache = $configFactory->createCache($loader);
|
$configCache = $configFactory->createCache($configFileManager);
|
||||||
|
|
||||||
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
|
$dbaDefinition = (new DbaDefinition($configCache->get('system', 'basepath')))->load();
|
||||||
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
|
$viewDefinition = (new ViewDefinition($configCache->get('system', 'basepath')))->load();
|
||||||
|
|
||||||
$this->dba = new StaticDatabase($configCache, $profiler, $dbaDefinition, $viewDefinition);
|
$this->dba = new StaticDatabase($configCache, $profiler, $dbaDefinition, $viewDefinition);
|
||||||
|
|
||||||
$this->config = new \Friendica\Core\Config\Model\Config($loader, $configCache);
|
$this->config = new \Friendica\Core\Config\Model\Config($configFileManager, $configCache);
|
||||||
$this->config->set('storage', 'name', 'Database');
|
$this->config->set('storage', 'name', 'Database');
|
||||||
$this->config->set('storage', 'filesystem_path', $this->root->getChild(Type\FilesystemConfig::DEFAULT_BASE_FOLDER)->url());
|
$this->config->set('storage', 'filesystem_path', $this->root->getChild(Type\FilesystemConfig::DEFAULT_BASE_FOLDER)
|
||||||
|
->url());
|
||||||
|
|
||||||
$this->l10n = \Mockery::mock(L10n::class);
|
$this->l10n = \Mockery::mock(L10n::class);
|
||||||
}
|
}
|
||||||
|
@ -113,21 +115,21 @@ class StorageManagerTest extends DatabaseTest
|
||||||
public function dataStorages()
|
public function dataStorages()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'empty' => [
|
'empty' => [
|
||||||
'name' => '',
|
'name' => '',
|
||||||
'valid' => false,
|
'valid' => false,
|
||||||
'interface' => ICanReadFromStorage::class,
|
'interface' => ICanReadFromStorage::class,
|
||||||
'assert' => null,
|
'assert' => null,
|
||||||
'assertName' => '',
|
'assertName' => '',
|
||||||
],
|
],
|
||||||
'database' => [
|
'database' => [
|
||||||
'name' => Type\Database::NAME,
|
'name' => Type\Database::NAME,
|
||||||
'valid' => true,
|
'valid' => true,
|
||||||
'interface' => ICanWriteToStorage::class,
|
'interface' => ICanWriteToStorage::class,
|
||||||
'assert' => Type\Database::class,
|
'assert' => Type\Database::class,
|
||||||
'assertName' => Type\Database::NAME,
|
'assertName' => Type\Database::NAME,
|
||||||
],
|
],
|
||||||
'filesystem' => [
|
'filesystem' => [
|
||||||
'name' => Filesystem::NAME,
|
'name' => Filesystem::NAME,
|
||||||
'valid' => true,
|
'valid' => true,
|
||||||
'interface' => ICanWriteToStorage::class,
|
'interface' => ICanWriteToStorage::class,
|
||||||
|
@ -141,7 +143,7 @@ class StorageManagerTest extends DatabaseTest
|
||||||
'assert' => SystemResource::class,
|
'assert' => SystemResource::class,
|
||||||
'assertName' => SystemResource::NAME,
|
'assertName' => SystemResource::NAME,
|
||||||
],
|
],
|
||||||
'invalid' => [
|
'invalid' => [
|
||||||
'name' => 'invalid',
|
'name' => 'invalid',
|
||||||
'valid' => false,
|
'valid' => false,
|
||||||
'interface' => null,
|
'interface' => null,
|
||||||
|
|
Loading…
Reference in a new issue