Initial commit
This commit is contained in:
219
content/lib/plugins/config/core/Configuration.php
Normal file
219
content/lib/plugins/config/core/Configuration.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?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 {
|
||||
|
||||
const KEYMARKER = '____';
|
||||
|
||||
/** @var Setting[] metadata as array of Settings objects */
|
||||
protected $settings = array();
|
||||
/** @var Setting[] undefined and problematic settings */
|
||||
protected $undefined = array();
|
||||
|
||||
/** @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 = isset($input[$key]) ? $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_merge(
|
||||
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 = isset($this->default[$key]) ? $this->default[$key] : null;
|
||||
$l = isset($this->local[$key]) ? $this->local[$key] : null;
|
||||
$p = isset($this->protected[$key]) ? $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';
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user