]> git.mxchange.org Git - friendica.git/commitdiff
Adding ConfigFileSaver and tests
authorPhilipp Holzer <admin@philipp.info>
Sun, 24 Mar 2019 11:54:26 +0000 (12:54 +0100)
committerPhilipp Holzer <admin@philipp.info>
Sun, 24 Mar 2019 12:47:35 +0000 (13:47 +0100)
24 files changed:
mod/admin.php
src/App.php
src/Core/Config/Cache/ConfigCache.php
src/Core/Console/AutomaticInstallation.php
src/Factory/ConfigFactory.php
src/Factory/DependencyFactory.php
src/Util/Config/ConfigCacheLoader.php [deleted file]
src/Util/Config/ConfigCacheManager.php [deleted file]
src/Util/Config/ConfigCacheSaver.php [deleted file]
src/Util/Config/ConfigFileLoader.php [new file with mode: 0644]
src/Util/Config/ConfigFileManager.php [new file with mode: 0644]
src/Util/Config/ConfigFileSaver.php [new file with mode: 0644]
tests/DatabaseTest.php
tests/datasets/config/.htconfig.test.php [deleted file]
tests/datasets/config/local.config.php
tests/datasets/config/local.ini.php
tests/include/ApiTest.php
tests/src/Database/DBATest.php
tests/src/Database/DBStructureTest.php
tests/src/Util/Config/ConfigCacheLoaderTest.php [deleted file]
tests/src/Util/Config/ConfigCacheSaverTest.php [deleted file]
tests/src/Util/Config/ConfigFileLoaderTest.php [new file with mode: 0644]
tests/src/Util/Config/ConfigFileSaverTest.php [new file with mode: 0644]
update.php

index 7808a87ef84c38ff0a3601151c5b6d8c70cf5a83..851dd0b093eb1a146cf6b5fa5ec5c83529b77bbb 100644 (file)
@@ -1087,8 +1087,9 @@ function admin_page_site_post(App $a)
                update_table($a, "gcontact", ['connect', 'addr'], $old_host, $new_host);
 
                // update config
-               $configCacheSaver = new \Friendica\Util\Config\ConfigCacheSaver($a->getBasePath());
-               $configCacheSaver->saveToConfigFile('system', 'hostname', parse_url($new_url, PHP_URL_HOST));
+               $configFileSaver = new \Friendica\Util\Config\ConfigFileSaver($a->getBasePath());
+               $configFileSaver->addConfigValue('system', 'hostname', parse_url($new_url, PHP_URL_HOST));
+               $configFileSaver->saveToConfigFile();
                Config::set('system', 'hostname', parse_url($new_url, PHP_URL_HOST));
                Config::set('system', 'url', $new_url);
                $a->setBaseURL($new_url);
index 7c88f0f02152b6b66b8aaf90406dd451e0642132..3a96182b1e25fa6d7e8804f140ae07cbb7c5e98c 100644 (file)
@@ -13,7 +13,7 @@ use Friendica\Core\Config\Configuration;
 use Friendica\Database\DBA;
 use Friendica\Model\Profile;
 use Friendica\Network\HTTPException\InternalServerErrorException;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 use Friendica\Util\HTTPSignature;
 use Friendica\Util\Profiler;
 use Psr\Log\LoggerInterface;
@@ -355,7 +355,7 @@ class App
                $this->getMode()->determine($this->getBasePath());
 
                if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
-                       $loader = new ConfigCacheLoader($this->getBasePath(), $this->getMode());
+                       $loader = new ConfigFileLoader($this->getBasePath(), $this->getMode());
                        $this->config->getCache()->load($loader->loadCoreConfig('addon'), true);
 
                        $this->profiler->update(
@@ -363,7 +363,7 @@ class App
                                $this->config->get('rendertime', 'callstack', false));
 
                        Core\Hook::loadHooks();
-                       $loader = new ConfigCacheLoader($this->getBasePath(), $this->mode);
+                       $loader = new ConfigFileLoader($this->getBasePath(), $this->mode);
                        Core\Hook::callAll('load_config', $loader);
                }
 
index cb299eb330956624e41eff564a074bd3973b0ed2..f61865cee627a6e310ed8474586584c83702361b 100644 (file)
@@ -5,7 +5,7 @@ namespace Friendica\Core\Config\Cache;
 /**
  * The Friendica config cache for the application
  * Initial, all *.config.php files are loaded into this cache with the
- * ConfigCacheLoader ( @see ConfigCacheLoader )
+ * ConfigFileLoader ( @see ConfigFileLoader )
  */
 class ConfigCache implements IConfigCache, IPConfigCache
 {
index 0c73c82b1b670297c95cc2ee043247b980cd74f4..911c1c00a8b732d958e24794fcf453c820e6c15d 100644 (file)
@@ -7,7 +7,7 @@ use Friendica\BaseObject;
 use Friendica\Core\Config;
 use Friendica\Core\Installer;
 use Friendica\Core\Theme;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 use RuntimeException;
 
 class AutomaticInstallation extends Console
@@ -104,8 +104,8 @@ HELP;
                        }
 
                        //reload the config cache
