Browse Source

Dynamic config loading

- Move settings, defaults and dbstructure to directory 'static'
- Dynamic loading of config files (after the static loading)
- Filter out '-sample.config.php' and '-sample.ini.php' files
- Remove unnecessary ConfigFileManager
- Move ConfigFileLoader to Utils
- Add tests for multi-loading for INI, config and sample-filtering
tags/2019.09
Philipp Holzer 3 months ago
parent
commit
92fb0a82ca
No account linked to committer's email address

+ 1
- 1
config/local-sample.config.php View File

@@ -12,7 +12,7 @@
12 12
  *
13 13
  * Then set the following for your MySQL installation
14 14
  *
15
- * If you're unsure about what any of the config keys below do, please check the config/defaults.config.php file for
15
+ * If you're unsure about what any of the config keys below do, please check the static/defaults.config.php file for
16 16
  * detailed documentation of their data type and behavior.
17 17
  */
18 18
 

+ 13
- 4
doc/Config.md View File

@@ -33,15 +33,24 @@ return [
33 33
 
34 34
 ### Configuration location
35 35
 
36
-The `config` directory holds key configuration files:
36
+The `config` directory holds key configuration files and can have different config files.
37
+All of them have to end with `.config.php` and must not include `-sample` in their name.
37 38
 
38
-- `defaults.config.php` holds the default values for all the configuration keys that can only be set in `local.config.php`.
39
-- `settings.config.php` holds the default values for some configuration keys that are set through the admin settings page.
39
+Some examples of common known configuration files:
40 40
 - `local.config.php` holds the current node custom configuration.
41 41
 - `addon.config.php` is optional and holds the custom configuration for specific addons.
42 42
 
43 43
 Addons can define their own default configuration values in `addon/[addon]/config/[addon].config.php` which is loaded when the addon is activated.
44 44
 
45
+### Static Configuration location
46
+
47
+The `static` directory holds the codebase default configurations files.
48
+They must not be changed by users, because they can get changed from release to release.
49
+
50
+Currently, the following configurations are included:
51
+- `defaults.config.php` holds the default values for all the configuration keys that can only be set in `local.config.php`.
52
+- `settings.config.php` holds the default values for some configuration keys that are set through the admin settings page.
53
+
45 54
 #### Migrating from .htconfig.php to config/local.config.php
46 55
 
47 56
 The legacy `.htconfig.php` configuration file is still supported, but is deprecated and will be removed in a subsequent Friendica release.
@@ -292,7 +301,7 @@ Or it is for testing purposes only.
292 301
 **Attention:** Please be warned that you shouldn't use one of these values without the knowledge what it could trigger.
293 302
 Especially don't do that with undocumented values.
294 303
 
295
-These configurations keys and their default value are listed in `config/defaults.config.php` and should be overwritten in `config/local.config.php`.
304
+These configurations keys and their default value are listed in `static/defaults.config.php` and should be overwritten in `config/local.config.php`.
296 305
 
297 306
 ## Administrator Options
298 307
 

+ 1
- 4
src/App.php View File

@@ -17,7 +17,7 @@ use Friendica\Database\DBA;
17 17
 use Friendica\Model\Profile;
18 18
 use Friendica\Network\HTTPException;
19 19
 use Friendica\Util\BaseURL;
20
-use Friendica\Util\Config\ConfigFileLoader;
20
+use Friendica\Util\ConfigFileLoader;
21 21
 use Friendica\Util\HTTPSignature;
22 22
 use Friendica\Util\Profiler;
23 23
 use Friendica\Util\Strings;
@@ -360,9 +360,6 @@ class App
360 360
 		$this->getMode()->determine($this->getBasePath());
361 361
 
362 362
 		if ($this->getMode()->has(App\Mode::DBAVAILABLE)) {
363
-			$loader = new ConfigFileLoader($this->getBasePath(), $this->getMode());
364
-			$this->config->getCache()->load($loader->loadCoreConfig('addon'), true);
365
-
366 363
 			$this->profiler->update(
367 364
 				$this->config->get('system', 'profiler', false),
368 365
 				$this->config->get('rendertime', 'callstack', false));

+ 1
- 1
src/Console/AutomaticInstallation.php View File

@@ -9,7 +9,7 @@ use Friendica\Core\Installer;
9 9
 use Friendica\Core\Theme;
10 10
 use Friendica\Util\BasePath;
11 11
 use Friendica\Util\BaseURL;
12
-use Friendica\Util\Config\ConfigFileLoader;
12
+use Friendica\Util\ConfigFileLoader;
13 13
 use RuntimeException;
14 14
 
15 15
 class AutomaticInstallation extends Console

+ 2
- 2
src/Core/Config/Configuration.php View File

@@ -45,7 +45,7 @@ abstract class Configuration
45 45
 	/**
46 46
 	 * @brief Loads all configuration values of family into a cached storage.
47 47
 	 *
48
-	 * All configuration values of the system are stored in the cache ( @see IConfigCache )
48
+	 * All configuration values of the system are stored in the cache ( @see ConfigCache )
49 49
 	 *
50 50
 	 * @param string $cat The category of the configuration value
51 51
 	 *
@@ -59,7 +59,7 @@ abstract class Configuration
59 59
 	 *
60 60
 	 * Get a particular config value from the given category ($cat)
61 61
 	 * and the $key from a cached storage either from the $this->configAdapter
62
-	 * (@see IConfigAdapter ) or from the $this->configCache (@see IConfigCache ).
62
+	 * (@see IConfigAdapter ) or from the $this->configCache (@see ConfigCache ).
63 63
 	 *
64 64
 	 * @param string  $cat        The category of the configuration value
65 65
 	 * @param string  $key           The configuration key to query

+ 4
- 4
src/Database/DBStructure.php View File

@@ -96,7 +96,7 @@ class DBStructure
96 96
 	 * Loads the database structure definition from the config/dbstructure.config.php file.
97 97
 	 * On first pass, defines DB_UPDATE_VERSION constant.
98 98
 	 *
99
-	 * @see config/dbstructure.config.php
99
+	 * @see static/dbstructure.config.php
100 100
 	 * @param boolean $with_addons_structure Whether to tack on addons additional tables
101 101
 	 * @param string  $basePath              The base path of this application
102 102
 	 * @return array
@@ -106,16 +106,16 @@ class DBStructure
106 106
 	{
107 107
 		if (!self::$definition) {
108 108
 
109
-			$filename = $basePath . '/config/dbstructure.config.php';
109
+			$filename = $basePath . '/static/dbstructure.config.php';
110 110
 
111 111
 			if (!is_readable($filename)) {
112
-				throw new Exception('Missing database structure config file config/dbstructure.config.php');
112
+				throw new Exception('Missing database structure config file static/dbstructure.config.php');
113 113
 			}
114 114
 
115 115
 			$definition = require $filename;
116 116
 
117 117
 			if (!$definition) {
118
-				throw new Exception('Corrupted database structure config file config/dbstructure.config.php');
118
+				throw new Exception('Corrupted database structure config file static/dbstructure.config.php');
119 119
 			}
120 120
 
121 121
 			self::$definition = $definition;

+ 1
- 1
src/Factory/ConfigFactory.php View File

@@ -5,9 +5,9 @@ namespace Friendica\Factory;
5 5
 use Friendica\Core;
6 6
 use Friendica\Core\Config;
7 7
 use Friendica\Core\Config\Cache;
8
+use Friendica\Util\ConfigFileLoader;
8 9
 use Friendica\Model\Config\Config as ConfigModel;
9 10
 use Friendica\Model\Config\PConfig as PConfigModel;
10
-use Friendica\Util\Config\ConfigFileLoader;
11 11
 
12 12
 class ConfigFactory
13 13
 {

+ 2
- 2
src/Factory/DependencyFactory.php View File

@@ -7,7 +7,7 @@ use Friendica\Core\Config\Cache\PConfigCache;
7 7
 use Friendica\Factory;
8 8
 use Friendica\Util\BasePath;
9 9
 use Friendica\Util\BaseURL;
10
-use Friendica\Util\Config;
10
+use Friendica\Util\ConfigFileLoader;
11 11
 
12 12
 class DependencyFactory
13 13
 {
@@ -27,7 +27,7 @@ class DependencyFactory
27 27
 		$basePath = BasePath::create($directory, $_SERVER);
28 28
 		$mode = new App\Mode($basePath);
29 29
 		$router = new App\Router();
30
-		$configLoader = new Config\ConfigFileLoader($basePath, $mode);
30
+		$configLoader = new ConfigFileLoader($basePath, $mode);
31 31
 		$configCache = Factory\ConfigFactory::createCache($configLoader);
32 32
 		$profiler = Factory\ProfilerFactory::create($configCache);
33 33
 		$database = Factory\DBFactory::init($configCache, $profiler, $_SERVER);

+ 1
- 1
src/Module/Admin/Summary.php View File

@@ -12,7 +12,7 @@ use Friendica\Database\DBA;
12 12
 use Friendica\Database\DBStructure;
13 13
 use Friendica\Model\Register;
14 14
 use Friendica\Module\BaseAdminModule;
15
-use Friendica\Util\Config\ConfigFileLoader;
15
+use Friendica\Util\ConfigFileLoader;
16 16
 use Friendica\Util\DateTimeFormat;
17 17
 use Friendica\Util\Network;
18 18
 

+ 0
- 90
src/Util/Config/ConfigFileManager.php View File

@@ -1,90 +0,0 @@
1
-<?php
2
-
3
-namespace Friendica\Util\Config;
4
-
5
-/**
6
- * An abstract class in case of handling with config files
7
- */
8
-abstract class ConfigFileManager
9
-{
10
-	/**
11
-	 * The Sub directory of the config-files
12
-	 * @var string
13
-	 */
14
-	const SUBDIRECTORY = 'config';
15
-
16
-	/**
17
-	 * The default name of the user defined config file
18
-	 * @var string
19
-	 */
20
-	const CONFIG_LOCAL    = 'local';
21
-
22
-	/**
23
-	 * The default name of the user defined ini file
24
-	 * @var string
25
-	 */
26
-	const CONFIG_INI      = 'local';
27
-
28
-	/**
29
-	 * The default name of the user defined legacy config file
30
-	 * @var string
31
-	 */
32
-	const CONFIG_HTCONFIG = 'htconfig';
33
-
34
-	protected $baseDir;
35
-	protected $configDir;
36
-
37
-	/**
38
-	 * @param string $baseDir The base directory of Friendica
39
-	 */
40
-	public function __construct($baseDir)
41
-	{
42
-		$this->baseDir = $baseDir;
43
-		$this->configDir = $baseDir . DIRECTORY_SEPARATOR . self::SUBDIRECTORY;
44
-	}
45
-
46
-	/**
47
-	 * Gets the full name (including the path) for a *.config.php (default is local.config.php)
48
-	 *
49
-	 * @param string $name The config name (default is empty, which means local.config.php)
50
-	 *
51
-	 * @return string The full name or empty if not found
52
-	 */
53
-	protected function getConfigFullName($name = '')
54
-	{
55
-		$name = !empty($name) ? $name : self::CONFIG_LOCAL;
56
-
57
-		$fullName = $this->configDir . DIRECTORY_SEPARATOR . $name . '.config.php';
58
-		return file_exists($fullName) ? $fullName : '';
59
-	}
60
-
61
-	/**
62
-	 * Gets the full name (including the path) for a *.ini.php (default is local.ini.php)
63
-	 *
64
-	 * @param string $name The config name (default is empty, which means local.ini.php)
65
-	 *
66
-	 * @return string The full name or empty if not found
67
-	 */
68
-	protected function getIniFullName($name = '')
69
-	{
70
-		$name = !empty($name) ? $name : self::CONFIG_INI;
71
-
72
-		$fullName = $this->configDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
73
-		return file_exists($fullName) ? $fullName : '';
74
-	}
75
-
76
-	/**
77
-	 * Gets the full name (including the path) for a .*.php (default is .htconfig.php)
78
-	 *
79
-	 * @param string $name The config name (default is empty, which means .htconfig.php)
80
-	 *
81
-	 * @return string The full name or empty if not found
82
-	 */
83
-	protected function getHtConfigFullName($name = '')
84
-	{
85
-		$name = !empty($name) ? $name : self::CONFIG_HTCONFIG;
86
-
87
-		$fullName = $this->baseDir  . DIRECTORY_SEPARATOR . '.' . $name . '.php';
88
-		return file_exists($fullName) ? $fullName : '';
89
-	}
90
-}

src/Util/Config/ConfigFileLoader.php → src/Util/ConfigFileLoader.php View File

@@ -1,7 +1,8 @@
1 1
 <?php
2 2
 
3
-namespace Friendica\Util\Config;
3
+namespace Friendica\Util;
4 4
 
5
+use Exception;
5 6
 use Friendica\App;
6 7
 use Friendica\Core\Addon;
7 8
 use Friendica\Core\Config\Cache\ConfigCache;
@@ -14,17 +15,66 @@ use Friendica\Core\Config\Cache\ConfigCache;
14 15
  * - *.ini.php      (deprecated)
15 16
  * - *.htconfig.php (deprecated)
16 17
  */
17
-class ConfigFileLoader extends ConfigFileManager
18
+class ConfigFileLoader
18 19
 {
20
+	/**
21
+	 * The Sub directory of the config-files
22
+	 *
23
+	 * @var string
24
+	 */
25
+	const CONFIG_DIR = 'config';
26
+
27
+	/**
28
+	 * The Sub directory of the static config-files
29
+	 *
30
+	 * @var string
31
+	 */
32
+	const STATIC_DIR = 'static';
33
+
34
+	/**
35
+	 * The default name of the user defined ini file
36
+	 *
37
+	 * @var string
38
+	 */
39
+	const CONFIG_INI = 'local';
40
+
41
+	/**
42
+	 * The default name of the user defined legacy config file
43
+	 *
44
+	 * @var string
45
+	 */
46
+	const CONFIG_HTCONFIG = 'htconfig';
47
+
48
+	/**
49
+	 * The sample string inside the configs, which shouldn't get loaded
50
+	 *
51
+	 * @var string
52
+	 */
53
+	const SAMPLE_END = '-sample';
54
+
19 55
 	/**
20 56
 	 * @var App\Mode
21 57
 	 */
22 58
 	private $appMode;
59
+	/**
60
+	 * @var string
61
+	 */
62
+	private $baseDir;
63
+	/**
64
+	 * @var string
65
+	 */
66
+	private $configDir;
67
+	/**
68
+	 * @var string
69
+	 */
70
+	private $staticDir;
23 71
 
24 72
 	public function __construct($baseDir, App\Mode $mode)
25 73
 	{
26
-		parent::__construct($baseDir);
27
-		$this->appMode = $mode;
74
+		$this->baseDir   = $baseDir;
75
+		$this->configDir = $baseDir . DIRECTORY_SEPARATOR . self::CONFIG_DIR;
76
+		$this->staticDir = $baseDir . DIRECTORY_SEPARATOR . self::STATIC_DIR;
77
+		$this->appMode   = $mode;
28 78
 	}
29 79
 
30 80
 	/**
@@ -36,17 +86,20 @@ class ConfigFileLoader extends ConfigFileManager
36 86
 	 * @param ConfigCache $config The config cache to load to
37 87
 	 * @param bool        $raw    Setup the raw config format
38 88
 	 *
39
-	 * @throws \Exception
89
+	 * @throws Exception
40 90
 	 */
41 91
 	public function setupCache(ConfigCache $config, $raw = false)
42 92
 	{
43
-		$config->load($this->loadCoreConfig('defaults'));
44
-		$config->load($this->loadCoreConfig('settings'));
93
+		// Load static config files first, the order is important
94
+		$config->load($this->loadStaticConfig('defaults'));
95
+		$config->load($this->loadStaticConfig('settings'));
45 96
 
97
+		// try to load the legacy config first
46 98
 		$config->load($this->loadLegacyConfig('htpreconfig'), true);
47 99
 		$config->load($this->loadLegacyConfig('htconfig'), true);
48 100
 
49
-		$config->load($this->loadCoreConfig('local'), true);
101
+		// Now load every other config you find inside the 'config/' directory
102
+		$this->loadCoreConfig($config);
50 103
 
51 104
 		// In case of install mode, add the found basepath (because there isn't a basepath set yet
52 105
 		if (!$raw && ($this->appMode->isInstall() || empty($config->get('system', 'basepath')))) {
@@ -56,25 +109,52 @@ class ConfigFileLoader extends ConfigFileManager
56 109
 	}
57 110
 
58 111
 	/**
59
-	 * Tries to load the specified core-configuration and returns the config array.
112
+	 * Tries to load the static core-configuration and returns the config array.
60 113
 	 *
61
-	 * @param string $name The name of the configuration (default is empty, which means 'local')
114
+	 * @param string $name The name of the configuration
62 115
 	 *
63 116
 	 * @return array The config array (empty if no config found)
64 117
 	 *
65
-	 * @throws \Exception if the configuration file isn't readable
118
+	 * @throws Exception if the configuration file isn't readable
66 119
 	 */
67
-	public function loadCoreConfig($name = '')
120
+	private function loadStaticConfig($name)
68 121
 	{
69
-		if (!empty($this->getConfigFullName($name))) {
70
-			return $this->loadConfigFile($this->getConfigFullName($name));
71
-		} elseif (!empty($this->getIniFullName($name))) {
72
-			return $this->loadINIConfigFile($this->getIniFullName($name));
122
+		$configName = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.config.php';
123
+		$iniName    = $this->staticDir . DIRECTORY_SEPARATOR . $name . '.ini.php';
124
+
125
+		if (file_exists($configName)) {
126
+			return $this->loadConfigFile($configName);
127
+		} elseif (file_exists($iniName)) {
128
+			return $this->loadINIConfigFile($iniName);
73 129
 		} else {
74 130
 			return [];
75 131
 		}
76 132
 	}
77 133
 
134
+	/**
135
+	 * Tries to load the specified core-configuration into the config cache.
136
+	 *
137
+	 * @param ConfigCache $config The Config cache
138
+	 *
139
+	 * @return array The config array (empty if no config found)
140
+	 *
141
+	 * @throws Exception if the configuration file isn't readable
142
+	 */
143
+	private function loadCoreConfig(ConfigCache $config)
144
+	{
145
+		// try to load legacy ini-files first
146
+		foreach ($this->getConfigFiles(true) as $configFile) {
147
+			$config->load($this->loadINIConfigFile($configFile), true);
148
+		}
149
+
150
+		// try to load supported config at last to overwrite it
151
+		foreach ($this->getConfigFiles() as $configFile) {
152
+			$config->load($this->loadConfigFile($configFile), true);
153
+		}
154
+
155
+		return [];
156
+	}
157
+
78 158
 	/**
79 159
 	 * Tries to load the specified addon-configuration and returns the config array.
80 160
 	 *
@@ -82,15 +162,15 @@ class ConfigFileLoader extends ConfigFileManager
82 162
 	 *
83 163
 	 * @return array The config array (empty if no config found)
84 164
 	 *
85
-	 * @throws \Exception if the configuration file isn't readable
165
+	 * @throws Exception if the configuration file isn't readable
86 166
 	 */
87 167
 	public function loadAddonConfig($name)
88 168
 	{
89 169
 		$filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/
90
-			Addon::DIRECTORY       . DIRECTORY_SEPARATOR . // addon/
91
-			$name                  . DIRECTORY_SEPARATOR . // openstreetmap/
92
-			self::SUBDIRECTORY     . DIRECTORY_SEPARATOR . // config/
93
-			$name . ".config.php";                         // openstreetmap.config.php
170
+		            Addon::DIRECTORY . DIRECTORY_SEPARATOR . // addon/
171
+		            $name . DIRECTORY_SEPARATOR . // openstreetmap/
172
+		            self::CONFIG_DIR . DIRECTORY_SEPARATOR . // config/
173
+		            $name . ".config.php";                         // openstreetmap.config.php
94 174
 
95 175
 		if (file_exists($filepath)) {
96 176
 			return $this->loadConfigFile($filepath);
@@ -99,6 +179,32 @@ class ConfigFileLoader extends ConfigFileManager
99 179
 		}
100 180
 	}
101 181
 
182
+	/**
183
+	 * Get the config files of the config-directory
184
+	 *
185
+	 * @param bool $ini True, if scan for ini-files instead of config files
186
+	 *
187
+	 * @return array
188
+	 */
189
+	private function getConfigFiles(bool $ini = false)
190
+	{
191
+		$files = scandir($this->configDir);
192
+		$found = array();
193
+
194
+		$filePattern = ($ini ? '*.ini.php' : '*.config.php');
195
+
196
+		// Don't load sample files
197
+		$sampleEnd = self::SAMPLE_END . ($ini ? '.ini.php' : '.config.php');
198
+
199
+		foreach ($files as $filename) {
200
+			if (fnmatch($filePattern, $filename) && substr_compare($filename, $sampleEnd, -strlen($sampleEnd))) {
201
+				$found[] = $this->configDir . '/' . $filename;
202
+			}
203
+		}
204
+
205
+		return $found;
206
+	}
207
+
102 208
 	/**
103 209
 	 * Tries to load the legacy config files (.htconfig.php, .htpreconfig.php) and returns the config array.
104 210
 	 *
@@ -110,11 +216,14 @@ class ConfigFileLoader extends ConfigFileManager
110 216
 	 */
111 217
 	private function loadLegacyConfig($name = '')
112 218
 	{
219
+		$name     = !empty($name) ? $name : self::CONFIG_HTCONFIG;
220
+		$fullName = $this->baseDir . DIRECTORY_SEPARATOR . '.' . $name . '.php';
221
+
113 222
 		$config = [];
114
-		if (!empty($this->getHtConfigFullName($name))) {
115
-			$a = new \stdClass();
223
+		if (file_exists($fullName)) {
224
+			$a         = new \stdClass();
116 225
 			$a->config = [];
117
-			include $this->getHtConfigFullName($name);
226
+			include $fullName;
118 227
 
119 228
 			$htConfigCategories = array_keys($a->config);
120 229
 
@@ -172,11 +281,11 @@ class ConfigFileLoader extends ConfigFileManager
172 281
 	/**
173 282
 	 * Tries to load the specified legacy configuration file and returns the config array.
174 283
 	 *
175
-	 * @deprecated since version 2018.12
176 284
 	 * @param string $filepath
177 285
 	 *
178 286
 	 * @return array The configuration array
179
-	 * @throws \Exception
287
+	 * @throws Exception
288
+	 * @deprecated since version 2018.12
180 289
 	 */
181 290
 	private function loadINIConfigFile($filepath)
182 291
 	{
@@ -185,7 +294,7 @@ class ConfigFileLoader extends ConfigFileManager
185 294
 		$config = parse_ini_string($contents, true, INI_SCANNER_TYPED);
186 295
 
187 296
 		if ($config === false) {
188
-			throw new \Exception('Error parsing INI config file ' . $filepath);
297
+			throw new Exception('Error parsing INI config file ' . $filepath);
189 298
 		}
190 299
 
191 300
 		return $config;
@@ -202,17 +311,18 @@ class ConfigFileLoader extends ConfigFileManager
202 311
 	 *      ],
203 312
 	 * ];
204 313
 	 *
205
-	 * @param  string $filepath The filepath of the
314
+	 * @param string $filepath The filepath of the
315
+	 *
206 316
 	 * @return array The config array0
207 317
 	 *
208
-	 * @throws \Exception if the config cannot get loaded.
318
+	 * @throws Exception if the config cannot get loaded.
209 319
 	 */
210 320
 	private function loadConfigFile($filepath)
211 321
 	{
212 322
 		$config = include($filepath);
213 323
 
214 324
 		if (!is_array($config)) {
215
-			throw new \Exception('Error loading config file ' . $filepath);
325
+			throw new Exception('Error loading config file ' . $filepath);
216 326
 		}
217 327
 
218 328
 		return $config;

config/dbstructure.config.php → static/dbstructure.config.php View File


config/defaults.config.php → static/defaults.config.php View File


config/settings.config.php → static/settings.config.php View File


+ 1
- 2
tests/DatabaseTest.php View File

@@ -6,14 +6,13 @@
6 6
 namespace Friendica\Test;
7 7
 
8 8
 use Friendica\App\Mode;
9
-use Friendica\App\Router;
10 9
 use Friendica\Core\Config\Cache\ConfigCache;
11 10
 use Friendica\Database\Database;
12 11
 use Friendica\Factory\ConfigFactory;
13 12
 use Friendica\Factory\DBFactory;
14 13
 use Friendica\Factory\ProfilerFactory;
15 14
 use Friendica\Util\BasePath;
16
-use Friendica\Util\Config\ConfigFileLoader;
15
+use Friendica\Util\ConfigFileLoader;
17 16
 use Friendica\Util\Profiler;
18 17
 use PHPUnit\DbUnit\DataSet\YamlDataSet;
19 18
 use PHPUnit\DbUnit\TestCaseTrait;

+ 12
- 10
tests/Util/VFSTrait.php View File

@@ -21,33 +21,34 @@ trait VFSTrait
21 21
 		$structure = [
22 22
 			'config' => [],
23 23
 			'bin' => [],
24
-			'test' => []
24
+			'static' => [],
25
+			'test' => [],
25 26
 		];
26 27
 
27 28
 		// create a virtual directory and copy all needed files and folders to it
28 29
 		$this->root = vfsStream::setup('friendica', 0777, $structure);
29 30
 
30
-		$this->setConfigFile('defaults.config.php');
31
-		$this->setConfigFile('settings.config.php');
31
+		$this->setConfigFile('defaults.config.php', true);
32
+		$this->setConfigFile('settings.config.php', true);
32 33
 		$this->setConfigFile('local.config.php');
33
-		$this->setConfigFile('dbstructure.config.php');
34 34
 	}
35 35
 
36 36
 	/**
37 37
 	 * Copying a config file from the file system to the Virtual File System
38 38
 	 *
39 39
 	 * @param string $filename The filename of the config file
40
+	 * @param bool $static True, if the folder `static` instead of `config` should be used
40 41
 	 */
41
-	protected function setConfigFile($filename)
42
+	protected function setConfigFile($filename, bool $static = false)
42 43
 	{
43 44
 		$file = dirname(__DIR__) . DIRECTORY_SEPARATOR .
44 45
 			'..' . DIRECTORY_SEPARATOR .
45
-			'config' . DIRECTORY_SEPARATOR .
46
+			($static ? 'static' : 'config') . DIRECTORY_SEPARATOR .
46 47
 			$filename;
47 48
 
48 49
 		if (file_exists($file)) {
49 50
 			vfsStream::newFile($filename)
50
-				->at($this->root->getChild('config'))
51
+				->at($this->root->getChild(($static ? 'static' : 'config')))
51 52
 				->setContent(file_get_contents($file));
52 53
 		}
53 54
 	}
@@ -56,11 +57,12 @@ trait VFSTrait
56 57
 	 * Delets a config file from the Virtual File System
57 58
 	 *
58 59
 	 * @param string $filename The filename of the config file
60
+	 * @param bool $static True, if the folder `static` instead of `config` should be used
59 61
 	 */
60
-	protected function delConfigFile($filename)
62
+	protected function delConfigFile($filename, bool $static = false)
61 63
 	{
62
-		if ($this->root->hasChild('config/' . $filename)) {
63
-			$this->root->getChild('config')->removeChild($filename);
64
+		if ($this->root->hasChild(($static ? 'static' : 'config') . '/' . $filename)) {
65
+			$this->root->getChild(($static ? 'static' : 'config'))->removeChild($filename);
64 66
 		}
65 67
 	}
66 68
 }

tests/datasets/config/local.config.php → tests/datasets/config/A.config.php View File


tests/datasets/config/local.ini.php → tests/datasets/config/A.ini.php View File


+ 29
- 0
tests/datasets/config/B.config.php View File

@@ -0,0 +1,29 @@
1
+<?php
2
+
3
+/**
4
+ * A test file for local configuration
5
+ *
6
+ */
7
+
8
+return [
9
+	'database' => [
10
+		'hostname' => 'testhost',
11
+		'username' => 'testuser',
12
+		'password' => 'testpw',
13
+		'database' => 'testdb',
14
+		'charset' => 'utf8mb4',
15
+	],
16
+
17
+	'config' => [
18
+		'admin_email' => 'admin@overwritten.local',
19
+		'sitename' => 'Friendica Social Network',
20
+		'register_policy' => \Friendica\Module\Register::OPEN,
21
+		'register_text' => '',
22
+	],
23
+	'system' => [
24
+		'default_timezone' => 'UTC',
25
+		'language' => 'en',
26
+		'theme' => 'frio',
27
+		'newKey' => 'newValue',
28
+	],
29
+];

+ 20
- 0
tests/datasets/config/B.ini.php View File

@@ -0,0 +1,20 @@
1
+<?php
2
+/**
3
+ * A test local ini file
4
+ */
5
+
6
+return <<<INI
7
+
8
+[database]
9
+hostname = testhost
10
+username = testuser
11
+password = testpw
12
+database = testdb
13
+
14
+[system]
15
+theme = changed
16
+newKey = newValue
17
+
18
+[config]
19
+admin_email = admin@overwritten.local
20
+INI;

+ 1
- 0
tests/include/ApiTest.php View File

@@ -14,6 +14,7 @@ use Friendica\Core\System;
14 14
 use Friendica\Factory;
15 15
 use Friendica\Network\HTTPException;
16 16
 use Friendica\Util\BaseURL;
17
+use Friendica\Util\ConfigFileLoader;
17 18
 use Monolog\Handler\TestHandler;
18 19
 
19 20
 require_once __DIR__ . '/../../include/api.php';

+ 1
- 1
tests/src/Console/AutomaticInstallationConsoleTest.php View File

@@ -392,7 +392,7 @@ FIN;
392 392
 
393 393
 // Local configuration
394 394
 
395
-// If you're unsure about what any of the config keys below do, please check the config/defaults.config.php for detailed
395
+// If you're unsure about what any of the config keys below do, please check the static/defaults.config.php for detailed
396 396
 // documentation of their data type and behavior.
397 397
 
398 398
 return [

+ 91
- 4
tests/src/Util/Config/ConfigFileLoaderTest.php View File

@@ -6,7 +6,7 @@ use Friendica\App;
6 6
 use Friendica\Core\Config\Cache\ConfigCache;
7 7
 use Friendica\Test\MockedTest;
8 8
 use Friendica\Test\Util\VFSTrait;
9
-use Friendica\Util\Config\ConfigFileLoader;
9
+use Friendica\Util\ConfigFileLoader;
10 10
 use Mockery\MockInterface;
11 11
 use org\bovigo\vfs\vfsStream;
12 12
 
@@ -73,7 +73,7 @@ class ConfigFileLoaderTest extends MockedTest
73 73
 			'..' . DIRECTORY_SEPARATOR .
74 74
 			'datasets' . DIRECTORY_SEPARATOR .
75 75
 			'config' . DIRECTORY_SEPARATOR .
76
-			'local.config.php';
76
+			'A.config.php';
77 77
 
78 78
 		vfsStream::newFile('local.config.php')
79 79
 			->at($this->root->getChild('config'))
@@ -105,7 +105,7 @@ class ConfigFileLoaderTest extends MockedTest
105 105
 			'..' . DIRECTORY_SEPARATOR .
106 106
 			'datasets' . DIRECTORY_SEPARATOR .
107 107
 			'config' . DIRECTORY_SEPARATOR .
108
-			'local.ini.php';
108
+			'A.ini.php';
109 109
 
110 110
 		vfsStream::newFile('local.ini.php')
111 111
 			->at($this->root->getChild('config'))
@@ -185,7 +185,7 @@ class ConfigFileLoaderTest extends MockedTest
185 185
 			'..' . DIRECTORY_SEPARATOR .
186 186
 			'datasets' . DIRECTORY_SEPARATOR .
187 187
 			'config' . DIRECTORY_SEPARATOR .
188
-			'local.config.php';
188
+			'A.config.php';
189 189
 
190 190
 		vfsStream::newFile('test.config.php')
191 191
 			->at($this->root->getChild('addon')->getChild('test')->getChild('config'))
@@ -202,4 +202,91 @@ class ConfigFileLoaderTest extends MockedTest
202 202
 
203 203
 		$this->assertEquals('admin@test.it', $conf['config']['admin_email']);
204 204
 	}
205
+
206
+	/**
207
+	 * test loading multiple config files - the last config should work
208
+	 */
209
+	public function testLoadMultipleConfigs()
210
+	{
211
+		$this->delConfigFile('local.config.php');
212
+
213
+		$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
214
+		        '..' . DIRECTORY_SEPARATOR .
215
+		        '..' . DIRECTORY_SEPARATOR .
216
+		        'datasets' . DIRECTORY_SEPARATOR .
217
+		        'config' . DIRECTORY_SEPARATOR;
218
+
219
+		vfsStream::newFile('A.config.php')
220
+		         ->at($this->root->getChild('config'))
221
+		         ->setContent(file_get_contents($fileDir . 'A.config.php'));
222
+		vfsStream::newFile('B.config.php')
223
+				->at($this->root->getChild('config'))
224
+		         ->setContent(file_get_contents($fileDir . 'B.config.php'));
225
+
226
+		$configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
227
+		$configCache = new ConfigCache();
228
+
229
+		$configFileLoader->setupCache($configCache);
230
+
231
+		$this->assertEquals('admin@overwritten.local', $configCache->get('config', 'admin_email'));
232
+		$this->assertEquals('newValue', $configCache->get('system', 'newKey'));
233
+	}
234
+
235
+	/**
236
+	 * test loading multiple config files - the last config should work (INI-version)
237
+	 */
238
+	public function testLoadMultipleInis()
239
+	{
240
+		$this->delConfigFile('local.config.php');
241
+
242
+		$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
243
+		           '..' . DIRECTORY_SEPARATOR .
244
+		           '..' . DIRECTORY_SEPARATOR .
245
+		           'datasets' . DIRECTORY_SEPARATOR .
246
+		           'config' . DIRECTORY_SEPARATOR;
247
+
248
+		vfsStream::newFile('A.ini.php')
249
+		         ->at($this->root->getChild('config'))
250
+		         ->setContent(file_get_contents($fileDir . 'A.ini.php'));
251
+		vfsStream::newFile('B.ini.php')
252
+		         ->at($this->root->getChild('config'))
253
+		         ->setContent(file_get_contents($fileDir . 'B.ini.php'));
254
+
255
+		$configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
256
+		$configCache = new ConfigCache();
257
+
258
+		$configFileLoader->setupCache($configCache);
259
+
260
+		$this->assertEquals('admin@overwritten.local', $configCache->get('config', 'admin_email'));
261
+		$this->assertEquals('newValue', $configCache->get('system', 'newKey'));
262
+	}
263
+
264
+	/**
265
+	 * Test that sample-files (e.g. local-sample.config.php) is never loaded
266
+	 */
267
+	public function testNotLoadingSamples()
268
+	{
269
+		$this->delConfigFile('local.config.php');
270
+
271
+		$fileDir = dirname(__DIR__) . DIRECTORY_SEPARATOR .
272
+		           '..' . DIRECTORY_SEPARATOR .
273
+		           '..' . DIRECTORY_SEPARATOR .
274
+		           'datasets' . DIRECTORY_SEPARATOR .
275
+		           'config' . DIRECTORY_SEPARATOR;
276
+
277
+		vfsStream::newFile('A.ini.php')
278
+		         ->at($this->root->getChild('config'))
279
+		         ->setContent(file_get_contents($fileDir . 'A.ini.php'));
280
+		vfsStream::newFile('B-sample.ini.php')
281
+		         ->at($this->root->getChild('config'))
282
+		         ->setContent(file_get_contents($fileDir . 'B.ini.php'));
283
+
284
+		$configFileLoader = new ConfigFileLoader($this->root->url(), $this->mode);
285
+		$configCache = new ConfigCache();
286
+
287
+		$configFileLoader->setupCache($configCache);
288
+
289
+		$this->assertEquals('admin@test.it', $configCache->get('config', 'admin_email'));
290
+		$this->assertEmpty($configCache->get('system', 'NewKey'));
291
+	}
205 292
 }

+ 3
- 3
update.php View File

@@ -22,7 +22,7 @@ use Friendica\Worker\Delivery;
22 22
  * This function is responsible for doing post update changes to the data
23 23
  * (not the structure) in the database.
24 24
  *
25
- * Database structure changes are done in config/dbstructure.config.php
25
+ * Database structure changes are done in static/dbstructure.config.php
26 26
  *
27 27
  * If there is a need for a post process to a structure change, update this file
28 28
  * by adding a new function at the end with the number of the new DB_UPDATE_VERSION.
@@ -33,8 +33,8 @@ use Friendica\Worker\Delivery;
33 33
  * You are currently on version 4711 and you are preparing changes that demand an update script.
34 34
  *
35 35
  * 1. Create a function "update_4712()" here in the update.php
36
- * 2. Apply the needed structural changes in config/dbStructure.php
37
- * 3. Set DB_UPDATE_VERSION in config/dbstructure.config.php to 4712.
36
+ * 2. Apply the needed structural changes in static/dbStructure.php
37
+ * 3. Set DB_UPDATE_VERSION in static/dbstructure.config.php to 4712.
38 38
  *
39 39
  * If you need to run a script before the database update, name the function "pre_update_4712()"
40 40
  */

+ 1
- 1
view/templates/local.config.tpl View File

@@ -2,7 +2,7 @@
2 2
 
3 3
 // Local configuration
4 4
 
5
-// If you're unsure about what any of the config keys below do, please check the config/defaults.config.php for detailed
5
+// If you're unsure about what any of the config keys below do, please check the static/defaults.config.php for detailed
6 6
 // documentation of their data type and behavior.
7 7
 
8 8
 return [

Loading…
Cancel
Save