Rework configuration loading to use a predefined file list or cascade

This change add the global $config_cascade which holds the list of files to be
read for each configuration setting group.  Dokuwiki adds in its configuration
file values after preload.php, giving preload.php to set its own configuration
cascade.

One side effect of the change is "local.protected.php" is part of the default
cascade, removing the need for it to be included at the bottom of local.php.

darcs-hash:20090118181204-f07c6-fea1c406da1bbdb0a52ab40914f11b835e797728.gz
This commit is contained in:
Chris Smith 2009-01-18 19:12:04 +01:00
parent 1cf7edcb7f
commit cb043f52e8
4 changed files with 113 additions and 57 deletions

View File

@ -39,11 +39,7 @@ function mimetype($file){
function getMimeTypes() {
static $mime = NULL;
if ( !$mime ) {
$mime = confToHash(DOKU_CONF.'mime.conf');
if (@file_exists(DOKU_CONF.'mime.local.conf')) {
$local = confToHash(DOKU_CONF.'mime.local.conf');
$mime = array_merge($mime, $local);
}
$mime = retrieveConfig('mime','confToHash');
}
return $mime;
}
@ -56,11 +52,7 @@ function getMimeTypes() {
function getAcronyms() {
static $acronyms = NULL;
if ( !$acronyms ) {
$acronyms = confToHash(DOKU_CONF.'acronyms.conf');
if (@file_exists(DOKU_CONF.'acronyms.local.conf')) {
$local = confToHash(DOKU_CONF.'acronyms.local.conf');
$acronyms = array_merge($acronyms, $local);
}
$acronyms = retrieveConfig('acronyms','confToHash');
}
return $acronyms;
}
@ -73,11 +65,7 @@ function getAcronyms() {
function getSmileys() {
static $smileys = NULL;
if ( !$smileys ) {
$smileys = confToHash(DOKU_CONF.'smileys.conf');
if (@file_exists(DOKU_CONF.'smileys.local.conf')) {
$local = confToHash(DOKU_CONF.'smileys.local.conf');
$smileys = array_merge($smileys, $local);
}
$smileys = retrieveConfig('smileys','confToHash');
}
return $smileys;
}
@ -90,11 +78,7 @@ function getSmileys() {
function getEntities() {
static $entities = NULL;
if ( !$entities ) {
$entities = confToHash(DOKU_CONF.'entities.conf');
if (@file_exists(DOKU_CONF.'entities.local.conf')) {
$local = confToHash(DOKU_CONF.'entities.local.conf');
$entities = array_merge($entities, $local);
}
$entities = retrieveConfig('entities','confToHash');
}
return $entities;
}
@ -107,11 +91,7 @@ function getEntities() {
function getInterwiki() {
static $wikis = NULL;
if ( !$wikis ) {
$wikis = confToHash(DOKU_CONF.'interwiki.conf',true);
if (@file_exists(DOKU_CONF.'interwiki.local.conf')) {
$local = confToHash(DOKU_CONF.'interwiki.local.conf');
$wikis = array_merge($wikis, $local);
}
$wikis = retrieveConfig('interwiki','confToHash');
}
//add sepecial case 'this'
$wikis['this'] = DOKU_URL.'{NAME}';
@ -125,11 +105,7 @@ function getInterwiki() {
function getWordblocks() {
static $wordblocks = NULL;
if ( !$wordblocks ) {
$wordblocks = file(DOKU_CONF.'wordblock.conf');
if (@file_exists(DOKU_CONF.'wordblock.local.conf')) {
$local = file(DOKU_CONF.'wordblock.local.conf');
$wordblocks = array_merge($wordblocks, $local);
}
$wordblocks = retrieveConfig('wordblock','file');
}
return $wordblocks;
}
@ -138,11 +114,7 @@ function getWordblocks() {
function getSchemes() {
static $schemes = NULL;
if ( !$schemes ) {
$schemes = file(DOKU_CONF.'scheme.conf');
if (@file_exists(DOKU_CONF.'scheme.local.conf')) {
$local = file(DOKU_CONF.'scheme.local.conf');
$schemes = array_merge($schemes, $local);
}
$schemes = retrieveConfig('scheme','file');
}
$schemes = array_map('trim', $schemes);
$schemes = preg_replace('/^#.*/', '', $schemes);
@ -182,6 +154,30 @@ function confToHash($file,$lower=false) {
return $conf;
}
/**
* Retrieve the requested configuration information
*
* @author Chris Smith <chris@jalakai.co.uk>
*
* @param string $type the configuration settings to be read, must correspond to a key/array in $config_cascade
* @param callback $fn the function used to process the configuration file into an array
* @return array configuration values
*/
function retrieveConfig($type,$fn) {
global $config_cascade;
$combined = array();
if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING);
foreach ($config_cascade[$type] as $file) {
if (@file_exists($file)) {
$config = $fn($file);
$combined = array_merge($combined, $config);
}
}
return $combined;
}
/**
* check if the given action was disabled in config
*

View File

@ -40,14 +40,55 @@
global $cache_authname; $cache_authname = array();
global $cache_metadata; $cache_metadata = array();
//set the configuration cascade - but only if its not already been set in preload.php
global $config_cascade;
if (empty($config_cascade)) {
$config_cascade = array(
'main' => array(
'default' => array(DOKU_CONF.'dokuwiki.php'),
'local' => array(DOKU_CONF.'local.php'),
'protected' => array(DOKU_CONF.'local.protected.php'),
),
'acronyms' => array(
'default' => array(DOKU_CONF.'acronyms.php'),
'local' => array(DOKU_CONF.'acronyms.local.php'),
),
'entities' => array(
'default' => array(DOKU_CONF.'entities.php'),
'local' => array(DOKU_CONF.'entities.local.php'),
),
'interwiki' => array(
'default' => array(DOKU_CONF.'interwiki.php'),
'local' => array(DOKU_CONF.'interwiki.local.php'),
),
'mime' => array(
'default' => array(DOKU_CONF.'mime.php'),
'local' => array(DOKU_CONF.'mime.local.php'),
),
'scheme' => array(
'default' => array(DOKU_CONF.'scheme.php'),
'local' => array(DOKU_CONF.'scheme.local.php'),
),
'smileys' => array(
'default' => array(DOKU_CONF.'smileys.php'),
'local' => array(DOKU_CONF.'smileys.local.php'),
),
'wordblock' => array(
'default' => array(DOKU_CONF.'wordblock.php'),
'local' => array(DOKU_CONF.'wordblock.local.php'),
),
);
}
//prepare config array()
global $conf;
$conf = array();
// load the config file(s)
require_once(DOKU_CONF.'dokuwiki.php');
if(@file_exists(DOKU_CONF.'local.php')){
require_once(DOKU_CONF.'local.php');
// load the global config file(s)
foreach ($config_cascade['main'] as $config_group) {
foreach ($config_group as $config_file) {
@include($config_file);
}
}
//prepare language array

View File

@ -18,16 +18,18 @@ if (!class_exists('configuration')) {
var $setting = array(); // array of setting objects
var $locked = false; // configuration is considered locked if it can't be updated
// filenames, these will be eval()'d prior to use so maintain any constants in output
var $_default_file = '';
var $_local_file = '';
var $_protected_file = '';
// configuration filenames
var $_default_files = array();
var $_local_files = array(); // updated configuration is written to the first file
var $_protected_files = array();
var $_plugin_list = null;
/**
* constructor
*/
function configuration($datafile) {
global $conf;
global $conf, $config_cascade;
if (!@file_exists($datafile)) {
msg('No configuration metadata found at - '.htmlspecialchars($datafile),-1);
@ -39,9 +41,13 @@ if (!class_exists('configuration')) {
if (isset($config['format'])) $this->_format = $config['format'];
if (isset($config['heading'])) $this->_heading = $config['heading'];
if (isset($file['default'])) $this->_default_file = $file['default'];
if (isset($file['local'])) $this->_local_file = $file['local'];
if (isset($file['protected'])) $this->_protected_file = $file['protected'];
$this->_default_files = $config_cascade['main']['default'];
$this->_local_files = $config_cascade['main']['local'];
$this->_protected_files = $config_cascade['main']['protected'];
# if (isset($file['default'])) $this->_default_file = $file['default'];
# if (isset($file['local'])) $this->_local_file = $file['local'];
# if (isset($file['protected'])) $this->_protected_file = $file['protected'];
$this->locked = $this->_is_locked();
@ -55,9 +61,9 @@ if (!class_exists('configuration')) {
$no_default_check = array('setting_fieldset', 'setting_undefined', 'setting_no_class');
if (!$this->_loaded) {
$default = array_merge($this->_read_config($this->_default_file), $this->get_plugintpl_default($conf['template']));
$local = $this->_read_config($this->_local_file);
$protected = $this->_read_config($this->_protected_file);
$default = array_merge($this->get_plugintpl_default($conf['template']), $this->_read_config_group($this->_default_files));
$local = $this->_read_config_group($this->_local_files);
$protected = $this->_read_config_group($this->_protected_files);
$keys = array_merge(array_keys($this->_metadata),array_keys($default), array_keys($local), array_keys($protected));
$keys = array_unique($keys);
@ -93,7 +99,8 @@ if (!class_exists('configuration')) {
if ($this->locked) return false;
$file = eval('return '.$this->_local_file.';');
# $file = eval('return '.$this->_local_file.';');
$file = $this->_local_files[0];
// backup current file (remove any existing backup)
if (@file_exists($file) && $backup) {
@ -120,6 +127,15 @@ if (!class_exists('configuration')) {
fclose($fh);
return true;
}
function _read_config_group($files) {
$config = array();
foreach ($files as $file) {
$config = array_merge($config, $this->_read_config($file));
}
return $config;
}
/**
* return an array of config settings
@ -129,7 +145,7 @@ if (!class_exists('configuration')) {
if (!$file) return array();
$config = array();
$file = eval('return '.$file.';');
# $file = eval('return '.$file.';');
if ($this->_format == 'php') {
@ -177,9 +193,9 @@ if (!class_exists('configuration')) {
function _out_footer() {
$out = '';
if ($this->_format == 'php') {
if ($this->_protected_file) {
$out .= "\n@include(".$this->_protected_file.");\n";
}
# if ($this->_protected_file) {
# $out .= "\n@include(".$this->_protected_file.");\n";
# }
$out .= "\n// end auto-generated content\n";
}
@ -189,9 +205,10 @@ if (!class_exists('configuration')) {
// 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
function _is_locked() {
if (!$this->_local_file) return true;
if (!$this->_local_files) return true;
$local = eval('return '.$this->_local_file.';');
# $local = eval('return '.$this->_local_file.';');
$local = $this->_local_files[0];
if (!is_writable(dirname($local))) return true;
if (@file_exists($local) && !is_writable($local)) return true;

View File

@ -64,11 +64,13 @@ $config['varname'] = 'conf'; // name of the config variable, sans $
// this value can be overriden when calling save_settings() method
$config['heading'] = 'Dokuwiki\'s Main Configuration File - Local Settings';
/* DEPRECATED
// ---------------[ setting files ]--------------------------------------
// these values can be string expressions, they will be eval'd before use
$file['local'] = "DOKU_CONF.'local.php'"; // mandatory (file doesn't have to exist)
$file['default'] = "DOKU_CONF.'dokuwiki.php'"; // optional
$file['protected'] = "DOKU_CONF.'local.protected.php'"; // optional
*/
// test value (FIXME, remove before publishing)
//$meta['test'] = array('multichoice','_choices' => array(''));