|
- <?php
-
- namespace dokuwiki\plugin\config\core;
-
- use dokuwiki\plugin\config\core\Setting\Setting;
- use dokuwiki\plugin\config\core\Setting\SettingNoClass;
- use dokuwiki\plugin\config\core\Setting\SettingNoDefault;
- use dokuwiki\plugin\config\core\Setting\SettingNoKnownClass;
- use dokuwiki\plugin\config\core\Setting\SettingUndefined;
-
- /**
- * Holds all the current settings and proxies the Loader and Writer
- *
- * @author Chris Smith <chris@jalakai.co.uk>
- * @author Ben Coburn <btcoburn@silicodon.net>
- * @author Andreas Gohr <andi@splitbrain.org>
- */
- class Configuration
- {
- public const KEYMARKER = '____';
-
- /** @var Setting[] metadata as array of Settings objects */
- protected $settings = [];
- /** @var Setting[] undefined and problematic settings */
- protected $undefined = [];
-
- /** @var array all metadata */
- protected $metadata;
- /** @var array all default settings */
- protected $default;
- /** @var array all local settings */
- protected $local;
- /** @var array all protected settings */
- protected $protected;
-
- /** @var bool have the settings been changed since loading from disk? */
- protected $changed = false;
-
- /** @var Loader */
- protected $loader;
- /** @var Writer */
- protected $writer;
-
- /**
- * ConfigSettings constructor.
- */
- public function __construct()
- {
- $this->loader = new Loader(new ConfigParser());
- $this->writer = new Writer();
-
- $this->metadata = $this->loader->loadMeta();
- $this->default = $this->loader->loadDefaults();
- $this->local = $this->loader->loadLocal();
- $this->protected = $this->loader->loadProtected();
-
- $this->initSettings();
- }
-
- /**
- * Get all settings
- *
- * @return Setting[]
- */
- public function getSettings()
- {
- return $this->settings;
- }
-
- /**
- * Get all unknown or problematic settings
- *
- * @return Setting[]
- */
- public function getUndefined()
- {
- return $this->undefined;
- }
-
- /**
- * Have the settings been changed since loading from disk?
- *
- * @return bool
- */
- public function hasChanged()
- {
- return $this->changed;
- }
-
- /**
- * Check if the config can be written
- *
- * @return bool
- */
- public function isLocked()
- {
- return $this->writer->isLocked();
- }
-
- /**
- * Update the settings using the data provided
- *
- * @param array $input as posted
- * @return bool true if all updates went through, false on errors
- */
- public function updateSettings($input)
- {
- $ok = true;
-
- foreach ($this->settings as $key => $obj) {
- $value = $input[$key] ?? null;
- if ($obj->update($value)) {
- $this->changed = true;
- }
- if ($obj->hasError()) $ok = false;
- }
-
- return $ok;
- }
-
- /**
- * Save the settings
- *
- * This save the current state as defined in this object, including the
- * undefined settings
- *
- * @throws \Exception
- */
- public function save()
- {
- // only save the undefined settings that have not been handled in settings
- $undefined = array_diff_key($this->undefined, $this->settings);
- $this->writer->save(array_merge($this->settings, $undefined));
- }
-
- /**
- * Touch the settings
- *
- * @throws \Exception
- */
- public function touch()
- {
- $this->writer->touch();
- }
-
- /**
- * Load the extension language strings
- *
- * @return array
- */
- public function getLangs()
- {
- return $this->loader->loadLangs();
- }
-
- /**
- * Initalizes the $settings and $undefined properties
- */
- protected function initSettings()
- {
- $keys = [
- ...array_keys($this->metadata),
- ...array_keys($this->default),
- ...array_keys($this->local),
- ...array_keys($this->protected)
- ];
- $keys = array_unique($keys);
-
- foreach ($keys as $key) {
- $obj = $this->instantiateClass($key);
-
- if ($obj->shouldHaveDefault() && !isset($this->default[$key])) {
- $this->undefined[$key] = new SettingNoDefault($key);
- }
-
- $d = $this->default[$key] ?? null;
- $l = $this->local[$key] ?? null;
- $p = $this->protected[$key] ?? null;
-
- $obj->initialize($d, $l, $p);
- }
- }
-
- /**
- * Instantiates the proper class for the given config key
- *
- * The class is added to the $settings or $undefined arrays and returned
- *
- * @param string $key
- * @return Setting
- */
- protected function instantiateClass($key)
- {
- if (isset($this->metadata[$key])) {
- $param = $this->metadata[$key];
- $class = $this->determineClassName(array_shift($param), $key); // first param is class
- $obj = new $class($key, $param);
- $this->settings[$key] = $obj;
- } else {
- $obj = new SettingUndefined($key);
- $this->undefined[$key] = $obj;
- }
- return $obj;
- }
-
- /**
- * Return the class to load
- *
- * @param string $class the class name as given in the meta file
- * @param string $key the settings key
- * @return string
- */
- protected function determineClassName($class, $key)
- {
- // try namespaced class first
- if (is_string($class)) {
- $modern = str_replace('_', '', ucwords($class, '_'));
- $modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern;
- if ($modern && class_exists($modern)) return $modern;
- // try class as given
- if (class_exists($class)) return $class;
- // class wasn't found add to errors
- $this->undefined[$key] = new SettingNoKnownClass($key);
- } else {
- // no class given, add to errors
- $this->undefined[$key] = new SettingNoClass($key);
- }
- return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting';
- }
- }
|