diff options
author | Anika Henke <anika@selfthinker.org> | 2011-09-10 20:11:29 +0100 |
---|---|---|
committer | Anika Henke <anika@selfthinker.org> | 2011-09-10 20:23:40 +0100 |
commit | 29d511bfa507384ae0872f75fb54acb44b1e915e (patch) | |
tree | bd9b3138f288fbc6786f3b28c7f3d438bf79c36f /inc | |
parent | 28b19f13203b5263ad89854a9c1df221975e4c38 (diff) | |
parent | a95a7bf3a77d3c38a54af67b2f7584c480381691 (diff) | |
download | rpg-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
Diffstat (limited to 'inc')
-rw-r--r-- | inc/config_cascade.php | 5 | ||||
-rw-r--r-- | inc/infoutils.php | 4 | ||||
-rw-r--r-- | inc/lang/en/lang.php | 2 | ||||
-rw-r--r-- | inc/plugincontroller.class.php | 165 | ||||
-rw-r--r-- | inc/pluginutils.php | 6 |
5 files changed, 150 insertions, 32 deletions
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(); +} |