Input filter: Case numbers (ex. [#12345]) turn into links automatically

jonathan_hunt - July 26, 2008 - 04:56
Project:Case Tracker
Version:6.x-1.x-dev
Component:User interface
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs work
Description

We use Trac but are migrating much of our internal project management to Drupal via Case Tracker. Below is code to implement an input filter that converts references to Cases in the form #800-7 to links also indicating case state (refer http://trac.edgewall.org/wiki/TracLinks).

casetracker_input_filter.info

; $Id$
name = CT Input Filter
description = Define text shortcuts for referring to Case Tracker content
package = Case Tracker
dependencies = casetracker

casetracker_input_filter.module
<?php
// $Id$

/**
* @file
* Define Trac-style input filter for Case Tracker
*
* @author Jonathan Hunt casetracker_input_filter@huntdesign.co.nz
*/

/**
* Implementation of hook_filter_tips()
*/
function casetracker_input_filter_filter_tips($delta, $format, $long = FALSE) {
  return t('Reference a Case Tracker case using #id where id is the Case number, e.g. #800-7');
}

/**
* Implementation of hook_filter()
*/
function casetracker_input_filter_filter($op, $delta = 0, $format = -1, $text = '') {
  switch ($op) {
    case 'list':
      return array(0 => t('Case Tracker'));
      break;
   
    case 'description':
      return t('Refer to Case Tracker Cases using a simple syntax.');
      break;
   
    case 'settings':
      // No settings for now
      break;
     
    case 'no cache':
      return TRUE; // TRUE during dev only
   
    case 'prepare':
      return $text;
   
    case 'process':
      return _casetracker_input_filter_process($text);
   
    default:
      return $text;
  }
}

/**
* Process text looking for cases in the format #nnn-nnn
* Matches are replaced in a link to the case node, wrapped in a span with CSS class: case-todo or case-done
*/
function _casetracker_input_filter_process($text) {
  if (preg_match_all("/#\d+-\d+/i", $text, $matches)) {
    foreach ($matches[0] as $key => $value) {
      $match[] = $matches[0][$key];
      $case_parts = explode('-', substr($value, 1));
      $result = db_fetch_object(db_query("SELECT cc.nid FROM {casetracker_case} cc LEFT JOIN {casetracker_project} cp ON (cc.pid = cp.nid) WHERE cp.project_number = %d AND cc.case_number = %d", $case_parts[0], $case_parts[1]));
     
      // Try to indicate status per dashboard settings
      // get the state keys that have to be counted as done
      $states_done = variable_get('casetracker_dashboard_states_done', array());
      // No API in Casetracker so we'll query the db directly
      $case_status = db_result(db_query("SELECT c.case_status_id FROM {casetracker_case} c LEFT JOIN {node} n ON n.nid=c.nid AND n.vid=c.vid WHERE n.nid=%d", $result->nid));
      $class = $states_done[$case_status]? 'done' : 'todo';
      $replace[] = '<span class="case-'. $class .'">'. l($value, 'node/'. $result->nid) .'</span>';
    }
    return str_replace($match, $replace, $text);
  }

  return $text;
}
Feel free to either incorporate this into CT as a contrib module, or bake it directly into CT if you find it useful.

#1

alex_b - April 14, 2009 - 00:14
Version:5.x-1.3-beta1» 6.x-1.x-dev

Updating to latest branch version.

#2

jmiccolis - June 9, 2009 - 22:11
Status:active» needs work

So, I'd really like to have functionality like this but there is one privacy issue with this approach on sites that have private content. For example, on sites that use Organic Groups we'd want to be sure that a malicious user could just type in a list of #123-1, #123-2, etc and just get the status of all tickets.

In the implementation above we don't check node access (which would mean probably joining against the node table and using db_rewrite_sql()). But even if we do check access it isn't clear how we'd be able to check access and still be compatible with the filter cache, as using the cache wouldn't run the access checks for the current user. If would cache the output for the user who happened to get to the post first after the cache was last cleared.

For my usage of case tracker I need a filter like this to be compatible with the filter cache and work with node access, so I'm setting it to 'needs work' for now.

#3

Roger Saner - September 16, 2009 - 08:20
Title:Trac-style input filter» Input filter: Case numbers (ex. [#12345]) turn into links automatically

This is very similar to project_issue module's filter "Project issue numbers (ex. [#12345]) turn into links automatically" and I'd love to see this in Case Tracker, but using the same syntax as the project module (i.e. to work more drupal-like than trac-like). Thanks for the code, jonathan_hunt :)

project_issue addresses the privacy issue by running a node_access('view', $node) on the issue number nid, which would address jmiccolis's concerns.

This is only about 100 lines of code in project_issue.module from line 1072 to 1184, and a little bit of css (anyone up for porting this? :)

#4

jmiccolis - September 16, 2009 - 19:53

If anyone is thinking about working on this please also read this discussion https://community.openatrium.com/issues/node/66 which goes into some more details about what the issues are with the idea of doing this in a filter process step. ...and some more ideas for a way to do it.

 
 

Drupal is a registered trademark of Dries Buytaert.