Extension:BugMilestone

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png
BugzillaMilestone

Release status: beta

Implementation Parser function
Description This extension adds a little Milestone dashboard a bit like Trac does, linked to a Bugzilla database.
Author(s) Bertrand Gorge http://www.epistema.com
Latest version 1.0
License No license specified
Download No link
Parameters
$GLOBALS['conf']['BugzillaMilestone'] = array(
        'bugzilla_url'  => 'http://bugzilla.your_company.com/',
        'database'      => "bugs",
        'user'          => "mysql_bug_user",
        'password'      => "mysql_bug_passwd");

Translate the BugMilestone extension if possible

Check usage and version matrix; code metrics

This extension adds a little Milestone dashboard a bit like Trac does, linked to a Bugzilla database.

A version exists that works for MediaWiki 1.6 (not based on parser functions). See the discussion page to get the code.

Installation[edit | edit source]

Add and complete this at the end of LocalSettings.php :

 include_once('extensions/BugzillaMilestone.php');
 $GLOBALS['conf']['BugzillaMilestone'] = array(
        'bugzilla_url'  => 'http://bugzilla.your_company.com/',
        'database'      => "bugs",
        'user'          => "mysql_bug_user",
        'password'      => "mysql_bug_passwd");

Copy the following code into extensions/BugzillaMilestone.php :

<?php
 
# Define a setup function
$wgExtensionFunctions[] = 'wfBugzillaMilestone_Setup';
# Add a hook to initialise the magic word
$wgHooks['LanguageGetMagic'][]       = 'wfBugzillaMilestone_Magic';
 
$wgExtensionCredits['other'][] = array(
	'name' => 'BugzillaMilestone',
	'author' => 'Bertrand Gorge',
	'description' => 'for showing milestone dashboard, like in Trac',
	'url' => 'http://www.mediawiki.org/wiki/Extension:BugMilestone',
);
 
function wfBugzillaMilestone_Setup() {
	global $wgParser;
	# Set a function hook associating the "Milestone" magic word with our function
	$wgParser->setFunctionHook('Milestone', 'wfBugzillaMilestone_Render');
}
 
function wfBugzillaMilestone_Magic( &$magicWords, $langCode = '') {
	# Add the magic word
	# The first array element is case sensitive, in this case it is not case sensitive
	# All remaining elements are synonyms for our parser function
	$magicWords['Milestone'] = array( 0, 'Milestone' );
	# unless we return true, other parser functions extensions won't get loaded.
	return true;
}
 
