summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnika Henke <anika@selfthinker.org>2011-09-10 20:11:29 +0100
committerAnika Henke <anika@selfthinker.org>2011-09-10 20:23:40 +0100
commit29d511bfa507384ae0872f75fb54acb44b1e915e (patch)
treebd9b3138f288fbc6786f3b28c7f3d438bf79c36f
parent28b19f13203b5263ad89854a9c1df221975e4c38 (diff)
parenta95a7bf3a77d3c38a54af67b2f7584c480381691 (diff)
downloadrpg-29d511bfa507384ae0872f75fb54acb44b1e915e.tar.gz
rpg-29d511bfa507384ae0872f75fb54acb44b1e915e.tar.bz2
Merge branch 'plugincontroller' of git://github.com/piyushmishra/dokuwiki into plugincontroller
This adds support for the config_cascade when enabling/disabling plugins, making farming easier. The changes have been implemented by Piyush Mishra and are a part of the new extension manager which will follow later. It's the result of a Google Summer of Code project, the official project page can be found at http://www.google-melange.com/gsoc/project/google/gsoc2011/piyushmishra/26001 Thanks to Piyush for the work and Google for sponsoring it! Conflicts: inc/lang/en/lang.php
-rw-r--r--.gitignore1
-rw-r--r--conf/plugins.protected.php11
-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.php165
-rw-r--r--inc/pluginutils.php6
-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, 192 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..26eb8888b
--- /dev/null
+++ b/conf/plugins.protected.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * This file configures the enabled/disabled status of plugins, which are also protected
+ * from changes by the extention manager. These settings will override any local settings.
+ * It is not recommended to change this file, as it is overwritten on DokuWiki upgrades.
+ */
+$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 6a02bbe0b..ab6a88497 100644
--- a/inc/lang/en/lang.php
+++ b/inc/lang/en/lang.php
@@ -361,4 +361,6 @@ $lang['js']['media_drop'] = 'Drop files here to upload';
$lang['js']['media_cancel'] = 'remove';
$lang['js']['media_overwrt'] = 'Overwrite existing files';
+$lang['plugin_install_err'] = "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..734331c94 100644
--- a/inc/plugincontroller.class.php
+++ b/inc/plugincontroller.class.php
@@ -11,11 +11,16 @@ 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_config_file = '';
- function Doku_Plugin_Controller() {
+ /**
+ * Populates the master list of plugins
+ */
+ function __construct() {
+ $this->loadConfig();
$this->_populateMasterList();
}
@@ -37,7 +42,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 +66,11 @@ 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 $lang;
list($plugin,$component) = $this->_splitName($name);
@@ -85,12 +92,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_install_err'],hsc($plugin),hsc($inf['base'])),-1);
}
return null;
}
@@ -100,30 +107,28 @@ 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)) {
+ $all_plugins = array();
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,119 @@ 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') ||
- ($plugin === 'plugin' && isset($conf['pluginmanager']) &&
- !$conf['pluginmanager'])){
- $this->list_disabled[] = $plugin;
+ } elseif (@file_exists(DOKU_PLUGIN.$plugin.'/disabled')) {
+ // treat this as a default disabled plugin(over-rideable by the plugin manager)
+ // deprecated 2011-09-10 (usage of disabled files)
+ if (empty($this->plugin_cascade['local'][$plugin])) {
+ $all_plugins[$plugin] = 0;
+ } else {
+ $all_plugins[$plugin] = 1;
+ }
+ $this->plugin_cascade['default'][$plugin] = 0;
+
+ } elseif ((array_key_exists($plugin,$this->tmp_plugins) && $this->tmp_plugins[$plugin] == 0) ||
+ ($plugin === 'plugin' && isset($conf['pluginmanager']) && !$conf['pluginmanager'])){
+ $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;
+ if (!file_exists($this->last_local_config_file)) {
+ $this->saveList(true);
+ }
+ }
+ }
+
+ 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($forceSave = false) {
+ global $conf;
+
+ if (empty($this->tmp_plugins)) return false;
+
+ // Rebuild list of local settings
+ $local_plugins = $this->rebuildLocal();
+ if($local_plugins != $this->plugin_cascade['local'] || $forceSave) {
+ $file = $this->last_local_config_file;
+ $out = "<?php\n/*\n * Local plugin enable/disable settings\n * Auto-generated through plugin/extension manager\n *\n".
+ " * NOTE: Plugins will not be added to this file unless there is a need to override a default setting. Plugins are\n".
+ " * enabled by default, unless having a 'disabled' file in their plugin folder.\n */\n";
+ foreach ($local_plugins as $plugin => $value) {
+ $out .= "\$plugins['$plugin'] = $value;\n";
+ }
+ // backup current file (remove any existing backup)
+ if (@file_exists($file)) {
+ $backup = $file.'.bak';
+ if (@file_exists($backup)) @unlink($backup);
+ if (!@copy($file,$backup)) return false;
+ if ($conf['fperm']) chmod($backup, $conf['fperm']);
+ }
+ //check if can open for writing, else restore
+ return io_saveFile($file,$out);
+ }
+ 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_config_file = array_pop($local);
+ $this->plugin_cascade['local'] = $this->checkRequire(array($this->last_local_config_file));
+ 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']);
}
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 +274,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..53cfedf82 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,7 @@ function plugin_directory($plugin) {
global $plugin_controller;
return $plugin_controller->get_directory($plugin);
}
+function plugin_getcascade() {
+ global $plugin_controller;
+ return $plugin_controller->getCascade();
+}
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