Hi,

i've begun to actively transform bugbits to be used in drupal 6.4, and i was wondering if i could request some help from other drupal developers or if i could become an active developer on this project so i can share my code with the community?

Thanks

Comments

tmckeown’s picture

Assigned: Unassigned » tmckeown

Daften,

I would be very interested in seeing what you put together. Would you mind posting the code in this ticket, or emailing me the code? Once I've looked over your code I can let you know about CVS access.

Thanks

Trevor

daften’s picture

Ok, here I go :)

bugbits.info:

; $Id$
name = BugBits
description = A module that integrates mantis with drupal. Don't forget to apply the patch.
core = 6.x

bugbits.module:

<?php
// TODO: make sure this works everywhere, remove dependency on structure of filesystem!!!
require_once('/var/www/drupal-6.4/modules/bugbits/core.php');

/**
* Display help and module information
* @param path which path of the site we're displaying help
* @param arg array that holds the current path as would be returned from arg() function
* @return help text for the path
*/
function bugbits_help($path, $arg) {
  $output = '';
  switch ($path) {
    case "admin/help#bugbits":
      $output = '<p>'.  t("Integrates the Mantis bugtracking system in drupal.") .'</p>';
      break;
  }
  return $output;
} // function bugbits_help

function bugbits_perm() {
  return array('bugbits access all');
}

function bugbits_menu() {

  $items = array();

  $items['mantis'] = array(
    'title'=> 'Issue Tracking',
    'description' => 'Integrate Mantis in Drupal',
    'page callback' => 'bugbits_all', 
    'access arguments' => array('bugbits access all'),
    'type' => MENU_CALLBACK,
    );
  return $items;
}

function bugbits_all(){

$output .= '<script type="text/javascript">

//Input the IDs of the IFRAMES you wish to dynamically resize to match its content height:
//Separate each ID with a comma. Examples: ["myframe1", "myframe2"] or ["myframe"] or [] for none:
var iframeids=["mantis_frame"]

//Should script hide iframe from browsers that dont support this script (non IE5+/NS6+ browsers. Recommended):
var iframehide="yes"

var getFFVersion=navigator.userAgent.substring(navigator.userAgent.indexOf("Firefox")).split("/")[1]
var FFextraHeight=parseFloat(getFFVersion)>=0.1? 16 : 0 //extra height in px to add to iframe in FireFox 1.0+ browsers

function resizeCaller() {
	var dyniframe=new Array()
	for (i=0; i<iframeids.length; i++){
		if (document.getElementById)
			resizeIframe(iframeids[i])
//reveal iframe for lower end browsers? (see var above):
		if ((document.all || document.getElementById) && iframehide=="no"){
			var tempobj=document.all? document.all[iframeids[i]] : document.getElementById(iframeids[i])
			tempobj.style.display="block"
		}
	}
}

function resizeIframe(frameid){
	var currentfr=document.getElementById(frameid)
	if (currentfr && !window.opera){
		currentfr.style.display="block"
		if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) //ns6 syntax
			currentfr.height = currentfr.contentDocument.body.offsetHeight+FFextraHeight; 
		else if (currentfr.Document && currentfr.Document.body.scrollHeight) //ie5+ syntax
			currentfr.height = currentfr.Document.body.scrollHeight;
		if (currentfr.addEventListener)
			currentfr.addEventListener("load", readjustIframe, false)
		else if (currentfr.attachEvent){
			currentfr.detachEvent("onload", readjustIframe) // Bug fix line
			currentfr.attachEvent("onload", readjustIframe)
		}
	}
}

function readjustIframe(loadevt) {
	var crossevt=(window.event)? event : loadevt
	var iframeroot=(crossevt.currentTarget)? crossevt.currentTarget : crossevt.srcElement
	if (iframeroot)
		resizeIframe(iframeroot.id);
}

