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 * Copyright 2013, Franck Villaume - TrivialDev
11 * http://fusionforge.org
13 * This file is part of FusionForge. FusionForge is free software;
14 * you can redistribute it and/or modify it under the terms of the
15 * GNU General Public License as published by the Free Software
16 * Foundation; either version 2 of the Licence, or (at your option)
19 * FusionForge is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License along
25 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 class Plugin extends Error {
39 * Plugin() - constructor
43 function Plugin($id=0) {
46 $this->hooks = array();
50 * GetHooks() - get list of hooks to subscribe to.
52 * @return array List of strings.
58 * _addHooks() - add a hook to the list of hooks.
61 * @return string name of the added hook
63 function _addHook($name) {
64 return $this->hooks[]=$name;
68 * GetName() - get plugin name.
70 * @return string the plugin name.
77 * getInstallDir() - get installation dir for the plugin.
79 * @return string the directory where the plugin should be linked.
81 function getInstallDir() {
82 if (isset($this->installdir) && $this->installdir)
83 return $this->installdir;
85 return 'plugins/'.$this->name;
89 * provide() - return true if plugin provides the feature.
91 * @param string $feature
92 * @return bool if feature is provided or not.
94 function provide($feature) {
95 return (isset($this->provides[$feature]) && $this->provides[$feature]);
99 * Added for Codendi compatibility
100 * getPluginPath() - get installation dir for the plugin.
102 * @return string the directory where the plugin should be linked.
104 function getPluginPath() {
105 if (isset($this->installdir) && $this->installdir)
106 return $this->installdir;
108 return 'plugins/'.$this->name;
112 * CallHook() - call a particular hook.
114 * @param string $hookname the "handle" of the hook.
115 * @param array $params array of parameters to pass the hook.
116 * @return bool true only
118 function CallHook($hookname, &$params) {
123 * getID - get the numeric ID of a plugin
125 * @return int identifier of the plugin
132 $res = db_query_params('SELECT plugin_id FROM plugins WHERE plugin_name=$1',
134 $this->id = db_result($res,0,'plugin_id');
139 * getGroups - get a list of all groups using a plugin.
141 * @return array array containing group objects.
143 function getGroups() {
145 $res = db_query_params('SELECT group_plugin.group_id
146 FROM group_plugin, plugins
147 WHERE group_plugin.plugin_id=plugins.plugin_id
148 AND plugins.plugin_name=$1
149 ORDER BY group_plugin.group_id ASC',
151 $rows = db_numrows($res);
153 for ($i=0; $i<$rows; $i++) {
154 $group_id = db_result($res,$i,'group_id');
155 $result[] = group_get_object($group_id);
161 * getThemePath - returns the directory of the theme for this plugin
163 * @return string the directory
165 function getThemePath(){
166 return util_make_url('plugins/'.$this->name.'/themes/default');
169 function registerRoleValues(&$params, $values) {
170 $role =& $params['role'];
174 $this->installCode();
175 $this->installConfig();
176 $this->installDatabase();
179 function installCode() {
181 $path = forge_get_config('plugins_path') . '/' . $name;
182 $installdir = $this->getInstallDir();
184 // Create a symbolic links to plugins/<plugin>/www (if directory exists).
185 if (is_dir($path . '/www')) { // if the plugin has a www dir make a link to it
186 // The apache group or user should have write perms the www/plugins folder...
187 $www = dirname(dirname(dirname(__FILE__))).'/www';
188 if (!is_link($www.'/'.$installdir)) {
189 $code = symlink($path . '/www', $www.'/'.$installdir);
191 $this->setError('['.$www.'/'.$installdir.'->'.$path . '/www]<br />'.
192 _('Soft link to www could not be created. Check the write permissions for apache in fusionforge www/plugins dir or create the link manually.'));
197 // Create a symbolic links to plugins/<plugin>/etc/plugins/<plugin> (if directory exists).
198 if (is_dir($path . '/etc/plugins/' . $name)) {
199 // The apache group or user should have write perms in /etc/fusionforge/plugins folder...
200 if (!is_link(forge_get_config('config_path'). '/plugins/'.$name) && !is_dir(forge_get_config('config_path'). '/plugins/'.$name)) {
201 $code = symlink($path . '/etc/plugins/' . $name, forge_get_config('config_path'). '/plugins/'.$name);
203 $this->setError('['.forge_get_config('config_path'). '/plugins/'.$name.'->'.$path . '/etc/plugins/' . $name . ']'.'<br />'.
204 _('Config file could not be linked to %s. Check the write permissions for apache in /etc/fusionforge/plugins or create the link manually.'), forge_get_config('config_path').'/plugins/'.$name);
210 function installConfig() {
212 $path = forge_get_config('plugins_path') . '/' . $name;
214 // Create a symbolic links to plugins/<plugin>/etc/plugins/<plugin> (if directory exists).
215 if (is_dir($path . '/etc/plugins/' . $name)) {
216 // The apache group or user should have write perms in /etc/fusionforge/plugins folder...
217 if (!is_link(forge_get_config('config_path'). '/plugins/'.$name) && !is_dir(forge_get_config('config_path'). '/plugins/'.$name)) {
218 $code = symlink($path . '/etc/plugins/' . $name, forge_get_config('config_path'). '/plugins/'.$name);
220 $this->setError('['.forge_get_config('config_path'). '/plugins/'.$name.'->'.$path . '/etc/plugins/' . $name . ']'.'<br />'.
221 _('Config file could not be linked to %s. Check the write permissions for apache in /etc/fusionforge/plugins or create the link manually.'), forge_get_config('config_path').'/plugins/'.$name);
227 function installDatabase() {
229 $path = forge_get_config('plugins_path') . '/' . $name . '/db';
231 require_once $GLOBALS['gfcommon'].'include/DatabaseInstaller.class.php';
232 $di = new DatabaseInstaller($name, $path);
234 // Search for database tables, if present then upgrade.
235 $res=db_query_params ('SELECT COUNT(*) FROM pg_class WHERE (relname=$1 OR relname like $2) AND relkind=$3',
236 array ('plugin_'.$name, 'plugin_'.$name.'_%', 'r'));
237 $count = db_result($res,0,0);
245 function groupisactivecheckbox (&$params) {
246 // Check if the group is active
247 // This code creates the checkbox in the project edit public info page
248 // to activate/deactivate the plugin
250 $title = _('Current plugin status is').' '.forge_get_config('plugin_status', $this->name);
251 $imgStatus = 'plugin_status_valid.png';
253 $group = group_get_object($params['group']);
255 if ( forge_get_config('plugin_status', $this->name) !== 'valid' ) {
257 $imgStatus = 'plugin_status_broken.png';
259 if ( forge_get_config('installation_environment') === 'development' || $group->usesPlugin($this->name)) {
264 $flag = strtolower('use_'.$this->name);
267 echo ' <input type="checkbox" name="'.$flag.'" value="1" ';
268 // checked or unchecked?
269 if ($group->usesPlugin($this->name)) {
270 echo 'checked="checked"';
274 $pluginObject = plugin_get_object($this->name);
275 if (method_exists($pluginObject, 'getPluginDescription')) {
276 echo '<td class="tabtitle" title="'.$description = $pluginObject->getPluginDescription().'">';
281 printf(_("Use %s"), $this->text);
283 echo html_image($imgStatus, '16', '16',array('alt'=>$title, 'title'=>$title, 'class'=>'tabtitle-sw'));
290 * @return bool actually only true ...
292 function groupisactivecheckboxpost(&$params) {
293 // this code actually activates/deactivates the plugin after the form was submitted in the project edit public info page
294 $group = group_get_object($params['group']);
295 $flag = strtolower('use_'.$this->name);
296 if ( getIntFromRequest($flag) == 1 ) {
297 $group->setPluginUse($this->name);
299 $group->setPluginUse($this->name, false);
304 function userisactivecheckbox(&$params) {
305 // Check if user is active
306 // This code creates the checkbox in the user account maintenance page
307 // to activate/deactivate the plugin
309 $title = _('Current plugin status is').' '.forge_get_config('plugin_status', $this->name);
310 $imgStatus = 'plugin_status_valid.png';
312 $user = $params['user'];
314 if ( forge_get_config('plugin_status', $this->name) !== 'valid' ) {
316 $imgStatus = 'plugin_status_broken.png';
318 if ( forge_get_config('installation_environment') === 'development' || $user->usesPlugin($this->name)) {
322 $flag = strtolower('use_'.$this->name);
324 echo ' <input type="checkbox" name="'.$flag.'" value="1" ';
325 // checked or unchecked?
326 if ($user->usesPlugin($this->name)) {
327 echo 'checked="checked"';
330 printf(_("Use %s"), $this->text);
331 echo html_image($imgStatus, '16', '16',array('alt'=>$title, 'title'=>$title));
336 function userisactivecheckboxpost(&$params) {
337 // this code actually activates/deactivates the plugin after the form was submitted in the user account manteinance page
338 $user = $params['user'];
339 $flag = strtolower('use_'.$this->name);
340 if (getIntFromRequest($flag) == 1) {
341 $user->setPluginUse($this->name);
343 $user->setPluginUse($this->name, false);
347 function getPluginDescription() {
348 return _('No description available.');
352 class PluginSpecificRoleSetting {
356 var $values = array();
357 var $default_values = array();
360 function PluginSpecificRoleSetting(&$role, $name, $global = false) {
361 $this->global = $global;
362 $this->role =& $role;
366 function SetAllowedValues($values) {
367 $this->role->role_values = array_replace_recursive($this->role->role_values,
368 array($this->name => $values));
370 $this->role->global_settings[] = $this->name;
374 function SetDefaultValues($defaults) {
375 foreach ($defaults as $rname => $v) {
376 $this->role->defaults[$rname][$this->name] = $v;
380 function setValueDescriptions($descs) {
381 global $rbac_permission_names ;
382 foreach ($descs as $k => $v) {
383 $rbac_permission_names[$this->name.$k] = $v;
387 function setDescription($desc) {
388 global $rbac_edit_section_names ;
389 $rbac_edit_section_names[$this->name] = $desc;
395 // c-file-style: "bsd"