Skip to main content

Redmine for Drupal 6

Posted in

Introduction

This is a Drupal 6 module for the Redmine Issue Tracker. After installation and configuration, it displays all open issue in a block. This module was developed and tested with Redmine version 1.1.1. It also works great with Drupal 6 Block Refresh

The issues are grouped by projects, and the project tree is hidden on load. Javascript and css files (included) enable the projects to be hidden/unhidden, so you can keep an overview in case there are many projects and issues. The issues are directly linked to the issues in Redmine.

Installation

  • Grab the module from my gitweb repository
  • Adjust the file redmine_issues.module now or after upload, see below for details
  • Install the module files in sites/all/modules/redmine_issues
  • Enable the module
  • go to Administer → User Management → Permissions and adjust access to Redmine Issues accordingly
  • go to Administer → Site Bulding → Blocks, and enable the Redmine Issues Block
  • Remmeber to enable the REST interface in Redmine: Administration → Settings → Authentication → “Enable REST web service”
  • have fun

Adjust redmine_issues.module

As there is no admin settings menu (yet), the following specific values have to be edited into the modules file:

  • Adjust below line to reflect your Redmine url. SSL was not tested , and it will probably not work without reconfiguration of the CURL settings. But if your Drupal is running on the same machine as your Redmine: Don't worry about ssl ;-)
// use these settings for direct connections to Redmine
curl_setopt($tuCurl, CURLOPT_URL, "http://www.dl2keb.de/redmine/issues.xml");
curl_setopt($tuCurl, CURLOPT_PORT , 80);
  • Adjust username and password. I recommend to create a read only user in Redmine:
// adjust username:password for direct connections to Redmine
//curl_setopt($tuCurl, CURLOPT_USERPWD, 'username:password');
  • Adjust the path to your Redmine issues directory. Below line will be used for the direct links to the issues in Redmine:
$block['content'] .= '<ul><li><a href=http://www.dl2keb.de/redmine/issues/' . $value2['id'] . '>'; 

redmine_issues.module

<?php
// $Id$
 
/**
 * Implementation of hook_perm().
 *
 * Since the access to our new custom pages will be granted based on
 * special permissions, we need to define what those permissions are here.
 * This ensures that they are available to enable on the user role
 * administration pages.
 */
function redmine_issues_perm() {
  return array(
      'access Redmine issues',
      );
}
 
/**
 * Implementation of hook_init().
 */
function redmine_issues_init() {
  // load javascript and css for "menu" style block tree (hideable projects)
  drupal_add_js(drupal_get_path('module', 'redmine_issues') .'/js/menu.js');
  drupal_add_css(drupal_get_path('module', 'redmine_issues') .'/css/menu.css');
}
 
/**
 * Implementation of hook_block().
 * @param string $op one of "list", "view", "save" and "configure"
 * @param integer $delta code to identify the block
 * @param array $edit only for "save" operation
 */
function redmine_issues_block($op = 'list', $delta = 0, $edit = array()) { 
  $block = array();
  if ($op == "list") {
    // Generate listing of blocks from this module, for the admin/block page
    $block[0]["info"] = t('Redmine Issues');
    return $block;
  }
  else if ($op == "view"){
    switch ($delta) {
      case 0:
        $block_content = '';
        $block['subject'] = t('Redmine Issues');  
 
        $tuCurl = curl_init();
        // use these settings for direct connections to Redmine
        curl_setopt($tuCurl, CURLOPT_URL, "http://www.dl2keb.de/redmine/issues.xml");
        curl_setopt($tuCurl, CURLOPT_PORT , 80);
        // use these settings for TCL proxied connection 
        /*
        curl_setopt($tuCurl, CURLOPT_URL, "http://www.dl2keb.de:8015/issues/");
        curl_setopt($tuCurl, CURLOPT_PORT , 8015);
         */
        // set CURLOPT_VERBOSE 1 for more information, visible on command line/stdout
        curl_setopt($tuCurl, CURLOPT_VERBOSE, 0);
        curl_setopt($tuCurl, CURLOPT_HEADER, 0);
        // adjust username:password for direct connections to Redmine
        //curl_setopt($tuCurl, CURLOPT_USERPWD, 'username:password');
        curl_setopt($tuCurl, CURLOPT_RETURNTRANSFER, 1);
 
        $tuData = curl_exec($tuCurl);
        if(!curl_errno($tuCurl)){
          $now2 = round(microtime(), 6);
          $xml = simplexml_load_string($tuData);
          $listing = array();
          $block['content'] .=  '<div class="RedmineIssues-block">'; 
 
          // grab issues from projects into array, with key: project name
          for ($i = 0; $i < $xml->count(); $i++) {
            $listing[(string)$xml->issue[$i]->project['name']][$i]['subject'] = (string)$xml->issue[$i]->subject;
            $listing[(string)$xml->issue[$i]->project['name']][$i]['id'] = (string)$xml->issue[$i]->id;
            //$listing[(string)$xml->issue[$i]->project['name']][$i]['id'] = (string)$xml->issue[$i]->tracker['id'];
          }
          // build the block tree
          foreach ($listing as $key1=>$value1) {
            $block['content'] .= '<div class="item-list"><h3><span class="collapse-icon">â–º</span>';
            $block['content'] .=  $key1 . ' (' . count($value1) . ')</h3>';
            foreach ($value1 as $key2=>$value2) {
              $block['content'] .= '<ul><li><a href=http://www.dl2keb.de/redmine/issues/' . $value2['id'] . '>'; 
                $block['content'] .= $value2['subject'] . '</a></li></ul>';
            }
            $block['content'] .= '</div>'; 
          }
          $block['content'] .=  '</div>'; 
        } else {
          $block['content'] .= 'Curl error: ' . curl_error($tuCurl);
          $block['content'] .=  $tuData; 
        }
 
        curl_close($tuCurl);
 
        break;
    }
    return $block;
  }
} // function redmine_issues_block
 
 
/**
 * Implementation of hook_access().
 */
function redmine_issues_access() {
  return user_access('access Redmine issues');
}
 
/**
 * Implementation of hook_help
 */
function redmine_issues_help($path, $arg) {
  switch ($path) {
    // Main module help for the block module
    case 'admin/help#redmine_issues':
      return '<p>' . t('Example help text (for Redmine Issues Module)') . '</p>';
 
  }
}