function loadintoIframe(iframeid, url){
	if (document.getElementById)
	document.getElementById(iframeid).src=url
}

if (window.addEventListener)
	window.addEventListener("load", resizeCaller, false)
else if (window.attachEvent)
	window.attachEvent("onload", resizeCaller)
else
	window.onload=resizeCaller

</script>';
$url = "http://" . $_SERVER["HTTP_HOST"] . "/drupal-6.4/modules/bugbits/view_all_bug_page.php";

$output .= '<iframe id="mantis_frame" src="' . $url .'" 
tyle="overflow:visible;width:100%; display:none" marginwidth="0" marginheight="0" frameborder="0" vspace="0" hspace="0" scrolling="no" width="100%"></iframe>';


print theme('page',$output);


}

function bugbits_user($op, &$edit, &$account, $category = NULL){

	switch($op){
		/** Edit has the following keys name, mail, status, roles, signature, timezone, mailalias,pass **/

		case "insert":
			_bugbits_create_user($edit["name"], $edit["pass"], $edit["mail"]);
		    break;
		case "after_update":
			_bugbits_uppass($account->name, $account->pass);
		    break;
		case "validate": 
			if(!_bugbits_check_name($edit["name"])){
				form_set_error('name', 'Sorry that username is not available');
			}
			if(!_bugbits_check_email($edit["mail"])){
				form_set_error('mail', 'Sorry that email address has already been taken');
			}
		    break;
		case "delete":
			_bugbits_userdel($account->name);
		    break;
		case "login":
		    /** $edit["pass"] is plain text while $account->pass is md5 hash of password **/
		    if(!auth_attempt_login($edit["name"], $account->pass, false)){
		    	watchdog("Mantis module", "Error user " . $account->name . " was not able to log into Mantis", array(), WATCHDOG_ERROR);
		    } else {
		    	watchdog("Mantis module", "Info user " . $account->name . " was able to log into Mantis", array(), WATCHDOG_INFO);
		    }
		    break;
//		case "logout":
//            auth_logout();
//            break;
	}
}

function _bugbits_check_name($name) {
	$result = mantis_db_query("SELECT username from mantis_user_table where username = '%s'", $name);
	$mant_unique = (mantis_db_affected_rows($result) > 0) ? false : true;

	if($mant_unique){
		watchdog('User Manager', 'Returning a true from check name', array(), WATCHDOG_WARNING);
		return true;
	}else{
		watchdog('User Manager', 'Returning a false from check name', array(), WATCHDOG_WARNING);
		return false;
	}
}

function _bugbits_check_email($email) {
	$result = mantis_db_query("SELECT email from mantis_user_table where email = '%s'", $email);
	$mant_unique = (mantis_db_affected_rows($result) > 0) ? false : true;

	if($mant_unique){
		watchdog('User Manager', 'Returning a true from check mail', array(), WATCHDOG_WARNING);
		return true;
	}else{
		watchdog('User Manager', 'Returning a false from check mail', array(), WATCHDOG_WARNING);
		return false;
	}
}

