summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--conf/plugins.protected.php6
-rw-r--r--inc/config_cascade.php5
-rw-r--r--inc/infoutils.php4
-rw-r--r--inc/lang/en/lang.php2
-rw-r--r--inc/plugincontroller.class.php167
-rw-r--r--inc/pluginutils.php33
-rw-r--r--lib/plugins/acl/admin.php14
-rw-r--r--lib/plugins/acl/plugin.info.txt6
-rw-r--r--lib/plugins/config/admin.php15
-rw-r--r--lib/plugins/config/plugin.info.txt6
-rw-r--r--lib/plugins/info/plugin.info.txt6
-rw-r--r--lib/plugins/revert/admin.php14
-rw-r--r--lib/plugins/revert/plugin.info.txt6
-rw-r--r--lib/plugins/usermanager/admin.php14
-rw-r--r--lib/plugins/usermanager/plugin.info.txt6
16 files changed, 216 insertions, 89 deletions
diff --git a/.gitignore b/.gitignore
index 6ad14d206..f70efa665 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
/conf/words.aspell
/conf/lang/*
/conf/plugin_lang/*
+/conf/plugins.local.*
.htaccess
*.swp
*.bak
diff --git a/conf/plugins.protected.php b/conf/plugins.protected.php
new file mode 100644
index 000000000..bdfe821c5
--- /dev/null
+++ b/conf/plugins.protected.php
@@ -0,0 +1,6 @@
+<?php
+$plugins['acl'] = 1;
+$plugins['plugin'] = 1;
+$plugins['config'] = 1;
+$plugins['usermanager'] = 1;
+$plugins['revert'] = 1;
diff --git a/inc/config_cascade.php b/inc/config_cascade.php
index 48ed5a000..c01778e99 100644
--- a/inc/config_cascade.php
+++ b/inc/config_cascade.php
@@ -64,6 +64,11 @@ $config_cascade = array_merge(
'plainauth.users' => array(
'default' => DOKU_CONF.'users.auth.php',
),
+
+ 'plugins' => array(
+ 'local' => array(DOKU_CONF.'plugins.local.php'),
+ 'protected' => array(DOKU_CONF.'plugins.protected.php'),
+ ),
),
$config_cascade
);
diff --git a/inc/infoutils.php b/inc/infoutils.php
index 786661d01..f1deec66b 100644
--- a/inc/infoutils.php
+++ b/inc/infoutils.php
@@ -66,8 +66,8 @@ function getVersionData(){
$chunk = fread($fh,2000);
fclose($fh);
$chunk = trim($chunk);
- $chunk = array_pop(explode("\n",$chunk)); //last log line
- $chunk = array_shift(explode("\t",$chunk)); //strip commit msg
+ $chunk = @array_pop(explode("\n",$chunk)); //last log line
+ $chunk = @array_shift(explode("\t",$chunk)); //strip commit msg
$chunk = explode(" ",$chunk);
array_pop($chunk); //strip timezone
$date = date('Y-m-d',array_pop($chunk));
diff --git a/inc/lang/en/lang.php b/inc/lang/en/lang.php
index 95356f7b4..02dff5cb7 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -318,5 +318,5 @@ $lang['seconds'] = '%d seconds ago';
$lang['wordblock'] = 'Your change was not saved because it contains blocked text (spam).';
-
+$lang['plugin_insterr'] = "Plugin installed incorrectly. Rename plugin directory '%s' to '%s'.";
//Setup VIM: ex: et ts=2 :
diff --git a/inc/plugincontroller.class.php b/inc/plugincontroller.class.php
index ea5725d47..6dcdcdfff 100644
--- a/inc/plugincontroller.class.php
+++ b/inc/plugincontroller.class.php
@@ -11,11 +11,18 @@ if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
class Doku_Plugin_Controller {
- var $list_enabled = array();
- var $list_disabled = array();
var $list_bytype = array();
+ var $tmp_plugins = array();
+ var $plugin_cascade = array('default'=>array(),'local'=>array(),'protected'=>array());
+ var $last_local = '';
+ //backup of tmp_plugins needed for write check
+ var $tmp_bak =array();
- function Doku_Plugin_Controller() {
+ /**
+ * Populates the master list of plugins
+ */
+ function __construct() {
+ $this->loadConfig();
$this->_populateMasterList();
}
@@ -37,7 +44,7 @@ class Doku_Plugin_Controller {
// request the complete list
if (!$type) {
- return $all ? array_merge($this->list_enabled,$this->list_disabled) : $this->list_enabled;
+ return $all ? array_keys($this->tmp_plugins) : array_keys(array_filter($this->tmp_plugins));
}
if (!isset($this->list_bytype[$type]['enabled'])) {
@@ -61,9 +68,10 @@ class Doku_Plugin_Controller {
* @param $disabled bool true to load even disabled plugins
* @return objectreference the plugin object or null on failure
*/
- function &load($type,$name,$new=false,$disabled=false){
+ function load($type,$name,$new=false,$disabled=false){
+
//we keep all loaded plugins available in global scope for reuse
- global $DOKU_PLUGINS;
+ global $DOKU_PLUGINS,$lang;
list($plugin,$component) = $this->_splitName($name);
@@ -85,12 +93,12 @@ class Doku_Plugin_Controller {
//construct class and instantiate
if (!class_exists($class, true)) {
+
# the plugin might be in the wrong directory
$dir = $this->get_directory($plugin);
$inf = confToHash(DOKU_PLUGIN."$dir/plugin.info.txt");
if($inf['base'] && $inf['base'] != $plugin){
- msg("Plugin installed incorrectly. Rename plugin directory '".
- hsc($plugin)."' to '".hsc($inf['base'])."'.",-1);
+ msg(sprintf($lang['plugin_insterr'],hsc($plugin),hsc($inf['base'])),-1);
}
return null;
}
@@ -100,30 +108,27 @@ class Doku_Plugin_Controller {
}
function isdisabled($plugin) {
- return (array_search($plugin, $this->list_enabled) === false);
+ return empty($this->tmp_plugins[$plugin]);
}
- function enable($plugin) {
- if (array_search($plugin, $this->list_disabled) !== false) {
- return @unlink(DOKU_PLUGIN.$plugin.'/disabled');
- }
- return false;
+ function disable($plugin) {
+ if(array_key_exists($plugin,$this->plugin_cascade['protected'])) return false;
+ $this->tmp_plugins[$plugin] = 0;
+ return $this->saveList();
}
- function disable($plugin) {
- if (array_search($plugin, $this->list_enabled) !== false) {
- return @touch(DOKU_PLUGIN.$plugin.'/disabled');
- }
- return false;
+ function enable($plugin) {
+ if(array_key_exists($plugin,$this->plugin_cascade['protected'])) return false;
+ $this->tmp_plugins[$plugin] = 1;
+ return $this->saveList();
}
function get_directory($plugin) {
return $plugin;
}
- function _populateMasterList() {
- global $conf;
- if ($dh = opendir(DOKU_PLUGIN)) {
+ protected function _populateMasterList() {
+ if ($dh = @opendir(DOKU_PLUGIN)) {
while (false !== ($plugin = readdir($dh))) {
if ($plugin[0] == '.') continue; // skip hidden entries
if (is_file(DOKU_PLUGIN.$plugin)) continue; // skip files, we're only interested in directories
@@ -132,19 +137,123 @@ class Doku_Plugin_Controller {
// the plugin was disabled by rc2009-01-26
// disabling mechanism was changed back very soon again
// to keep everything simple we just skip the plugin completely
- }elseif(@file_exists(DOKU_PLUGIN.$plugin.'/disabled') ||
+ }elseif(@file_exists(DOKU_PLUGIN.$plugin.'/disabled')) {
+ if(empty($this->plugin_cascade['local'][$plugin]))
+ $all_plugins[$plugin] = 0;
+ else
+ $all_plugins[$plugin] = 1;
+ //treat this as a default disabled plugin(over-rideable by the plugin manager)
+ $this->plugin_cascade['default'][$plugin] = 0;
+ //TODO take this out before final release,
+ //it is here only for other developers to be able to switch branches easily
+ //@unlink(DOKU_PLUGIN.$plugin.'/disabled');
+ continue;
+ }
+ elseif((array_key_exists($plugin,$this->tmp_plugins) && $this->tmp_plugins[$plugin] == 0) ||
($plugin === 'plugin' && isset($conf['pluginmanager']) &&
!$conf['pluginmanager'])){
- $this->list_disabled[] = $plugin;
+ $all_plugins[$plugin] = 0;
+ } elseif((array_key_exists($plugin,$this->tmp_plugins) && $this->tmp_plugins[$plugin] == 1)) {
+ $all_plugins[$plugin] = 1;
} else {
- $this->list_enabled[] = $plugin;
+ $all_plugins[$plugin] = 1;
}
}
+ $this->tmp_plugins = $all_plugins;
+ $this->saveList();
}
}
+ protected function checkRequire($files) {
+ $plugins = array();
+ foreach($files as $file) {
+ if(file_exists($file)) {
+ @include_once($file);
+ }
+ }
+ return $plugins;
+ }
+
+ function getCascade() {
+ return $this->plugin_cascade;
+ }
+ /**
+ * Save the current list of plugins
+ */
+ function saveList() {
+ if(!empty($this->tmp_plugins)) {
+ //quick check to ensure rewrite is necessary
+ if($this->tmp_plugins != $this->tmp_bak) {
+ //Rebuild local for better check and saving
+ $local_plugins = $this->rebuildLocal();
+ //only write if the list has changed
+ if($local_plugins != $this->plugin_cascade['local']) {
+ $file = $this->last_local;
+ $out = "<?php\n";
+ foreach ($local_plugins as $plugin => $value) {
+ $out .= "\$plugins['$plugin'] = $value;\n";
+ }
+ // backup current file (remove any existing backup)
+ if (@file_exists($file)) {
+ if (@file_exists($file.'.bak')) @unlink($file.'.bak');
+ if (!io_rename($file, $file.'.bak')) return false;
+ }
+ //check if can open for writing, else restore
+ if (!$fh = @fopen($file, 'wb')) {
+ io_rename($file.'.bak', $file);// problem opening, restore the backup
+ return false;
+ }
+ @fwrite($fh, $out);
+ fclose($fh);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Rebuild the set of local plugins
+ * @return array array of plugins to be saved in end($config_cascade['plugins']['local'])
+ */
+ function rebuildLocal() {
+ //assign to local variable to avoid overwriting
+ $backup = $this->tmp_plugins;
+ //Can't do anything about protected one so rule them out completely
+ $local_default = array_diff_key($backup,$this->plugin_cascade['protected']);
+ //Diff between local+default and default
+ //gives us the ones we need to check and save
+ $diffed_ones = array_diff_key($local_default,$this->plugin_cascade['default']);
+ //The ones which we are sure of (list of 0s not in default)
+ $sure_plugins = array_filter($diffed_ones,array($this,'negate'));
+ //the ones in need of diff
+ $conflicts = array_diff_key($local_default,$diffed_ones);
+ //The final list
+ return array_merge($sure_plugins,array_diff_assoc($conflicts,$this->plugin_cascade['default']));
+ }
+
+ /**
+ * Build the list of plugins and cascade
+ *
+ */
+ function loadConfig() {
+ global $config_cascade;
+ foreach(array('default','protected') as $type) {
+ if(array_key_exists($type,$config_cascade['plugins']))
+ $this->plugin_cascade[$type] = $this->checkRequire($config_cascade['plugins'][$type]);
+ }
+ $local = $config_cascade['plugins']['local'];
+ $this->last_local = array_pop($local);
+ $this->plugin_cascade['local'] = $this->checkRequire(array($this->last_local));
+ if(is_array($local)) {
+ $this->plugin_cascade['default'] = array_merge($this->plugin_cascade['default'],$this->checkRequire($local));
+ }
+ $this->tmp_plugins = array_merge($this->plugin_cascade['default'],$this->plugin_cascade['local'],$this->plugin_cascade['protected']);
+ $this->tmp_bak = $this->tmp_plugins;
+ }
+
function _getListByType($type, $enabled) {
- $master_list = $enabled ? $this->list_enabled : $this->list_disabled;
+ $master_list = $enabled ? array_keys(array_filter($this->tmp_plugins)) : array_keys(array_filter($this->tmp_plugins,array($this,'negate')));
$plugins = array();
foreach ($master_list as $plugin) {
@@ -169,11 +278,13 @@ class Doku_Plugin_Controller {
}
function _splitName($name) {
- if (array_search($name, $this->list_enabled + $this->list_disabled) === false) {
+ if (array_search($name, array_keys($this->tmp_plugins)) === false) {
return explode('_',$name,2);
}
return array($name,'');
}
-
+ function negate($input) {
+ return !(bool) $input;
+ }
}
diff --git a/inc/pluginutils.php b/inc/pluginutils.php
index 85bcaee1e..897020a6c 100644
--- a/inc/pluginutils.php
+++ b/inc/pluginutils.php
@@ -16,7 +16,7 @@ function plugin_list($type='',$all=false) {
global $plugin_controller;
return $plugin_controller->getList($type,$all);
}
-function &plugin_load($type,$name,$new=false,$disabled=false) {
+function plugin_load($type,$name,$new=false,$disabled=false) {
global $plugin_controller;
return $plugin_controller->load($type,$name,$new,$disabled);
}
@@ -36,3 +36,34 @@ function plugin_directory($plugin) {
global $plugin_controller;
return $plugin_controller->get_directory($plugin);
}
+function plugin_getcascade() {
+ global $plugin_controller;
+ return $plugin_controller->getCascade();
+}
+/**
+ * return a list (name & type) of all the component plugins that make up this plugin
+ *
+ */
+function get_plugin_components($plugin) {
+ global $plugin_types;
+ static $plugins;
+ if(empty($plugins[$plugin])) {
+ $components = array();
+ $path = DOKU_PLUGIN.plugin_directory($plugin).'/';
+
+ foreach ($plugin_types as $type) {
+ if (@file_exists($path.$type.'.php')) { $components[] = array('name'=>$plugin, 'type'=>$type); continue; }
+
+ if ($dh = @opendir($path.$type.'/')) {
+ while (false !== ($cp = readdir($dh))) {
+ if ($cp == '.' || $cp == '..' || strtolower(substr($cp,-4)) != '.php') continue;
+
+ $components[] = array('name'=>$plugin.'_'.substr($cp, 0, -4), 'type'=>$type);
+ }
+ closedir($dh);
+ }
+ }
+ $plugins[$plugin] = $components;
+ }
+ return $plugins[$plugin];
+}
diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php
index 53f6db0cc..a6b0624bc 100644
--- a/lib/plugins/acl/admin.php
+++ b/lib/plugins/acl/admin.php
@@ -31,20 +31,6 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin {
var $specials = array();
/**
- * return some info
- */
- function getInfo(){
- return array(
- 'author' => 'Andreas Gohr',
- 'email' => 'andi@splitbrain.org',
- 'date' => '2011-04-16',
- 'name' => 'ACL Manager',
- 'desc' => 'Manage Page Access Control Lists',
- 'url' => 'http://dokuwiki.org/plugin:acl',
- );
- }
-
- /**
* return prompt for admin menu
*/
function getMenuText($language) {
diff --git a/lib/plugins/acl/plugin.info.txt b/lib/plugins/acl/plugin.info.txt
new file mode 100644
index 000000000..f108a2390
--- /dev/null
+++ b/lib/plugins/acl/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2011-04-16
+name ACL Manager
+desc Manage Page Access Control Lists
+url http://dokuwiki.org/plugin:acl
diff --git a/lib/plugins/config/admin.php b/lib/plugins/config/admin.php
index e24f3b87b..64906171d 100644
--- a/lib/plugins/config/admin.php
+++ b/lib/plugins/config/admin.php
@@ -32,21 +32,6 @@ class admin_plugin_config extends DokuWiki_Admin_Plugin {
var $_session_started = false;
var $_localised_prompts = false;
- /**
- * return some info
- */
- function getInfo(){
-
- return array(
- 'author' => 'Christopher Smith',
- 'email' => 'chris@jalakai.co.uk',
- 'date' => '2007-08-05',
- 'name' => 'Configuration Manager',
- 'desc' => "Manage Dokuwiki's Configuration Settings",
- 'url' => 'http://dokuwiki.org/plugin:config',
- );
- }
-
function getMenuSort() { return 100; }
/**
diff --git a/lib/plugins/config/plugin.info.txt b/lib/plugins/config/plugin.info.txt
new file mode 100644
index 000000000..ace4889b6
--- /dev/null
+++ b/lib/plugins/config/plugin.info.txt
@@ -0,0 +1,6 @@
+author Christopher Smith
+email chris@jalakai.co.uk
+date 2007-08-05
+name Configuration Manager
+desc Manage Dokuwiki's Configuration Settings
+url http://dokuwiki.org/plugin:config
diff --git a/lib/plugins/info/plugin.info.txt b/lib/plugins/info/plugin.info.txt
new file mode 100644
index 000000000..2432225f1
--- /dev/null
+++ b/lib/plugins/info/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2008-09-12
+name Info Plugin
+desc Displays information about various DokuWiki internals
+url http://dokuwiki.org/plugin:info
diff --git a/lib/plugins/revert/admin.php b/lib/plugins/revert/admin.php
index e188e2488..2aaf1395f 100644
--- a/lib/plugins/revert/admin.php
+++ b/lib/plugins/revert/admin.php
@@ -21,20 +21,6 @@ class admin_plugin_revert extends DokuWiki_Admin_Plugin {
}
/**
- * return some info
- */
- function getInfo(){
- return array(
- 'author' => 'Andreas Gohr',
- 'email' => 'andi@splitbrain.org',
- 'date' => '2008-12-10',
- 'name' => 'Revert Manager',
- 'desc' => 'Allows you to mass revert recent edits',
- 'url' => 'http://dokuwiki.org/plugin:revert',
- );
- }
-
- /**
* access for managers
*/
function forAdminOnly(){
diff --git a/lib/plugins/revert/plugin.info.txt b/lib/plugins/revert/plugin.info.txt
new file mode 100644
index 000000000..5bb6f3413
--- /dev/null
+++ b/lib/plugins/revert/plugin.info.txt
@@ -0,0 +1,6 @@
+author Andreas Gohr
+email andi@splitbrain.org
+date 2008-12-10
+name Revert Manager
+desc Allows you to mass revert recent edits
+url http://dokuwiki.org/plugin:revert
diff --git a/lib/plugins/usermanager/admin.php b/lib/plugins/usermanager/admin.php
index e40ee9b7e..8e90be093 100644
--- a/lib/plugins/usermanager/admin.php
+++ b/lib/plugins/usermanager/admin.php
@@ -51,20 +51,6 @@ class admin_plugin_usermanager extends DokuWiki_Admin_Plugin {
}
}
- /**
- * return some info
- */
- function getInfo(){
-
- return array(
- 'author' => 'Chris Smith',
- 'email' => 'chris@jalakai.co.uk',
- 'date' => '2008-09-17',
- 'name' => 'User Manager',
- 'desc' => 'Manage users '.$this->disabled,
- 'url' => 'http://dokuwiki.org/plugin:usermanager',
- );
- }
/**
* return prompt for admin menu
*/
diff --git a/lib/plugins/usermanager/plugin.info.txt b/lib/plugins/usermanager/plugin.info.txt
new file mode 100644
index 000000000..7ec5fafd5
--- /dev/null
+++ b/lib/plugins/usermanager/plugin.info.txt
@@ -0,0 +1,6 @@
+author Chris Smith
+email chris@jalakai.co.uk
+date 2008-09-17
+name User Manager
+desc Manage users
+url http://dokuwiki.org/plugin:usermanager