3 * FusionForge plugin system
5 * Copyright 2002, Roland Mas
6 * Copyright 2010, Franck Villaume - Capgemini
7 * Copyright 2001-2009, Xerox Corporation, Codendi Team
8 * Copyright 2010, Mélanie Le Bail
9 * Copyright 2011, Alain Peyrat - Alcatel-Lucent
10 * http://fusionforge.org
12 * This file is part of FusionForge. FusionForge is free software;
13 * you can redistribute it and/or modify it under the terms of the
14 * GNU General Public License as published by the Free Software
15 * Foundation; either version 2 of the Licence, or (at your option)
18 * FusionForge is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 class Plugin extends Error {
38 * Plugin() - constructor
42 function Plugin($id=0) {
45 $this->hooks = array();
49 * GetHooks() - get list of hooks to subscribe to.
51 * @return array List of strings.
57 * _addHooks() - add a hook to the list of hooks.
59 * @return string name of the added hook
61 function _addHook($name) {
62 return $this->hooks[]=$name;
66 * GetName() - get plugin name.
68 * @return string the plugin name.
75 * getInstallDir() - get installation dir for the plugin.
77 * @return string the directory where the plugin should be linked.
79 function getInstallDir() {
80 if (isset($this->installdir) && $this->installdir)
81 return $this->installdir;
83 return 'plugins/'.$this->name;
87 * provide() - return true if plugin provides the feature.
89 * @return bool if feature is provided or not.
91 function provide($feature) {
92 return (isset($this->provides[$feature]) && $this->provides[$feature]);
96 * Added for Codendi compatibility
97 * getPluginPath() - get installation dir for the plugin.
99 * @return string the directory where the plugin should be linked.
101 function getPluginPath() {
102 if (isset($this->installdir) && $this->installdir)
103 return $this->installdir;
105 return 'plugins/'.$this->name;
109 * CallHook() - call a particular hook.
111 * @param string the "handle" of the hook.
112 * @param array array of parameters to pass the hook.
113 * @return bool true only
115 function CallHook($hookname, &$params) {
120 * getID - get the numeric ID of a plugin
122 * @return int identifier of the plugin
129 $res = db_query_params('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
131 $this->id = db_result($res,0,'plugin_id');
136 * getGroups - get a list of all groups using a plugin.
138 * @return array array containing group objects.
140 function getGroups() {
142 $res = db_query_params('SELECT group_plugin.group_id
143 FROM group_plugin, plugins
144 WHERE group_plugin.plugin_id=plugins.plugin_id
145 AND plugins.plugin_name=$1
146 ORDER BY group_plugin.group_id ASC',
148 $rows = db_numrows($res);
150 for ($i=0; $i<$rows; $i++) {
151 $group_id = db_result($res,$i,'group_id');
152 $result[] = group_get_object($group_id);
158 * getThemePath - returns the directory of the theme for this plugin
160 * @return string the directory
162 function getThemePath(){
163 return util_make_url('plugins/'.$this->name.'/themes/default');
166 function registerRoleValues(&$params, $values) {
167 $role =& $params['role'];
171 $this->installCode();
172 $this->installConfig();
173 $this->installDatabase();
176 function installCode() {
178 $path = forge_get_config('plugins_path') . '/' . $name;
179 $installdir = $this->getInstallDir();
181 // Create a symbolic links to plugins/<plugin>/www (if directory exists).
182 if (is_dir($path . '/www')) { // if the plugin has a www dir make a link to it
183 // The apache group or user should have write perms the www/plugins folder...
184 $www = dirname(dirname(dirname(__FILE__))).'/www';
185 if (!is_link($www.'/'.$installdir)) {
186 $code = symlink($path . '/www', $www.'/'.$installdir);
188 $this->setError('['.$www.'/'.$installdir.'->'.$path . '/www]'.
189 '<br />Soft link to www couldn\'t be created. Check the write permissions for apache in gforge www/plugins dir or create the link manually.');
194 // Create a symbolic links to plugins/<plugin>/etc/plugins/<plugin> (if directory exists).
195 if (is_dir($path . '/etc/plugins/' . $name)) {
196 // The apache group or user should have write perms in /etc/gforge/plugins folder...
197 if (!is_link(forge_get_config('config_path'). '/plugins/'.$name) && !is_dir(forge_get_config('config_path'). '/plugins/'.$name)) {
198 $code = symlink($path . '/etc/plugins/' . $name, forge_get_config('config_path'). '/plugins/'.$name);
200 $this->setError('['.forge_get_config('config_path'). '/plugins/'.$name.'->'.$path . '/etc/plugins/' . $name . ']'.'<br />'.
201 _('Config file could not be linked to etc/gforge/plugins/%1$s. Check the write permissions for apache in /etc/gforge/plugins or create the link manually.'), $name);
207 function installConfig() {
209 $path = forge_get_config('plugins_path') . '/' . $name;
211 // Create a symbolic links to plugins/<plugin>/etc/plugins/<plugin> (if directory exists).
212 if (is_dir($path . '/etc/plugins/' . $name)) {
213 // The apache group or user should have write perms in /etc/gforge/plugins folder...
214 if (!is_link(forge_get_config('config_path'). '/plugins/'.$name) && !is_dir(forge_get_config('config_path'). '/plugins/'.$name)) {
215 $code = symlink($path . '/etc/plugins/' . $name, forge_get_config('config_path'). '/plugins/'.$name);
217 $this->setError('['.forge_get_config('config_path'). '/plugins/'.$name.'->'.$path . '/etc/plugins/' . $name . ']'.'<br />'.
218 _('Config file could not be linked to etc/gforge/plugins/%1$s. Check the write permissions for apache in /etc/gforge/plugins or create the link manually.'), $name);
224 function installDatabase() {
226 $path = forge_get_config('plugins_path') . '/' . $name . '/db';
228 require_once $GLOBALS['gfcommon'].'include/DatabaseInstaller.class.php';
229 $di = new DatabaseInstaller($name, $path);
231 // Search for database tables, if present then upgrade.
232 $res=db_query_params ('SELECT COUNT(*) FROM pg_class WHERE (relname=$1 OR relname like $2) AND relkind=$3',
233 array ('plugin_'.$name, 'plugin_'.$name.'_%', 'r'));
234 $count = db_result($res,0,0);
242 function groupisactivecheckbox (&$params) {
243 // Check if the group is active
244 // This code creates the checkbox in the project edit public info page
245 // to activate/deactivate the plugin
247 $title = _('current plugin status is:').' '.forge_get_config('plugin_status', $this->name);
248 $imgStatus = 'plugin_status_valid.png';
250 $group = group_get_object($params['group']);
252 if ( forge_get_config('plugin_status', $this->name) !== 'valid' ) {
254 $imgStatus = 'plugin_status_broken.png';
256 if ( forge_get_config('installation_environment') === 'development' || $group->usesPlugin($this->name)) {
261 $flag = strtolower('use_'.$this->name);
264 echo ' <input type="checkbox" name="'.$flag.'" value="1" ';
265 // checked or unchecked?
266 if ($group->usesPlugin($this->name)) {
267 echo 'checked="checked"';
271 $pluginObject = plugin_get_object($this->name);
272 if (method_exists($pluginObject, 'getPluginDescription')) {
273 echo '<td class="tabtitle" title="'.$description = $pluginObject->getPluginDescription().'">';
277 echo '<strong>'. sprintf(_('Use %s Plugin'), $this->text) .'</strong>';
278 echo html_image($imgStatus, '16', '16',array('alt'=>$title, 'title'=>$title, 'class'=>'tabtitle-sw'));
285 * @return bool actually only true ...
287 function groupisactivecheckboxpost(&$params) {
288 // this code actually activates/deactivates the plugin after the form was submitted in the project edit public info page
289 $group = group_get_object($params['group']);
290 $flag = strtolower('use_'.$this->name);
291 if ( getIntFromRequest($flag) == 1 ) {
292 $group->setPluginUse($this->name);
294 $group->setPluginUse($this->name, false);
299 function userisactivecheckbox(&$params) {
300 // Check if user is active
301 // This code creates the checkbox in the user account maintenance page
302 // to activate/deactivate the plugin
304 $title = _('current plugin status is:').' '.forge_get_config('plugin_status', $this->name);
305 $imgStatus = 'plugin_status_valid.png';
307 $user = $params['user'];
309 if ( forge_get_config('plugin_status', $this->name) !== 'valid' ) {
311 $imgStatus = 'plugin_status_broken.png';
313 if ( forge_get_config('installation_environment') === 'development' || $user->usesPlugin($this->name)) {
317 $flag = strtolower('use_'.$this->name);
320 echo ' <input type="checkbox" name="'.$flag.'" value="1" ';
321 // checked or unchecked?
322 if ($user->usesPlugin($this->name)) {
323 echo 'checked="checked"';
325 echo ' /> '. sprintf(_('Use %s Plugin'), $this->text);
326 echo html_image($imgStatus, '16', '16',array('alt'=>$title, 'title'=>$title));
332 function userisactivecheckboxpost(&$params) {
333 // this code actually activates/deactivates the plugin after the form was submitted in the user account manteinance page
334 $user = $params['user'];
335 $flag = strtolower('use_'.$this->name);
336 if (getIntFromRequest($flag) == 1) {
337 $user->setPluginUse($this->name);
339 $user->setPluginUse($this->name, false);
343 function getPluginDescription() {
344 return _('No description available.');
348 class PluginSpecificRoleSetting {
352 var $values = array();
353 var $default_values = array();
356 function PluginSpecificRoleSetting(&$role, $name, $global = false) {
357 $this->global = $global;
358 $this->role =& $role;
362 function SetAllowedValues($values) {
363 $this->role->role_values = array_replace_recursive($this->role->role_values,
364 array($this->name => $values));
366 $this->role->global_settings[] = $this->name;
370 function SetDefaultValues($defaults) {
371 foreach ($defaults as $rname => $v) {
372 $this->role->defaults[$rname][$this->name] = $v;
376 function setValueDescriptions($descs) {
377 global $rbac_permission_names ;
378 foreach ($descs as $k => $v) {
379 $rbac_permission_names[$this->name.$k] = $v;
383 function setDescription($desc) {
384 global $rbac_edit_section_names ;
385 $rbac_edit_section_names[$this->name] = $desc;
391 // c-file-style: "bsd"