From f4c717a50ab2ed1f34b30d157ed3f30c70fdb006 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 10 Jul 2017 16:16:39 +0200 Subject: [baseconfig] Add new hook system supporting config priorities --- modules-available/baseconfig/api.inc.php | 103 +++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 18 deletions(-) (limited to 'modules-available/baseconfig') diff --git a/modules-available/baseconfig/api.inc.php b/modules-available/baseconfig/api.inc.php index af780d99..5d52a449 100644 --- a/modules-available/baseconfig/api.inc.php +++ b/modules-available/baseconfig/api.inc.php @@ -10,6 +10,77 @@ if ($uuid !== false && strlen($uuid) !== 36) { $uuid = false; } +class ConfigHolder +{ + private $config = []; + + private $context = ''; + + public function setContext($name) + { + $this->context = $name; + } + + public function addArray($array, $prio = 0) + { + foreach ($array as $key => $value) { + $this->add($key, $value, $prio); + } + } + + public function add($key, $value, $prio = 0) + { + if (!isset($this->config[$key])) { + $this->config[$key] = []; + } + $new = [ + 'prio' => $prio, + 'value' => $value, + 'context' => $this->context, + ]; + if (empty($this->config[$key]) || $this->config[$key][0]['prio'] > $prio) { + // Existing is higher, append new one + array_push($this->config[$key], $new); + } else { + // New one has highest prio or matches existing, put in front + array_unshift($this->config[$key], $new); + } + } + + public function getConfig() + { + $ret = []; + foreach ($this->config as $key => $list) { + if ($list[0]['value'] === false) + continue; + $ret[$key] = $list[0]['value']; + } + return $ret; + } + + public function outputConfig() + { + foreach ($this->config as $key => $list) { + echo '##', $key, "\n"; + foreach ($list as $pos => $item) { + echo '# (', $item['context'], ':', $item['prio'], ')'; + if ($pos != 0 || $item['value'] === false) { + if ($pos == 0) { + echo " \n"; + } else { + echo ': ', str_replace(array("\r", "\n"), array('\r', '\n'), $item['value']), "\n"; + } + continue; + } + echo "⤵\n", $key, "='", escape($item['value']), "'\n"; + } + } + } + +} + +$CONFIG = new ConfigHolder(); + /** * Escape given string so it is a valid string in sh that can be surrounded * by single quotes ('). This basically turns _'_ into _'"'"'_ @@ -29,11 +100,12 @@ function escape($string) * global setting. */ -$configVars = array(); function handleModule($file, $ip, $uuid) // Pass ip and uuid instead of global to make them read only { - global $configVars; + global $CONFIG; + $configVars = []; include_once $file; + $CONFIG->addArray($configVars, 1); } // Handle any hooks by other modules first @@ -47,9 +119,11 @@ foreach (glob('modules/*/baseconfig/getconfig.inc.php') as $file) { foreach ($mod->getDependencies() as $dep) { $depFile = 'modules/' . $dep . '/baseconfig/getconfig.inc.php'; if (file_exists($depFile) && Module::isAvailable($dep)) { + $CONFIG->setContext($dep); handleModule($depFile, $ip, $uuid); } } + $CONFIG->setContext($out[1]); handleModule($file, $ip, $uuid); } @@ -57,28 +131,23 @@ foreach (glob('modules/*/baseconfig/getconfig.inc.php') as $file) { $defaults = BaseConfigUtil::getVariables(); // Dump global config from DB +$CONFIG->setContext(''); $res = Database::simpleQuery('SELECT setting, value, enabled FROM setting_global'); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - if (isset($configVars[$row['setting']]) // Already set by a hook above, ignore - || !isset($defaults[$row['setting']])) // Setting is not defined in any /baseconfig/settings.json - continue; + if (!isset($defaults[$row['setting']])) + continue; // Setting is not defined in any /baseconfig/settings.json if ($row['enabled'] != 1) { // Setting is disabled - $configVars[$row['setting']] = false; + $CONFIG->add($row['setting'], false, 0); } else { - $configVars[$row['setting']] = $row['value']; + $CONFIG->add($row['setting'], $row['value'], 0); } } // Fallback to default values from json files +$CONFIG->setContext(''); foreach ($defaults as $setting => $value) { - if (isset($configVars[$setting])) { - if ($configVars[$setting] === false) { - unset($configVars[$setting]); - } - } else { - $configVars[$setting] = $value['defaultvalue']; - } + $CONFIG->add($setting, $value['defaultvalue'], -1000); } // All done, now output @@ -86,7 +155,7 @@ foreach ($defaults as $setting => $value) { if (Request::any('save') === 'true') { // output AND save to disk: Generate contents $lines = ''; - foreach ($configVars as $setting => $value) { + foreach ($CONFIG->getConfig() as $setting => $value) { $lines .= $setting . "='" . escape($value) . "'\n"; } // Save to all the locations @@ -105,9 +174,7 @@ if (Request::any('save') === 'true') { echo $lines; } else { // Only output to client - foreach ($configVars as $setting => $value) { - echo $setting, "='", escape($value), "'\n"; - } + $CONFIG->outputConfig(); } // For quick testing or custom extensions: Include external file that should do nothing -- cgit v1.2.3-55-g7522