function _bugbits_create_user($username, $password, $email){ 
			$password_hash = md5($password);
			
			$cookie_hash = "";
			$lcv = 0;
			$c_flag = false;
			do{
				if($c_flag){
					$cookie_hash = md5($cookie_hash);
				}else{
					$cookie_hash = md5($username . "openmfg" . $password . $email);
				}		
				
				$c_flag = bad_cookie($cookie_hash);
				$lcv++;	

			}while($c_flag && $lcv < 5);
			
            $insert_user = "INSERT INTO mantis_user_table
	               ( username, email, password, date_created, last_visit,
	                enabled, access_level, login_count, cookie_string, realname )
	             VALUES
	               ( '$username', '$email', '$password_hash', now(), now(), 1, 10, 0, '$cookie_hash', '');";
			$result = mantis_db_query($insert_user);
			
			if(!$result){
				$error = "ERROR:  User $username did not insert into the database";
				watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
			}
			
			$query = "select id from mantis_user_table where username = '$username';";
			$result = mantis_db_query($query);
			$num_rows = mantis_db_affected_rows($result);
			
			if($num_rows > 1 || $num_rows == 0){
				$error = "ERROR:  There was an error in finding the user $username";
				watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
			}else{
				$row = mantis_db_fetch_array($result);
				$id = $row["id"];
			}

            $insert_user_pref = "INSERT INTO mantis_user_pref_table (user_id, project_id, default_profile, default_project, advanced_report, advanced_view, advanced_update, refresh_delay, redirect_delay, bugnote_order, email_on_new, email_on_assigned, email_on_feedback, email_on_resolved, email_on_closed, email_on_reopened, email_on_bugnote, email_on_status, email_on_priority, email_on_new_min_severity, email_on_assigned_min_severity, email_on_feedback_min_severity, email_on_resolved_min_severity, email_on_closed_min_severity, email_on_reopened_min_severity, email_on_bugnote_min_severity, email_on_status_min_severity, email_on_priority_min_severity,email_bugnote_limit, language)
                        VALUES ($id, '0', '0', '0', '0', '0', '0', '30', '2', 'ASC', '1', '1', '1', '1', '1', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'english');";
			$result = mantis_db_query($insert_user_pref);
			
			if(!$result){
				$error = "ERROR:  There was an error in creating user $username";
				watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
			}

			watchdog("Mantis Module", "User $username was successfully created", array(), WATCHDOG_NOTICE);
}

function bad_cookie($cookie){
	$query = "select cookie_string from mantis_user_table where cookie_string = '$cookie';";
	$result = mantis_db_query($query);
	if(mantis_db_affected_rows($result) >= 1){
		return true;
	} else{
		return false;
	}
}

function _bugbits_uppass($username, $password){
	$query = "update mantis_user_table set password = '$password' where username = '$username';";
	$result = mantis_db_query($query);
	if(!$result){
		$error = "ERROR: There was an error update $username 's password";
		watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
	}
}

function _bugbits_userdel($username){
	$query = "select id from mantis_user_table where username = '$username';";
	$result = mantis_db_query($query);
	$num_rows = mantis_db_affected_rows($result);
	
	if($num_rows > 1 || $num_rows == 0){
		$error = "ERROR:  There was an error in finding the user $username";
		watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
	}else{
		$row = mantis_db_fetch_array($result);
		$id = $row["id"];
	}
	
	watchdog('User manager', "Deleting user $username", WATCHDOG_WARNING);
	$query = "delete from mantis_user_table where username = '$username';";
	$result = mantis_db_query($query);
	if(!$result){
		$error = "ERROR: There was an error deleting user $username from mantis_user_table";
		watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
	}
	
	$query = "delete from mantis_user_pref_table where user_id = '$id';";
	$result = mantis_db_query($query);
	if(!$result){
		$error = "ERROR: There was an error deleting user $username from mantis_user_pref_table";
		watchdog("Mantis Module", $error, array(), WATCHDOG_ERROR);
	}
	
	watchdog("Mantis Module", "User $username was successfully deleted", array(), WATCHDOG_NOTICE);
}

Especially the inclusion of the core.php file should be done properly, this is a quick dirty fix. Watchdog should be replaced with the new syslogd facilities i think. I also think it should be possible to do EVERYTHING through the mantis API, but this off course depends on the mantis team.

I've also changed al the conflicting database functions (e.g. db_query()) so they are prefixed with mantis_ (like you did in the patch file). I had to do this 'by hand' because the patch file didn't work correctly anymore.

Now I ran into an annoying bug: when the function config_get_global from the config_api.php file (in the core folder) get's called, certain global variables can't be found in the $GLOBALS array. I'm in the process of debugging that, but it goes very slowly :)

daften’s picture