-                       $loader = new ConfigCacheLoader($a->getBasePath(), $a->getMode());
-                       $loader->loadConfigFiles($configCache);
+                       $loader = new ConfigFileLoader($a->getBasePath(), $a->getMode());
+                       $loader->setupCache($configCache);
 
                } else {
                        // Creating config file
index 7a281d97a54980840f0484c0879812ee0cb6e175..1f9662bddbdf1f15095c9f7dcc86ac4fc8c816ec 100644 (file)
@@ -6,19 +6,19 @@ use Friendica\Core;
 use Friendica\Core\Config;
 use Friendica\Core\Config\Adapter;
 use Friendica\Core\Config\Cache;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 
 class ConfigFactory
 {
        /**
-        * @param ConfigCacheLoader $loader The Config Cache loader (INI/config/.htconfig)
+        * @param ConfigFileLoader $loader The Config Cache loader (INI/config/.htconfig)
         *
         * @return Cache\ConfigCache
         */
-       public static function createCache(ConfigCacheLoader $loader)
+       public static function createCache(ConfigFileLoader $loader)
        {
                $configCache = new Cache\ConfigCache();
-               $loader->loadConfigFiles($configCache);
+               $loader->setupCache($configCache);
 
                return $configCache;
        }
index 9322a44cfe69e5894aae976a95e2727a97dafa89..65bdf37140a4ebc232d55932a21a4b89eddfdd09 100644 (file)
@@ -24,7 +24,7 @@ class DependencyFactory
        {
                $basePath = BasePath::create($directory, $_SERVER);
                $mode = new App\Mode($basePath);
-               $configLoader = new Config\ConfigCacheLoader($basePath, $mode);
+               $configLoader = new Config\ConfigFileLoader($basePath, $mode);
                $configCache = Factory\ConfigFactory::createCache($configLoader);
                $profiler = Factory\ProfilerFactory::create($configCache);
                Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
diff --git a/src/Util/Config/ConfigCacheLoader.php b/src/Util/Config/ConfigCacheLoader.php
deleted file mode 100644 (file)
index 6eced06..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-<?php
-
-namespace Friendica\Util\Config;
-
-use Friendica\App;
-use Friendica\Core\Addon;
-use Friendica\Core\Config\Cache\IConfigCache;
-
-/**
- * The ConfigCacheLoader loads config-files and stores them in a IConfigCache ( @see IConfigCache )
- *
- * It is capable of loading the following config files:
- * - *.config.php   (current)
- * - *.ini.php      (deprecated)
- * - *.htconfig.php (deprecated)
- */
-class ConfigCacheLoader extends ConfigCacheManager
-{
-       /**
-        * @var App\Mode
-        */
-       private $appMode;
-
-       public function __construct($baseDir, App\Mode $mode)
-       {
-               parent::__construct($baseDir);
-               $this->appMode = $mode;
-       }
-
-       /**
-        * Load the configuration files
-        *
-        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
-        * expected local.config.php
-        *
-        * @param IConfigCache The config cache to load to
-        *
-        * @throws \Exception
-        */
-       public function loadConfigFiles(IConfigCache $config)
-       {
-               $config->load($this->loadCoreConfig('defaults'));
-               $config->load($this->loadCoreConfig('settings'));
-
-               $config->load($this->loadLegacyConfig('htpreconfig'), true);
-               $config->load($this->loadLegacyConfig('htconfig'), true);
-
-               $config->load($this->loadCoreConfig('local'), true);
-
-               // In case of install mode, add the found basepath (because there isn't a basepath set yet
-               if ($this->appMode->isInstall()) {
-                       // Setting at least the basepath we know
-                       $config->set('system', 'basepath', $this->baseDir);
-               }
-       }
-
-       /**
-        * Tries to load the specified core-configuration and returns the config array.
-        *
-        * @param string $name The name of the configuration (default is empty, which means 'local')
-        *
-        * @return array The config array (empty if no config found)
-        *
-        * @throws \Exception if the configuration file isn't readable
-        */
-       public function loadCoreConfig($name = '')
-       {
-               if (!empty($this->getConfigFullName($name))) {
-                       return $this->loadConfigFile($this->getConfigFullName($name));
-               } elseif (!empty($this->getIniFullName($name))) {
-                       return $this->loadINIConfigFile($this->getIniFullName($name));
-               } else {
-                       return [];
-               }
-       }
-
-       /**
-        * Tries to load the specified addon-configuration and returns the config array.
-        *
-        * @param string $name The name of the configuration
-        *
-        * @return array The config array (empty if no config found)
-        *
-        * @throws \Exception if the configuration file isn't readable
-        */
-       public function loadAddonConfig($name)
-       {
-               $filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
-                       Addon::DIRECTORY       . DIRECTORY_SEPARATOR . // addon/
-                       $name                  . DIRECTORY_SEPARATOR . // openstreetmap/
-                       self::SUBDIRECTORY     . DIRECTORY_SEPARATOR . // config/
-                       $name . ".config.php";                         // openstreetmap.config.php
-
-               if (file_exists($filepath)) {
-                       return $this->loadConfigFile($filepath);
-               } else {
-                       return [];
-               }
-       }
-
-       /**
-        * Tries to load the legacy config files (.htconfig.php, .htpreconfig.php) and returns the config array.
-        *
-        * @param string $name The name of the config file (default is empty, which means .htconfig.php)
-        *
-        * @return array The configuration array (empty if no config found)
-        *
-        * @deprecated since version 2018.09
-        */
-       private function loadLegacyConfig($name = '')
-       {
-               $config = [];
-               if (!empty($this->getHtConfigFullName($name))) {
-                       $a = new \stdClass();
-                       $a->config = [];
-                       include $this->getHtConfigFullName($name);
-
-                       $htConfigCategories = array_keys($a->config);
-
-                       // map the legacy configuration structure to the current structure
-                       foreach ($htConfigCategories as $htConfigCategory) {
-                               if (is_array($a->config[$htConfigCategory])) {
-                                       $keys = array_keys($a->config[$htConfigCategory]);
-
-                                       foreach ($keys as $key) {
-                                               $config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
-                                       }
-                               } else {
-                                       $config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
-                               }
-                       }
-
-                       unset($a);
-
-                       if (isset($db_host)) {
-                               $config['database']['hostname'] = $db_host;
-                               unset($db_host);
-                       }
-                       if (isset($db_user)) {
-                               $config['database']['username'] = $db_user;
-                               unset($db_user);
-                       }
-                       if (isset($db_pass)) {
-                               $config['database']['password'] = $db_pass;
-                               unset($db_pass);
-                       }
-                       if (isset($db_data)) {
-                               $config['database']['database'] = $db_data;
-                               unset($db_data);
-                       }
-                       if (isset($config['system']['db_charset'])) {
-                               $config['database']['charset'] = $config['system']['db_charset'];
-                       }
-                       if (isset($pidfile)) {
-                               $config['system']['pidfile'] = $pidfile;
-                               unset($pidfile);
-                       }
-                       if (isset($default_timezone)) {
-                               $config['system']['default_timezone'] = $default_timezone;
-                               unset($default_timezone);
-                       }
-                       if (isset($lang)) {
-                               $config['system']['language'] = $lang;
-                               unset($lang);
-                       }
-               }
-
-               return $config;
-       }
-
-       /**
-        * Tries to load the specified legacy configuration file and returns the config array.
-        *
-        * @deprecated since version 2018.12
-        * @param string $filepath
-        *
-        * @return array The configuration array
-        * @throws \Exception
-        */
-       private function loadINIConfigFile($filepath)
-       {
-               $contents = include($filepath);
-
-               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
-
-               if ($config === false) {
-                       throw new \Exception('Error parsing INI config file ' . $filepath);
-               }
-
-               return $config;
-       }
-
-       /**
-        * Tries to load the specified configuration file and returns the config array.
-        *
-        * The config format is PHP array and the template for configuration files is the following:
-        *
-        * <?php return [
-        *      'section' => [
-        *          'key' => 'value',
-        *      ],
-        * ];
-        *
-        * @param  string $filepath The filepath of the
-        * @return array The config array0
-        *
-        * @throws \Exception if the config cannot get loaded.
-        */
-       private function loadConfigFile($filepath)
-       {
-               $config = include($filepath);
-
-               if (!is_array($config)) {
-                       throw new \Exception('Error loading config file ' . $filepath);
-               }
-
-               return $config;
-       }
-}
diff --git a/src/Util/Config/ConfigCacheManager.php b/src/Util/Config/ConfigCacheManager.php
deleted file mode 100644 (file)
index 8fb9232..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-namespace Friendica\Util\Config;
-
-abstract class ConfigCacheManager
-{
-       /**
-        * The Sub directory of the config-files
-        * @var string
-        */
-       const SUBDIRECTORY = 'config';
-
-       /**
-        * The default name of the user defined config file
-        * @var string
-        */
-       const CONFIG_LOCAL    = 'local';
-
-       /**
-        * The default name of the user defined ini file
-        * @var string
-        */
-       const CONFIG_INI      = 'ini';
-
-       /**
-        * The default name of the user defined legacy config file
-        * @var string
-        */
-       const CONFIG_HTCONFIG = 'htconfig';
-
-       protected $baseDir;
-       protected $configDir;
-
-       /**
-        * @param string $baseDir The base directory of Friendica
-        */
-       public function __construct($baseDir)
-       {
-               $this->baseDir = $baseDir;
-               $this->configDir = $baseDir . DIRECTORY_SEPARATOR . self::SUBDIRECTORY;
-       }
-
-       /**
-        * Gets the full name (including the path) for a *.config.php (default is local.config.php)
-        *
-        * @param string $name The config name (default is empty, which means local.config.php)
-        *
-        * @return string The full name or empty if not found
-        */
-       protected function getConfigFullName($name = '')
-       {
-               $name = !empty($name) ? $name : self::CONFIG_LOCAL;
-
-               $fullName = $this->configDir . DIRECTORY_SEPARATOR . $name . '.config.php';
-               return file_exists($fullName) ? $fullName : '';
-       }
-
-       /**
-        * Gets the full name (including the path) for a *.ini.php (default is local.ini.php)
-        *
-        * @param string $name The config name (default is empty, which means local.ini.php)
-        *
-        * @return string The full name or empty if not found
-        */
-       protected function getIniFullName($name = '')
-       {
-               $name = !empty($name) ? $name : self::CONFIG_INI;
-
-               $fullName = $this->configDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
-               return file_exists($fullName) ? $fullName : '';
-       }
-
-       /**
-        * Gets the full name (including the path) for a .*.php (default is .htconfig.php)
-        *
-        * @param string $name The config name (default is empty, which means .htconfig.php)
-        *
-        * @return string The full name or empty if not found
-        */
-       protected function getHtConfigFullName($name = '')
-       {
-               $name = !empty($name) ? $name : self::CONFIG_HTCONFIG;
-
-               $fullName = $this->baseDir  . DIRECTORY_SEPARATOR . '.' . $name . '.php';
-               return file_exists($fullName) ? $fullName : '';
-       }
-}
diff --git a/src/Util/Config/ConfigCacheSaver.php b/src/Util/Config/ConfigCacheSaver.php
deleted file mode 100644 (file)
index 41ebca1..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-<?php
-
-namespace Friendica\Util\Config;
-
-/**
- * The ConfigCacheSaver saves specific variables back from the ConfigCache (@see ConfigCache )
- * into the config-files
- *
- * It is capable of loading the following config files:
- * - *.config.php   (current)
- * - *.ini.php      (deprecated)
- * - *.htconfig.php (deprecated)
- */
-class ConfigCacheSaver extends ConfigCacheManager
-{
-       /**
-        * The standard indentation for config files
-        * @var string
-        */
-       const INDENT = "\t";
-
-       /**
-        * The settings array to save to
-        * @var array
-        */
-       private $settings = [];
-
-       /**
-        * Adds a given value to the config file
-        * Either it replaces the current value or it will get added
-        *
-        * @param string $cat   The configuration category
-        * @param string $key   The configuration key
-        * @param string $value The new value
-        */
-       public function addConfigValue($cat, $key, $value)
-       {
-               $this->settings[$cat][$key] = $value;
-       }
-
-       public function reset()
-       {
-               $this->settings = [];
-       }
-
-       public function saveToConfigFile($name = '')
-       {
-               $saved = false;
-
-               if (!empty($this->getConfigFullName($name))) {
-                       $this->saveConfigFile($this->getConfigFullName($name));
-                       $saved = true;
-               }
-
-               if (!empty($this->getIniFullName($name))) {
-                       $this->saveINIConfigFile($this->getIniFullName($name));
-                       $saved = true;
-               }
-
-               if (!empty($this->getHtConfigFullName($name))) {
-                       $this->saveToLegacyConfig($this->getHtConfigFullName($name));
-                       $saved = true;
-               }
-
-               return $saved;
-       }
-
-       /**
-        * Saves a value to either an config or an ini file
-        *
-        * @param string $name  The configuration file name ('local', 'addon', ..)
-        * @param string $cat   The configuration category
-        * @param string $key   The configuration key
-        * @param string $value The new value
-        */
-       private function saveToCoreConfig($name, $cat, $key, $value)
-       {
-               if (!empty($this->getConfigFullName($name))) {
-                       $this->saveConfigFile($this->getConfigFullName($name), $cat, $key, $value);
-               } elseif (!empty($this->getIniFullName($name))) {
-                       $this->saveINIConfigFile($this->getIniFullName($name), $cat, $key, $value);
-               } else {
-                       return;
-               }
-       }
-
-       /**
-        * Saves a value to a config file
-        *
-        * @param string $fullName The configuration full name (including the path)
-        * @param string $cat   The configuration category
-        * @param string $key   The configuration key
-        * @param string $value The new value
-        *
-        * @throws \Exception In case a file operation doesn't work
-        */
-       private function saveConfigFile($fullName, $cat, $key, $value)
-       {
-               $reading = fopen($fullName, 'r');
-               if (!$reading) {
-                       throw new \Exception('Cannot open config file \'' . $fullName . '\'.');
-               }
-               $writing = fopen($fullName . '.tmp', 'w');
-               if (!$writing) {
-                       throw new \Exception('Cannot create temporary config file \'' . $fullName . '.tmp\'.');
-               }
-               $categoryFound = false;
-               $categoryBracketFound = false;
-               $lineFound = false;
-               $lineArrowFound = false;
-               while (!feof($reading)) {
-                       $line = fgets($reading);
-                       // find the first line like "'system' =>"
-                       if (!$categoryFound && stristr($line, sprintf('\'%s\'', $cat))) {
-                               $categoryFound = true;
-                       }
-                       // find the first line with a starting bracket ( "[" )
-                       if ($categoryFound && !$categoryBracketFound && stristr($line, '[')) {
-                               $categoryBracketFound = true;
-                       }
-                       // find the first line with the key like "'value'"
-                       if ($categoryBracketFound && !$lineFound && stristr($line, sprintf('\'%s\'', $key))) {
-                               $lineFound = true;
-                       }
-                       // find the first line with an arrow ("=>") after finding the key
-                       if ($lineFound && !$lineArrowFound && stristr($line, '=>')) {
-                               $lineArrowFound = true;
-                       }
-                       // find the current value and replace it
-                       if ($lineArrowFound && preg_match_all('/\'(.*?)\'/', $line, $matches, PREG_SET_ORDER)) {
-                               $lineVal = end($matches)[0];
-                               $writeLine = str_replace($lineVal, '\'' . $value . '\'', $line);
-                               $categoryFound = false;
-                               $categoryBracketFound = false;
-                               $lineFound = false;
-                               $lineArrowFound = false;
-                               // if a line contains a closing bracket for the category ( "]" ) and we didn't find the key/value pair,
-                               // add it as a new line before the closing bracket
-                       } elseif ($categoryBracketFound && !$lineArrowFound && stristr($line, ']')) {
-                               $categoryFound = false;
-                               $categoryBracketFound = false;
-                               $lineFound = false;
-                               $lineArrowFound = false;
-                               $writeLine = sprintf(self::INDENT . self::INDENT .'\'%s\' => \'%s\',' . PHP_EOL, $key, $value);
-                               $writeLine .= $line;
-                       } else {
-                               $writeLine = $line;
-                       }
-                       fputs($writing, $writeLine);
-               }
-               if (!fclose($reading)) {
-                       throw new \Exception('Cannot close config file \'' . $fullName . '\'.');
-               };
-               if (!fclose($writing)) {
-                       throw new \Exception('Cannot close temporary config file \'' . $fullName . '.tmp\'.');
-               };
-               if (!rename($fullName, $fullName . '.old')) {
-                       throw new \Exception('Cannot backup current config file \'' . $fullName . '\'.');
-               }
-               if (!rename($fullName . '.tmp', $fullName)) {
-                       throw new \Exception('Cannot move temporary config file \'' . $fullName . '.tmp\' to current.');
-               }
-       }
-
-       /**
-        * Saves a value to a ini file
-        *
-        * @param string $fullName The configuration full name (including the path)
-        * @param string $cat   The configuration category
-        * @param string $key   The configuration key
-        * @param string $value The new value
-        */
-       private function saveINIConfigFile($fullName, $cat, $key, $value)
-       {
-               $reading = fopen($fullName, 'r');
-               $writing = fopen($fullName . '.tmp', 'w');
-               $categoryFound = false;
-               while (!feof($reading)) {
-                       $line = fgets($reading);
-                       if (!$categoryFound && stristr($line, sprintf('[%s]', $cat))) {
-                               $categoryFound = true;
-                               $writeLine = $line;
-                       } elseif ($categoryFound && preg_match_all('/^' . $key . '\s*=\s*(.*?)$/', $line, $matches, PREG_SET_ORDER)) {
-                               $writeLine = $key . ' = ' . $value . PHP_EOL;
-                               $categoryFound = false;
-                       } elseif ($categoryFound && (preg_match_all('/^\[.*?\]$/', $line) || preg_match_all('/^INI;.*$/', $line))) {
-                               $categoryFound = false;
-                               $writeLine = $key . ' = ' .  $value . PHP_EOL;
-                               $writeLine .= $line;
-                       } else {
-                               $writeLine = $line;
-                       }
-                       fputs($writing, $writeLine);
-               }
-               fclose($reading);
-               fclose($writing);
-               rename($fullName, $fullName . '.old');
-               rename($fullName . '.tmp', $fullName);
-       }
-
-       private function saveToLegacyConfig($name, $cat, $key, $value)
-       {
-               if (empty($this->getHtConfigFullName($name))) {
-                       return;
-               }
-               $fullName = $this->getHtConfigFullName($name);
-               $reading = fopen($fullName, 'r');
-               $writing = fopen($fullName . '.tmp', 'w');
-               $found = false;
-               while (!feof($reading)) {
-                       $line = fgets($reading);
-                       if (preg_match_all('/^\$a\-\>config\[\'' . $cat . '\',\'' . $key . '\'\]\s*=\s\'*(.*?)\'$/', $line, $matches, PREG_SET_ORDER)) {
-                               $writeLine = $key . ' = ' . $value . PHP_EOL;
-                               $found = true;
-                       } else {
-                               $writeLine = $line;
-                       }
-                       fputs($writing, $writeLine);
-               }
-               if (!$found) {
-                       $writeLine = $key . ' = ' . $value . PHP_EOL;
-                       fputs($writing, $writeLine);
-               }
-               fclose($reading);
-               fclose($writing);
-               rename($fullName, $fullName . '.old');
-               rename($fullName . '.tmp', $fullName);
-       }
-}
diff --git a/src/Util/Config/ConfigFileLoader.php b/src/Util/Config/ConfigFileLoader.php
new file mode 100644 (file)
index 0000000..67a44a0
--- /dev/null
@@ -0,0 +1,219 @@
+<?php
+
+namespace Friendica\Util\Config;
+
+use Friendica\App;
+use Friendica\Core\Addon;
+use Friendica\Core\Config\Cache\IConfigCache;
+
+/**
+ * The ConfigFileLoader loads config-files and stores them in a IConfigCache ( @see IConfigCache )
+ *
+ * It is capable of loading the following config files:
+ * - *.config.php   (current)
+ * - *.ini.php      (deprecated)
+ * - *.htconfig.php (deprecated)
+ */
+class ConfigFileLoader extends ConfigFileManager
+{
+       /**
+        * @var App\Mode
+        */
+       private $appMode;
+
+       public function __construct($baseDir, App\Mode $mode)
+       {
+               parent::__construct($baseDir);
+               $this->appMode = $mode;
+       }
+
+       /**
+        * Load the configuration files into an configuration cache
+        *
+        * First loads the default value for all the configuration keys, then the legacy configuration files, then the
+        * expected local.config.php
+        *
+        * @param IConfigCache The config cache to load to
+        *
+        * @throws \Exception
+        */
+       public function setupCache(IConfigCache $config)
+       {
+               $config->load($this->loadCoreConfig('defaults'));
+               $config->load($this->loadCoreConfig('settings'));
+
+               $config->load($this->loadLegacyConfig('htpreconfig'), true);
+               $config->load($this->loadLegacyConfig('htconfig'), true);
+
+               $config->load($this->loadCoreConfig('local'), true);
+
+               // In case of install mode, add the found basepath (because there isn't a basepath set yet
+               if ($this->appMode->isInstall()) {
+                       // Setting at least the basepath we know
+                       $config->set('system', 'basepath', $this->baseDir);
+               }
+       }
+
+       /**
+        * Tries to load the specified core-configuration and returns the config array.
+        *
+        * @param string $name The name of the configuration (default is empty, which means 'local')
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws \Exception if the configuration file isn't readable
+        */
+       public function loadCoreConfig($name = '')
+       {
+               if (!empty($this->getConfigFullName($name))) {
+                       return $this->loadConfigFile($this->getConfigFullName($name));
+               } elseif (!empty($this->getIniFullName($name))) {
+                       return $this->loadINIConfigFile($this->getIniFullName($name));
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the specified addon-configuration and returns the config array.
+        *
+        * @param string $name The name of the configuration
+        *
+        * @return array The config array (empty if no config found)
+        *
+        * @throws \Exception if the configuration file isn't readable
+        */
+       public function loadAddonConfig($name)
+       {
+               $filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
+                       Addon::DIRECTORY       . DIRECTORY_SEPARATOR . // addon/
+                       $name                  . DIRECTORY_SEPARATOR . // openstreetmap/
+                       self::SUBDIRECTORY     . DIRECTORY_SEPARATOR . // config/
+                       $name . ".config.php";                         // openstreetmap.config.php
+
+               if (file_exists($filepath)) {
+                       return $this->loadConfigFile($filepath);
+               } else {
+                       return [];
+               }
+       }
+
+       /**
+        * Tries to load the legacy config files (.htconfig.php, .htpreconfig.php) and returns the config array.
+        *
+        * @param string $name The name of the config file (default is empty, which means .htconfig.php)
+        *
+        * @return array The configuration array (empty if no config found)
+        *
+        * @deprecated since version 2018.09
+        */
+       private function loadLegacyConfig($name = '')
+       {
+               $config = [];
+               if (!empty($this->getHtConfigFullName($name))) {
+                       $a = new \stdClass();
+                       $a->config = [];
+                       include $this->getHtConfigFullName($name);
+
+                       $htConfigCategories = array_keys($a->config);
+
+                       // map the legacy configuration structure to the current structure
+                       foreach ($htConfigCategories as $htConfigCategory) {
+                               if (is_array($a->config[$htConfigCategory])) {
+                                       $keys = array_keys($a->config[$htConfigCategory]);
+
+                                       foreach ($keys as $key) {
+                                               $config[$htConfigCategory][$key] = $a->config[$htConfigCategory][$key];
+                                       }
+                               } else {
+                                       $config['config'][$htConfigCategory] = $a->config[$htConfigCategory];
+                               }
+                       }
+
+                       unset($a);
+
+                       if (isset($db_host)) {
+                               $config['database']['hostname'] = $db_host;
+                               unset($db_host);
+                       }
+                       if (isset($db_user)) {
+                               $config['database']['username'] = $db_user;
+                               unset($db_user);
+                       }
+                       if (isset($db_pass)) {
+                               $config['database']['password'] = $db_pass;
+                               unset($db_pass);
+                       }
+                       if (isset($db_data)) {
+                               $config['database']['database'] = $db_data;
+                               unset($db_data);
+                       }
+                       if (isset($config['system']['db_charset'])) {
+                               $config['database']['charset'] = $config['system']['db_charset'];
+                       }
+                       if (isset($pidfile)) {
+                               $config['system']['pidfile'] = $pidfile;
+                               unset($pidfile);
+                       }
+                       if (isset($default_timezone)) {
+                               $config['system']['default_timezone'] = $default_timezone;
+                               unset($default_timezone);
+                       }
+                       if (isset($lang)) {
+                               $config['system']['language'] = $lang;
+                               unset($lang);
+                       }
+               }
+
+               return $config;
+       }
+
+       /**
+        * Tries to load the specified legacy configuration file and returns the config array.
+        *
+        * @deprecated since version 2018.12
+        * @param string $filepath
+        *
+        * @return array The configuration array
+        * @throws \Exception
+        */
+       private function loadINIConfigFile($filepath)
+       {
+               $contents = include($filepath);
+
+               $config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
+
+               if ($config === false) {
+                       throw new \Exception('Error parsing INI config file ' . $filepath);
+               }
+
+               return $config;
+       }
+
+       /**
+        * Tries to load the specified configuration file and returns the config array.
+        *
+        * The config format is PHP array and the template for configuration files is the following:
+        *
+        * <?php return [
+        *      'section' => [
+        *          'key' => 'value',
+        *      ],
+        * ];
+        *
+        * @param  string $filepath The filepath of the
+        * @return array The config array0
+        *
+        * @throws \Exception if the config cannot get loaded.
+        */
+       private function loadConfigFile($filepath)
+       {
+               $config = include($filepath);
+
+               if (!is_array($config)) {
+                       throw new \Exception('Error loading config file ' . $filepath);
+               }
+
+               return $config;
+       }
+}
diff --git a/src/Util/Config/ConfigFileManager.php b/src/Util/Config/ConfigFileManager.php
new file mode 100644 (file)
index 0000000..729e59d
--- /dev/null
@@ -0,0 +1,90 @@
+<?php
+
+namespace Friendica\Util\Config;
+
+/**
+ * An abstract class in case of handling with config files
+ */
+abstract class ConfigFileManager
+{
+       /**
+        * The Sub directory of the config-files
+        * @var string
+        */
+       const SUBDIRECTORY = 'config';
+
+       /**
+        * The default name of the user defined config file
+        * @var string
+        */
+       const CONFIG_LOCAL    = 'local';
+
+       /**
+        * The default name of the user defined ini file
+        * @var string
+        */
+       const CONFIG_INI      = 'local';
+
+       /**
+        * The default name of the user defined legacy config file
+        * @var string
+        */
+       const CONFIG_HTCONFIG = 'htconfig';
+
+       protected $baseDir;
+       protected $configDir;
+
+       /**
+        * @param string $baseDir The base directory of Friendica
+        */
+       public function __construct($baseDir)
+       {
+               $this->baseDir = $baseDir;
+               $this->configDir = $baseDir . DIRECTORY_SEPARATOR . self::SUBDIRECTORY;
+       }
+
+       /**
+        * Gets the full name (including the path) for a *.config.php (default is local.config.php)
+        *
+        * @param string $name The config name (default is empty, which means local.config.php)
+        *
+        * @return string The full name or empty if not found
+        */
+       protected function getConfigFullName($name = '')
+       {
+               $name = !empty($name) ? $name : self::CONFIG_LOCAL;
+
+               $fullName = $this->configDir . DIRECTORY_SEPARATOR . $name . '.config.php';
+               return file_exists($fullName) ? $fullName : '';
+       }
+
+       /**
+        * Gets the full name (including the path) for a *.ini.php (default is local.ini.php)
+        *
+        * @param string $name The config name (default is empty, which means local.ini.php)
+        *
+        * @return string The full name or empty if not found
+        */
+       protected function getIniFullName($name = '')
+       {
+               $name = !empty($name) ? $name : self::CONFIG_INI;
+
+               $fullName = $this->configDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
+               return file_exists($fullName) ? $fullName : '';
+       }
+
+       /**
+        * Gets the full name (including the path) for a .*.php (default is .htconfig.php)
+        *
+        * @param string $name The config name (default is empty, which means .htconfig.php)
+        *
+        * @return string The full name or empty if not found
+        */
+       protected function getHtConfigFullName($name = '')
+       {
+               $name = !empty($name) ? $name : self::CONFIG_HTCONFIG;
+
+               $fullName = $this->baseDir  . DIRECTORY_SEPARATOR . '.' . $name . '.php';
+               return file_exists($fullName) ? $fullName : '';
+       }
+}
diff --git a/src/Util/Config/ConfigFileSaver.php b/src/Util/Config/ConfigFileSaver.php
new file mode 100644 (file)
index 0000000..2c12718
--- /dev/null
@@ -0,0 +1,294 @@
+<?php
+
+namespace Friendica\Util\Config;
+
+/**
+ * The ConfigFileSaver saves specific variables into the config-files
+ *
+ * It is capable of loading the following config files:
+ * - *.config.php   (current)
+ * - *.ini.php      (deprecated)
+ * - *.htconfig.php (deprecated)
+ */
+class ConfigFileSaver extends ConfigFileManager
+{
+       /**
+        * The standard indentation for config files
+        * @var string
+        */
+       const INDENT = "\t";
+
+       /**
+        * The settings array to save to
+        * @var array
+        */
+       private $settings = [];
+
+       /**
+        * Adds a given value to the config file
+        * Either it replaces the current value or it will get added
+        *
+        * @param string $cat   The configuration category
+        * @param string $key   The configuration key
+        * @param string $value The new value
+        */
+       public function addConfigValue($cat, $key, $value)
+       {
+               $this->settings[] = ['cat' => $cat, 'key' => $key, 'value' => $value];
+       }
+
+       /**
+        * Resetting all added configuration entries so far
+        */
+       public function reset()
+       {
+               $this->settings = [];
+       }
+
+       /**
+        * Save all added configuration entries to the given config files
+        * After updating the config entries, all configuration entries will be reseted
+        *
+        * @param string $name The name of the configuration file (default is empty, which means the default name each type)
+        *
+        * @return bool true, if at least one configuration file was successfully updated
+        */
+       public function saveToConfigFile($name = '')
+       {
+               $saved = false;
+
+               // Check for the *.config.php file inside the /config/ path
+               list($reading, $writing) = $this->openFile($this->getConfigFullName($name));
+               if (isset($reading) && isset($writing)) {
+                       $this->saveConfigFile($reading, $writing);
+                       // Close the current file handler and rename them
+                       if ($this->closeFile($this->getConfigFullName($name), $reading, $writing)) {
+                               // just return true, if everything went fine
+                               $saved = true;
+                       }
+               }
+
+               // Check for the *.ini.php file inside the /config/ path
+               list($reading, $writing) = $this->openFile($this->getIniFullName($name));
+               if (isset($reading) && isset($writing)) {
+                       $this->saveINIConfigFile($reading, $writing);
+                       // Close the current file handler and rename them
+                       if ($this->closeFile($this->getIniFullName($name), $reading, $writing)) {
+                               // just return true, if everything went fine
+                               $saved = true;
+                       }
+               }
+
+               // Check for the *.php file (normally .htconfig.php) inside the / path
+               list($reading, $writing) = $this->openFile($this->getHtConfigFullName($name));
+               if (isset($reading) && isset($writing)) {
+                       $this->saveToLegacyConfig($reading, $writing);
+                       // Close the current file handler and rename them
+                       if ($this->closeFile($this->getHtConfigFullName($name), $reading, $writing)) {
+                               // just return true, if everything went fine
+                               $saved = true;
+                       }
+               }
+
+               $this->reset();
+
+               return $saved;
+       }
+
+       /**
+        * Opens a config file and returns two handler for reading and writing
+        *
+        * @param string $fullName The full name of the current config
+        *
+        * @return array An array containing the two reading and writing handler
+        */
+       private function openFile($fullName)
+       {
+               if (empty($fullName)) {
+                       return [null, null];
+               }
+
+               $reading = fopen($fullName, 'r');
+
+               if (!$reading) {
+                       return [null, null];
+               }
+
+               $writing = fopen($fullName . '.tmp', 'w');
+
+               if (!$writing) {
+                       fclose($reading);
+                       return [null, null];
+               }
+
+               return [$reading, $writing];
+       }
+
+       /**
+        * Close and rename the config file
+        *
+        * @param string   $fullName The full name of the current config
+        * @param resource $reading  The reading resource handler
+        * @param resource $writing  The writing resource handler
+        *
+        * @return bool True, if the close was successful
+        */
+       private function closeFile($fullName, $reading, $writing)
+       {
+               fclose($reading);
+               fclose($writing);
+
+               if (!rename($fullName, $fullName . '.old')) {
+                       return false;
+               }
+
+               if (!rename($fullName . '.tmp', $fullName)) {
+                       // revert the move of the current config file to have at least the old config
+                       rename($fullName . '.old', $fullName);
+                       return false;
+               }
+
+               return true;
+       }
+
+       /**
+        * Saves all configuration values to a config file
+        *
+        * @param resource $reading The reading handler
+        * @param resource $writing The writing handler
+        */
+       private function saveConfigFile($reading, $writing)
+       {
+               $settingsCount = count(array_keys($this->settings));
+               $categoryFound = array_fill(0, $settingsCount, false);
+               $categoryBracketFound = array_fill(0, $settingsCount, false);;
+               $lineFound = array_fill(0, $settingsCount, false);;
+               $lineArrowFound = array_fill(0, $settingsCount, false);;
+
+               while (!feof($reading)) {
+
+                       $line = fgets($reading);
+
+                       // check for each added setting if we have to replace a config line
+                       for ($i = 0; $i < $settingsCount; $i++) {
+
+                               // find the first line like "'system' =>"
+                               if (!$categoryFound[$i] && stristr($line, sprintf('\'%s\'', $this->settings[$i]['cat']))) {
+                                       $categoryFound[$i] = true;
+                               }
+
+                               // find the first line with a starting bracket ( "[" )
+                               if ($categoryFound[$i] && !$categoryBracketFound[$i] && stristr($line, '[')) {
+                                       $categoryBracketFound[$i] = true;
+                               }
+
+                               // find the first line with the key like "'value'"
+                               if ($categoryBracketFound[$i] && !$lineFound[$i] && stristr($line, sprintf('\'%s\'', $this->settings[$i]['key']))) {
+                                       $lineFound[$i] = true;
+                               }
+
+                               // find the first line with an arrow ("=>") after finding the key
+                               if ($lineFound[$i] && !$lineArrowFound[$i] && stristr($line, '=>')) {
+                                       $lineArrowFound[$i] = true;
+                               }
+
+                               // find the current value and replace it
+                               if ($lineArrowFound[$i] && preg_match_all('/\'(.*?)\'/', $line, $matches, PREG_SET_ORDER)) {
+                                       $lineVal = end($matches)[0];
+                                       $line = str_replace($lineVal, '\'' . $this->settings[$i]['value'] . '\'', $line);
+                                       $categoryFound[$i] = false;
+                                       $categoryBracketFound[$i] = false;
+                                       $lineFound[$i] = false;
+                                       $lineArrowFound[$i] = false;
+                                       // if a line contains a closing bracket for the category ( "]" ) and we didn't find the key/value pair,
+                                       // add it as a new line before the closing bracket
+                               } elseif ($categoryBracketFound[$i] && !$lineArrowFound[$i] && stristr($line, ']')) {
+                                       $categoryFound[$i] = false;
+                                       $categoryBracketFound[$i] = false;
+                                       $lineFound[$i] = false;
+                                       $lineArrowFound[$i] = false;
+                                       $newLine = sprintf(self::INDENT . self::INDENT . '\'%s\' => \'%s\',' . PHP_EOL, $this->settings[$i]['key'], $this->settings[$i]['value']);
+                                       $line = $newLine . $line;
+                               }
+                       }
+
+                       fputs($writing, $line);
+               }
+       }
+
+       /**
+        * Saves a value to a ini file
+        *
+        * @param resource $reading The reading handler
+        * @param resource $writing The writing handler
+        */
+       private function saveINIConfigFile($reading, $writing)
+       {
+               $settingsCount = count(array_keys($this->settings));
+               $categoryFound = array_fill(0, $settingsCount, false);
+
+               while (!feof($reading)) {
+
+                       $line = fgets($reading);
+
+                       // check for each added setting if we have to replace a config line
+                       for ($i = 0; $i < $settingsCount; $i++) {
+
+                               if (!$categoryFound[$i] && stristr($line, sprintf('[%s]', $this->settings[$i]['cat']))) {
+                                       $categoryFound[$i] = true;
+                               } elseif ($categoryFound[$i] && preg_match_all('/^' . $this->settings[$i]['key'] . '\s*=\s*(.*?)$/', $line, $matches, PREG_SET_ORDER)) {
+                                       $line = $this->settings[$i]['key'] . ' = ' . $this->settings[$i]['value'] . PHP_EOL;
+                                       $categoryFound[$i] = false;
+                               } elseif ($categoryFound[$i] && (preg_match_all('/^\[.*?\]$/', $line) || preg_match_all('/^INI;.*$/', $line))) {
+                                       $categoryFound[$i] = false;
+                                       $newLine = $this->settings[$i]['key'] . ' = ' . $this->settings[$i]['value'] . PHP_EOL;
+                                       $line = $newLine . $line;
+                               }
+                       }
+
+                       fputs($writing, $line);
+               }
+       }
+
+       /**
+        * Saves a value to a .php file (normally .htconfig.php)
+        *
+        * @param resource $reading The reading handler
+        * @param resource $writing The writing handler
+        */
+       private function saveToLegacyConfig($reading, $writing)
+       {
+               $settingsCount = count(array_keys($this->settings));
+               $found  = array_fill(0, $settingsCount, false);
+               while (!feof($reading)) {
+
+                       $line = fgets($reading);
+
+                       // check for each added setting if we have to replace a config line
+                       for ($i = 0; $i < $settingsCount; $i++) {
+
+                               if ($this->settings[$i]['cat'] !== 'config' && preg_match_all('/^\$a\-\>config\[\'' . $this->settings[$i]['cat'] . '\'\]\[\'' . $this->settings[$i]['key'] . '\'\]\s*=\s\'*(.*?)\';$/', $line, $matches, PREG_SET_ORDER)) {
+                                       $line = '$a->config[\'' . $this->settings[$i]['cat'] . '\'][\'' . $this->settings[$i]['key'] . '\'] = \'' . $this->settings[$i]['value'] . '\';' . PHP_EOL;
+                                       $found[$i] = true;
+                               } elseif ($this->settings[$i]['cat'] === 'config' && preg_match_all('/^\$a\-\>config\[\'' . $this->settings[$i]['key'] . '\'\]\s*=\s\'*(.*?)\';$/', $line, $matches, PREG_SET_ORDER)) {
+                                       $line = '$a->config[\'' . $this->settings[$i]['key'] . '\'] = \'' . $this->settings[$i]['value'] . '\';' . PHP_EOL;
+                                       $found[$i] = true;
+                               }
+                       }
+
+                       fputs($writing, $line);
+               }
+
+               for ($i = 0; $i < $settingsCount; $i++) {
+                       if (!$found[$i]) {
+                               if ($this->settings[$i]['cat'] !== 'config') {
+                                       $line = '$a->config[\'' . $this->settings[$i]['cat'] . '\'][\'' . $this->settings[$i]['key'] . '\'] = \'' . $this->settings[$i]['value'] . '\';' . PHP_EOL;
+                               } else {
+                                       $line = '$a->config[\'' . $this->settings[$i]['key'] . '\'] = \'' . $this->settings[$i]['value'] . '\';' . PHP_EOL;
+                               }
+
+                               fputs($writing, $line);
+                       }
+               }
+       }
+}
index d434674061ebba013c3c82786142390d8401b733..fec31b05af6f69aa49deee5c16a9c957a445b5c7 100644 (file)
@@ -9,7 +9,7 @@ use Friendica\App;
 use Friendica\Database\DBA;
 use Friendica\Factory;
 use Friendica\Util\BasePath;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 use Friendica\Util\Profiler;
 use PHPUnit\DbUnit\DataSet\YamlDataSet;
 use PHPUnit\DbUnit\TestCaseTrait;
@@ -43,7 +43,7 @@ abstract class DatabaseTest extends MockedTest
 
                $basePath = BasePath::create(dirname(__DIR__));
                $mode = new App\Mode($basePath);
-               $configLoader = new ConfigCacheLoader($basePath, $mode);
+               $configLoader = new ConfigFileLoader($basePath, $mode);
                $config = Factory\ConfigFactory::createCache($configLoader);
 
                $profiler = \Mockery::mock(Profiler::class);
diff --git a/tests/datasets/config/.htconfig.test.php b/tests/datasets/config/.htconfig.test.php
deleted file mode 100644 (file)
index 193142c..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-/**
- * A test .htconfig file
- */
-
-$db_host = 'testhost';
-$db_user = 'testuser';
-$db_pass = 'testpw';
-$db_data = 'testdb';
-
-$pidfile = '/var/run/friendica.pid';
-
-// Set the database connection charset to UTF8.
-// Changing this value will likely corrupt the special characters.
-// You have been warned.
-$a->config['system']['db_charset'] = "anotherCharset";
-
-// Choose a legal default timezone. If you are unsure, use "America/Los_Angeles".
-// It can be changed later and only applies to timestamps for anonymous viewers.
-$default_timezone = 'Europe/Berlin';
-$lang = 'fr';
-
-// What is your site name?
-$a->config['sitename'] = "Friendica My Network";
-
-// Your choices are REGISTER_OPEN, REGISTER_APPROVE, or REGISTER_CLOSED.
-// Be certain to create your own personal account before setting
-// REGISTER_CLOSED. 'register_text' (if set) will be displayed prominently on
-// the registration page. REGISTER_APPROVE requires you set 'admin_email'
-// to the email address of an already registered person who can authorise
-// and/or approve/deny the request.
-// In order to perform system administration via the admin panel, admin_email
-// must precisely match the email address of the person logged in.
-$a->config['register_policy'] = REGISTER_OPEN;
-$a->config['register_text'] = 'A register text';
-$a->config['admin_email'] = 'admin@friendica.local';
-$a->config['admin_nickname'] = 'Friendly admin';
-
-// Maximum size of an imported message, 0 is unlimited
-$a->config['max_import_size'] = 999;
-
-// maximum size of uploaded photos
-$a->config['system']['maximagesize'] = 666;
-
-// Location of PHP command line processor
-$a->config['php_path'] = '/another/php';
-
-// PuSH - aka pubsubhubbub URL. This makes delivery of public posts as fast as private posts
-$a->config['system']['huburl'] = '[internal]';
-
-// allowed themes (change this from admin panel after installation)
-$a->config['system']['allowed_themes'] = 'quattro,vier,duepuntozero';
-
-// default system theme
-$a->config['system']['theme'] = 'duepuntozero';
-
-// By default allow pseudonyms
-$a->config['system']['no_regfullname'] = true;
-
-//Deny public access to the local directory
-//$a->config['system']['block_local_dir'] = false;
-// Location of the global directory
-$a->config['system']['directory'] = 'http://another.url';
index 8a392909f261454e40bd89903593df7b127a87a5..f28e1f2e85004ade3269508f564f1a8c0b8d1e00 100644 (file)
@@ -23,5 +23,6 @@ return [
        'system' => [
                'default_timezone' => 'UTC',
                'language' => 'en',
+               'theme' => 'frio',
        ],
 ];
index 1fea0b028eddfd93e71ddc1ef83d7c17e6d790df..a9e462d13e1b09d10dc3b8c7f30cac27e8c9879b 100644 (file)
@@ -11,6 +11,9 @@ username = testuser
 password = testpw
 database = testdb
 
+[system]
+theme = frio
+
 [config]
 admin_email = admin@test.it
 INI;
index bd1b041082818a52397eb52d600ee235a8693fed..5c2e1657af0e1d25ba88bff0674cdc64ef86d0eb 100644 (file)
@@ -13,7 +13,7 @@ use Friendica\Core\System;
 use Friendica\Factory;
 use Friendica\Network\HTTPException;
 use Friendica\Util\BasePath;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 use Monolog\Handler\TestHandler;
 
 require_once __DIR__ . '/../../include/api.php';
@@ -38,7 +38,7 @@ class ApiTest extends DatabaseTest
        {
                $basePath = BasePath::create(dirname(__DIR__) . '/../');
                $mode = new App\Mode($basePath);
-               $configLoader = new ConfigCacheLoader($basePath, $mode);
+               $configLoader = new ConfigFileLoader($basePath, $mode);
                $configCache = Factory\ConfigFactory::createCache($configLoader);
                $profiler = Factory\ProfilerFactory::create($configCache);
                Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
index 28f5afbd778a4eef8a650f342e46170f07e42200..bc8743da5b8cf5f4c8e4df38e647c6f1b79579e2 100644 (file)
@@ -7,7 +7,7 @@ use Friendica\Database\DBA;
 use Friendica\Factory;
 use Friendica\Test\DatabaseTest;
 use Friendica\Util\BasePath;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 
 class DBATest extends DatabaseTest
 {
@@ -15,7 +15,7 @@ class DBATest extends DatabaseTest
        {
                $basePath = BasePath::create(dirname(__DIR__) . '/../../');
                $mode = new App\Mode($basePath);
-               $configLoader = new ConfigCacheLoader($basePath, $mode);
+               $configLoader = new ConfigFileLoader($basePath, $mode);
                $configCache = Factory\ConfigFactory::createCache($configLoader);
                $profiler = Factory\ProfilerFactory::create($configCache);
                Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
index 65d5c85a421a1b92cda70f57b41442cc866543d3..0c1da172f5de8ef72c1884c3c8318e1780aa9311 100644 (file)
@@ -7,7 +7,7 @@ use Friendica\Database\DBStructure;
 use Friendica\Factory;
 use Friendica\Test\DatabaseTest;
 use Friendica\Util\BasePath;
-use Friendica\Util\Config\ConfigCacheLoader;
+use Friendica\Util\Config\ConfigFileLoader;
 
 class DBStructureTest extends DatabaseTest
 {
@@ -15,7 +15,7 @@ class DBStructureTest extends DatabaseTest
        {
                $basePath = BasePath::create(dirname(__DIR__) . '/../../');
                $mode = new App\Mode($basePath);
-               $configLoader = new ConfigCacheLoader($basePath, $mode);
+               $configLoader = new ConfigFileLoader($basePath, $mode);
                $configCache = Factory\ConfigFactory::createCache($configLoader);
                $profiler = Factory\ProfilerFactory::create($configCache);
                Factory\DBFactory::init($basePath, $configCache, $profiler, $_SERVER);
diff --git a/tests/src/Util/Config/ConfigCacheLoaderTest.php b/tests/src/Util/Config/ConfigCacheLoaderTest.php
deleted file mode 100644 (file)
index 45245d4..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Util\Config;
-
-use Friendica\App;
-use Friendica\Core\Config\Cache\ConfigCache;
-use Friendica\Test\MockedTest;
-use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\Config\ConfigCacheLoader;
-use Mockery\MockInterface;
-use org\bovigo\vfs\vfsStream;
-
-class ConfigCacheLoaderTest extends MockedTest
-{
-       use VFSTrait;
-
-       /**
-        * @var App\Mode|MockInterface
-        */
-       private $mode;
-
-       protected function setUp()
-       {
-               parent::setUp();
-
-               $this->setUpVfsDir();
-
-               $this->mode = \Mockery::mock(App\Mode::class);
-               $this->mode->shouldReceive('isInstall')->andReturn(true);
-       }
-
-       /**
-        * Test the loadConfigFiles() method with default values
-        */
-       public function testLoadConfigFiles()
-       {
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-
-               $configCacheLoader->loadConfigFiles($configCache);
-
-               $this->assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
-       }
-
-       /**
-        * Test the loadConfigFiles() method with a wrong local.config.php
-        * @expectedException \Exception
-        * @expectedExceptionMessageRegExp /Error loading config file \w+/
-        */
-       public function testLoadConfigWrong()
-       {
-               $this->delConfigFile('local.config.php');
-
-               vfsStream::newFile('local.config.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent('<?php return true;');
-
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-
-               $configCacheLoader->loadConfigFiles($configCache);
-       }
-
-       /**
-        * Test the loadConfigFiles() method with a local.config.php file
-        */
-       public function testLoadConfigFilesLocal()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'local.config.php';
-
-               vfsStream::newFile('local.config.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-
-               $configCacheLoader->loadConfigFiles($configCache);
-
-               $this->assertEquals('testhost', $configCache->get('database', 'hostname'));
-               $this->assertEquals('testuser', $configCache->get('database', 'username'));
-               $this->assertEquals('testpw', $configCache->get('database', 'password'));
-               $this->assertEquals('testdb', $configCache->get('database', 'database'));
-
-               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               $this->assertEquals('Friendica Social Network', $configCache->get('config', 'sitename'));
-       }
-
-       /**
-        * Test the loadConfigFile() method with a local.ini.php file
-        */
-       public function testLoadConfigFilesINI()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'local.ini.php';
-
-               vfsStream::newFile('local.ini.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-
-               $configCacheLoader->loadConfigFiles($configCache);
-
-               $this->assertEquals('testhost', $configCache->get('database', 'hostname'));
-               $this->assertEquals('testuser', $configCache->get('database', 'username'));
-               $this->assertEquals('testpw', $configCache->get('database', 'password'));
-               $this->assertEquals('testdb', $configCache->get('database', 'database'));
-
-               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-       }
-
-       /**
-        * Test the loadConfigFile() method with a .htconfig.php file
-        */
-       public function testLoadConfigFilesHtconfig()
-       {
-               $this->delConfigFile('local.config.php');
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       '.htconfig.test.php';
-
-               vfsStream::newFile('.htconfig.php')
-                       ->at($this->root)
-                       ->setContent(file_get_contents($file));
-
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-
-               $configCacheLoader->loadConfigFiles($configCache);
-
-               $this->assertEquals('testhost', $configCache->get('database', 'hostname'));
-               $this->assertEquals('testuser', $configCache->get('database', 'username'));
-               $this->assertEquals('testpw', $configCache->get('database', 'password'));
-               $this->assertEquals('testdb', $configCache->get('database', 'database'));
-               $this->assertEquals('anotherCharset', $configCache->get('database', 'charset'));
-
-               $this->assertEquals('/var/run/friendica.pid', $configCache->get('system', 'pidfile'));
-               $this->assertEquals('Europe/Berlin', $configCache->get('system', 'default_timezone'));
-               $this->assertEquals('fr', $configCache->get('system', 'language'));
-
-               $this->assertEquals('admin@friendica.local', $configCache->get('config', 'admin_email'));
-               $this->assertEquals('Friendly admin', $configCache->get('config', 'admin_nickname'));
-
-               $this->assertEquals('/another/php', $configCache->get('config', 'php_path'));
-               $this->assertEquals('999', $configCache->get('config', 'max_import_size'));
-               $this->assertEquals('666', $configCache->get('system', 'maximagesize'));
-
-               $this->assertEquals('quattro,vier,duepuntozero', $configCache->get('system', 'allowed_themes'));
-               $this->assertEquals('1', $configCache->get('system', 'no_regfullname'));
-       }
-
-       public function testLoadAddonConfig()
-       {
-               $structure = [
-                       'addon' => [
-                               'test' => [
-                                       'config' => [],
-                               ],
-                       ],
-               ];
-
-               vfsStream::create($structure, $this->root);
-
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'local.config.php';
-
-               vfsStream::newFile('test.config.php')
-                       ->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-
-               $conf = $configCacheLoader->loadAddonConfig('test');
-
-               $this->assertEquals('testhost', $conf['database']['hostname']);
-               $this->assertEquals('testuser', $conf['database']['username']);
-               $this->assertEquals('testpw', $conf['database']['password']);
-               $this->assertEquals('testdb', $conf['database']['database']);
-
-               $this->assertEquals('admin@test.it', $conf['config']['admin_email']);
-       }
-}
diff --git a/tests/src/Util/Config/ConfigCacheSaverTest.php b/tests/src/Util/Config/ConfigCacheSaverTest.php
deleted file mode 100644 (file)
index a0d9502..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Util\Config;
-
-use Friendica\App;
-use Friendica\Core\Config\Cache\ConfigCache;
-use Friendica\Test\MockedTest;
-use Friendica\Test\Util\VFSTrait;
-use Friendica\Util\Config\ConfigCacheLoader;
-use Friendica\Util\Config\ConfigCacheSaver;
-use Mockery\MockInterface;
-use org\bovigo\vfs\vfsStream;
-
-class ConfigCacheSaverTest extends MockedTest
-{
-       use VFSTrait;
-       /**
-        * @var App\Mode|MockInterface
-        */
-       private $mode;
-       protected function setUp()
-       {
-               parent::setUp();
-               $this->setUpVfsDir();
-               $this->mode = \Mockery::mock(App\Mode::class);
-               $this->mode->shouldReceive('isInstall')->andReturn(true);
-       }
-       /**
-        * Test the saveToConfigFile() method with a local.config.php file
-        */
-       public function testSaveToConfigFileLocal()
-       {
-               $this->delConfigFile('local.config.php');
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'local.config.php';
-
-               vfsStream::newFile('local.config.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent(file_get_contents($file));
-
-               $configCacheSaver = new ConfigCacheSaver($this->root->url());
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-               $configCacheLoader->loadConfigFiles($configCache);
-
-               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               $this->assertNull($configCache->get('config', 'test_val'));
-
-               $configCacheSaver->saveToConfigFile('config', 'admin_email', 'new@mail.it');
-               $configCacheSaver->saveToConfigFile('config', 'test_val', 'Testing$!"$with@all.we can!');
-
-               $newConfigCache = new ConfigCache();
-               $configCacheLoader->loadConfigFiles($newConfigCache);
-
-               $this->assertEquals('new@mail.it', $newConfigCache->get('config', 'admin_email'));
-               $this->assertEquals('Testing$!"$with@all.we can!', $newConfigCache->get('config', 'test_val'));
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php.old'));
-               $this->assertFalse($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php.tmp'));
-
-               $this->assertEquals(file_get_contents($file), file_get_contents($this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.config.php.old')->url()));
-       }
-       /**
-        * Test the saveToConfigFile() method with a local.ini.php file
-        */
-       public function testSaveToConfigFileINI()
-       {
-               $this->delConfigFile('local.config.php');
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       'local.ini.php';
-               vfsStream::newFile('local.ini.php')
-                       ->at($this->root->getChild('config'))
-                       ->setContent(file_get_contents($file));
-               $configCacheSaver = new ConfigCacheSaver($this->root->url());
-               $configCacheLoader = new ConfigCacheLoader($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-               $configCacheLoader->loadConfigFiles($configCache);
-               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               $this->assertNull($configCache->get('config', 'test_val'));
-               $configCacheSaver->saveToConfigFile('config', 'admin_email', 'new@mail.it');
-               $configCacheSaver->saveToConfigFile('config', 'test_val', "Testing@with.all we can");
-               $newConfigCache = new ConfigCache();
-               $configCacheLoader->loadConfigFiles($newConfigCache);
-               $this->assertEquals('new@mail.it', $newConfigCache->get('config', 'admin_email'));
-               $this->assertEquals("Testing@with.all we can", $newConfigCache->get('config', 'test_val'));
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php.old'));
-               $this->assertFalse($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php.tmp'));
-               $this->assertEquals(file_get_contents($file), file_get_contents($this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.ini.old')->url()));
-       }
-       /**
-        * Test the saveToConfigFile() method with a .htconfig.php file
-        * @todo fix it after 2019.03 merge to develop
-        */
-       public function testSaveToConfigFileHtconfig()
-       {
-               $this->markTestSkipped('Needs 2019.03 merge to develop first');
-               $this->delConfigFile('local.config.php');
-               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       '..' . DIRECTORY_SEPARATOR .
-                       'datasets' . DIRECTORY_SEPARATOR .
-                       'config' . DIRECTORY_SEPARATOR .
-                       '.htconfig.test.php';
-               vfsStream::newFile('.htconfig.php')
-                       ->at($this->root)
-                       ->setContent(file_get_contents($file));
-               $configCacheSaver = new ConfigCacheSaver($this->root->url(), $this->mode);
-               $configCache = new ConfigCache();
-               $configCacheSaver->loadConfigFiles($configCache);
-               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
-               $this->assertEquals('!<unset>!', $configCache->get('config', 'test_val'));
-               $configCacheSaver->saveToConfigFile('config', 'admin_email', 'new@mail.it');
-               $configCacheSaver->saveToConfigFile('config', 'test_val', 'Testing$!"$with@all.we can!');
-               $newConfigCache = new ConfigCache();
-               $configCacheSaver->loadConfigFiles($newConfigCache);
-               $this->assertEquals('new@mail.it', $newConfigCache->get('config', 'admin_email'));
-               $this->assertEquals('Testing$!"$with@all.we can!', $newConfigCache->get('config', 'test_val'));
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . '.htconfig.php'));
-               $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . '.htconfig.php.old'));
-               $this->assertFalse($this->root->hasChild('config' . DIRECTORY_SEPARATOR . '.htconfig.php.tmp'));
-               $this->assertEquals(file_get_contents($file), file_get_contents($this->root->getChild('config' . DIRECTORY_SEPARATOR . '.htconfig.php.old')->url()));
-       }
-}
diff --git a/tests/src/Util/Config/ConfigFileLoaderTest.php b/tests/src/Util/Config/ConfigFileLoaderTest.php
new file mode 100644 (file)
index 0000000..ad0fe8a
--- /dev/null
@@ -0,0 +1,205 @@
+<?php
+
+namespace Friendica\Test\src\Util\Config;
+
+use Friendica\App;
+use Friendica\Core\Config\Cache\ConfigCache;
+use Friendica\Test\MockedTest;
+use Friendica\Test\Util\VFSTrait;
+use Friendica\Util\Config\ConfigFileLoader;
+use Mockery\MockInterface;
+use org\bovigo\vfs\vfsStream;
+
+class ConfigFileLoaderTest extends MockedTest
+{
+       use VFSTrait;
+
+       /**
+        * @var App\Mode|MockInterface
+        */
+       private $mode;
+
+       protected function setUp()
+       {
+               parent::setUp();
+
+               $this->setUpVfsDir();
+
+               $this->mode = \Mockery::mock(App\Mode::class);
+               $this->mode->shouldReceive('isInstall')->andReturn(true);
+       }
+
+       /**
+        * Test the loadConfigFiles() method with default values
+        */
+       public function testLoadConfigFiles()
+       {
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+               $configCache = new ConfigCache();
+
+               $configFileLoader->setupCache($configCache);
+
+               $this->assertEquals($this->root->url(), $configCache->get('system', 'basepath'));
+       }
+
+       /**
+        * Test the loadConfigFiles() method with a wrong local.config.php
+        * @expectedException \Exception
+        * @expectedExceptionMessageRegExp /Error loading config file \w+/
+        */
+       public function testLoadConfigWrong()
+       {
+               $this->delConfigFile('local.config.php');
+
+               vfsStream::newFile('local.config.php')
+                       ->at($this->root->getChild('config'))
+                       ->setContent('<?php return true;');
+
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+               $configCache = new ConfigCache();
+
+               $configFileLoader->setupCache($configCache);
+       }
+
+       /**
+        * Test the loadConfigFiles() method with a local.config.php file
+        */
+       public function testLoadConfigFilesLocal()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       'local.config.php';
+
+               vfsStream::newFile('local.config.php')
+                       ->at($this->root->getChild('config'))
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+               $configCache = new ConfigCache();
+
+               $configFileLoader->setupCache($configCache);
+
+               $this->assertEquals('testhost', $configCache->get('database', 'hostname'));
+               $this->assertEquals('testuser', $configCache->get('database', 'username'));
+               $this->assertEquals('testpw', $configCache->get('database', 'password'));
+               $this->assertEquals('testdb', $configCache->get('database', 'database'));
+
+               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+               $this->assertEquals('Friendica Social Network', $configCache->get('config', 'sitename'));
+       }
+
+       /**
+        * Test the loadConfigFile() method with a local.ini.php file
+        */
+       public function testLoadConfigFilesINI()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       'local.ini.php';
+
+               vfsStream::newFile('local.ini.php')
+                       ->at($this->root->getChild('config'))
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+               $configCache = new ConfigCache();
+
+               $configFileLoader->setupCache($configCache);
+
+               $this->assertEquals('testhost', $configCache->get('database', 'hostname'));
+               $this->assertEquals('testuser', $configCache->get('database', 'username'));
+               $this->assertEquals('testpw', $configCache->get('database', 'password'));
+               $this->assertEquals('testdb', $configCache->get('database', 'database'));
+
+               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+       }
+
+       /**
+        * Test the loadConfigFile() method with a .htconfig.php file
+        */
+       public function testLoadConfigFilesHtconfig()
+       {
+               $this->delConfigFile('local.config.php');
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       '.htconfig.php';
+
+               vfsStream::newFile('.htconfig.php')
+                       ->at($this->root)
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+               $configCache = new ConfigCache();
+
+               $configFileLoader->setupCache($configCache);
+
+               $this->assertEquals('testhost', $configCache->get('database', 'hostname'));
+               $this->assertEquals('testuser', $configCache->get('database', 'username'));
+               $this->assertEquals('testpw', $configCache->get('database', 'password'));
+               $this->assertEquals('testdb', $configCache->get('database', 'database'));
+               $this->assertEquals('anotherCharset', $configCache->get('database', 'charset'));
+
+               $this->assertEquals('/var/run/friendica.pid', $configCache->get('system', 'pidfile'));
+               $this->assertEquals('Europe/Berlin', $configCache->get('system', 'default_timezone'));
+               $this->assertEquals('fr', $configCache->get('system', 'language'));
+
+               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+               $this->assertEquals('Friendly admin', $configCache->get('config', 'admin_nickname'));
+
+               $this->assertEquals('/another/php', $configCache->get('config', 'php_path'));
+               $this->assertEquals('999', $configCache->get('config', 'max_import_size'));
+               $this->assertEquals('666', $configCache->get('system', 'maximagesize'));
+
+               $this->assertEquals('quattro,vier,duepuntozero', $configCache->get('system', 'allowed_themes'));
+               $this->assertEquals('1', $configCache->get('system', 'no_regfullname'));
+       }
+
+       public function testLoadAddonConfig()
+       {
+               $structure = [
+                       'addon' => [
+                               'test' => [
+                                       'config' => [],
+                               ],
+                       ],
+               ];
+
+               vfsStream::create($structure, $this->root);
+
+               $file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       '..' . DIRECTORY_SEPARATOR .
+                       'datasets' . DIRECTORY_SEPARATOR .
+                       'config' . DIRECTORY_SEPARATOR .
+                       'local.config.php';
+
+               vfsStream::newFile('test.config.php')
+                       ->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
+                       ->setContent(file_get_contents($file));
+
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+
+               $conf = $configFileLoader->loadAddonConfig('test');
+
+               $this->assertEquals('testhost', $conf['database']['hostname']);
+               $this->assertEquals('testuser', $conf['database']['username']);
+               $this->assertEquals('testpw', $conf['database']['password']);
+               $this->assertEquals('testdb', $conf['database']['database']);
+
+               $this->assertEquals('admin@test.it', $conf['config']['admin_email']);
+       }
+}
diff --git a/tests/src/Util/Config/ConfigFileSaverTest.php b/tests/src/Util/Config/ConfigFileSaverTest.php
new file mode 100644 (file)
index 0000000..5b472df
--- /dev/null
@@ -0,0 +1,139 @@
+<?php
+
+namespace Friendica\Test\src\Util\Config;
+
+use Friendica\App;
+use Friendica\Core\Config\Cache\ConfigCache;
+use Friendica\Test\MockedTest;
+use Friendica\Test\Util\VFSTrait;
+use Friendica\Util\Config\ConfigFileLoader;
+use Friendica\Util\Config\ConfigFileSaver;
+use Mockery\MockInterface;
+use org\bovigo\vfs\vfsStream;
+
+class ConfigFileSaverTest extends MockedTest
+{
+       use VFSTrait;
+
+       /**
+        * @var App\Mode|MockInterface
+        */
+       private $mode;
+
+       protected function setUp()
+       {
+               parent::setUp();
+               $this->setUpVfsDir();
+               $this->mode = \Mockery::mock(App\Mode::class);
+               $this->mode->shouldReceive('isInstall')->andReturn(true);
+       }
+
+       public function dataConfigFiles()
+       {
+               return [
+                       'config' => [
+                               'fileName' => 'local.config.php',
+                               'filePath' => dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                                       '..' . DIRECTORY_SEPARATOR .
+                                       '..' . DIRECTORY_SEPARATOR .
+                                       'datasets' . DIRECTORY_SEPARATOR .
+                                       'config',
+                               'relativePath' => 'config',
+                       ],
+                       'ini' => [
+                               'fileName' => 'local.ini.php',
+                               'filePath' => dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                                       '..' . DIRECTORY_SEPARATOR .
+                                       '..' . DIRECTORY_SEPARATOR .
+                                       'datasets' . DIRECTORY_SEPARATOR .
+                                       'config',
+                               'relativePath' => 'config',
+                       ],
+                       'htconfig' => [
+                               'fileName' => '.htconfig.php',
+                               'filePath' => dirname(__DIR__) . DIRECTORY_SEPARATOR .
+                                       '..' . DIRECTORY_SEPARATOR .
+                                       '..' . DIRECTORY_SEPARATOR .
+                                       'datasets' . DIRECTORY_SEPARATOR .
+                                       'config',
+                               'relativePath' => '',
+                       ],
+               ];
+       }
+
+       /**
+        * Test the saveToConfigFile() method
+        * @dataProvider dataConfigFiles
+        *
+        * @todo 20190324 [nupplaphil] for ini-configs, it isn't possible to use $ or ! inside values
+        */
+       public function testSaveToConfig($fileName, $filePath, $relativePath)
+       {
+               $this->delConfigFile('local.config.php');
+
+               if (empty($relativePath)) {
+                       $root = $this->root;
+                       $relativeFullName = $fileName;
+               } else {
+                       $root = $this->root->getChild($relativePath);
+                       $relativeFullName = $relativePath . DIRECTORY_SEPARATOR . $fileName;
+               }
+
+               vfsStream::newFile($fileName)
+                       ->at($root)
+                       ->setContent(file_get_contents($filePath . DIRECTORY_SEPARATOR . $fileName));
+
+               $configFileSaver = new ConfigFileSaver($this->root->url());
+               $configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
+               $configCache = new ConfigCache();
+               $configFileLoader->setupCache($configCache);
+
+               $this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
+               $this->assertNull($configCache->get('config', 'test_val'));
+               $this->assertNull($configCache->get('system', 'test_val2'));
+
+               $configFileSaver->addConfigValue('system', 'theme', 'frio');
+               $configFileSaver->addConfigValue('config', 'admin_email', 'new@mail.it');
+               $configFileSaver->addConfigValue('config', 'test_val', 'Testingwith@all.we can');
+               $configFileSaver->addConfigValue('system', 'theme', 'vier');
+               $configFileSaver->addConfigValue('system', 'test_val2', 'TestIt Now');
+               $this->assertTrue($configFileSaver->saveToConfigFile());
+
+               $newConfigCache = new ConfigCache();
+               $configFileLoader->setupCache($newConfigCache);
+
+               $this->assertEquals('new@mail.it', $newConfigCache->get('config', 'admin_email'));
+               $this->assertEquals('Testingwith@all.we can', $newConfigCache->get('config', 'test_val'));
+               $this->assertEquals('vier', $newConfigCache->get('system', 'theme'));
+               $this->assertEquals('TestIt Now', $newConfigCache->get('system', 'test_val2'));
+
+               $this->assertTrue($this->root->hasChild($relativeFullName));
+               $this->assertTrue($this->root->hasChild($relativeFullName . '.old'));
+               $this->assertFalse($this->root->hasChild($relativeFullName . '.tmp'));
+
+               $this->assertEquals(file_get_contents($filePath . DIRECTORY_SEPARATOR . $fileName), file_get_contents($this->root->getChild($relativeFullName . '.old')->url()));
+       }
+
+       /**
+        * Test the saveToConfigFile() method without permissions
+        * @dataProvider dataConfigFiles
+        */
+       public function testNoPermission($fileName, $filePath, $relativePath)
+       {
+               $this->delConfigFile('local.config.php');
+
+               if (empty($relativePath)) {
+                       $root = $this->root;
+                       $relativeFullName = $fileName;
+               } else {
+                       $root = $this->root->getChild($relativePath);
+                       $relativeFullName = $relativePath . DIRECTORY_SEPARATOR . $fileName;
+               }
+
+               $root->chmod(000);
+
+               vfsStream::newFile($fileName)
+                       ->at($root)
+                       ->setContent(file_get_contents($filePath . DIRECTORY_SEPARATOR . $fileName));
+       }
+}
index 140c8fcb58d3722a64869037d89e3acd7d240497..4ee85739d3bd71a8c0c461641b2f937abe215578 100644 (file)
@@ -12,7 +12,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\GContact;
 use Friendica\Model\Item;
 use Friendica\Model\User;
-use Friendica\Util\Config\ConfigCacheSaver;
+use Friendica\Util\Config\ConfigFileSaver;
 use Friendica\Util\DateTimeFormat;
 
 /**
@@ -357,8 +357,9 @@ function update_1303()
 {
        $app = \Friendica\BaseObject::getApp();
        $configCache = $app->getConfigCache();
-       $configCacheSaver = new ConfigCacheSaver($app->getBasePath());
-       $updateConfigEntry = function($cat, $key) use ($configCache, $configCacheSaver) {
+       $configFileSaver = new ConfigFileSaver($app->getBasePath());
+
+       $updateConfigEntry = function($cat, $key) use ($configCache, $configFileSaver) {
                // check if the config file differs from the whole configuration (= The db contains other values)
                $fileConfig = $configCache->get($cat, $key);
                if ($fileConfig === '!<unset>!') {
@@ -367,11 +368,14 @@ function update_1303()
                $savedConfig = Config::get($cat, $key, null, true);
                if ($fileConfig !== $savedConfig) {
                        Logger::info('Difference in config found', ['cat' => $cat, 'key' => $key, 'file' => $fileConfig, 'saved' => $savedConfig]);
-                       $configCacheSaver->saveToConfigFile($cat, $key, $savedConfig);
+                       $configFileSaver->addConfigValue($cat, $key, $savedConfig);
                } else {
                        Logger::info('No Difference in config found', ['cat' => $cat, 'key' => $key, 'value' => $fileConfig, 'saved' => $savedConfig]);
                }
        };
+
+       $configFileSaver->saveToConfigFile();
+
        $updateConfigEntry('config', 'hostname');
        $updateConfigEntry('system', 'basepath');
        return Update::SUCCESS;