5 * Copyright 2009, Fabien Dubois - Capgemini
6 * Copyright 2009-2011, Franck Villaume - Capgemini
7 * Copyright 2011-2012, Franck Villaume - TrivialDev
8 * http://fusionforge.org
10 * This file is part of FusionForge. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 class MantisBTPlugin extends Plugin {
28 function __construct() {
30 $this->name = "mantisbt";
31 $this->text = "MantisBT"; // To show in the tabs, use...
32 $this->_addHook('user_personal_links'); //to make a link to the user's personal part of the plugin
33 $this->_addHook('usermenu');
34 $this->_addHook('groupmenu'); // To put into the project tabs
35 $this->_addHook('groupisactivecheckbox'); // The "use ..." checkbox in editgroupinfo
36 $this->_addHook('groupisactivecheckboxpost'); //
37 $this->_addHook('userisactivecheckbox'); // The "use ..." checkbox in user account
38 $this->_addHook('userisactivecheckboxpost'); //
39 $this->_addHook('project_admin_plugins'); // to show up in the admin page fro group
40 $this->_addHook('group_delete');
41 $this->_addHook('group_update');
42 $this->_addHook('site_admin_option_hook');
43 $this->_addHook('widget_instance', 'myPageBox', false);
44 $this->_addHook('widgets', 'widgets', false);
47 function CallHook($hookname, &$params) {
48 global $G_SESSION, $HTML;
52 if ($G_SESSION->usesPlugin($this->name)) {
53 $param = '?type=user&user_id=' . $G_SESSION->getId() . '&pluginname=' . $this->name; // we indicate the part we're calling is the user one
54 echo $HTML->PrintSubMenu(array($this->text), array('/plugins/mantisbt/index.php' . $param), array(array('class'=> 'tabtitle', 'title' => _('Personal MantisBT page'))));
60 $group_id = $params['group'];
61 $project = group_get_object($group_id);
62 if (!$project || !is_object($project) || $project->isError() || !$project->isProject()) {
65 if ($project->usesPlugin($this->name)) {
66 $params['TITLES'][] = $this->text;
67 $params['DIRS'][] = '/plugins/'.$this->name.'/?type=group&group_id=' . $group_id . '&pluginname=' . $this->name;
68 $params['TOOLTIPS'][] = _('Tickets Management');
69 if (session_loggedin()) {
70 $user = session_get_user();
71 $userperm = $project->getPermission();
72 if ($userperm->isAdmin()) {
73 $params['ADMIN'][] = '/plugins/'.$this->name.'/?type=admin&group_id=' . $group_id . '&pluginname=' . $this->name;
76 if (isset($params['toptab'])) {
77 (($params['toptab'] == $this->name) ? $params['selected'] = (count($params['TITLES'])-1) : '' );
83 case "user_personal_links": {
84 // this displays the link in the user's profile page to it's personal MantisBT (if you want other sto access it, youll have to change the permissions in the index.php
85 $userid = $params['user_id'];
86 $user = user_get_object($userid);
87 //check if the user has the plugin activated
88 if ($user->usesPlugin($this->name)) {
91 $arr_t[] = array('title' => _('Manage your mantisbt account and follow your tickets'), 'class' => 'tabtitle');
92 echo util_make_link('/plugins/'.$this->name.'/?user_id='.$userid.'&type=user&pluginname='.$this->name, _('View Personal MantisBT'), $arr_t);
98 case "project_admin_plugins": {
99 // this displays the link in the project admin options page to it's MantisBT administration
100 $group_id = $params['group_id'];
101 $group = group_get_object($group_id);
102 if ($group->usesPlugin($this->name)) {
104 echo util_make_link("/plugins/mantisbt/?group_id=$group_id&type=admin&pluginname=".$this->name, _('View Admin MantisBT'), array('class' => 'tabtitle', 'title' => _('MantisBT administration page')));
110 case "site_admin_option_hook": {
111 echo '<li>'.$this->getAdminOptionLink().'</li>';
115 case "group_delete": {
116 $group_id = $params['group_id'];
117 $group = group_get_object($group_id);
118 if ($group->usesPlugin($this->name)) {
119 if ($this->isProjectMantisCreated($group_id)) {
120 if ($this->removeProjectMantis($group_id)) {
131 case "group_update": {
132 $group_id = $params['group_id'];
133 $group_name =$params['group_name'];
134 $group_ispublic = $params['group_ispublic'];
135 $group = group_get_object($group_id);
136 if ($group->usesPlugin($this->name)) {
137 if ($this->isProjectMantisCreated($group_id)) {
138 if ($this->updateProjectMantis($group_id, $group_name, $group_ispublic)) {
150 $group = group_get_object($GLOBALS['group_id']);
151 if ($group->usesPlugin($this->name)) {
152 return $this->widgets($params);
156 case "widget_instance": {
157 $group = group_get_object($GLOBALS['group_id']);
158 if ((is_object($group)? $group->usesPlugin($this->name) : false) || $G_SESSION->usesPlugin($this->name)) {
159 return $this->myPageBox($params);
168 * addUserMantisBT - inject the User into MantisBT thru SOAP
170 * @param array Configuration Array (url, soap_user, soap_password, mantisbt_password)
171 * @return bool success or not
173 function addUserMantisBT($confArr) {
175 $mantisbtAccount = array();
176 $mantisbtAccount['name'] = $user->getUnixName();
177 $mantisbtAccount['real_name'] = $user->getRealName();
178 $mantisbtAccount['email'] = $user->getEmail();
179 $mantisbtAccount['password'] = $confArr['mantisbt_password'];
181 $clientSOAP = new SoapClient($confArr['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
182 $idUserMantisBT = $clientSOAP->__soapCall('mc_account_create', array("username" => $confArr['soap_user'], "password" => $confArr['soap_password'], "account" => $mantisbtAccount));
183 } catch (SoapFault $soapFault) {
184 $user->setError('addUserMantisBT::Error: ' . $soapFault->faultstring);
187 if (!isset($idUserMantisBT) || !is_int($idUserMantisBT)){
188 $user->setError('addUserMantisBT::Error: ' . _('Unable to create user in Mantisbt'));
191 return $idUserMantisBT;
195 * addProjectMantis - inject the Group into Mantisbt thru SOAP
197 * @param array Configuration Array (url, soap_user, soap_password, sync_roles)
198 * @return bool success or not
200 function addProjectMantis($groupId, $confArr) {
201 $groupObject = group_get_object($groupId);
203 $project['name'] = $groupObject->getPublicName();
204 $project['status'] = "development";
206 //TODO : make it works correctly and use the config soap api to get the real value.
207 if ($groupObject->isPublic()) {
208 $project['view_state'] = 10;
210 $project['view_state'] = 50;
213 $project['description'] = $groupObject->getDescription();
216 $clientSOAP = new SoapClient($confArr['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
217 $idProjetMantis = $clientSOAP->__soapCall('mc_project_add', array("username" => $confArr['soap_user'], "password" => $confArr['soap_password'], "project" => $project));
218 } catch (SoapFault $soapFault) {
219 $groupObject->setError('addProjectMantis::Error: ' . $soapFault->faultstring);
222 if (!isset($idProjetMantis) || !is_int($idProjetMantis)){
223 $groupObject->setError('addProjectMantis::Error: ' . _('Unable to create project in Mantisbt'));
226 return $idProjetMantis;
229 function removeProjectMantis($idProjet) {
230 $groupObject = group_get_object($idProjet);
231 $localMantisbtConf = $this->getMantisBTConf($groupObject->getID());
233 if (!$localMantisbtConf) {
234 $groupObject->setError('removeProjetMantis::Error' . ' '. _('No project found'));
238 $clientSOAP = new SoapClient($localMantisbtConf['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
239 $delete = $clientSOAP->__soapCall('mc_project_delete', array("username" => $localMantisbtConf['soap_user'], "password" => $localMantisbtConf['soap_password'], "project_id" => $localMantisbtConf['id_mantisbt']));
240 } catch (SoapFault $soapFault) {
241 $groupObject->setError('removeProjetMantis::Error' . ' '.$soapFault->faultstring);
244 if (!isset($delete)) {
245 $groupObject->setError('removeProjetMantis:: ' . _('No project found in MantisBT') . ' ' .$localMantisbtConf['id_mantisbt']);
248 $res = db_query_params('DELETE FROM plugin_mantisbt WHERE id_mantisbt = $1',
249 array($localMantisbtConf['id_mantisbt']));
251 $groupObject->setError('removeProjetMantis:: ' . _('Cannot delete in database') . ' ' .$localMantisbtConf['id_mantisbt']);
260 * updateProjectMantis - update the Group informations into Mantisbt
261 * @param int id of the Group
262 * @param string group name
263 * @param int public or private
264 * @return bool success or not
266 function updateProjectMantis($groupId, $groupName, $groupIspublic) {
267 $groupObject = group_get_object($groupId);
269 $localMantisbtConf = $this->getMantisBTConf($groupObject->getID());
270 $project['name'] = $groupName;
271 $project['status'] = "development";
273 // should check the config on mantisbt side and not used hard coded values
274 if ($groupIspublic) {
275 $project['view_state'] = 10;
277 $project['view_state'] = 50;
280 if ($localMantisbtConf['id_mantisbt'] != 0) {
282 $clientSOAP = new SoapClient($localMantisbtConf['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
283 $update = $clientSOAP->__soapCall('mc_project_update', array("username" => $localMantisbtConf['soap_user'], "password" => $localMantisbtConf['soap_password'], "project_id" => $localMantisbtConf['id_mantisbt'], "project" => $project));
284 } catch (SoapFault $soapFault) {
285 $groupObject->setError('updateProjectMantis::Error' . ' '. $soapFault->faultstring);
288 if (!isset($update)) {
289 $groupObject->setError('updateProjectMantis::Error' . ' ' . _('Update MantisBT project'));
293 $groupObject->setError('updateProjectMantis::Error ' . _('ID MantisBT project not found'));
300 * isProjectMantisCreated - check if the Project is already created
302 * @param int the Group Id
303 * @return boolean created or not
305 function isProjectMantisCreated($idProjet){
306 $resIdProjetMantis = db_query_params('SELECT id_mantisbt FROM plugin_mantisbt WHERE id_group = $1',
308 if (!$resIdProjetMantis)
311 if (db_numrows($resIdProjetMantis) > 0) {
319 * getMantisBTConf - get the mantisbt configuration id for a specific group_id
321 * @param integer the group_id
322 * @return array the mantisbt configuration array
325 function getMantisBTConf($group_id) {
326 $group = group_get_object($group_id);
327 $mantisbtConfArray = array();
328 $resIdProjetMantis = db_query_params('SELECT * FROM plugin_mantisbt WHERE id_group = $1', array($group_id));
329 if (!$resIdProjetMantis) {
330 $group->setError('getMantisBTId::error '.db_error());
331 return $mantisbtConfArray;
334 $row = db_numrows($resIdProjetMantis);
336 if ($row == null || count($row) > 2) {
337 $mantisbtConfArray['id_mantisbt'] = 0;
338 return $mantisbtConfArray;
341 $row = db_fetch_array($resIdProjetMantis);
342 $mantisbtConfArray['id_mantisbt'] = $row['id_mantisbt'];
343 $mantisbtConfArray['sync_roles'] = $row['sync_roles'];
344 $mantisbtConfArray['use_global'] = $row['use_global'];
345 if ($mantisbtConfArray['use_global']) {
346 $mantisbtGlobConf = $this->getGlobalconf();
347 $mantisbtConfArray['url'] = $mantisbtGlobConf['url'];
348 $mantisbtConfArray['soap_user'] = $mantisbtGlobConf['soap_user'];
349 $mantisbtConfArray['soap_password'] = $mantisbtGlobConf['soap_password'];
351 $mantisbtConfArray['url'] = $row['url'];
352 $mantisbtConfArray['soap_user'] = $row['soap_user'];
353 $mantisbtConfArray['soap_password'] = $row['soap_password'];
356 return $mantisbtConfArray;
360 * getInitDisplay - display the init page
361 * @return bool true only currently
363 function getInitDisplay() {
365 require_once $gfplugins.$this->name.'/view/init.php';
370 * getAdminView - display the admin page
371 * @return bool true only currently
373 function getAdminView() {
375 require_once $gfplugins.$this->name.'/www/admin/index.php';
380 * getSubMenu - display the submenu
382 * @param int enable tooltips : default NO
383 * @return bool true only currently
385 function getSubMenu() {
389 $group = group_get_object($group_id);
391 $labelTitle = array();
392 $labelTitle[] = _('Roadmap');
393 $labelTitle[] = _('Tickets');
394 $labelPage = array();
395 $labelPage[] = "/plugins/".$this->name."/?type=group&group_id=".$group_id."&pluginname=".$this->name."&view=roadmap";
396 $labelPage[] = "/plugins/".$this->name."/?type=group&group_id=".$group_id."&pluginname=".$this->name;
397 $labelAttr = array();
398 $labelAttr[] = array('title' => _('View the roadmap, per version tickets'), 'id' => 'roadmapView', 'class' => 'tabtitle-nw');
399 $labelAttr[] = array('title' => _('View all tickets.'), 'id' => 'ticketView', 'class' => 'tabtitle');
400 $userperm = $group->getPermission();
401 if ($userperm->isAdmin()) {
402 $labelTitle[] = _('Administration');
403 $labelPage[] = "/plugins/".$this->name."/?type=admin&group_id=".$group_id."&pluginname=".$this->name;
404 $labelTitle[] = _('Statistics');
405 $labelPage[] = "/plugins/".$this->name."/?type=admin&group_id=".$group_id."&pluginname=".$this->name."&view=stat";
406 $labelAttr[] = array('title' => _('Manage versions, categories and general configuration.'), 'id' => 'adminView', 'class' => 'tabtitle');
407 $labelAttr[] = array('title' => _('View global statistics.'), 'id' => 'statView', 'class' => 'tabtitle');
410 echo $HTML->subMenu($labelTitle, $labelPage, $labelAttr);
414 * getHeader - initialize header and js
415 * @param string type : user, project (aka group)
416 * @return bool success or not
418 function getHeader($type) {
421 use_javascript('/plugins/'.$this->name.'/scripts/MantisBTController.js');
422 use_stylesheet('/plugins/'.$this->name.'/style.css');
426 $params['toptab'] = $this->name;
427 $params['group'] = $group_id;
428 $params['title'] = $this->name.' Project Plugin!';
429 $params['pagename'] = $this->name;
430 $params['sectionvals'] = array(group_getname($group_id));
431 site_project_header($params);
437 $params['user_id'] = $user_id;
438 site_user_header($params);
442 case 'globaladmin': {
443 session_require_global_perm('forge_admin');
445 require_once($gfwww.'admin/admin_utils.php');
446 site_admin_header(array('title'=>_('Site Global MantisBT Admin'), 'toptab' => ''));
458 * initialize - initialize the mantisbt plugin
459 * create mantisbt project if needed
461 * @param int the group id
462 * @param array configuration array
463 * @return bool success or not
465 function initialize($group_id, $confArr) {
466 if ($confArr['globalconf']) {
467 $globalConfArr = $this->getGlobalconf();
468 $confArr['url'] = $globalConfArr['url'];
469 $confArr['soap_user'] = $globalConfArr['soap_user'];
470 $confArr['soap_password'] = $globalConfArr['soap_password'];
472 if ($confArr['mantisbtcreate']) {
473 $idProjectMantis = $this->addProjectMantis($group_id, $confArr);
474 } elseif ($confArr['mantisbtname'] && sizeof($confArr['mantisbtname'])) {
475 $idProjectMantis = $this->getProjectMantisByName($group_id, $confArr);
477 $groupObject = group_get_object($group_id);
478 $groupObject->setError('initialize::Error: '. _('MantisBT project not initialized, missing params'));
481 if (isset($idProjectMantis) && $idProjectMantis) {
482 $result = db_query_params('insert into plugin_mantisbt (id_group, id_mantisbt, url, soap_user, soap_password, sync_roles, use_global)
483 values ($1, $2, $3, $4, $5, $6, $7)',
487 $confArr['soap_user'],
488 $confArr['soap_password'],
489 $confArr['sync_roles'],
490 $confArr['globalconf']));
492 $groupObject = group_get_object($group_id);
493 $groupObject->setError('initialize::Error: '. db_error());
502 * initialize - initialize the mantisbt user
504 * @param array configuration array
505 * @return bool success or not
507 function initializeUser($confArr) {
509 if ($confArr['mantisbt_useglobal']) {
510 $globalConfArr = $this->getGlobalconf();
511 $confArr['url'] = $globalConfArr['url'];
512 $confArr['soap_user'] = $globalConfArr['soap_user'];
513 $confArr['soap_password'] = $globalConfArr['soap_password'];
516 if ($confArr['mantisbtcreate']) {
517 $idMantisBTUser = $this->addUserMantisBT($confArr);
518 $confArr['mantisbt_user'] = $user->getUnixName();
520 if ($idMantisBTUser || !$confArr['mantisbtcreate']) {
521 $result = db_query_params('insert into plugin_mantisbt_users (id_user, mantisbt_user, mantisbt_password)
522 values ($1, $2, $3)',
523 array($user->getID(),
524 $confArr['mantisbt_user'],
525 $confArr['mantisbt_password']));
527 $user->setError('initializeUser::Error: '. db_error());
536 * updateConf - update the MantisBT plugin configuration
538 * @param int the group_id
539 * @param array configuration array
540 * @return bool success or not
542 function updateConf($group_id, $confArr) {
543 $result = db_query_params('update plugin_mantisbt set url = $1 , soap_user = $2, soap_password = $3, use_global = $4
544 where id_group = $5',
545 array($confArr['url'],
546 $confArr['soap_user'],
547 $confArr['soap_password'],
548 $confArr['global_conf'],
557 * updateUserConf - update the MantisBT User configuration
559 * @param array configuration array
560 * @return bool success or not
562 function updateUserConf($confArr) {
564 $result = db_query_params('update plugin_mantisbt_users set mantisbt_user = $1 , mantisbt_password = $2
566 array($confArr['mantisbt_user'],
567 $confArr['mantisbt_password'],
576 * getProjectMantisByName - find the project to link with
578 * @param array configuration array
579 * @return int the mantisbt id
581 function getProjectMantisByName($group_id, $confArr) {
582 $groupObject = group_get_object($group_id);
584 $clientSOAP = new SoapClient($confArr['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
585 $mantisbtProjectArr = $clientSOAP->__soapCall('mc_projects_get_user_accessible', array("username" => $confArr['soap_user'], "password" => $confArr['soap_password']));
586 } catch (SoapFault $soapFault) {
587 $groupObject->setError('getProjectMantisByName::Error: ' . $soapFault->faultstring);
590 foreach ($mantisbtProjectArr as $mantisbtProject) {
591 if ($mantisbtProject->name == $confArr['mantisbtname']) {
592 return $mantisbtProject->id;
595 $groupObject->setError('getProjectMantisByName::Error: '. _('MantisBT project not found'));
600 * getUserConf - return the user / password for the user id mantisbt account
602 * @return array the user configuration
604 function getUserConf() {
607 $resIdUser = db_query_params('SELECT mantisbt_user, mantisbt_password FROM plugin_mantisbt_users WHERE id_user = $1', array($user->getID()));
609 $user->setError('getUserConf::error '.db_error());
613 $row = db_numrows($resIdUser);
615 if ($row == null || count($row) > 2) {
619 $row = db_fetch_array($resIdUser);
620 $userConf['user'] = $row['mantisbt_user'];
621 $userConf['password'] = $row['mantisbt_password'];
622 $userConf['url'] = array();
623 foreach ($user->getGroups() as $groupObject) {
624 if ($groupObject->usesPlugin($this->name)) {
625 $mantisbtGroupConf = $this->getMantisBTConf($groupObject->getID());
626 $userConf['url'][] = $mantisbtGroupConf['url'];
633 * getGlobalconf - return the global configuration defined at forge level
635 * @return array the global configuration array
637 function getGlobalconf() {
638 $resGlobConf = db_query_params('SELECT * from plugin_mantisbt_global',array());
643 $row = db_numrows($resGlobConf);
645 if ($row == null || count($row) > 2) {
649 return db_fetch_array($resGlobConf);
653 * updateGlobalConf - update the global configuration in database
655 * @param array configuration array (url, soap_user, soap_password)
656 * @return bool true on success
658 function updateGlobalConf($confArr) {
659 if (!isset($confArr['url']) || !isset($confArr['soap_user']) || !isset($confArr['soap_password']))
662 $res = db_query_params('truncate plugin_mantisbt_global', array());
666 $res = db_query_params('insert into plugin_mantisbt_global (url, soap_user, soap_password)
667 values ($1, $2, $3)',
670 $confArr['soap_user'],
671 $confArr['soap_password'],
680 * getGlobalAdminView - display the Global Admin View
684 function getGlobalAdminView() {
686 $user = session_get_user();
687 include $gfplugins.$this->name.'/view/admin/viewGlobalConfiguration.php';
691 function getAdminOptionLink() {
692 return util_make_link('/plugins/'.$this->name.'/?type=globaladmin', _('Global MantisBT admin'), array('class' => 'tabtitle', 'title' => _('Direct link to global configuration of this plugin')));
697 * getPluginDescription - display the description of this plugin in pluginman admin page
699 * @return string the description
701 function getPluginDescription() {
702 return _('Use Mantis Bugtracker as another ticket management tool.');
705 /** Widgets function **/
707 function widgets($params) {
708 $group = group_get_object($GLOBALS['group_id']);
709 if ( !$group || !$group->usesPlugin ( $this->name ) ) {
712 require_once 'common/widget/WidgetLayoutManager.class.php';
713 if ($params['owner_type'] == WidgetLayoutManager::OWNER_TYPE_GROUP) {
714 $params['fusionforge_widgets'][] = 'plugin_mantisbt_project_latestissues';
719 function myPageBox($params) {
721 require_once 'common/widget/WidgetLayoutManager.class.php';
722 if ($params['widget'] == 'plugin_mantisbt_project_latestissues') {
723 require_once $gfplugins.$this->name.'/common/mantisbt_Widget_ProjectLastIssues.class.php';
724 $params['instance'] = new mantisbt_Widget_ProjectLastIssues($this);
730 // c-file-style: "bsd"