Initial commit
This commit is contained in:
90
content/lib/plugins/config/core/ConfigParser.php
Normal file
90
content/lib/plugins/config/core/ConfigParser.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core;
|
||||
|
||||
/**
|
||||
* A naive PHP file parser
|
||||
*
|
||||
* This parses our very simple config file in PHP format. We use this instead of simply including
|
||||
* the file, because we want to keep expressions such as 24*60*60 as is.
|
||||
*
|
||||
* @author Chris Smith <chris@jalakai.co.uk>
|
||||
*/
|
||||
class ConfigParser {
|
||||
/** @var string variable to parse from the file */
|
||||
protected $varname = 'conf';
|
||||
/** @var string the key to mark sub arrays */
|
||||
protected $keymarker = Configuration::KEYMARKER;
|
||||
|
||||
/**
|
||||
* Parse the given PHP file into an array
|
||||
*
|
||||
* When the given files does not exist, this returns an empty array
|
||||
*
|
||||
* @param string $file
|
||||
* @return array
|
||||
*/
|
||||
public function parse($file) {
|
||||
if(!file_exists($file)) return array();
|
||||
|
||||
$config = array();
|
||||
$contents = @php_strip_whitespace($file);
|
||||
$pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s';
|
||||
$matches = array();
|
||||
preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER);
|
||||
|
||||
for($i = 0; $i < count($matches); $i++) {
|
||||
$value = $matches[$i][2];
|
||||
|
||||
// merge multi-dimensional array indices using the keymarker
|
||||
$key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]);
|
||||
|
||||
// handle arrays
|
||||
if(preg_match('/^array ?\((.*)\)/', $value, $match)) {
|
||||
$arr = explode(',', $match[1]);
|
||||
|
||||
// remove quotes from quoted strings & unescape escaped data
|
||||
$len = count($arr);
|
||||
for($j = 0; $j < $len; $j++) {
|
||||
$arr[$j] = trim($arr[$j]);
|
||||
$arr[$j] = $this->readValue($arr[$j]);
|
||||
}
|
||||
|
||||
$value = $arr;
|
||||
} else {
|
||||
$value = $this->readValue($value);
|
||||
}
|
||||
|
||||
$config[$key] = $value;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert php string into value
|
||||
*
|
||||
* @param string $value
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function readValue($value) {
|
||||
$removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s';
|
||||
$unescape_pairs = array(
|
||||
'\\\\' => '\\',
|
||||
'\\\'' => '\'',
|
||||
'\\"' => '"'
|
||||
);
|
||||
|
||||
if($value == 'true') {
|
||||
$value = true;
|
||||
} elseif($value == 'false') {
|
||||
$value = false;
|
||||
} else {
|
||||
// remove quotes from quoted strings & unescape escaped data
|
||||
$value = preg_replace($removequotes_pattern, '$2', $value);
|
||||
$value = strtr($value, $unescape_pairs);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
}
|
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';
|
||||
}
|
||||
|
||||
}
|
269
content/lib/plugins/config/core/Loader.php
Normal file
269
content/lib/plugins/config/core/Loader.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core;
|
||||
|
||||
use dokuwiki\Extension\Event;
|
||||
|
||||
/**
|
||||
* Configuration loader
|
||||
*
|
||||
* Loads configuration meta data and settings from the various files. Honors the
|
||||
* configuration cascade and installed plugins.
|
||||
*/
|
||||
class Loader {
|
||||
/** @var ConfigParser */
|
||||
protected $parser;
|
||||
|
||||
/** @var string[] list of enabled plugins */
|
||||
protected $plugins;
|
||||
/** @var string current template */
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* Loader constructor.
|
||||
* @param ConfigParser $parser
|
||||
* @triggers PLUGIN_CONFIG_PLUGINLIST
|
||||
*/
|
||||
public function __construct(ConfigParser $parser) {
|
||||
global $conf;
|
||||
$this->parser = $parser;
|
||||
$this->plugins = plugin_list();
|
||||
$this->template = $conf['template'];
|
||||
// allow plugins to remove configurable plugins
|
||||
Event::createAndTrigger('PLUGIN_CONFIG_PLUGINLIST', $this->plugins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the settings meta data
|
||||
*
|
||||
* Reads the main file, plugins and template settings meta data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadMeta() {
|
||||
// load main file
|
||||
$meta = array();
|
||||
include DOKU_PLUGIN . 'config/settings/config.metadata.php';
|
||||
|
||||
// plugins
|
||||
foreach($this->plugins as $plugin) {
|
||||
$meta = array_merge(
|
||||
$meta,
|
||||
$this->loadExtensionMeta(
|
||||
DOKU_PLUGIN . $plugin . '/conf/metadata.php',
|
||||
'plugin',
|
||||
$plugin
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// current template
|
||||
$meta = array_merge(
|
||||
$meta,
|
||||
$this->loadExtensionMeta(
|
||||
tpl_incdir() . '/conf/metadata.php',
|
||||
'tpl',
|
||||
$this->template
|
||||
)
|
||||
);
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the default values
|
||||
*
|
||||
* Reads the main file, plugins and template defaults
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadDefaults() {
|
||||
// load main files
|
||||
global $config_cascade;
|
||||
$conf = $this->loadConfigs($config_cascade['main']['default']);
|
||||
|
||||
// plugins
|
||||
foreach($this->plugins as $plugin) {
|
||||
$conf = array_merge(
|
||||
$conf,
|
||||
$this->loadExtensionConf(
|
||||
DOKU_PLUGIN . $plugin . '/conf/default.php',
|
||||
'plugin',
|
||||
$plugin
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// current template
|
||||
$conf = array_merge(
|
||||
$conf,
|
||||
$this->loadExtensionConf(
|
||||
tpl_incdir() . '/conf/default.php',
|
||||
'tpl',
|
||||
$this->template
|
||||
)
|
||||
);
|
||||
|
||||
return $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the language strings
|
||||
*
|
||||
* Only reads extensions, main one is loaded the usual way
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadLangs() {
|
||||
$lang = array();
|
||||
|
||||
// plugins
|
||||
foreach($this->plugins as $plugin) {
|
||||
$lang = array_merge(
|
||||
$lang,
|
||||
$this->loadExtensionLang(
|
||||
DOKU_PLUGIN . $plugin . '/',
|
||||
'plugin',
|
||||
$plugin
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// current template
|
||||
$lang = array_merge(
|
||||
$lang,
|
||||
$this->loadExtensionLang(
|
||||
tpl_incdir() . '/',
|
||||
'tpl',
|
||||
$this->template
|
||||
)
|
||||
);
|
||||
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the local settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadLocal() {
|
||||
global $config_cascade;
|
||||
return $this->loadConfigs($config_cascade['main']['local']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the protected settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadProtected() {
|
||||
global $config_cascade;
|
||||
return $this->loadConfigs($config_cascade['main']['protected']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the config values from the given files
|
||||
*
|
||||
* @param string[] $files paths to config php's
|
||||
* @return array
|
||||
*/
|
||||
protected function loadConfigs($files) {
|
||||
$conf = array();
|
||||
foreach($files as $file) {
|
||||
$conf = array_merge($conf, $this->parser->parse($file));
|
||||
}
|
||||
return $conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read settings file from an extension
|
||||
*
|
||||
* This is used to read the settings.php files of plugins and templates
|
||||
*
|
||||
* @param string $file php file to read
|
||||
* @param string $type should be 'plugin' or 'tpl'
|
||||
* @param string $extname name of the extension
|
||||
* @return array
|
||||
*/
|
||||
protected function loadExtensionMeta($file, $type, $extname) {
|
||||
if(!file_exists($file)) return array();
|
||||
$prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
|
||||
|
||||
// include file
|
||||
$meta = array();
|
||||
include $file;
|
||||
if(empty($meta)) return array();
|
||||
|
||||
// read data
|
||||
$data = array();
|
||||
$data[$prefix . $type . '_settings_name'] = ['fieldset'];
|
||||
foreach($meta as $key => $value) {
|
||||
if($value[0] == 'fieldset') continue; //plugins only get one fieldset
|
||||
$data[$prefix . $key] = $value;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a default file from an extension
|
||||
*
|
||||
* This is used to read the default.php files of plugins and templates
|
||||
*
|
||||
* @param string $file php file to read
|
||||
* @param string $type should be 'plugin' or 'tpl'
|
||||
* @param string $extname name of the extension
|
||||
* @return array
|
||||
*/
|
||||
protected function loadExtensionConf($file, $type, $extname) {
|
||||
if(!file_exists($file)) return array();
|
||||
$prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
|
||||
|
||||
// parse file
|
||||
$conf = $this->parser->parse($file);
|
||||
if(empty($conf)) return array();
|
||||
|
||||
// read data
|
||||
$data = array();
|
||||
foreach($conf as $key => $value) {
|
||||
$data[$prefix . $key] = $value;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the language file of an extension
|
||||
*
|
||||
* @param string $dir directory of the extension
|
||||
* @param string $type should be 'plugin' or 'tpl'
|
||||
* @param string $extname name of the extension
|
||||
* @return array
|
||||
*/
|
||||
protected function loadExtensionLang($dir, $type, $extname) {
|
||||
global $conf;
|
||||
$ll = $conf['lang'];
|
||||
$prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
|
||||
|
||||
// include files
|
||||
$lang = array();
|
||||
if(file_exists($dir . 'lang/en/settings.php')) {
|
||||
include $dir . 'lang/en/settings.php';
|
||||
}
|
||||
if($ll != 'en' && file_exists($dir . 'lang/' . $ll . '/settings.php')) {
|
||||
include $dir . 'lang/' . $ll . '/settings.php';
|
||||
}
|
||||
|
||||
// set up correct keys
|
||||
$strings = array();
|
||||
foreach($lang as $key => $val) {
|
||||
$strings[$prefix . $key] = $val;
|
||||
}
|
||||
|
||||
// add fieldset key
|
||||
$strings[$prefix . $type . '_settings_name'] = ucwords(str_replace('_', ' ', $extname));
|
||||
|
||||
return $strings;
|
||||
}
|
||||
}
|
294
content/lib/plugins/config/core/Setting/Setting.php
Normal file
294
content/lib/plugins/config/core/Setting/Setting.php
Normal file
@@ -0,0 +1,294 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
use dokuwiki\plugin\config\core\Configuration;
|
||||
|
||||
/**
|
||||
* Class Setting
|
||||
*/
|
||||
class Setting {
|
||||
/** @var string unique identifier of this setting */
|
||||
protected $key = '';
|
||||
|
||||
/** @var mixed the default value of this setting */
|
||||
protected $default = null;
|
||||
/** @var mixed the local value of this setting */
|
||||
protected $local = null;
|
||||
/** @var mixed the protected value of this setting */
|
||||
protected $protected = null;
|
||||
|
||||
/** @var array valid alerts, images matching the alerts are in the plugin's images directory */
|
||||
static protected $validCautions = array('warning', 'danger', 'security');
|
||||
|
||||
protected $pattern = '';
|
||||
protected $error = false; // only used by those classes which error check
|
||||
protected $input = null; // only used by those classes which error check
|
||||
protected $caution = null; // used by any setting to provide an alert along with the setting
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The given parameters will be set up as class properties
|
||||
*
|
||||
* @see initialize() to set the actual value of the setting
|
||||
*
|
||||
* @param string $key
|
||||
* @param array|null $params array with metadata of setting
|
||||
*/
|
||||
public function __construct($key, $params = null) {
|
||||
$this->key = $key;
|
||||
|
||||
if(is_array($params)) {
|
||||
foreach($params as $property => $value) {
|
||||
$property = trim($property, '_'); // we don't use underscores anymore
|
||||
$this->$property = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current values for the setting $key
|
||||
*
|
||||
* This is used to initialize the setting with the data read form the config files.
|
||||
*
|
||||
* @see update() to set a new value
|
||||
* @param mixed $default default setting value
|
||||
* @param mixed $local local setting value
|
||||
* @param mixed $protected protected setting value
|
||||
*/
|
||||
public function initialize($default = null, $local = null, $protected = null) {
|
||||
$this->default = $this->cleanValue($default);
|
||||
$this->local = $this->cleanValue($local);
|
||||
$this->protected = $this->cleanValue($protected);
|
||||
}
|
||||
|
||||
/**
|
||||
* update changed setting with validated user provided value $input
|
||||
* - if changed value fails validation check, save it to $this->input (to allow echoing later)
|
||||
* - if changed value passes validation check, set $this->local to the new value
|
||||
*
|
||||
* @param mixed $input the new value
|
||||
* @return boolean true if changed, false otherwise
|
||||
*/
|
||||
public function update($input) {
|
||||
if(is_null($input)) return false;
|
||||
if($this->isProtected()) return false;
|
||||
$input = $this->cleanValue($input);
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
// validate new value
|
||||
if($this->pattern && !preg_match($this->pattern, $input)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
|
||||
// update local copy of this setting with new value
|
||||
$this->local = $input;
|
||||
|
||||
// setting ready for update
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean a value read from a config before using it internally
|
||||
*
|
||||
* Default implementation returns $value as is. Subclasses can override.
|
||||
* Note: null should always be returned as null!
|
||||
*
|
||||
* This is applied in initialize() and update()
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
protected function cleanValue($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this type of config have a default?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldHaveDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this setting's unique key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getKey() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the key of this setting marked up human readable
|
||||
*
|
||||
* @param bool $url link to dokuwiki.org manual?
|
||||
* @return string
|
||||
*/
|
||||
public function getPrettyKey($url = true) {
|
||||
$out = str_replace(Configuration::KEYMARKER, "»", $this->key);
|
||||
if($url && !strstr($out, '»')) {//provide no urls for plugins, etc.
|
||||
if($out == 'start') {
|
||||
// exception, because this config name is clashing with our actual start page
|
||||
return '<a href="http://www.dokuwiki.org/config:startpage">' . $out . '</a>';
|
||||
} else {
|
||||
return '<a href="http://www.dokuwiki.org/config:' . $out . '">' . $out . '</a>';
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns setting key as an array key separator
|
||||
*
|
||||
* This is used to create form output
|
||||
*
|
||||
* @return string key
|
||||
*/
|
||||
public function getArrayKey() {
|
||||
return str_replace(Configuration::KEYMARKER, "']['", $this->key);
|
||||
}
|
||||
|
||||
/**
|
||||
* What type of configuration is this
|
||||
*
|
||||
* Returns one of
|
||||
*
|
||||
* 'plugin' for plugin configuration
|
||||
* 'template' for template configuration
|
||||
* 'dokuwiki' for core configuration
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType() {
|
||||
if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) {
|
||||
return 'plugin';
|
||||
} else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) {
|
||||
return 'template';
|
||||
} else {
|
||||
return 'dokuwiki';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build html for label and input of setting
|
||||
*
|
||||
* @param \admin_plugin_config $plugin object of config plugin
|
||||
* @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting
|
||||
* @return string[] with content array(string $label_html, string $input_html)
|
||||
*/
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
$disable = '';
|
||||
|
||||
if($this->isProtected()) {
|
||||
$value = $this->protected;
|
||||
$disable = 'disabled="disabled"';
|
||||
} else {
|
||||
if($echo && $this->error) {
|
||||
$value = $this->input;
|
||||
} else {
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
}
|
||||
}
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
$value = formText($value);
|
||||
|
||||
$label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
|
||||
$input = '<textarea rows="3" cols="40" id="config___' . $key .
|
||||
'" name="config[' . $key . ']" class="edit" ' . $disable . '>' . $value . '</textarea>';
|
||||
return array($label, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the current local value be saved?
|
||||
*
|
||||
* @see out() to run when this returns true
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldBeSaved() {
|
||||
if($this->isProtected()) return false;
|
||||
if($this->local === null) return false;
|
||||
if($this->default == $this->local) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate string to save local setting value to file according to $fmt
|
||||
*
|
||||
* @see shouldBeSaved() to check if this should be called
|
||||
* @param string $var name of variable
|
||||
* @param string $fmt save format
|
||||
* @return string
|
||||
*/
|
||||
public function out($var, $fmt = 'php') {
|
||||
if($fmt != 'php') return '';
|
||||
|
||||
$tr = array("\\" => '\\\\', "'" => '\\\''); // escape the value
|
||||
$out = '$' . $var . "['" . $this->getArrayKey() . "'] = '" . strtr(cleanText($this->local), $tr) . "';\n";
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the localized prompt
|
||||
*
|
||||
* @param \admin_plugin_config $plugin object of config plugin
|
||||
* @return string text
|
||||
*/
|
||||
public function prompt(\admin_plugin_config $plugin) {
|
||||
$prompt = $plugin->getLang($this->key);
|
||||
if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key));
|
||||
return $prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is setting protected
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isProtected() {
|
||||
return !is_null($this->protected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is setting the default?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDefault() {
|
||||
return !$this->isProtected() && is_null($this->local);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has an error?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasError() {
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns caution
|
||||
*
|
||||
* @return false|string caution string, otherwise false for invalid caution
|
||||
*/
|
||||
public function caution() {
|
||||
if(empty($this->caution)) return false;
|
||||
if(!in_array($this->caution, Setting::$validCautions)) {
|
||||
throw new \RuntimeException(
|
||||
'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"'
|
||||
);
|
||||
}
|
||||
return $this->caution;
|
||||
}
|
||||
|
||||
}
|
105
content/lib/plugins/config/core/Setting/SettingArray.php
Normal file
105
content/lib/plugins/config/core/Setting/SettingArray.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_array
|
||||
*/
|
||||
class SettingArray extends Setting {
|
||||
|
||||
/**
|
||||
* Create an array from a string
|
||||
*
|
||||
* @param string $string
|
||||
* @return array
|
||||
*/
|
||||
protected function fromString($string) {
|
||||
$array = explode(',', $string);
|
||||
$array = array_map('trim', $array);
|
||||
$array = array_filter($array);
|
||||
$array = array_unique($array);
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string from an array
|
||||
*
|
||||
* @param array $array
|
||||
* @return string
|
||||
*/
|
||||
protected function fromArray($array) {
|
||||
return join(', ', (array) $array);
|
||||
}
|
||||
|
||||
/**
|
||||
* update setting with user provided value $input
|
||||
* if value fails error check, save it
|
||||
*
|
||||
* @param string $input
|
||||
* @return bool true if changed, false otherwise (incl. on error)
|
||||
*/
|
||||
public function update($input) {
|
||||
if(is_null($input)) return false;
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
$input = $this->fromString($input);
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
foreach($input as $item) {
|
||||
if($this->pattern && !preg_match($this->pattern, $item)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escaping
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
protected function escape($string) {
|
||||
$tr = array("\\" => '\\\\', "'" => '\\\'');
|
||||
return "'" . strtr(cleanText($string), $tr) . "'";
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function out($var, $fmt = 'php') {
|
||||
if($fmt != 'php') return '';
|
||||
|
||||
$vals = array_map(array($this, 'escape'), $this->local);
|
||||
$out = '$' . $var . "['" . $this->getArrayKey() . "'] = array(" . join(', ', $vals) . ");\n";
|
||||
return $out;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
$disable = '';
|
||||
|
||||
if($this->isProtected()) {
|
||||
$value = $this->protected;
|
||||
$disable = 'disabled="disabled"';
|
||||
} else {
|
||||
if($echo && $this->error) {
|
||||
$value = $this->input;
|
||||
} else {
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
}
|
||||
}
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
$value = htmlspecialchars($this->fromArray($value));
|
||||
|
||||
$label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
|
||||
$input = '<input id="config___' . $key . '" name="config[' . $key .
|
||||
']" type="text" class="edit" value="' . $value . '" ' . $disable . '/>';
|
||||
return array($label, $input);
|
||||
}
|
||||
}
|
60
content/lib/plugins/config/core/Setting/SettingAuthtype.php
Normal file
60
content/lib/plugins/config/core/Setting/SettingAuthtype.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_authtype
|
||||
*/
|
||||
class SettingAuthtype extends SettingMultichoice {
|
||||
|
||||
/** @inheritdoc */
|
||||
public function initialize($default = null, $local = null, $protected = null) {
|
||||
/** @var $plugin_controller \dokuwiki\Extension\PluginController */
|
||||
global $plugin_controller;
|
||||
|
||||
// retrieve auth types provided by plugins
|
||||
foreach($plugin_controller->getList('auth') as $plugin) {
|
||||
$this->choices[] = $plugin;
|
||||
}
|
||||
|
||||
parent::initialize($default, $local, $protected);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
/** @var $plugin_controller \dokuwiki\Extension\PluginController */
|
||||
global $plugin_controller;
|
||||
|
||||
// is an update possible/requested?
|
||||
$local = $this->local; // save this, parent::update() may change it
|
||||
if(!parent::update($input)) return false; // nothing changed or an error caught by parent
|
||||
$this->local = $local; // restore original, more error checking to come
|
||||
|
||||
// attempt to load the plugin
|
||||
$auth_plugin = $plugin_controller->load('auth', $input);
|
||||
|
||||
// @TODO: throw an error in plugin controller instead of returning null
|
||||
if(is_null($auth_plugin)) {
|
||||
$this->error = true;
|
||||
msg('Cannot load Auth Plugin "' . $input . '"', -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify proper instantiation (is this really a plugin?) @TODO use instanceof? implement interface?
|
||||
if(is_object($auth_plugin) && !method_exists($auth_plugin, 'getPluginName')) {
|
||||
$this->error = true;
|
||||
msg('Cannot create Auth Plugin "' . $input . '"', -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
// did we change the auth type? logout
|
||||
global $conf;
|
||||
if($conf['authtype'] != $input) {
|
||||
msg('Authentication system changed. Please re-login.');
|
||||
auth_logoff();
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_compression
|
||||
*/
|
||||
class SettingCompression extends SettingMultichoice {
|
||||
|
||||
protected $choices = array('0'); // 0 = no compression, always supported
|
||||
|
||||
/** @inheritdoc */
|
||||
public function initialize($default = null, $local = null, $protected = null) {
|
||||
|
||||
// populate _choices with the compression methods supported by this php installation
|
||||
if(function_exists('gzopen')) $this->choices[] = 'gz';
|
||||
if(function_exists('bzopen')) $this->choices[] = 'bz2';
|
||||
|
||||
parent::initialize($default, $local, $protected);
|
||||
}
|
||||
}
|
33
content/lib/plugins/config/core/Setting/SettingDirchoice.php
Normal file
33
content/lib/plugins/config/core/Setting/SettingDirchoice.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_dirchoice
|
||||
*/
|
||||
class SettingDirchoice extends SettingMultichoice {
|
||||
|
||||
protected $dir = '';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function initialize($default = null, $local = null, $protected = null) {
|
||||
|
||||
// populate $this->_choices with a list of directories
|
||||
$list = array();
|
||||
|
||||
if($dh = @opendir($this->dir)) {
|
||||
while(false !== ($entry = readdir($dh))) {
|
||||
if($entry == '.' || $entry == '..') continue;
|
||||
if($this->pattern && !preg_match($this->pattern, $entry)) continue;
|
||||
|
||||
$file = (is_link($this->dir . $entry)) ? readlink($this->dir . $entry) : $this->dir . $entry;
|
||||
if(is_dir($file)) $list[] = $entry;
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
sort($list);
|
||||
$this->choices = $list;
|
||||
|
||||
parent::initialize($default, $local, $protected);
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_disableactions
|
||||
*/
|
||||
class SettingDisableactions extends SettingMulticheckbox {
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
global $lang;
|
||||
|
||||
// make some language adjustments (there must be a better way)
|
||||
// transfer some DokuWiki language strings to the plugin
|
||||
$plugin->addLang($this->key . '_revisions', $lang['btn_revs']);
|
||||
foreach($this->choices as $choice) {
|
||||
if(isset($lang['btn_' . $choice])) $plugin->addLang($this->key . '_' . $choice, $lang['btn_' . $choice]);
|
||||
}
|
||||
|
||||
return parent::html($plugin, $echo);
|
||||
}
|
||||
}
|
58
content/lib/plugins/config/core/Setting/SettingEmail.php
Normal file
58
content/lib/plugins/config/core/Setting/SettingEmail.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_email
|
||||
*/
|
||||
class SettingEmail extends SettingString {
|
||||
protected $multiple = false;
|
||||
protected $placeholders = false;
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if(is_null($input)) return false;
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
if($input === '') {
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
$mail = $input;
|
||||
|
||||
if($this->placeholders) {
|
||||
// replace variables with pseudo values
|
||||
$mail = str_replace('@USER@', 'joe', $mail);
|
||||
$mail = str_replace('@NAME@', 'Joe Schmoe', $mail);
|
||||
$mail = str_replace('@MAIL@', 'joe@example.com', $mail);
|
||||
}
|
||||
|
||||
// multiple mail addresses?
|
||||
if($this->multiple) {
|
||||
$mails = array_filter(array_map('trim', explode(',', $mail)));
|
||||
} else {
|
||||
$mails = array($mail);
|
||||
}
|
||||
|
||||
// check them all
|
||||
foreach($mails as $mail) {
|
||||
// only check the address part
|
||||
if(preg_match('#(.*?)<(.*?)>#', $mail, $matches)) {
|
||||
$addr = $matches[2];
|
||||
} else {
|
||||
$addr = $mail;
|
||||
}
|
||||
|
||||
if(!mail_isvalid($addr)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
17
content/lib/plugins/config/core/Setting/SettingFieldset.php
Normal file
17
content/lib/plugins/config/core/Setting/SettingFieldset.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* A do-nothing class used to detect the 'fieldset' type.
|
||||
*
|
||||
* Used to start a new settings "display-group".
|
||||
*/
|
||||
class SettingFieldset extends Setting {
|
||||
|
||||
/** @inheritdoc */
|
||||
public function shouldHaveDefault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
10
content/lib/plugins/config/core/Setting/SettingHidden.php
Normal file
10
content/lib/plugins/config/core/Setting/SettingHidden.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_hidden
|
||||
*/
|
||||
class SettingHidden extends Setting {
|
||||
// Used to explicitly ignore a setting in the configuration manager.
|
||||
}
|
28
content/lib/plugins/config/core/Setting/SettingImConvert.php
Normal file
28
content/lib/plugins/config/core/Setting/SettingImConvert.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_im_convert
|
||||
*/
|
||||
class SettingImConvert extends SettingString {
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
$input = trim($input);
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
if($input && !file_exists($input)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
23
content/lib/plugins/config/core/Setting/SettingLicense.php
Normal file
23
content/lib/plugins/config/core/Setting/SettingLicense.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_license
|
||||
*/
|
||||
class SettingLicense extends SettingMultichoice {
|
||||
|
||||
protected $choices = array(''); // none choosen
|
||||
|
||||
/** @inheritdoc */
|
||||
public function initialize($default = null, $local = null, $protected = null) {
|
||||
global $license;
|
||||
|
||||
foreach($license as $key => $data) {
|
||||
$this->choices[] = $key;
|
||||
$this->lang[$this->key . '_o_' . $key] = $data['name']; // stored in setting
|
||||
}
|
||||
|
||||
parent::initialize($default, $local, $protected);
|
||||
}
|
||||
}
|
163
content/lib/plugins/config/core/Setting/SettingMulticheckbox.php
Normal file
163
content/lib/plugins/config/core/Setting/SettingMulticheckbox.php
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_multicheckbox
|
||||
*/
|
||||
class SettingMulticheckbox extends SettingString {
|
||||
|
||||
protected $choices = array();
|
||||
protected $combine = array();
|
||||
protected $other = 'always';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
// split any combined values + convert from array to comma separated string
|
||||
$input = ($input) ? $input : array();
|
||||
$input = $this->array2str($input);
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
if($this->pattern && !preg_match($this->pattern, $input)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
|
||||
$disable = '';
|
||||
|
||||
if($this->isProtected()) {
|
||||
$value = $this->protected;
|
||||
$disable = 'disabled="disabled"';
|
||||
} else {
|
||||
if($echo && $this->error) {
|
||||
$value = $this->input;
|
||||
} else {
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
}
|
||||
}
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
|
||||
// convert from comma separated list into array + combine complimentary actions
|
||||
$value = $this->str2array($value);
|
||||
$default = $this->str2array($this->default);
|
||||
|
||||
$input = '';
|
||||
foreach($this->choices as $choice) {
|
||||
$idx = array_search($choice, $value);
|
||||
$idx_default = array_search($choice, $default);
|
||||
|
||||
$checked = ($idx !== false) ? 'checked="checked"' : '';
|
||||
|
||||
// @todo ideally this would be handled using a second class of "default"
|
||||
$class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : "";
|
||||
|
||||
$prompt = ($plugin->getLang($this->key . '_' . $choice) ?
|
||||
$plugin->getLang($this->key . '_' . $choice) : htmlspecialchars($choice));
|
||||
|
||||
$input .= '<div class="selection' . $class . '">' . "\n";
|
||||
$input .= '<label for="config___' . $key . '_' . $choice . '">' . $prompt . "</label>\n";
|
||||
$input .= '<input id="config___' . $key . '_' . $choice . '" name="config[' . $key .
|
||||
'][]" type="checkbox" class="checkbox" value="' . $choice . '" ' . $disable . ' ' . $checked . "/>\n";
|
||||
$input .= "</div>\n";
|
||||
|
||||
// remove this action from the disabledactions array
|
||||
if($idx !== false) unset($value[$idx]);
|
||||
if($idx_default !== false) unset($default[$idx_default]);
|
||||
}
|
||||
|
||||
// handle any remaining values
|
||||
if($this->other != 'never') {
|
||||
$other = join(',', $value);
|
||||
// test equivalent to ($this->_other == 'always' || ($other && $this->_other == 'exists')
|
||||
// use != 'exists' rather than == 'always' to ensure invalid values default to 'always'
|
||||
if($this->other != 'exists' || $other) {
|
||||
|
||||
$class = (
|
||||
(count($default) == count($value)) &&
|
||||
(count($value) == count(array_intersect($value, $default)))
|
||||
) ?
|
||||
" selectiondefault" : "";
|
||||
|
||||
$input .= '<div class="other' . $class . '">' . "\n";
|
||||
$input .= '<label for="config___' . $key . '_other">' .
|
||||
$plugin->getLang($key . '_other') .
|
||||
"</label>\n";
|
||||
$input .= '<input id="config___' . $key . '_other" name="config[' . $key .
|
||||
'][other]" type="text" class="edit" value="' . htmlspecialchars($other) .
|
||||
'" ' . $disable . " />\n";
|
||||
$input .= "</div>\n";
|
||||
}
|
||||
}
|
||||
$label = '<label>' . $this->prompt($plugin) . '</label>';
|
||||
return array($label, $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* convert comma separated list to an array and combine any complimentary values
|
||||
*
|
||||
* @param string $str
|
||||
* @return array
|
||||
*/
|
||||
protected function str2array($str) {
|
||||
$array = explode(',', $str);
|
||||
|
||||
if(!empty($this->combine)) {
|
||||
foreach($this->combine as $key => $combinators) {
|
||||
$idx = array();
|
||||
foreach($combinators as $val) {
|
||||
if(($idx[] = array_search($val, $array)) === false) break;
|
||||
}
|
||||
|
||||
if(count($idx) && $idx[count($idx) - 1] !== false) {
|
||||
foreach($idx as $i) unset($array[$i]);
|
||||
$array[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert array of values + other back to a comma separated list, incl. splitting any combined values
|
||||
*
|
||||
* @param array $input
|
||||
* @return string
|
||||
*/
|
||||
protected function array2str($input) {
|
||||
|
||||
// handle other
|
||||
$other = trim($input['other']);
|
||||
$other = !empty($other) ? explode(',', str_replace(' ', '', $input['other'])) : array();
|
||||
unset($input['other']);
|
||||
|
||||
$array = array_unique(array_merge($input, $other));
|
||||
|
||||
// deconstruct any combinations
|
||||
if(!empty($this->combine)) {
|
||||
foreach($this->combine as $key => $combinators) {
|
||||
|
||||
$idx = array_search($key, $array);
|
||||
if($idx !== false) {
|
||||
unset($array[$idx]);
|
||||
$array = array_merge($array, $combinators);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return join(',', array_unique($array));
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_multichoice
|
||||
*/
|
||||
class SettingMultichoice extends SettingString {
|
||||
protected $choices = array();
|
||||
public $lang; //some custom language strings are stored in setting
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
$disable = '';
|
||||
$nochoice = '';
|
||||
|
||||
if($this->isProtected()) {
|
||||
$value = $this->protected;
|
||||
$disable = ' disabled="disabled"';
|
||||
} else {
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
}
|
||||
|
||||
// ensure current value is included
|
||||
if(!in_array($value, $this->choices)) {
|
||||
$this->choices[] = $value;
|
||||
}
|
||||
// disable if no other choices
|
||||
if(!$this->isProtected() && count($this->choices) <= 1) {
|
||||
$disable = ' disabled="disabled"';
|
||||
$nochoice = $plugin->getLang('nochoice');
|
||||
}
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
|
||||
$label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
|
||||
|
||||
$input = "<div class=\"input\">\n";
|
||||
$input .= '<select class="edit" id="config___' . $key . '" name="config[' . $key . ']"' . $disable . '>' . "\n";
|
||||
foreach($this->choices as $choice) {
|
||||
$selected = ($value == $choice) ? ' selected="selected"' : '';
|
||||
$option = $plugin->getLang($this->key . '_o_' . $choice);
|
||||
if(!$option && isset($this->lang[$this->key . '_o_' . $choice])) {
|
||||
$option = $this->lang[$this->key . '_o_' . $choice];
|
||||
}
|
||||
if(!$option) $option = $choice;
|
||||
|
||||
$choice = htmlspecialchars($choice);
|
||||
$option = htmlspecialchars($option);
|
||||
$input .= ' <option value="' . $choice . '"' . $selected . ' >' . $option . '</option>' . "\n";
|
||||
}
|
||||
$input .= "</select> $nochoice \n";
|
||||
$input .= "</div>\n";
|
||||
|
||||
return array($label, $input);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if(is_null($input)) return false;
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
if(!in_array($input, $this->choices)) return false;
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
12
content/lib/plugins/config/core/Setting/SettingNoClass.php
Normal file
12
content/lib/plugins/config/core/Setting/SettingNoClass.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_no_class
|
||||
* A do-nothing class used to detect settings with a missing setting class.
|
||||
* Used internaly to hide undefined settings, and generate the undefined settings list.
|
||||
*/
|
||||
class SettingNoClass extends SettingUndefined {
|
||||
protected $errorMessage = '_msg_setting_no_class';
|
||||
}
|
13
content/lib/plugins/config/core/Setting/SettingNoDefault.php
Normal file
13
content/lib/plugins/config/core/Setting/SettingNoDefault.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_no_default
|
||||
*
|
||||
* A do-nothing class used to detect settings with no default value.
|
||||
* Used internaly to hide undefined settings, and generate the undefined settings list.
|
||||
*/
|
||||
class SettingNoDefault extends SettingUndefined {
|
||||
protected $errorMessage = '_msg_setting_no_default';
|
||||
}
|
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* A do-nothing class used to detect settings with a missing setting class.
|
||||
* Used internaly to hide undefined settings, and generate the undefined settings list.
|
||||
*/
|
||||
class SettingNoKnownClass extends SettingUndefined {
|
||||
protected $errorMessage = '_msg_setting_no_known_class';
|
||||
}
|
42
content/lib/plugins/config/core/Setting/SettingNumeric.php
Normal file
42
content/lib/plugins/config/core/Setting/SettingNumeric.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_numeric
|
||||
*/
|
||||
class SettingNumeric extends SettingString {
|
||||
// This allows for many PHP syntax errors...
|
||||
// var $_pattern = '/^[-+\/*0-9 ]*$/';
|
||||
// much more restrictive, but should eliminate syntax errors.
|
||||
protected $pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/';
|
||||
protected $min = null;
|
||||
protected $max = null;
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
$local = $this->local;
|
||||
$valid = parent::update($input);
|
||||
if($valid && !(is_null($this->min) && is_null($this->max))) {
|
||||
$numeric_local = (int) eval('return ' . $this->local . ';');
|
||||
if((!is_null($this->min) && $numeric_local < $this->min) ||
|
||||
(!is_null($this->max) && $numeric_local > $this->max)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
$this->local = $local;
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function out($var, $fmt = 'php') {
|
||||
if($fmt != 'php') return '';
|
||||
|
||||
$local = $this->local === '' ? "''" : $this->local;
|
||||
$out = '$' . $var . "['" . $this->getArrayKey() . "'] = " . $local . ";\n";
|
||||
|
||||
return $out;
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_numericopt
|
||||
*/
|
||||
class SettingNumericopt extends SettingNumeric {
|
||||
// just allow an empty config
|
||||
protected $pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* Empty string is valid for numericopt
|
||||
*/
|
||||
public function update($input) {
|
||||
if($input === '') {
|
||||
if($input == $this->local) return false;
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
|
||||
return parent::update($input);
|
||||
}
|
||||
}
|
57
content/lib/plugins/config/core/Setting/SettingOnoff.php
Normal file
57
content/lib/plugins/config/core/Setting/SettingOnoff.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_onoff
|
||||
*/
|
||||
class SettingOnoff extends SettingNumeric {
|
||||
|
||||
/**
|
||||
* We treat the strings 'false' and 'off' as false
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function cleanValue($value) {
|
||||
if($value === null) return null;
|
||||
|
||||
if(is_string($value)) {
|
||||
if(strtolower($value) === 'false') return 0;
|
||||
if(strtolower($value) === 'off') return 0;
|
||||
if(trim($value) === '') return 0;
|
||||
}
|
||||
|
||||
return (int) (bool) $value;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
$disable = '';
|
||||
|
||||
if($this->isProtected()) {
|
||||
$value = $this->protected;
|
||||
$disable = ' disabled="disabled"';
|
||||
} else {
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
}
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
$checked = ($value) ? ' checked="checked"' : '';
|
||||
|
||||
$label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
|
||||
$input = '<div class="input"><input id="config___' . $key . '" name="config[' . $key .
|
||||
']" type="checkbox" class="checkbox" value="1"' . $checked . $disable . '/></div>';
|
||||
return array($label, $input);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
$input = ($input) ? 1 : 0;
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
39
content/lib/plugins/config/core/Setting/SettingPassword.php
Normal file
39
content/lib/plugins/config/core/Setting/SettingPassword.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_password
|
||||
*/
|
||||
class SettingPassword extends SettingString {
|
||||
|
||||
protected $code = 'plain'; // mechanism to be used to obscure passwords
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if($this->isProtected()) return false;
|
||||
if(!$input) return false;
|
||||
|
||||
if($this->pattern && !preg_match($this->pattern, $input)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->local = conf_encodeString($input, $this->code);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
|
||||
$disable = $this->isProtected() ? 'disabled="disabled"' : '';
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
|
||||
$label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
|
||||
$input = '<input id="config___' . $key . '" name="config[' . $key .
|
||||
']" autocomplete="off" type="password" class="edit" value="" ' . $disable . ' />';
|
||||
return array($label, $input);
|
||||
}
|
||||
}
|
34
content/lib/plugins/config/core/Setting/SettingRegex.php
Normal file
34
content/lib/plugins/config/core/Setting/SettingRegex.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_regex
|
||||
*/
|
||||
class SettingRegex extends SettingString {
|
||||
|
||||
protected $delimiter = '/'; // regex delimiter to be used in testing input
|
||||
protected $pregflags = 'ui'; // regex pattern modifiers to be used in testing input
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
|
||||
// let parent do basic checks, value, not changed, etc.
|
||||
$local = $this->local;
|
||||
if(!parent::update($input)) return false;
|
||||
$this->local = $local;
|
||||
|
||||
// see if the regex compiles and runs (we don't check for effectiveness)
|
||||
$regex = $this->delimiter . $input . $this->delimiter . $this->pregflags;
|
||||
$lastError = error_get_last();
|
||||
@preg_match($regex, 'testdata');
|
||||
if(preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) {
|
||||
$this->input = $input;
|
||||
$this->error = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
56
content/lib/plugins/config/core/Setting/SettingRenderer.php
Normal file
56
content/lib/plugins/config/core/Setting/SettingRenderer.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* additional setting classes specific to these settings
|
||||
*
|
||||
* @author Chris Smith <chris@jalakai.co.uk>
|
||||
*/
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_renderer
|
||||
*/
|
||||
class SettingRenderer extends SettingMultichoice {
|
||||
protected $prompts = array();
|
||||
protected $format = null;
|
||||
|
||||
/** @inheritdoc */
|
||||
public function initialize($default = null, $local = null, $protected = null) {
|
||||
$format = $this->format;
|
||||
|
||||
foreach(plugin_list('renderer') as $plugin) {
|
||||
$renderer = plugin_load('renderer', $plugin);
|
||||
if(method_exists($renderer, 'canRender') && $renderer->canRender($format)) {
|
||||
$this->choices[] = $plugin;
|
||||
|
||||
$info = $renderer->getInfo();
|
||||
$this->prompts[$plugin] = $info['name'];
|
||||
}
|
||||
}
|
||||
|
||||
parent::initialize($default, $local, $protected);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
|
||||
// make some language adjustments (there must be a better way)
|
||||
// transfer some plugin names to the config plugin
|
||||
foreach($this->choices as $choice) {
|
||||
if(!$plugin->getLang($this->key . '_o_' . $choice)) {
|
||||
if(!isset($this->prompts[$choice])) {
|
||||
$plugin->addLang(
|
||||
$this->key . '_o_' . $choice,
|
||||
sprintf($plugin->getLang('renderer__core'), $choice)
|
||||
);
|
||||
} else {
|
||||
$plugin->addLang(
|
||||
$this->key . '_o_' . $choice,
|
||||
sprintf($plugin->getLang('renderer__plugin'), $this->prompts[$choice])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parent::html($plugin, $echo);
|
||||
}
|
||||
}
|
26
content/lib/plugins/config/core/Setting/SettingSavedir.php
Normal file
26
content/lib/plugins/config/core/Setting/SettingSavedir.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_savedir
|
||||
*/
|
||||
class SettingSavedir extends SettingString {
|
||||
|
||||
/** @inheritdoc */
|
||||
public function update($input) {
|
||||
if($this->isProtected()) return false;
|
||||
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
if($value == $input) return false;
|
||||
|
||||
if(!init_path($input)) {
|
||||
$this->error = true;
|
||||
$this->input = $input;
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->local = $input;
|
||||
return true;
|
||||
}
|
||||
}
|
18
content/lib/plugins/config/core/Setting/SettingSepchar.php
Normal file
18
content/lib/plugins/config/core/Setting/SettingSepchar.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_sepchar
|
||||
*/
|
||||
class SettingSepchar extends SettingMultichoice {
|
||||
|
||||
/** @inheritdoc */
|
||||
public function __construct($key, $param = null) {
|
||||
$str = '_-.';
|
||||
for($i = 0; $i < strlen($str); $i++) $this->choices[] = $str[$i];
|
||||
|
||||
// call foundation class constructor
|
||||
parent::__construct($key, $param);
|
||||
}
|
||||
}
|
32
content/lib/plugins/config/core/Setting/SettingString.php
Normal file
32
content/lib/plugins/config/core/Setting/SettingString.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
/**
|
||||
* Class setting_string
|
||||
*/
|
||||
class SettingString extends Setting {
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
$disable = '';
|
||||
|
||||
if($this->isProtected()) {
|
||||
$value = $this->protected;
|
||||
$disable = 'disabled="disabled"';
|
||||
} else {
|
||||
if($echo && $this->error) {
|
||||
$value = $this->input;
|
||||
} else {
|
||||
$value = is_null($this->local) ? $this->default : $this->local;
|
||||
}
|
||||
}
|
||||
|
||||
$key = htmlspecialchars($this->key);
|
||||
$value = htmlspecialchars($value);
|
||||
|
||||
$label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
|
||||
$input = '<input id="config___' . $key . '" name="config[' . $key .
|
||||
']" type="text" class="edit" value="' . $value . '" ' . $disable . '/>';
|
||||
return array($label, $input);
|
||||
}
|
||||
}
|
40
content/lib/plugins/config/core/Setting/SettingUndefined.php
Normal file
40
content/lib/plugins/config/core/Setting/SettingUndefined.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core\Setting;
|
||||
|
||||
use dokuwiki\plugin\config\core\Configuration;
|
||||
|
||||
/**
|
||||
* A do-nothing class used to detect settings with no metadata entry.
|
||||
* Used internaly to hide undefined settings, and generate the undefined settings list.
|
||||
*/
|
||||
class SettingUndefined extends SettingHidden {
|
||||
|
||||
protected $errorMessage = '_msg_setting_undefined';
|
||||
|
||||
/** @inheritdoc */
|
||||
public function shouldHaveDefault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function html(\admin_plugin_config $plugin, $echo = false) {
|
||||
// determine the name the meta key would be called
|
||||
if(preg_match(
|
||||
'/^(?:plugin|tpl)' . Configuration::KEYMARKER . '.*?' . Configuration::KEYMARKER . '(.*)$/',
|
||||
$this->getKey(),
|
||||
$undefined_setting_match
|
||||
)) {
|
||||
$undefined_setting_key = $undefined_setting_match[1];
|
||||
} else {
|
||||
$undefined_setting_key = $this->getKey();
|
||||
}
|
||||
|
||||
$label = '<span title="$meta[\'' . $undefined_setting_key . '\']">$' .
|
||||
'conf' . '[\'' . $this->getArrayKey() . '\']</span>';
|
||||
$input = $plugin->getLang($this->errorMessage);
|
||||
|
||||
return array($label, $input);
|
||||
}
|
||||
|
||||
}
|
116
content/lib/plugins/config/core/Writer.php
Normal file
116
content/lib/plugins/config/core/Writer.php
Normal file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace dokuwiki\plugin\config\core;
|
||||
use dokuwiki\plugin\config\core\Setting\Setting;
|
||||
|
||||
/**
|
||||
* Writes the settings to the correct local file
|
||||
*/
|
||||
class Writer {
|
||||
/** @var string header info */
|
||||
protected $header = 'Dokuwiki\'s Main Configuration File - Local Settings';
|
||||
|
||||
/** @var string the file where the config will be saved to */
|
||||
protected $savefile;
|
||||
|
||||
/**
|
||||
* Writer constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
global $config_cascade;
|
||||
$this->savefile = end($config_cascade['main']['local']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the given settings
|
||||
*
|
||||
* @param Setting[] $settings
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function save($settings) {
|
||||
global $conf;
|
||||
if($this->isLocked()) throw new \Exception('no save');
|
||||
|
||||
// backup current file (remove any existing backup)
|
||||
if(file_exists($this->savefile)) {
|
||||
if(file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php');
|
||||
if(!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup');
|
||||
}
|
||||
|
||||
if(!$fh = @fopen($this->savefile, 'wb')) {
|
||||
io_rename($this->savefile . '.bak.php', $this->savefile); // problem opening, restore the backup
|
||||
throw new \Exception('no save');
|
||||
}
|
||||
|
||||
$out = $this->getHeader();
|
||||
foreach($settings as $setting) {
|
||||
if($setting->shouldBeSaved()) {
|
||||
$out .= $setting->out('conf', 'php');
|
||||
}
|
||||
}
|
||||
|
||||
fwrite($fh, $out);
|
||||
fclose($fh);
|
||||
if($conf['fperm']) chmod($this->savefile, $conf['fperm']);
|
||||
$this->opcacheUpdate($this->savefile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update last modified time stamp of the config file
|
||||
*
|
||||
* Will invalidate all DokuWiki caches
|
||||
*
|
||||
* @throws \Exception when the config isn't writable
|
||||
*/
|
||||
public function touch() {
|
||||
if($this->isLocked()) throw new \Exception('no save');
|
||||
@touch($this->savefile);
|
||||
$this->opcacheUpdate($this->savefile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate the opcache of the given file
|
||||
*
|
||||
* @todo this should probably be moved to core
|
||||
* @param string $file
|
||||
*/
|
||||
protected function opcacheUpdate($file) {
|
||||
if(!function_exists('opcache_invalidate')) return;
|
||||
opcache_invalidate($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration is considered locked if there is no local settings filename
|
||||
* or the directory its in is not writable or the file exists and is not writable
|
||||
*
|
||||
* @return bool true: locked, false: writable
|
||||
*/
|
||||
public function isLocked() {
|
||||
if(!$this->savefile) return true;
|
||||
if(!is_writable(dirname($this->savefile))) return true;
|
||||
if(file_exists($this->savefile) && !is_writable($this->savefile)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PHP intro header for the config file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getHeader() {
|
||||
return join(
|
||||
"\n",
|
||||
array(
|
||||
'<?php',
|
||||
'/*',
|
||||
' * ' . $this->header,
|
||||
' * Auto-generated by config plugin',
|
||||
' * Run for user: ' . $_SERVER['REMOTE_USER'],
|
||||
' * Date: ' . date('r'),
|
||||
' */',
|
||||
'',
|
||||
''
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user