diff --git a/src/Core/Config/Cache.php b/src/Core/Config/Cache.php index b78b57f57d..25b25550e0 100644 --- a/src/Core/Config/Cache.php +++ b/src/Core/Config/Cache.php @@ -36,6 +36,8 @@ class Cache const SOURCE_DB = 1; /** @var int Indicates that the cache entry is set by a server environment variable - High Priority */ const SOURCE_ENV = 3; + /** @var int Indicates that the cache entry is fixed and must not be changed */ + const SOURCE_FIX = 4; /** @var int Default value for a config source */ const SOURCE_DEFAULT = self::SOURCE_FILE; diff --git a/src/Database/Database.php b/src/Database/Database.php index e25323b382..727c2df93c 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -66,7 +66,7 @@ class Database protected $testmode = false; private $relation = []; - public function __construct(Cache $configCache, Profiler $profiler, LoggerInterface $logger, array $server = []) + public function __construct(Cache $configCache, Profiler $profiler, LoggerInterface $logger) { // We are storing these values for being able to perform a reconnect $this->configCache = $configCache; diff --git a/src/Factory/ConfigFactory.php b/src/Factory/ConfigFactory.php index 954f893959..3110490fd3 100644 --- a/src/Factory/ConfigFactory.php +++ b/src/Factory/ConfigFactory.php @@ -37,10 +37,10 @@ class ConfigFactory * * @throws Exception */ - public function createCache(ConfigFileLoader $loader) + public function createCache(ConfigFileLoader $loader, array $server = []) { $configCache = new Cache(); - $loader->setupCache($configCache); + $loader->setupCache($configCache, $server); return $configCache; } diff --git a/src/Util/ConfigFileLoader.php b/src/Util/ConfigFileLoader.php index 54c2ebe0c0..60e82c04f1 100644 --- a/src/Util/ConfigFileLoader.php +++ b/src/Util/ConfigFileLoader.php @@ -97,11 +97,12 @@ class ConfigFileLoader * expected local.config.php * * @param Cache $config The config cache to load to + * @param array $server The $_SERVER array * @param bool $raw Setup the raw config format * * @throws Exception */ - public function setupCache(Cache $config, $raw = false) + public function setupCache(Cache $config, array $server = [], $raw = false) { // Load static config files first, the order is important $config->load($this->loadStaticConfig('defaults'), Cache::SOURCE_FILE); @@ -114,10 +115,12 @@ class ConfigFileLoader // Now load every other config you find inside the 'config/' directory $this->loadCoreConfig($config); + $config->load($this->loadEnvConfig($server), Cache::SOURCE_ENV); + // In case of install mode, add the found basepath (because there isn't a basepath set yet if (!$raw && empty($config->get('system', 'basepath'))) { // Setting at least the basepath we know - $config->set('system', 'basepath', $this->baseDir); + $config->set('system', 'basepath', $this->baseDir, Cache::SOURCE_FILE); } } @@ -192,6 +195,38 @@ class ConfigFileLoader } } + /** + * Tries to load environment specific variables, based on the `env.config.php` mapping table + * + * @param array $server The $_SERVER variable + * + * @return array The config array (empty if no config was found) + * + * @throws Exception if the configuration file isn't readable + */ + public function loadEnvConfig(array $server) + { + $filepath = $this->baseDir . DIRECTORY_SEPARATOR . // /var/www/html/ + self::STATIC_DIR . DIRECTORY_SEPARATOR . // static/ + "env.config.php"; // env.config.php + + if (!file_exists($filepath)) { + return []; + } + + $envConfig = $this->loadConfigFile($filepath); + + $return = []; + + foreach ($envConfig as $envKey => $configStructure) { + if (isset($server[$envKey])) { + $return[$configStructure[0]][$configStructure[1]] = $server[$envKey]; + } + } + + return $return; + } + /** * Get the config files of the config-directory * diff --git a/static/defaults.config.php b/static/defaults.config.php index 11731f2148..18b70d3c15 100644 --- a/static/defaults.config.php +++ b/static/defaults.config.php @@ -32,6 +32,11 @@ return [ // Can contain the port number with the syntax "hostname:port". 'hostname' => '', + // port (Integer) + // Port of the database server. + // Can be used instead of adding a port number to the hostname + 'port' => null, + // user (String) // Database user name. Please don't use "root". 'username' => '', diff --git a/static/dependencies.config.php b/static/dependencies.config.php index b1a54786ac..ca9b788534 100644 --- a/static/dependencies.config.php +++ b/static/dependencies.config.php @@ -75,13 +75,13 @@ return [ Util\ConfigFileLoader::class => [ 'shared' => true, 'constructParams' => [ - [Dice::INSTANCE => '$basepath'], + [Dice::INSTANCE => '$basepath'] ], ], Config\Cache::class => [ 'instanceOf' => Factory\ConfigFactory::class, 'call' => [ - ['createCache', [], Dice::CHAIN_CALL], + ['createCache', [$_SERVER], Dice::CHAIN_CALL], ], ], App\Mode::class => [ @@ -105,7 +105,6 @@ return [ Database::class => [ 'constructParams' => [ [Dice::INSTANCE => \Psr\Log\NullLogger::class], - $_SERVER, ], ], /** diff --git a/static/env.config.php b/static/env.config.php new file mode 100644 index 0000000000..e2b9d2b5b6 --- /dev/null +++ b/static/env.config.php @@ -0,0 +1,31 @@ +. + * + * Main mapping table of environment variables to correct config values + * + */ + +return [ + 'MYSQL_HOST' => ['database', 'hostname'], + 'MYSQL_USERNAME' => ['database', 'username'], + 'MYSQL_USER' => ['database', 'username'], + 'MYSQL_PORT' => ['database', 'port'], + 'MYSQL_PASSWORD' => ['database', 'password'], + 'MYSQL_DATABASE' => ['database', 'database'], +]; diff --git a/tests/src/Core/Config/CacheTest.php b/tests/src/Core/Config/CacheTest.php index 02b98c7ec1..1acdd1f4fc 100644 --- a/tests/src/Core/Config/CacheTest.php +++ b/tests/src/Core/Config/CacheTest.php @@ -94,6 +94,19 @@ class CacheTest extends MockedTest $this->assertEquals($override['system']['test'], $configCache->get('system', 'test')); $this->assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue')); + + // Don't overwrite server ENV variables - even in load mode + $configCache->load($data, Cache::SOURCE_DB); + + $this->assertEquals($override['system']['test'], $configCache->get('system', 'test')); + $this->assertEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue')); + + // Overwrite ENV variables with ENV variables + $configCache->load($data, Cache::SOURCE_ENV); + + $this->assertConfigValues($data, $configCache); + $this->assertNotEquals($override['system']['test'], $configCache->get('system', 'test')); + $this->assertNotEquals($override['system']['boolTrue'], $configCache->get('system', 'boolTrue')); } /**