1ee20e7d1Sandi<?php 2ee20e7d1Sandi/** 3ee20e7d1Sandi * Utilities for handling plugins 4ee20e7d1Sandi * 5ee20e7d1Sandi * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6ee20e7d1Sandi * @author Andreas Gohr <andi@splitbrain.org> 7ee20e7d1Sandi */ 8ee20e7d1Sandi 9087b3a7fSchris// plugin related constants 1003c4aec3Schrisif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 11*10e43949SChris Smith 127d992a19SEsther Brunner$plugin_types = array('admin','syntax','action','renderer', 'helper'); 134b15e09dSAndreas Gohr 14*10e43949SChris Smithglobal $plugin_controller_class, $plugin_controller; 15*10e43949SChris Smithif (empty($plugin_controller_class)) $plugin_controller_class = 'Doku_Plugin_Controller'; 16*10e43949SChris Smith 17*10e43949SChris Smith$plugin_controller = new $plugin_controller_class(); 18*10e43949SChris Smith 19*10e43949SChris Smith/** 20*10e43949SChris Smith * Original plugin functions, remain for backwards compatibility 21*10e43949SChris Smith */ 22*10e43949SChris Smithfunction plugin_list($type='',$all=false) { global $plugin_controller; return $plugin_controller->getList($type,$all); } 23*10e43949SChris Smithfunction &plugin_load($type,$name,$new=false) { global $plugin_controller; return $plugin_controller->load($type,$name,$new); } 24*10e43949SChris Smithfunction plugin_isdisabled($plugin) { global $plugin_controller; return $plugin_controller->isdisabled($plugin); } 25*10e43949SChris Smithfunction plugin_enable($plugin) { global $plugin_controller; return $plugin_controller->enable($plugin); } 26*10e43949SChris Smithfunction plugin_disable($plugin) { global $plugin_controller; return $plugin_controller->disable($plugin); } 27*10e43949SChris Smithfunction plugin_directory($plugin) { global $plugin_controller; return $plugin_controller->get_directory($plugin); } 28*10e43949SChris Smith 29*10e43949SChris Smithclass Doku_Plugin_Controller { 30*10e43949SChris Smith 31*10e43949SChris Smith var $list_enabled = array(); 32*10e43949SChris Smith var $list_disabled = array(); 33*10e43949SChris Smith var $list_bytype = array(); 34*10e43949SChris Smith 35*10e43949SChris Smith function Doku_Plugin_Controller() { 36*10e43949SChris Smith $this->_populateMasterList(); 37*10e43949SChris Smith } 38*10e43949SChris Smith 394b15e09dSAndreas Gohr /** 40ee20e7d1Sandi * Returns a list of available plugins of given type 41ee20e7d1Sandi * 42087b3a7fSchris * @param $type string, plugin_type name; 43087b3a7fSchris * the type of plugin to return, 44087b3a7fSchris * use empty string for all types 45087b3a7fSchris * @param $all bool; 46087b3a7fSchris * false to only return enabled plugins, 47087b3a7fSchris * true to return both enabled and disabled plugins 48087b3a7fSchris * 49087b3a7fSchris * @return array of plugin names 504b15e09dSAndreas Gohr * 51ee20e7d1Sandi * @author Andreas Gohr <andi@splitbrain.org> 52ee20e7d1Sandi */ 53*10e43949SChris Smith function getList($type='',$all=false){ 54ee20e7d1Sandi 55*10e43949SChris Smith // request the complete list 56*10e43949SChris Smith if (!$type) { 57*10e43949SChris Smith return $all ? array_merge($this->list_enabled,$this->list_disabled) : $this->list_enabled; 58*10e43949SChris Smith } 59087b3a7fSchris 60*10e43949SChris Smith if (!isset($this->list_bytype[$type]['enabled'])) { 61*10e43949SChris Smith $this->list_bytype[$type]['enabled'] = $this->_getListByType($type,true); 627fb56887Schris } 63*10e43949SChris Smith if ($all && !isset($this->list_bytype[$type]['disabled'])) { 64*10e43949SChris Smith $this->list_bytype[$type]['disabled'] = $this->_getListByType($type,false); 657fb56887Schris } 66*10e43949SChris Smith 67*10e43949SChris Smith return $all ? array_merge($this->list_bytype[$type]['enabled'],$this->list_bytype[$type]['disabled']) : $this->list_bytype[$type]['enabled']; 68ee20e7d1Sandi } 69ee20e7d1Sandi 70ee20e7d1Sandi /** 71ee20e7d1Sandi * Loads the given plugin and creates an object of it 72ee20e7d1Sandi * 73ee20e7d1Sandi * @author Andreas Gohr <andi@splitbrain.org> 74ee20e7d1Sandi * 75ee20e7d1Sandi * @param $type string type of plugin to load 76ee20e7d1Sandi * @param $name string name of the plugin to load 7794806c6fSChris Smith * @param $new bool true to return a new instance of the plugin, false to use an already loaded instance 784f32716eSAndreas Gohr * @return objectreference the plugin object or null on failure 79ee20e7d1Sandi */ 80*10e43949SChris Smith function &load($type,$name,$new=false){ 81ee20e7d1Sandi //we keep all loaded plugins available in global scope for reuse 82ee20e7d1Sandi global $DOKU_PLUGINS; 83ee20e7d1Sandi 84ee20e7d1Sandi //plugin already loaded? 8503c4aec3Schris if(!empty($DOKU_PLUGINS[$type][$name])){ 8694806c6fSChris Smith if ($new) { 8794806c6fSChris Smith $class = $type.'_plugin_'.$name; 8894806c6fSChris Smith return class_exists($class) ? new $class : null; 8994806c6fSChris Smith } else { 90a46d0d65SAndreas Gohr return $DOKU_PLUGINS[$type][$name]; 91ee20e7d1Sandi } 9294806c6fSChris Smith } 93ee20e7d1Sandi 94ee20e7d1Sandi //try to load the wanted plugin file 95*10e43949SChris Smith list($plugin,$component) = $this->_splitName($name); 96*10e43949SChris Smith $dir = !$this->isdisabled($plugin) ? $plugin : $plugin.'.disabled'; 97*10e43949SChris Smith $file = $component ? "$type/$component.php" : "$type.php"; 98*10e43949SChris Smith 99*10e43949SChris Smith if (!include_once(DOKU_PLUGIN."$dir/$file")) { 100a46d0d65SAndreas Gohr return null; 101ee20e7d1Sandi } 1027fb56887Schris 103173f2783Schris //construct class and instantiate 104ee20e7d1Sandi $class = $type.'_plugin_'.$name; 105c90b2fb1Schris if (!class_exists($class)) return null; 106c90b2fb1Schris 107ee20e7d1Sandi $DOKU_PLUGINS[$type][$name] = new $class; 108a46d0d65SAndreas Gohr return $DOKU_PLUGINS[$type][$name]; 109ee20e7d1Sandi } 110087b3a7fSchris 111*10e43949SChris Smith function isdisabled($plugin) { 112*10e43949SChris Smith return (array_search($plugin, $this->list_enabled) === false); 113*10e43949SChris Smith } 114*10e43949SChris Smith 115*10e43949SChris Smith function enable($plugin) { 116*10e43949SChris Smith if (array_search($plugin, $this->list_disabled) !== false) { 117*10e43949SChris Smith return @rename(DOKU_PLUGIN.$plugin.'.disabled',DOKU_PLUGIN.$plugin); 118*10e43949SChris Smith } 119*10e43949SChris Smith return false; 120*10e43949SChris Smith } 121*10e43949SChris Smith 122*10e43949SChris Smith function disable($plugin) { 123*10e43949SChris Smith if (array_search($plugin, $this->list_enabled) !== false) { 124*10e43949SChris Smith return @rename(DOKU_PLUGIN.$plugin,DOKU_PLUGIN.$plugin.'.disabled'); 125*10e43949SChris Smith } 126*10e43949SChris Smith return false; 127*10e43949SChris Smith } 128*10e43949SChris Smith 129*10e43949SChris Smith function get_directory($plugin) { 130*10e43949SChris Smith return $this->isdisabled($plugin) ? $plugin.'.disabled' : $plugin; 131*10e43949SChris Smith } 132*10e43949SChris Smith 133*10e43949SChris Smith function _populateMasterList() { 134*10e43949SChris Smith if ($dh = opendir(DOKU_PLUGIN)) { 135*10e43949SChris Smith while (false !== ($plugin = readdir($dh))) { 136*10e43949SChris Smith if ($plugin == '.' || $plugin == '..' || $plugin == 'tmp') continue; 137*10e43949SChris Smith if (is_file(DOKU_PLUGIN.$plugin)) continue; 138*10e43949SChris Smith 139*10e43949SChris Smith if (substr($plugin,-9) == '.disabled') { 140*10e43949SChris Smith $this->list_disabled[] = substr($plugin,0,-9); 141*10e43949SChris Smith } else { 142*10e43949SChris Smith $this->list_enabled[] = $plugin; 143*10e43949SChris Smith } 144*10e43949SChris Smith } 145*10e43949SChris Smith } 146*10e43949SChris Smith } 147*10e43949SChris Smith 148*10e43949SChris Smith function _getListByType($type, $enabled) { 149*10e43949SChris Smith $master_list = $enabled ? $this->list_enabled : $this->list_disabled; 150*10e43949SChris Smith 151*10e43949SChris Smith $plugins = array(); 152*10e43949SChris Smith foreach ($master_list as $plugin) { 153*10e43949SChris Smith $dir = $enabled ? $plugin : $plugin.'.disabled'; 154*10e43949SChris Smith 155*10e43949SChris Smith if (@file_exists(DOKU_PLUGIN."$dir/$type.php")){ 156*10e43949SChris Smith $plugins[] = $plugin; 157*10e43949SChris Smith } else { 158*10e43949SChris Smith if ($dp = @opendir(DOKU_PLUGIN."$dir/$type/")) { 159*10e43949SChris Smith while (false !== ($component = readdir($dp))) { 160*10e43949SChris Smith if (substr($component,0,1) == '.' || strtolower(substr($component, -4)) != ".php") continue; 161*10e43949SChris Smith if (is_file(DOKU_PLUGIN."$dir/$type/$component")) { 162*10e43949SChris Smith $plugins[] = $plugin.'_'.substr($component, 0, -4); 163*10e43949SChris Smith } 164*10e43949SChris Smith } 165*10e43949SChris Smith closedir($dp); 166*10e43949SChris Smith } 167*10e43949SChris Smith } 168*10e43949SChris Smith } 169*10e43949SChris Smith 170*10e43949SChris Smith return $plugins; 171*10e43949SChris Smith } 172*10e43949SChris Smith 173*10e43949SChris Smith function _splitName($name) { 174*10e43949SChris Smith if (array_search($name, $this->list_enabled + $this->list_disabled) === false) { 175*10e43949SChris Smith return explode('_',$name,2); 176*10e43949SChris Smith } 177*10e43949SChris Smith 178*10e43949SChris Smith return array($name,''); 179*10e43949SChris Smith } 180*10e43949SChris Smith 181*10e43949SChris Smith} 182