3 * FusionForge plugin system
5 * Copyright 2002, 2009, Roland Mas
6 * http://fusionforge.org
8 * This file is part of FusionForge. FusionForge is free software;
9 * you can redistribute it and/or modify it under the terms of the
10 * GNU General Public License as published by the Free Software
11 * Foundation; either version 2 of the Licence, or (at your option)
14 * FusionForge is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 class PluginManager extends Error {
26 var $plugins_to_hooks;
27 var $hooks_to_plugins;
28 var $returned_values = array();
31 * PluginManager() - constructor
34 function PluginManager() {
36 $this->plugins_objects = array();
37 $this->plugins_to_hooks = array();
38 $this->hooks_to_plugins = array();
40 //to work with Codendi files
41 static function instance() {
42 global $PLUGINMANAGER_OBJ;
43 if (!isset($PLUGINMANAGER_OBJ) || !$PLUGINMANAGER_OBJ) {
44 $PLUGINMANAGER_OBJ = new PluginManager;
46 return $PLUGINMANAGER_OBJ ;
50 * GetPlugins() - get a list of installed plugins
52 * @return hash of plugin id => plugin names
54 function GetPlugins() {
55 if (!isset($this->plugins_data)) {
56 $this->plugins_data = array();
57 $res = db_query_params('SELECT plugin_id, plugin_name FROM plugins',
59 $rows = db_numrows($res);
60 for ($i=0; $i<$rows; $i++) {
61 $plugin_id = db_result($res, $i, 'plugin_id');
62 $this->plugins_data[$plugin_id] = db_result($res, $i, 'plugin_name');
65 return $this->plugins_data;
69 * GetPluginObject() - get a particular plugin object
71 * @param string name of plugin
72 * @return object plugin object or false if not available
74 function GetPluginObject($pluginname) {
75 if (!isset($this->plugins_objects[$pluginname])) {
78 return $this->plugins_objects[$pluginname];
81 //Added for Codendi compatibility
82 function getPluginByName($pluginname) {
83 return @$this->plugins_objects[$pluginname];
86 * PluginIsInstalled() - is a plugin installed?
88 * @param string name of plugin
89 * @return boolean true if installed
91 function PluginIsInstalled ($pluginname) {
92 $plugins_data = $this->getPlugins();
93 foreach ($plugins_data as $p_id => $p_name) {
94 if ($p_name == $pluginname) {
100 function isPluginAvailable($plugin) {
101 $pluginname = $plugin->GetName();
102 $plugins_data = $this->getPlugins();
103 foreach ($plugins_data as $p_id => $p_name) {
104 if ($p_name == $pluginname) {
110 function activate($pluginname) {
111 $res = db_query_params('INSERT INTO plugins (plugin_name,plugin_desc) VALUES ($1,$2)',
112 array($pluginname, "This is the $pluginname plugin"));
114 $res = db_query_params ('SELECT plugin_id, plugin_name FROM plugins WHERE plugin_name=$1',
115 array ($pluginname));
116 if (db_numrows($res) == 1) {
117 $plugin_id = db_result($res, 0, 'plugin_id');
118 $this->plugins_data[$plugin_id] = db_result($res,0,'plugin_name');
125 function deactivate($pluginname) {
126 $res = db_query_params('DELETE FROM plugins WHERE plugin_name = $1', array($pluginname));
130 foreach ($this->plugins_data as $i => $n) {
131 if ($n == $pluginname) {
136 unset($this->plugins_data[$p_id]) ;
142 * LoadPlugin() - load a specific plugin
145 function LoadPlugin($p_name) {
146 global $gfplugins, $gfcommon, $gfwww;
148 $plugins_data = $this->GetPlugins();
149 $include_path = forge_get_config('plugins_path');
150 $filename = $include_path . '/'. $p_name . "/common/".$p_name."-init.php";
151 if (file_exists ($filename)) {
152 require_once ($filename);
154 $filename = $include_path . '/'. $p_name . "/common/".$p_name."Plugin.class.php" ;
155 if (file_exists($filename)) {
156 require_once($filename);
157 $p_class = $p_name.'Plugin';
158 register_plugin (new $p_class);
159 } else { //if we didn't find it in common/ it may be an old plugin that has its files in include/
160 $filename = $include_path . '/' . $p_name . "/include/".$p_name."-init.php" ;
161 if (file_exists ($filename)) {
162 require_once ($filename);
164 // we can't find the plugin so we remove it from the array
165 foreach ($plugins_data as $i => $n) {
170 unset($this->plugins_data[$p_id]);
179 * LoadPlugins() - load available plugins
182 function LoadPlugins() {
183 $plugins_data = $this->GetPlugins();
184 foreach ($plugins_data as $p_id => $p_name) {
185 if (!$this->LoadPlugin($p_name)) {
186 // we can't find the plugin so we remove it from the array
187 unset($this->plugins_data[$p_id]);
194 * SetupHooks() - setup all hooks for installed plugins
197 function SetupHooks() {
198 $this->hooks_to_plugins = array();
199 foreach ($this->plugins_to_hooks as $p_name => $hook_list) {
200 foreach ($hook_list as $hook_name) {
201 if (!isset ($this->hooks_to_plugins[$hook_name])) {
202 $this->hooks_to_plugins[$hook_name] = array();
204 $this->hooks_to_plugins[$hook_name][] = $p_name;
211 * RegisterPlugin() - register a plugin
213 * @param object an object of a subclass of the Plugin class
215 function RegisterPlugin(&$pluginobject) {
216 if (!$pluginobject->GetName()) {
217 exit_error(_("Some plugin did not provide a name. I'd gladly tell you which one, but obviously I cannot. Sorry."),'');
219 $p_name = $pluginobject->GetName() ;
220 $this->plugins_objects[$p_name] =& $pluginobject;
221 $this->plugins_to_hooks[$p_name] = array_unique($pluginobject->GetHooks ()) ;
226 * RunHooks() - call hooks from a particular point
228 * @param hookname - name of the hook
229 * @param params - array of extra parameters
231 * @return boolean, true if all returned true.
233 function RunHooks($hookname, & $params) {
235 $this->returned_values[$hookname] = array();
236 if (isset($this->hooks_to_plugins[$hookname])) {
237 $p_list = $this->hooks_to_plugins[$hookname];
238 foreach ($p_list as $p_name) {
239 $p_obj = $this->plugins_objects[$p_name] ;
240 if (method_exists($p_obj, $hookname)) {
241 $returned = $p_obj->$hookname($params);
243 $returned = $p_obj->CallHook($hookname, $params);
245 $this->returned_values[$hookname][$p_name] = $returned;
246 $result = $result && $returned;
249 // Return true only if all the plugins have returned true.
253 function getReturnedValues($hookname) {
254 return $this->returned_values[$hookname];
257 function getReturnedValuesAsString($hookname) {
260 if (isset($this->returned_values[$hookname])) {
261 foreach ($this->returned_values[$hookname] as $value) {
270 * CountHookListeners() - number of listeners on a particular hook
272 * @param string name of the hook
273 * @return int nb of listeners for this hookname
275 function CountHookListeners($hookname) {
276 if (isset($this->hooks_to_plugins[$hookname])) {
277 $p_list = $this->hooks_to_plugins[$hookname];
278 return count ($p_list);
284 function isPluginAllowedForProject($p, $group_id) {
285 $Group = group_get_object($group_id);
286 return $Group->usesPlugin($p->getName());
291 * plugin_manager_get_object() - get the PluginManager object
293 * @return PluginManager the PluginManager object
295 function &plugin_manager_get_object() {
296 global $PLUGINMANAGER_OBJ;
297 if (!isset($PLUGINMANAGER_OBJ) || !$PLUGINMANAGER_OBJ) {
298 $PLUGINMANAGER_OBJ = new PluginManager ;
300 return $PLUGINMANAGER_OBJ ;
304 * plugin_get_object() - get a particular Plugin object
306 * @param string $pluginname - a plugin name
307 * @return Plugin The Plugin object
309 function &plugin_get_object ($pluginname) {
310 global $PLUGINMANAGER_OBJ;
311 $result=$PLUGINMANAGER_OBJ->Getpluginobject ($pluginname) ;
316 * register_plugin () - register a plugin
318 * @param pluginobject - an object of a subclass of the Plugin class
320 function register_plugin(&$pluginobject) {
321 $pm =& plugin_manager_get_object () ;
322 return $pm->RegisterPlugin ($pluginobject) ;
326 * plugin_hook () - run a set of hooks
328 * @param hookname - name of the hook
329 * @param params - parameters for the hook
331 function plugin_hook($hookname, $params = false) {
332 $pm =& plugin_manager_get_object () ;
333 return $pm->RunHooks($hookname, $params) ;
337 * plugin_hook_by_reference () - run a set of hooks with params passed by reference
339 * @param hookname - name of the hook
340 * @param params - parameters for the hook
342 function plugin_hook_by_reference ($hookname, &$params) {
343 $pm =& plugin_manager_get_object () ;
344 return $pm->RunHooks ($hookname, $params) ;
348 * plugin_hook_listeners () - count the number of listeners on a hook
350 * @param hookname - name of the hook
352 function plugin_hook_listeners ($hookname, $params=false) {
353 $pm =& plugin_manager_get_object () ;
354 return $pm->CountHookListeners ($hookname) ;
358 * setup_plugin_manager () - initialise the plugin infrastructure
361 function setup_plugin_manager() {
362 $pm =& plugin_manager_get_object() ;
370 // c-file-style: "bsd"