function wfBugzillaMilestone_Render( &$parser, $Milestone = '') {
	# The parser function itself
	# The input parameters are wikitext with templates expanded
	# The output should be wikitext too

	$parser->disableCache();
 
	global $wgDBserver, $wgDBname, $wgDBUser, $wgDBPassword;
 
	$Source = $GLOBALS['conf']['BugzillaMilestone'];
 
	if (empty($Source['host']))
		$Source['host'] = $wgDBserver;
	if (empty($Source['database']))
		$Source['database'] = $wgDBname;
	if (empty($Source['user']))
		$Source['user'] = $wgDBUser;
	if (empty($Source['password']))
		$Source['password'] = $wgDBPassword;
	if (empty($Source['prefix']))
		$Source['prefix'] = "";
 
	$Link = @mysql_connect($Source['host'], $Source['user'], $Source['password'], true);
	if (!$Link)
		return pBugMilestone_NoConnection;
 
	if (!mysql_select_db($Source['database'], $Link)) {
		mysql_close($Link);
		return pBugMilestone_DBNotFound;
	}
 
	if (empty($Source['bugzilla_url']))
		$Source['bugzilla_url'] = 'http://yourbugzilla.installation.com/';
 
	$openURL =  $Source['bugzilla_url'] . 'buglist.cgi?query_format=advanced&target_milestone='.rawurlencode($Milestone).'&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED';
	$closedURL = $Source['bugzilla_url'] . 'buglist.cgi?query_format=advanced&target_milestone='.rawurlencode($Milestone).'&bug_status=RESOLVED&bug_status=VERIFIED&bug_status=CLOSED';
 
	$OpenBugCountSQL = "SELECT COUNT(1) FROM " . $Source['prefix'] . "bugs WHERE bug_status IN ('UNCONFIRMED', 'NEW', 'ASSIGNED', 'REOPENED') AND target_milestone='".mysql_escape_string($Milestone)."'";
	$Result = @mysql_query($OpenBugCountSQL, $Link);
	if (!$Result) {
		mysql_close($Link);
		return pBugMilestone_QueryError;
	}
	if ($Row = mysql_fetch_row($Result))
		$OpenBugCount = $Row[0];
 
	$ClosedBugCountSQL = "SELECT COUNT(1) FROM " . $Source['prefix'] . "bugs WHERE bug_status IN ('RESOLVED', 'VERIFIED', 'CLOSED') AND target_milestone='".mysql_escape_string($Milestone)."'";
	$Result = @mysql_query($ClosedBugCountSQL, $Link);
	if (!$Result) {
		mysql_close($Link);
		return pBugMilestone_QueryError;
	}
	if ($Row = mysql_fetch_row($Result))
		$ClosedBugCount = $Row[0];
 
	mysql_free_result($Result);
	mysql_close($Link);
 
	$TotalBugsInMilestone = $ClosedBugCount + $OpenBugCount;
	if ($TotalBugsInMilestone > 0)
		$ClosedPercent = round($ClosedBugCount / $TotalBugsInMilestone * 100);
	else
		$ClosedPercent = 100;
 
	$strMiletone = '';
 
	if (empty($GLOBALS['BugMilestoneCSS'])) {
		$GLOBALS['BugMilestoneCSS'] = true;
		$strMiletone .= '<style type="text/css" media="print, screen, all">' . "\n";
		$strMiletone .= 'table.progress {' . "\n";
		$strMiletone .= ' border: 1px solid #d7d7d7;' . "\n";
		$strMiletone .= ' border-collapse: collapse;' . "\n";
		$strMiletone .= ' border-spacing: 0;' . "\n";
		$strMiletone .= ' float: left;' . "\n";
		$strMiletone .= ' margin: 0;' . "\n";
		$strMiletone .= ' padding: 0;' . "\n";
		$strMiletone .= ' empty-cells: show;' . "\n";
		$strMiletone .= '}' . "\n";
		$strMiletone .= 'table.progress a, table.progress :link, table.progress :visited,' . "\n";
		$strMiletone .= 'table.progress :link:hover, table.progress :visited:hover {' . "\n";
		$strMiletone .= ' border: none;' . "\n";
		$strMiletone .= ' display: block;' . "\n";
		$strMiletone .= ' width: 100%;' . "\n";
		$strMiletone .= ' height: 1.2em;' . "\n";
		$strMiletone .= ' padding: 0;' . "\n";
		$strMiletone .= ' margin: 0;' . "\n";
		$strMiletone .= ' text-decoration: none' . "\n";
		$strMiletone .= '}' . "\n";
		$strMiletone .= 'table.progress td { background: #fff; padding: 0 }' . "\n";
		$strMiletone .= 'table.progress td.closed { background: #bae0ba }' . "\n";
		$strMiletone .= 'table.progress td :hover { background: none }' . "\n";
		$strMiletone .= 'p.percent { font-size: 10px; line-height: 2.4em; margin: 0.9em 0 0 }' . "\n";
		$strMiletone .= 'ul.milestones { margin: 2em 0 0; padding: 0 }' . "\n";
		$strMiletone .= 'li.milestone { list-style: none; margin-bottom: 4em }' . "\n";
		$strMiletone .= '.milestone .info { white-space: nowrap }' . "\n";
		$strMiletone .= '.milestone .info h2 {' . "\n";
		$strMiletone .= ' background: #f7f7f7;' . "\n";
		$strMiletone .= ' border-bottom: 1px solid #d7d7d7;' . "\n";
		$strMiletone .= ' margin: 0;' . "\n";
		$strMiletone .= '}' . "\n";
		$strMiletone .= '.milestone .info .progress { margin: 1em 1em 0; width: 40em; max-width: 70% }' . "\n";
		$strMiletone .= '.milestone .info dl {' . "\n";
		$strMiletone .= ' font-size: 10px;' . "\n";
		$strMiletone .= ' font-style: italic;' . "\n";
		$strMiletone .= ' margin: 0 1em 2em;' . "\n";
		$strMiletone .= ' white-space: nowrap;' . "\n";
		$strMiletone .= ' clear: both;' . "\n";
		$strMiletone .= '}' . "\n";
		$strMiletone .= '.milestone .info dt { display: inline; margin-left: .5em }' . "\n";
		$strMiletone .= '.milestone .info dd { display: inline; margin: 0 1em 0 .5em }' . "\n";
		$strMiletone .= '</style>' . "\n";
	}
 
	$strMiletone .= '<ul class="milestones">  <li class="milestone">   <div class="info">' . "\n";
	$strMiletone .= '<table class="progress">' . "\n";
	$strMiletone .= ' <tr>' . "\n";
	$strMiletone .= '  <td class="closed" style="width: '.$ClosedPercent.'%;"><a target="_blank" href="'.$closedURL.'" title="'.$ClosedBugCount.' of '.$TotalBugsInMilestone.' tickets closed"></a></td>' . "\n";
	$strMiletone .= '  <td class="open" style="width: '.(100-$ClosedPercent).'%;"><a target="_blank" href="'.$openURL.'" title="'.$OpenBugCount.' of '.$TotalBugsInMilestone.' tickets active"></a></td>' . "\n";
	$strMiletone .= ' </tr>' . "\n";
	$strMiletone .= '</table>' . "\n";
	$strMiletone .= '<p class="percent">'.$ClosedPercent.'%</p>' . "\n";
	$strMiletone .= '<dl>' . "\n";
	$strMiletone .= ' <dt>Closed tickets:</dt>' . "\n";
	$strMiletone .= ' <dd><a target="_blank" href="'.$closedURL.'">'.$ClosedBugCount.'</a></dd>' . "\n";
	$strMiletone .= ' <dt>Active tickets:</dt>' . "\n";
	$strMiletone .= ' <dd><a target="_blank" href="'.$openURL.'">'.$OpenBugCount.'</a></dd>' . "\n";
	$strMiletone .= '</dl>' . "\n";
	$strMiletone .= '</div> </li>  </ul>' . "\n";
 
	return array($strMiletone, 'noparse' => true, 'isHTML' => true);
}

Usage[edit | edit source]

Example: {{#Milestone: A milestone in Bugzilla}}

See also[edit | edit source]

The Extension:BugSquish extension that gave me the id to link Bugzilla to MediaWiki...

Credits[edit | edit source]

Created by Bertrand Gorge - http://www.epistema.com/