Added config layers.
Configs are now layered on top of each other. If a config file is found in multiple directories, they are merged together. Higher fields will override lower fields. This way, if one field is missing in a higher priority file, the lower priority can still be used.
This commit is contained in:
parent
44ae26404c
commit
0014c2d9f6
|
@ -52,6 +52,10 @@ class Config
|
||||||
{
|
{
|
||||||
use ComponentPathsTrait;
|
use ComponentPathsTrait;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->addComponentPath(Core::$coreDir . DS . 'Config', Priority::LOWEST);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array where all config files are saved while FuzeWorks runs
|
* Array where all config files are saved while FuzeWorks runs
|
||||||
*
|
*
|
||||||
|
@ -150,6 +154,7 @@ class Config
|
||||||
return new ConfigORM();
|
return new ConfigORM();
|
||||||
|
|
||||||
// Cycle through all priorities if they exist
|
// Cycle through all priorities if they exist
|
||||||
|
$configORM = new ConfigORM();
|
||||||
for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
|
for ($i=Priority::getHighestPriority(); $i<=Priority::getLowestPriority(); $i++)
|
||||||
{
|
{
|
||||||
if (!isset($event->configPaths[$i]))
|
if (!isset($event->configPaths[$i]))
|
||||||
|
@ -161,41 +166,23 @@ class Config
|
||||||
// If file exists, load it and break the loop
|
// If file exists, load it and break the loop
|
||||||
$file = $configPath . DS . 'config.'.strtolower($event->configName).'.php';
|
$file = $configPath . DS . 'config.'.strtolower($event->configName).'.php';
|
||||||
if (file_exists($file))
|
if (file_exists($file))
|
||||||
{
|
$configORM->addFile($i, $file);
|
||||||
// Load object
|
|
||||||
$configORM = (new ConfigORM())->load($file);
|
|
||||||
|
|
||||||
// Override config values if they exist
|
|
||||||
if (isset(self::$configOverrides[$event->configName]))
|
|
||||||
{
|
|
||||||
foreach (self::$configOverrides[$event->configName] as $configKey => $configValue)
|
|
||||||
$configORM->{$configKey} = $configValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return object
|
|
||||||
return $configORM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try fallback
|
// And initialize the ORM
|
||||||
$file = Core::$coreDir . DS . 'Config' . DS . 'config.' . $event->configName . '.php';
|
$configORM->init();
|
||||||
if (file_exists($file))
|
|
||||||
|
// Override config values if they exist
|
||||||
|
if (isset(self::$configOverrides[$event->configName]))
|
||||||
{
|
{
|
||||||
// Load object
|
foreach (self::$configOverrides[$event->configName] as $configKey => $configValue)
|
||||||
$configORM = (new ConfigORM())->load($file);
|
$configORM->{$configKey} = $configValue;
|
||||||
|
|
||||||
// Override config values if they exist
|
|
||||||
if (isset(self::$configOverrides[$event->configName]))
|
|
||||||
{
|
|
||||||
foreach (self::$configOverrides[$event->configName] as $configKey => $configValue)
|
|
||||||
$configORM->{$configKey} = $configValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return object
|
|
||||||
return $configORM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($configORM->loaded)
|
||||||
|
return $configORM;
|
||||||
|
|
||||||
throw new ConfigException("Could not load config. File $event->configName not found", 1);
|
throw new ConfigException("Could not load config. File $event->configName not found", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
namespace FuzeWorks\ConfigORM;
|
namespace FuzeWorks\ConfigORM;
|
||||||
use FuzeWorks\Exception\ConfigException;
|
use FuzeWorks\Exception\ConfigException;
|
||||||
|
use FuzeWorks\Priority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ORM class for config files in PHP files.
|
* ORM class for config files in PHP files.
|
||||||
|
@ -48,37 +49,61 @@ use FuzeWorks\Exception\ConfigException;
|
||||||
class ConfigORM extends ConfigORMAbstract
|
class ConfigORM extends ConfigORMAbstract
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The current filename.
|
* The path to the highest priority filename.
|
||||||
*
|
*
|
||||||
* @var string filename
|
* @var string filename
|
||||||
*/
|
*/
|
||||||
private string $file;
|
protected string $file;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the ConfigORM file.
|
* Files the ConfigORM is built on
|
||||||
*
|
*
|
||||||
* @param string $file
|
* @var array files
|
||||||
* @return ConfigORM
|
|
||||||
* @throws ConfigException
|
|
||||||
*/
|
*/
|
||||||
public function load(string $file = ''): ConfigORM
|
protected array $files = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the ConfigORM is loaded or not.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public bool $loaded = false;
|
||||||
|
|
||||||
|
public function addFile(int $priority, string $file)
|
||||||
{
|
{
|
||||||
if (empty($file))
|
if (!isset($this->files[$priority]))
|
||||||
{
|
$this->files[$priority] = [];
|
||||||
throw new ConfigException('Could not load config file. No file provided', 1);
|
|
||||||
}
|
$this->files[$priority][] = $file;
|
||||||
elseif (file_exists($file))
|
}
|
||||||
{
|
|
||||||
$this->file = $file;
|
public function init()
|
||||||
$this->cfg = (array) include $file;
|
{
|
||||||
$this->originalCfg = $this->cfg;
|
// Set cfg
|
||||||
}
|
$this->cfg = [];
|
||||||
else
|
|
||||||
{
|
for ($i = Priority::getLowestPriority(); $i >= Priority::getHighestPriority(); $i--) {
|
||||||
throw new ConfigException('Could not load config file. Config file does not exist', 1);
|
|
||||||
|
// If priority does not exist for this file, skip it
|
||||||
|
if (!isset($this->files[$i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Pass over each file in this priority
|
||||||
|
foreach ($this->files[$i] as $file) {
|
||||||
|
// Read the contents
|
||||||
|
$contents = (array) include $file;
|
||||||
|
|
||||||
|
// Merge them with the config as we know it
|
||||||
|
$this->cfg = array_replace_recursive($this->cfg, $contents);
|
||||||
|
|
||||||
|
// And save the last file that we found (with the highest priority)
|
||||||
|
$this->file = $file;
|
||||||
|
$this->loaded = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
// When done, save originalCfg
|
||||||
|
$this->originalCfg = $this->cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -404,6 +404,10 @@ class Configurator
|
||||||
$container->{$component}->setDirectories($priorityArray);
|
$container->{$component}->setDirectories($priorityArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// And add the fallback directory
|
||||||
|
$container->config->addComponentPath(Core::$coreDir . DS . 'Config', Priority::LOWEST);
|
||||||
|
|
||||||
|
// Initialize and return the container
|
||||||
$container->initFactory();
|
$container->initFactory();
|
||||||
Logger::stopLevel();
|
Logger::stopLevel();
|
||||||
return $container;
|
return $container;
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksCore
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 i15
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author i15
|
||||||
|
* @copyright Copyright (c) 2013 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.3.2
|
||||||
|
*/
|
||||||
|
return array(
|
||||||
|
'first' => 'world',
|
||||||
|
'onlyInHigh' => 'highValue',
|
||||||
|
'override' => 'firstValue'
|
||||||
|
);
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* FuzeWorksCore
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013-2021 i15
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author i15
|
||||||
|
* @copyright Copyright (c) 2013 - 2021, i15. (https://i15.nl)
|
||||||
|
* @license https://opensource.org/licenses/MIT MIT License
|
||||||
|
*
|
||||||
|
* @since Version 1.0.0
|
||||||
|
*
|
||||||
|
* @version Version 1.3.2
|
||||||
|
*/
|
||||||
|
return array(
|
||||||
|
'first' => 'hello',
|
||||||
|
'onlyInLow' => 'lowValue'
|
||||||
|
);
|
|
@ -207,4 +207,27 @@ class configTest extends CoreTestAbstract
|
||||||
$this->assertEquals('somethingDefault', $config->get('otherKey'));
|
$this->assertEquals('somethingDefault', $config->get('otherKey'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::loadConfigFile
|
||||||
|
* @depends testLoadConfigCoreOverride
|
||||||
|
*/
|
||||||
|
public function testCumulativeConfigFile()
|
||||||
|
{
|
||||||
|
// Add folders
|
||||||
|
$this->config->addComponentPath('test'.DS.'config'.DS.'TestCumulativeConfigFile'.DS.'HighPriorityFolder', Priority::HIGH);
|
||||||
|
$this->config->addComponentPath('test'.DS.'config'.DS.'TestCumulativeConfigFile'.DS.'LowPriorityFolder', Priority::LOW);
|
||||||
|
|
||||||
|
// And override a value
|
||||||
|
Config::overrideConfig('cumulative', 'override', 'secondValue');
|
||||||
|
|
||||||
|
// Load the config
|
||||||
|
$config = $this->config->get('cumulative');
|
||||||
|
|
||||||
|
// Check values
|
||||||
|
$this->assertEquals("world", $config->get('first'));
|
||||||
|
$this->assertEquals("highValue", $config->get('onlyInHigh'));
|
||||||
|
$this->assertEquals("lowValue", $config->get('onlyInLow'));
|
||||||
|
$this->assertEquals("secondValue", $config->get('override'));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue