diff options
Diffstat (limited to 'modules-available/baseconfig/inc/baseconfig.inc.php')
-rw-r--r-- | modules-available/baseconfig/inc/baseconfig.inc.php | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/modules-available/baseconfig/inc/baseconfig.inc.php b/modules-available/baseconfig/inc/baseconfig.inc.php new file mode 100644 index 00000000..36622dce --- /dev/null +++ b/modules-available/baseconfig/inc/baseconfig.inc.php @@ -0,0 +1,151 @@ +<?php + +class BaseConfig +{ + + private static $modulesDone = []; + + /** + * @var array key-value-pairs of override vars, can be accessed by hooks + */ + private static $overrides = []; + + /** + * Fill the ConfigHolder with values from various hooks, while taking + * into account UUID and IP-address of the client making the current + * HTTP request. + */ + public static function prepareFromRequest() + { + $ip = $_SERVER['REMOTE_ADDR'] ?? null; + if ($ip === null) + ErrorHandler::traceError('No REMOTE_ADDR given in $_SERVER'); + if (substr($ip, 0, 7) === '::ffff:') { + $ip = substr($ip, 7); + } + $uuid = Request::any('uuid', null, 'string'); + if ($uuid !== null && strlen($uuid) !== 36) { + $uuid = null; + } + // Handle any hooks by other modules first + // other modules should generally only populate $configVars + foreach (glob('modules/*/baseconfig/getconfig.inc.php') as $file) { + preg_match('#^modules/([^/]+)/#', $file, $out); + ConfigHolder::setContext($out[1]); + self::handleModule($out[1], $ip, $uuid, false); + } + self::commonBase(); + } + + /** + * Fill the ConfigHolder with data from various hooks that supply + * static overrides for config variables. The overrides can be used + * to make the hooks behave in certain ways, by setting specific values like + * 'locationid' + * @param array $overrides key value pairs of overrides + */ + public static function prepareWithOverrides(array $overrides): void + { + self::$overrides = $overrides; + $ip = $uuid = null; + if (self::hasOverride('ip')) { + $ip = self::getOverride('ip'); + } + if (self::hasOverride('uuid')) { + $uuid = self::getOverride('uuid'); + } + // Handle only static hooks that don't dynamically generate output + foreach (glob('modules/*/baseconfig/hook.json') as $file) { + preg_match('#^modules/([^/]+)/#', $file, $out); + ConfigHolder::setContext($out[1]); + self::handleModule($out[1], $ip, $uuid, true); + } + self::commonBase(); + } + + /** + * Just fill the ConfigHolder with the defaults from all the json files + * that define config variables. + */ + public static function prepareDefaults() + { + $defaults = BaseConfigUtil::getVariables(); + self::addDefaults($defaults); + } + + private static function commonBase() + { + $defaults = BaseConfigUtil::getVariables(); + + // Dump global config from DB + ConfigHolder::setContext('<global>', function($id) { + return [ + 'name' => Dictionary::translate('source-global'), + 'locationid' => 0, + ]; + }); + $res = Database::simpleQuery('SELECT setting, value, displayvalue FROM setting_global'); + foreach ($res as $row) { + if (!isset($defaults[$row['setting']])) + continue; // Setting is not defined in any <module>/baseconfig/settings.json + ConfigHolder::add($row['setting'], $row, -1); + } + + // Fallback to default values from json files + self::addDefaults($defaults); + + } + + private static function addDefaults($defaults) + { + ConfigHolder::setContext('<default>', function($id) { + return [ + 'name' => Dictionary::translate('source-default'), + 'locationid' => 0, + ]; + }); + foreach ($defaults as $setting => $value) { + ConfigHolder::add($setting, $value['defaultvalue'], -1000); + } + } + + private static function handleModule(string $name, ?string $ip, ?string $uuid, bool $needJsonHook): void + { + // Pass ip and uuid instead of global to make them read only + if (isset(self::$modulesDone[$name])) + return; + self::$modulesDone[$name] = true; + // Module has getconfig hook + $file = 'modules/' . $name . '/baseconfig/getconfig.inc.php'; + if (!is_file($file)) + return; + // We want only static hooks that have a json config (currently used for displaying inheritance tree) + if ($needJsonHook && !is_file('modules/' . $name . '/baseconfig/hook.json')) + return; + // Properly registered and can be activated + $mod = Module::get($name); + if ($mod === false) + return; + if (!$mod->activate(1, false)) + return; + // Process dependencies first + foreach ($mod->getDependencies() as $dep) { + self::handleModule($dep, $ip, $uuid, $needJsonHook); + } + ConfigHolder::setContext($name); + (function (string $file, ?string $ip, ?string $uuid) { + include_once($file); + })($file, $ip, $uuid); + } + + public static function hasOverride($key): bool + { + return array_key_exists($key, self::$overrides); + } + + public static function getOverride($key) + { + return self::$overrides[$key]; + } + +}
\ No newline at end of file |