5 * Copyright 2009, Fabien Dubois - Capgemini
6 * Copyright 2009-2011, Franck Villaume - Capgemini
7 * http://fusionforge.org
9 * This file is part of FusionForge.
11 * FusionForge is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
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
22 * along with FusionForge; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 * @todo : need a massive cleanup
28 * deal correctly with password (might need direct db access ?)
29 * limit non SOAP call aka direct db access to mantisbt
32 class MantisBTPlugin extends Plugin {
34 function MantisBTPlugin() {
36 $this->name = "mantisbt" ;
37 $this->text = "MantisBT" ; // To show in the tabs, use...
38 $this->_addHook('user_personal_links'); //to make a link to the user's personal part of the plugin
39 $this->_addHook('usermenu');
40 $this->_addHook('groupmenu'); // To put into the project tabs
41 $this->_addHook('groupisactivecheckbox'); // The "use ..." checkbox in editgroupinfo
42 $this->_addHook('groupisactivecheckboxpost'); //
43 $this->_addHook('userisactivecheckbox'); // The "use ..." checkbox in user account
44 $this->_addHook('userisactivecheckboxpost'); //
45 $this->_addHook('project_admin_plugins'); // to show up in the admin page fro group
46 $this->_addHook('change_cal_permission');
47 $this->_addHook('change_cal_mail');
48 $this->_addHook('add_cal_link_father');
49 $this->_addHook('del_cal_link_father');
50 $this->_addHook('group_approved');
51 $this->_addHook('group_delete');
52 $this->_addHook('group_update');
55 function CallHook($hookname, &$params) {
56 global $G_SESSION, $HTML;
60 if ($G_SESSION->usesPlugin($this->name)) {
61 $param = '?type=user&user_id=' . $G_SESSION->getId() . '&pluginname=' . $this->name; // we indicate the part we're calling is the user one
62 echo $HTML->PrintSubMenu(array($this->text), array('/plugins/mantisbt/index.php' . $param), array(_('Personnal MantisBT page')));
68 $group_id = $params['group'];
69 $project = group_get_object($group_id);
70 if (!$project || !is_object($project) || $project->isError() || !$project->isProject()) {
73 if ($project->usesPlugin($this->name)) {
74 $params['TITLES'][] = $this->text;
75 $params['DIRS'][] = '/plugins/'.$this->name.'/?type=group&group_id=' . $group_id . '&pluginname=' . $this->name;
76 if (session_loggedin()) {
77 $user = session_get_user();
78 $userperm = $project->getPermission($user);
79 if ($userperm->isAdmin()) {
80 $params['TITLES'][] = $this->text . _('Admin');
81 $params['ADMIN'][] = '/plugins/'.$this->name.'/?type=admin&group_id=' . $group_id . '&pluginname=' . $this->name;
85 if ($params['toptab'] == $this->name) {
86 $params['selected']=(count($params['TITLES'])-1);
91 case "user_personal_links": {
92 // 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
93 $userid = $params['user_id'];
94 $user = user_get_object($userid);
95 $text = $params['text'];
96 //check if the user has the plugin activated
97 if ($user->usesPlugin($this->name)) {
99 echo util_make_link('/plugins/'.$this->name.'/?user_id=$userid&type=user&pluginname='.$this->name, _('View Personal MantisBT'));
105 case "project_admin_plugins": {
106 // this displays the link in the project admin options page to it's MantisBT administration
107 $group_id = $params['group_id'];
108 $group = group_get_object($group_id);
109 if ($group->usesPlugin($this->name)) {
111 echo util_make_link("/plugins/mantisbt/?group_id=$group_id&type=admin&pluginname=".$this->name,
112 _('View Admin MantisBT')
119 case "change_cal_permission": {
120 // mise a jour des utilisateurs avec les roles
121 $group_id = $params[1];
122 $group = group_get_object($group_id);
124 foreach($group->getMembers() as $member){
125 $members[] = $member->data_array['user_name'];
127 $this->updateUsersProjetMantis($group->data_array['group_id'],$members);
130 // mise a jour de l'adresse mail utilisateur
131 case "change_cal_mail": {
132 $user_id = $params[1];
133 // before activate this, please fix updateUserInMantis
134 //$this->updateUserInMantis($user_id);
138 case "add_cal_link_father":
139 case "del_cal_link_father": {
140 $sub_group_id = $params[0];
141 $group_id = $params[1];
142 // before activate this, please fix refreshHierarchyMantisBt
143 //$this->refreshHierarchyMantisBt();
147 case "group_delete": {
148 $group_id = $params['group_id'];
149 $group = group_get_object($group_id);
150 if ($group->usesPlugin($this->name)) {
151 if ($this->isProjectMantisCreated($group_id)) {
152 if ($this->removeProjectMantis($group_id)) {
163 case "group_update": {
164 $group_id = $params['group_id'];
165 $group_name =$params['group_name'];
166 $group_ispublic = $params['group_ispublic'];
167 $group = group_get_object($group_id);
168 if ($group->usesPlugin($this->name)) {
169 if ($this->isProjectMantisCreated($group_id)) {
170 if ($this->updateProjectMantis($group_id, $group_name, $group_ispublic)) {
186 * addProjectMantis - inject the Group into Mantisbt thru SOAP
188 * @param array Configuration Array (url, soap_user, soap_password, sync_roles)
189 * @return bool success or not
191 function addProjectMantis($groupId, $confArr) {
192 $groupObject = group_get_object($groupId);
194 $project['name'] = $groupObject->getPublicName();
195 $project['status'] = "development";
197 if ($groupObject->isPublic()) {
198 $project['view_state'] = 10;
200 $project['view_state'] = 50;
203 $project['description'] = $groupObject->getDescription();
206 $clientSOAP = new SoapClient($confArr['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
207 $idProjetMantis = $clientSOAP->__soapCall('mc_project_add', array("username" => $confArr['soap_user'], "password" => $confArr['soap_password'], "project" => $project));
208 } catch (SoapFault $soapFault) {
209 $groupObject->setError('addProjectMantis::Error: ' . $soapFault->faultstring);
212 if (!isset($idProjetMantis) || !is_int($idProjetMantis)){
213 $groupObject->setError('addProjectMantis::Error: ' . _('Unable to create project in Mantisbt'));
216 return $idProjetMantis;
219 function removeProjectMantis($idProjet) {
220 $groupObject = group_get_object($idProjet);
221 $localMantisbtConf = $this->getMantisBTConf();
223 if (!$localMantisbtConf) {
224 $groupObject->setError('removeProjetMantis::Error' . ' '. _('No project found'));
228 $clientSOAP = new SoapClient($localMantisbtConf['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
229 $delete = $clientSOAP->__soapCall('mc_project_delete', array("username" => $localMantisbtConf['soap_user'], "password" => $localMantisbtConf['soap_password'], "project_id" => $localMantisbtConf['id_mantisbt']));
230 } catch (SoapFault $soapFault) {
231 $groupObject->setError('removeProjetMantis::Error' . ' '.$soapFault->faultstring);
234 if (!isset($delete)) {
235 $groupObject->setError('removeProjetMantis:: ' . _('No project found in MantisBT') . ' ' .$localMantisbtConf['id_mantisbt']);
238 db_query_params('DELETE FROM plugin_mantisbt WHERE id_mantisbt = $1',
239 array($localMantisbtConf['id_mantisbt']));
246 * updateProjectMantis - update the Group informations into Mantisbt
247 * @param int id of the Group
248 * @param string group name
249 * @param int public or private
250 * @return bool success or not
252 function updateProjectMantis($groupId, $groupName, $groupIspublic) {
253 $groupObject = group_get_object($groupId);
255 $project['name'] = $groupName;
256 $project['status'] = "development";
258 // should check the config on mantisbt side and not used hard coded values
259 if ($groupIspublic) {
260 $project['view_state'] = 10;
262 $project['view_state'] = 50;
266 $idMantisbt = getIdProjetMantis($groupId);
270 $clientSOAP = new SoapClient(forge_get_config('server_url','mantisbt')."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
271 $update = $clientSOAP->__soapCall('mc_project_update', array("username" => forge_get_config('adminsoap_user','mantisbt'), "password" => forge_get_config('adminsoap_password','mantisbt'), "project_id" => $idMantisbt, "project" => $project));;
272 } catch (SoapFault $soapFault) {
273 $groupObject->setError('updateProjectMantis::Error' . ' '. $soapFault->faultstring);
276 if (!isset($update)) {
277 $groupObject->setError('updateProjectMantis::Error' . ' ' . _('Update MantisBT project'));
281 $groupObject->setError('updateProjectMantis::Error ' . _('ID MantisBT project not found'));
288 * isProjectMantisCreated - check if the Project is already created
290 * @param int the Group Id
291 * @return boolean created or not
293 function isProjectMantisCreated($idProjet){
294 $resIdProjetMantis = db_query_params('SELECT id_mantisbt FROM plugin_mantisbt WHERE id_group = $1',
296 if (!$resIdProjetMantis)
299 if (db_numrows($resIdProjetMantis) > 0) {
306 function updateUserInMantis($user_id) {
307 global $sys_mantisbt_host, $sys_mantisbt_db_user, $sys_mantisbt_db_password, $sys_mantisbt_db_port, $sys_mantisbt_db_name;
308 // recuperation du nouveau mail
309 $resUser = db_query_params('SELECT user_name, email FROM users WHERE user_id = $1',array($user_id));
311 $row = db_fetch_array($resUser);
313 // WONT WORK : db_connect_host is not in any fusionforge api
314 $dbConnection = db_connect_host($sys_mantisbt_db_name, $sys_mantisbt_db_user, $sys_mantisbt_db_password, $sys_mantisbt_host, $sys_mantisbt_db_port);
316 $errMantis1 = "Error : Could not open connection" . db_error($dbConnection);
318 db_rollback($dbConnection);
320 db_query_params('UPDATE mantis_user_table set email = $1 where username = $2',array($row['email'],$row['user_name']),'-1','0',$dbConnection);
326 * updateUsersProjectMantis - inject Username in mantisbt for specific project
328 * @param int Group Id
329 * @param array Unix username array
330 * @return boolean success or not
332 function updateUsersProjectMantis($groupId, $members) {
333 $groupObject = group_get_object($groupId);
337 // @TODO put that in config file ?
339 $role['Manager'] = 70;
340 $role['Concepteur'] = 55;
341 $role['Collaborateur'] = 55;
342 $role['Rapporteur'] = 55;
345 // @TODO : make a robust function there based on RBAC ?
346 $stateForge = array();
347 foreach ($members as $key => $member){
348 $resUserRole = db_query_params('SELECT role.role_name
349 FROM role, user_group, users
350 WHERE users.user_name = $1
351 AND ( user_group.user_id = users.user_id AND user_group.group_id = $2 )
352 AND user_group.role_id = role.role_id',
353 array($member, $groupObject->getID()));
355 $groupObject->setError('updateUsersProjectMantis::'. _('Error : Cannot retrieve information about role') . ' ' .db_error());
358 $row = db_fetch_array($resUserRole);
359 $stateForge[$member]['name'] = $member;
360 $stateForge[$member]['role'] = $row['role_name'];
364 if ($this->__getDBType() === "pgsql") {
365 if ($this->__updateUsersProjectMantisPgsql($groupObject->getID(), $stateForge)) {
374 function refreshHierarchyMantisBt(){
375 global $sys_mantisbt_host, $sys_mantisbt_db_user, $sys_mantisbt_db_password, $sys_mantisbt_db_port, $sys_mantisbt_db_name;
377 $hierarchies=db_query_params('SELECT project_id, sub_project_id FROM plugin_projects_hierarchy WHERE activated=true',array());
379 // WONT WORK : db_connect_host is not in any fusionforge api
380 $dbConnection = db_connect_host($sys_mantisbt_db_name, $sys_mantisbt_db_user, $sys_mantisbt_db_password, $sys_mantisbt_host, $sys_mantisbt_db_port);
382 db_rollback($dbConnection);
386 db_begin($dbConnection);
387 db_query_params('TRUNCATE TABLE mantis_project_hierarchy_table', array() , '-1', 0, $dbConnection);
388 while ($hierarchy = db_fetch_array($hierarchies)) {
389 $result = db_query_params ('INSERT INTO mantis_project_hierarchy_table (child_id, parent_id, inherit_parent) VALUES ($1, $2, $3)',
390 array (getIdProjetMantis($hierarchy['sub_project_id']), getIdProjetMantis($hierarchy['project_id']), 1),
396 $this->setError(_('Insert Failed') . db_error($dbConnection));
402 db_commit($dbConnection);
403 pg_close($dbConnection);
408 * __updateUsersProjectMantisPgsql - update Users for this project in PostgreSQL DB
410 * @param int this Group Id
411 * @param array the role of this forge
412 * @return boolean success or not
415 function __updateUsersProjectMantisPgsql($groupId, $stateForge) {
416 $groupObject = group_get_object($groupId);
418 // WONT WORK : db_connect_host is not in any fusionforge api
419 $dbConnection = db_connect_host(forge_get_config('db_name','mantisbt'), forge_get_config('db_user','mantisbt'), forge_get_config('db_password','mantisbt'), forge_get_config('db_host','mantisbt'), forge_get_config('db_port','mantisbt'));
421 $groupObject->setError('updateUsersProjectMantis::'. _('Error : Could not open connection') . db_error($dbConnection));
422 db_rollback($dbConnection);
424 $idMantis = getIdProjetMantis($groupId);
425 $result = pg_delete($dbConnection,"mantis_project_user_list_table",array("project_id"=>$idMantis));
427 echo 'updateUsersProjectMantis::Error '. _('Unable to clean roles in Mantisbt');
429 foreach($stateForge as $member => $array){
431 $resultIdUser = db_query_params('SELECT mantis_user_table.id FROM mantis_user_table WHERE mantis_user_table.username = $1',
432 array($member), '-1', 0, $dbConnection);
434 $rowIdUser = db_fetch_array($resultIdUser);
435 $idUser = $rowIdUser['id'];
437 $resultInsert = pg_insert($dbConnection,
438 "mantis_project_user_list_table",
439 array("project_id" => $idMantis, "user_id" => $idUser, "access_level" => $role[$array['role']])
441 if (!isset($resultInsert)) {
442 echo 'updateUsersProjectMantis::Error '. _('Unable to update roles in mantisbt');
453 * __getDBType - return the type of DB used for mantisbt
455 * @return string type of the DB
458 function __getDBType() {
459 switch (forge_get_config('db_name','mantisbt')) {
472 * getMantisBTConf - get the mantisbt configuration id for a specific group_id
474 * @return array the mantisbt configuration array
477 function getMantisBTConf() {
479 $group = group_get_object($group_id);
480 $mantisbtConfArray = array();
481 $resIdProjetMantis = db_query_params('SELECT * FROM plugin_mantisbt WHERE id_group = $1', array($group_id));
482 if (!$resIdProjetMantis) {
483 $group->setError('getMantisBTId::error '.db_error());
484 return $mantisbtConfArray;
487 $row = db_numrows($resIdProjetMantis);
489 if ($row == null || count($row) > 2) {
490 $mantisbtConfArray['id_mantisbt'] = 0;
491 return $mantisbtConfArray;
494 $row = db_fetch_array($resIdProjetMantis);
495 $mantisbtConfArray['id_mantisbt'] = $row['id_mantisbt'];
496 $mantisbtConfArray['url'] = $row['url'];
497 $mantisbtConfArray['soap_user'] = $row['soap_user'];
498 $mantisbtConfArray['soap_password'] = $row['soap_password'];
499 $mantisbtConfArray['sync_roles'] = $row['sync_roles'];
500 return $mantisbtConfArray;
504 * getInitDisplay - display the init page
505 * @return bool true only currently
507 function getInitDisplay() {
509 require_once $gfplugins.$this->name.'/view/init.php';
514 * getAdminView - display the admin page
515 * @return bool true only currently
517 function getAdminView() {
519 require_once $gfplugins.$this->name.'/www/admin/index.php';
524 * getSubMenu - display the submenu
526 * @param int enable tooltips : default NO
527 * @return bool true only currently
529 function getSubMenu($enable_tooltips = 0) {
533 $group = group_get_object($group_id);
535 $labelTitle = array();
536 $labelTitle[] = _('Roadmap');
537 $labelTitle[] = _('Tickets');
538 $labelPage = array();
539 $labelPage[] = "/plugins/".$this->name."/?type=group&group_id=".$group_id."&pluginname=".$this->name."&view=roadmap";
540 $labelPage[] = "/plugins/".$this->name."/?type=group&group_id=".$group_id."&pluginname=".$this->name;
541 $labelAttr = array();
542 if ($enable_tooltips) {
543 $labelAttr[] = array('title' => _('View the roadmap, per version tickets'), 'id' => 'roadmapView');
544 $labelAttr[] = array('title' => _('View all tickets.'), 'id' => 'ticketView');
546 $labelAttr[] = array();
547 $labelAttr[] = array();
549 $userperm = $group->getPermission($user);
550 if ( $userperm->isAdmin() ) {
551 $labelTitle[] = _('Administration');
552 $labelPage[] = "/plugins/".$this->name."/?type=admin&group_id=".$group_id."&pluginname=".$this->name;
553 $labelTitle[] = _('Statistics');
554 $labelPage[] = "/plugins/".$this->name."/?type=admin&group_id=".$group_id."&pluginname=".$this->name."&view=stat";
555 if ($enable_tooltips) {
556 $labelAttr[] = array('title' => _('Manage versions, categories and general configuration.'), 'id' => 'adminView');
557 $labelAttr[] = array('title' => _('View global statistics.'), 'id' => 'statView');
559 $labelAttr[] = array();
560 $labelAttr[] = array();
564 echo $HTML->subMenu($labelTitle, $labelPage, $labelAttr);
568 * getHeader - initialize header and js
569 * @param string type : user, project (aka group)
570 * @return bool success or not
572 function getHeader($type) {
576 use_javascript('/plugins/'.$this->name.'/scripts/MantisBTController.js');
580 $params['toptab'] = $this->name;
581 $params['group'] = $group_id;
582 $params['title'] = $this->name.' Project Plugin!';
583 $params['pagename'] = $this->name;
584 $params['sectionvals'] = array(group_getname($group_id));
585 site_project_header($params);
591 $params['user'] = $user_id;
592 site_user_header($params);
604 * initialize - initialize the mantisbt plugin
605 * create mantisbt project if needed
607 * @param int the group id
608 * @param array configuration array
609 * @return bool success or not
611 function initialize($group_id, $confArr) {
612 if ($confArr['mantisbtcreate']) {
613 $idProjectMantis = $this->addProjectMantis($group_id, $confArr);
615 $idProjectMantis = $this->getProjectMantisByName($group_id, $confArr);
617 if ($idProjectMantis) {
618 $result = db_query_params('insert into plugin_mantisbt (id_group, id_mantisbt, url, soap_user, soap_password, sync_roles)
619 values ($1, $2, $3, $4, $5, $6, $7)',
623 $confArr['soap_user'],
624 $confArr['soap_password'],
625 $confArr['sync_roles']));
635 * initialize - initialize the mantisbt user
637 * @param array configuration array
638 * @return bool success or not
640 function initializeUser($confArr) {
642 $result = db_query_params('insert into plugin_mantisbt_users (id_user, mantisbt_user, mantisbt_password)
643 values ($1, $2, $3)',
644 array($user->getID(),
645 $confArr['mantisbt_user'],
646 $confArr['mantisbt_password']));
654 * updateConf - update the MantisBT plugin configuration
656 * @param int the group_id
657 * @param array configuration array
658 * @return bool success or not
660 function updateConf($group_id, $confArr) {
661 $result = db_query_params('update plugin_mantisbt set url = $1 , soap_user = $2, soap_password = $3
662 where id_group = $4',
663 array($confArr['url'],
664 $confArr['soap_user'],
665 $confArr['soap_password'],
674 * updateUserConf - update the MantisBT User configuration
676 * @param array configuration array
677 * @return bool success or not
679 function updateUserConf($confArr) {
681 $result = db_query_params('update plugin_mantisbt_users set mantisbt_user = $1 , mantisbt_password = $2
683 array($confArr['mantisbt_user'],
684 $confArr['mantisbt_password'],
693 * getProjectMantisByName - find the project to link with
695 * @param array configuration array
696 * @return int the mantisbt id
698 function getProjectMantisByName($group_id, $confArr) {
699 $groupObject = group_get_object($group_id);
701 $clientSOAP = new SoapClient($confArr['url']."/api/soap/mantisconnect.php?wsdl", array('trace'=>true, 'exceptions'=>true));
702 $mantisbtProjectArr = $clientSOAP->__soapCall('mc_projects_get_user_accessible', array("username" => $confArr['soap_user'], "password" => $confArr['soap_password']));
703 } catch (SoapFault $soapFault) {
704 $groupObject->setError('getProjectMantisByName::Error: ' . $soapFault->faultstring);
707 foreach ($mantisbtProjectArr as $mantisbtProject) {
708 if ($mantisbtProject->name == $confArr['mantisbtname']) {
709 return $mantisbtProject->id;
712 $groupObject->setError('getProjectMantisByName::Error: mantisbt project not found');
717 * getUserConf - return the user / password for the user id mantisbt account
719 * @return array the user configuration
721 function getUserConf() {
724 $resIdUser = db_query_params('SELECT mantisbt_user, mantisbt_password FROM plugin_mantisbt_users WHERE id_user = $1', array($user->getID()));
726 $user->setError('getUserConf::error '.db_error());
730 $row = db_numrows($resIdUser);
732 if ($row == null || count($row) > 2) {
736 $row = db_fetch_array($resIdUser);
737 $userConf['user'] = $row['mantisbt_user'];
738 $userConf['password'] = $row['mantisbt_password'];
744 // c-file-style: "bsd"