So basically, i copied your code and tried to adapt it to drupal 6.x. That works now, but mantis is being annoying ;)

tmckeown’s picture

Draften,

You are quite correct that including the mantis files is sort of a bad idea :-). I *believe* I fixed this in an version that I did not commit to CVS. I need to pull some files off an old hard drive to be sure. I will commit to getting your code and my older code merged into together over the next week or so. Be sure to keep a look out for a dev version for 6.x. In the mean time, lets discuss the future plans of this module. Are you interested in participating in active development? I have had some big plans for this module, but never the resources to see them through. Contact me via my user name and lets discuss.

--Trevor

daften’s picture

How can I contact you through your username? I can't find a contact button or a contact-addres anywhere :s

Thanks for the help btw, we would actually need this module in action next week or so :)

stephthegeek’s picture

Not a developer, but we're thinking about using Mantis internally and would be interested in helping with this as we can (sponsorship, testing).

tmckeown’s picture

stephthegeek,

Thank you for your interest. Your are the third person in the last month that has expressed an interest in this module. Obviously just getting the single login working again would be a first step, but by no means a permanent solution.

Ideally I would like to write a specification document on how the integration is going to happen, scope out the project and possible initial release dates, then get to programming. I have a 'gut' feeling how long api integration would take, but I would hate to speak out of turn before the spec is written.

I have enabled the contact tab on my profile, so please feel free to email me with any questions or comments, or post below.

Cheers,

--Trevor

bobke81’s picture

Hello,

Being involved in a startup company with an open source strategy we would like to use bugbits on the website we are developing (using Drupal 6). Have you any idea when a first version for drupal 6 would be available?

greetings,
Matthias

stephthegeek’s picture

Any more movement on this? We've been actively using Mantis in our organization for a few weeks now, and boy is it ever a hugely productive step up from Drupal's Project module for our needs.

Anyway, we've also been looking at putting a more extensive contact form on our website rather than Drupal's built in one. Debating between doing this as CCK or with the Webform module. Any thoughts on how integration with Mantis might work? Obviously there are a lot of ways to do this, with varying degrees of complexity. It could be a one-way entry into Mantis (ie. a CCK/Webform submission on the Drupal site gets added as an issue in Mantis, with at least some limited mapping of fields/categories/projects) without any further customer interaction with Mantis. The person responding to the customer could manually add the reply to the Mantis issue when resolving it. Even this would be a big step forward.

Thoughts?

tmckeown’s picture

Stepthegreek,

I have created a drupal and mantis setup, but my development would be much more productive if I hade some mantis test data. Would you be able to provide a db_dump of mantis to test against? I think your right, let's start small, get this one feature out of the way, and build from there.

In terms of the bug posting feature I would suggest we stick with a CCK to and mantis field level mapping.

Thanks for your direction and I will see if I can get a start on this one feature ... no promises ..

stephthegeek’s picture

Great! That would be a wonderful step... CCK form on our site -> Mantis issue, with perhaps project name and category that could be mapped. That's our use case at least, for customer support, but I could see priority and auto-assigning to a certain person as being important too.

While I'd love to share, we've got hundreds of issues and I think it would take more time to remove all the confidential information in them than it would be to create a few test categories/fields/issues. Let me know if I can help with that though -- if you can provide admin access to your Mantis install I would be happy to spend some time populating it.

daften’s picture

Hi, i could probably provide you with a database dump from mantis, let me know if you need it!

How far along are you with the single sign on feature, I have some spare time, so maybe I could help you along?

tmckeown’s picture

Draften,

Yes that would be awesome. I think you have my email address, so please send a db dump there. Also please try to get a cvs account with drupal and you can start helping me out with the code base. Once you have a cvs account i can give you access to the bugbits branch.

Cheers,

Trevor

daften’s picture

I sent it to your email address!

daften’s picture

Status: Active » Closed (fixed)

Trevor and I are both working on the 6.x version, so closed