web/ticket.php
authorAlan Knowles <alan@akbkhome.com>
Thu, 27 Jan 2011 14:22:15 +0000 (22:22 +0800)
committerAlan Knowles <alan@akbkhome.com>
Thu, 27 Jan 2011 14:22:15 +0000 (22:22 +0800)
web/ticket.php [deleted file]

diff --git a/web/ticket.php b/web/ticket.php
deleted file mode 100644 (file)
index f6883e6..0000000
+++ /dev/null
@@ -1,1274 +0,0 @@
-<?php # vim:ts=2:sw=2:et:
-/* For licensing and copyright terms, see the file named LICENSE */
-include '../inc/common.php';
-
-if ($pi = mtrack_get_pathinfo()) {
-  $id = $pi;
-} else {
-  $id = $_GET['id'];
-}
-
-if ($id == 'new') {
-  $issue = new MTrackIssue;
-  $issue->priority = 'normal';
-} else {
-  if (strlen($id) == 32) {
-    $issue = MTrackIssue::loadById($id);
-  } else {
-    $issue = MTrackIssue::loadByNSIdent($id);
-  }
-  if (!$issue) {
-    throw new Exception("Invalid ticket $id");
-  }
-}
-
-
-
-$FIELDSET = array(
-    array(
-      "description" => array(
-        "label" => "Full description",
-        "ownrow" => true,
-        "type" => "wiki",
-        "rows" => 10,
-        "cols" => 78,
-        "editonly" => true,
-        ),
-      ),
-    "Properties" => array(
-      "milestone" => array(
-        "label" => "Milestone",
-        "type" => "multiselect",
-        ),
-      "component" => array(
-        "label" => "Component",
-        "type" => "multiselect",
-        ),
-      "classification" => array(
-        "label" => "Classification",
-        "type" => "select",
-        ),
-      "priority" => array(
-        "label" => "Priority",
-        "type" => "select",
-        ),
-      "severity" => array(
-        "label" => "Severity",
-        "type" => "select",
-        ),
-      "keywords" => array(
-          "label" => "Keywords",
-          "type" => "text",
-          ),
-      "changelog" => array(
-          "label" => "ChangeLog (customer visible)",
-          "type" => "multi",
-          "ownrow" => true,
-          "rows" => 5,
-          "cols" => 78,
-       #   "condition" => $issue->status == 'closed'
-          ),
-      ),
-      "Resources" => array(
-          "owner" => array(
-            "label" => "Responsible",
-            "type" => "select"
-            ),
-          "estimated" => array(
-            "label" => "Estimated Hours",
-            "type" => "text"
-            ),
-          "spent" => array(
-            "label" => "Spent Hours",
-            "type" => "text",
-            "readonly" => true,
-            ),
-          "cc" => array(
-            "label" => "Cc",
-            "type" => "text"
-            ),
-          ),
-      );
-$issue->augmentFormFields($FIELDSET);
-
-
-$preview = false;
-$error = array();
-
-if ($_SERVER['REQUEST_METHOD'] == 'POST') 
-{
-  if (isset($_POST['cancel'])) {
-    header("Location: {$ABSWEB}ticket.php/$issue->nsident");
-    exit;
-  }
-  if (!MTrackCaptcha::check('ticket')) {
-    $error[] = "CAPTCHA failed, please try again";
-  }
-  $preview = isset($_POST['preview']) ? true : false;
-
-  $comment = '';
-  try {
-    if ($id == 'new') {
-      MTrackACL::requireAllRights("Tickets", 'create');
-    } else {
-      MTrackACL::requireAllRights("ticket:" . $issue->tid, 'modify');
-    }
-  } catch (Exception $e) {
-    $error[] = $e->getMessage();
-  }
-  
-  if ($id == 'new') {
-    $comment = empty($_POST['comment']) ? '' : $_POST['comment'];
-  }
-  
-  if (!strlen($comment)) {
-    $comment = $_POST['summary'];
-  }
-  try {
-    $CS = MTrackChangeset::begin("ticket:X", $comment);
-  } catch (Exception $e) {
-    $error[] = $e->getMessage();
-    $CS = null;
-  }
-  if ($id == 'new') {
-    // compute next id number.
-    // We don't use auto-number, because we allow for importing multiple
-    // projects with their own ticket sequence.
-    // During "normal" user-driven operation, we do want plain old id numbers
-    // so we compute it here, under a transaction
-    $db = MTrackDB::get();
-    if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'pgsql') {
-        // Some versions of postgres don't like that we have "abc123" for
-        // identifiers, so match on the bigest number nsident fields only
-      $max = "select max(cast(nsident as integer)) + 1 from tickets where nsident ~ '^\\\\d+$'";
-    } else {
-      $max = 'select max(cast(nsident as integer)) + 1 from tickets';
-    }
-    list($issue->nsident) = MTrackDB::q($max)->fetchAll(PDO::FETCH_COLUMN, 0);
-    if ($issue->nsident === null) {
-      $issue->nsident = 1;
-    }
-  }
-
-  if (isset($_POST['action']) && !$preview) {
-    $act= explode('_', $_POST['action'] , 2);
-    //var_dump($act);exit;
-    switch ($act[0]) {
-      case 'leave':
-        break;
-      case 'reopen':
-        $issue->reOpen();
-        break;
-      case 'fixed':
-        $issue->resolution = 'fixed';
-        $issue->close();
-        $_POST['estimated'] = $issue->estimated;
-        break;
-        
-      
-      case 'accept':
-        // will be applied to the issue further down
-        $_POST['owner'] = MTrackAuth::whoami();
-        if ($issue->status == 'new') {
-          $issue->status = 'open';
-        }
-        break;
-        
-        
-      case 'resolve':
-        //$issue->resolution = $_POST['resolution'];
-        $issue->resolution = $act[1];
-        $issue->close();
-        $_POST['estimated'] = $issue->estimated;
-        break;  
-        
-      case 'change':
-        $issue->status = $act[1];
-        break;
-    }
-  }
-
-  $fields = array(
-    'summary',
-    'description',
-    'classification',
-    'priority',
-    'severity',
-    'changelog',
-    'owner',
-    'cc',
-  );
-
-  $issue->applyPOSTData($_POST);
-
-  
-  foreach ($fields as $fieldname) {
-    if (isset($_POST[$fieldname]) && strlen($_POST[$fieldname])) {
-      $issue->$fieldname = $_POST[$fieldname];
-    } else {
-      $issue->$fieldname = null;
-    }
-  }
-
-  $kw = $issue->getKeywords();
-  $kill = array_values($kw);
-  foreach (preg_split('/[ \t,]+/', $_POST['keywords']) as $w) {
-    if (!strlen($w)) {
-      continue;
-    }
-    $x = array_search($w, $kw);
-    if ($x === false) {
-      $k = MTrackKeyword::loadByWord($w);
-      if ($k === null) {
-        $k = new MTrackKeyword;
-        $k->keyword = $w;
-        $k->save($CS);
-      }
-      $issue->assocKeyword($k);
-    } else {
-      $w = array_search($w, $kill);
-      if ($w !== false) {
-        unset($kill[$w]);
-      }
-    }
-  }
-  foreach ($kill as $w) {
-    $issue->dissocKeyword($w);
-  }
-
-  $ms = $issue->getMilestones();
-  $kill = $ms;
-  if (isset($_POST['milestone']) && is_array($_POST['milestone'])) {
-    foreach ($_POST['milestone'] as $mid) {
-      $issue->assocMilestone($mid);
-      unset($kill[$mid]);
-    }
-  }
-  foreach ($kill as $mid) {
-    $issue->dissocMilestone($mid);
-  }
-
-  $ms = $issue->getComponents();
-  $kill = $ms;
-  if (isset($_POST['component']) && is_array($_POST['component'])) {
-    foreach ($_POST['component'] as $mid) {
-      $issue->assocComponent($mid);
-      unset($kill[$mid]);
-    }
-  }
-  foreach ($kill as $mid) {
-    $issue->dissocComponent($mid);
-  }
-  
-    if (!empty($_POST['comment'])) {
-       $issue->addComment($_POST['comment']);
-    }
-  
-  $issue->addEffort($_POST['spent'], $_POST['estimated']);
-
-  if (!count($error)) {
-    try {
-      $issue->save($CS);
-      
-      // make sure everyone is watching it!!!!
-        if($issue->owner && $issue->tid) {
-          // make sure owner is tracking it...
-            MTrackWatch::watch_object('ticket', $issue->tid,  $issue->owner);
-        }
-        
-        if ($id == 'new') {
-            MTrackWatch::watch_object('ticket', $issue->tid,  MTrackAuth::whoami());
-        }
-      
-      
-      $CS->setObject("ticket:" . $issue->tid);
-    } catch (Exception $e) {
-      $error[] = $e->getMessage();
-    }
-  }
-
-  if (!count($error)) {
-    if (isset($_FILES['attachments']) && is_array($_FILES['attachments'])) {
-      foreach ($_FILES['attachments']['name'] as $fileid => $name) {
-        MTrackAttachment::add("ticket:$issue->tid",
-            $_FILES['attachments']['tmp_name'][$fileid],
-            $_FILES['attachments']['name'][$fileid],
-            $CS);
-      }
-    }
-  }
-  if (!count($error) && $id != 'new') {
-    MTrackAttachment::process_delete("ticket:$issue->tid", $CS);
-  }
-
-  if (isset($_POST['apply']) && !count($error)) {
-    $CS->commit();
-    header("Location: {$ABSWEB}ticket.php/$issue->nsident");
-    exit;
-  }
-}
-
-if ($id == 'new') {
-  MTrackACL::requireAllRights("Tickets", 'create');
-  mtrack_head("New ticket");
-} else {
-  MTrackACL::requireAllRights("ticket:" . $issue->tid, 'read');
-  if ($issue->nsident) {
-    mtrack_head("#$issue->nsident " . $issue->summary);
-  } else {
-    mtrack_head("#$id " . $issue->summary);
-  }
-}
-
-echo "<form id='tktedit' method='post' action='{$ABSWEB}ticket.php/$id' enctype='multipart/form-data'>\n";
-/* now to render the edit controls, if suitably privileged */
-if ($id == 'new') {
-  $editable = MTrackACL::hasAllRights("Tickets", 'create');
-} else {
-  $editable = MTrackACL::hasAllRights("ticket:" . $issue->tid, 'modify');
-}
-
-echo <<<HTML
-<div id="issue-desc">
-HTML;
-
-if ($preview) {
-  echo <<<HTML
-<div class='ui-state-highlight ui-corner-all'>
-    <span class='ui-icon ui-icon-info'></span>
-    This is a preview of your pending changes.  It does not show
-    changes to the resolution; those will be applied when you submit.
-</div>
-
-HTML;
-}
-if (count($error)) {
-  foreach ($error as $e) {
-    echo <<<HTML
-<div class='ui-state-error ui-corner-all'>
-    <span class='ui-icon ui-icon-alert'></span>
-HTML;
-    echo htmlentities($e, ENT_QUOTES, 'utf-8') . "\n</div>\n";
-  }
-}
-
-if ($id != 'new') {
-  echo "<h1>";
-  if (!$issue->isOpen()) {
-    echo "<del>";
-  }
-  if ($issue->nsident) {
-    echo "#$issue->nsident ";
-  } else {
-    echo "#$id ";
-  }
-  echo ' [' . $issue->status . '] ';
-  echo htmlentities($issue->summary, ENT_QUOTES, 'utf-8');
-
-  if (!$issue->isOpen()) {
-    echo "</del>";
-  }
-  echo "</h1>\n";
-}
-
-if ($id == 'new') {
-  $created = new stdClass;
-  $created->when = MTrackDB::unixtime(time());
-  $created->who = MTrackAuth::whoami();
-} else {
-  $created = MTrackChangeset::get($issue->created);
-}
-
-$opened = mtrack_date($created->when);
-echo <<<HTML
-<div id="ticketinfo">
-HTML;
-
-$pseudo_fields = array();
-
-if ($id != 'new') {
-  echo "<table id='ctime'><tr><td><label>Opened</label>:</td><td>",
-       mtrack_date($created->when),
-       "</td><td>",
-       mtrack_username($created->who, array('no_image' => true)),
-       "</td></tr>\n";
-  if ($issue->updated != $issue->created) {
-    $updated = MTrackChangeset::get($issue->updated);
-    echo "<tr><td><label>Updated</label>:</td><td>",
-      mtrack_date($updated->when),
-      "</td><td>",
-      mtrack_username($updated->who, array('no_image' => true)),
-      "</td></tr>";
-  }
-  echo "</table>";
-
-  $v = get_components_list(join(',', array_keys($issue->getComponents())));
-  $pseudo_fields['@components'] = $v;
-
-  $v = get_milestones_list(join(',', array_keys($issue->getMilestones())));
-  $pseudo_fields['@milestones'] = $v;
-
-  $v = get_keywords_list(join(',', array_keys($issue->getKeywords())));
-  $pseudo_fields['@keywords'] = $v;
-
-  $ROFIELDSET = $FIELDSET;
-  $ROFIELDSET['Properties']['resolution'] = array(
-    'label' => 'Resolution',
-    'type' => 'text',
-  );
-
-  foreach ($ROFIELDSET as $fsid => $fieldset) {
-    $emited = false;
-    foreach ($fieldset as $propname => $info) {
-      if (isset($info['editonly'])) {
-        continue;
-      }
-      $value = null;
-      switch ($propname) {
-        case 'keywords':
-          $value = array();
-          foreach ($issue->getKeywords() as $kw) {
-            $value[] = mtrack_keyword($kw);
-          }
-          $value = join(' ', $value);
-          break;
-        case 'milestone':
-          $value = $pseudo_fields['@milestones'];
-          break;
-        case 'component':
-          $value = $pseudo_fields['@components'];
-          break;
-        default:
-          $value = $issue->$propname;
-      }
-
-      if (strlen($value)) {
-        if (!$emited) {
-          $rfsid = 'readonly-tkt-' .
-            preg_replace('/[^a-z]+/', '', strtolower($fsid));
-          echo "<fieldset id='$rfsid'><legend>$fsid</legend>\n<table>";
-          $emited = true;
-        }
-
-        switch ($info['type']) {
-          case 'wiki':
-            $value = MTrackWiki::format_to_html($value);
-            break;
-          case 'multi':
-            $value = nl2br(htmlentities($value, ENT_QUOTES, 'utf-8'));
-            break;
-        }
-
-        if (isset($info['ownrow']) && $info['ownrow'] == 'true') {
-          echo "<tr><td colspan='2'><label>$info[label]</label>:</td></tr>";
-          echo "<td colspan='2'>$value</td></tr>\n";
-        } else {
-          echo "<tr><td><label>$info[label]</label>:</td><td width='100%'>$value</td></tr>\n";
-        }
-      }
-    }
-    if ($emited) {
-      echo "</table></fieldset>\n";
-    }
-  }
-}
-echo "</div>\n";
-
-if ($issue->tid !== null) {
-  echo MTrackAttachment::renderList("ticket:$issue->tid");
-}
-
-if ($id != 'new') {
-  echo "<div id='readonly-tkt-description'>";
-  echo MTrackWiki::format_to_html($issue->description);
-  echo "</div>";
-}
-
-if ($editable && $id != 'new' && !$preview) {
-  echo "<br><div id='tkt-view-button-block' class='button-float'>";
-  echo "<button class='mtrack-edit-desc'>Edit</button>";
-  echo " <button class='mtrack-make-comment'>Add Comment / Update Status</button>";
-  MTrackWatch::renderWatchUI('ticket', $issue->tid);
-  echo "</div>";
-}
-echo "</div>"; # issue-desc
-
-$hide_unless_preview = ($preview || $_SERVER['REQUEST_METHOD'] == 'POST') ?
-  '' :
-  ' style="display:none" ';
-
-if ($editable && $id != 'new') {
-  echo <<<HTML
-<div id="edit-issue-desc" $hide_unless_preview >
-HTML;
-}
-
-if ($editable) {
-
-  echo " <input class='summaryedit' id='summary' name='summary' value='" .
-    htmlentities($issue->summary, ENT_QUOTES, 'utf-8') .
-    "' size='80'>";
-
-  echo renderEditForm($issue);
-}
-
-if ($editable && $id != 'new') {
-  echo "</div>";
-}
-
-
-function get_components_list($value)
-{
-  $res = array();
-  if (strlen($value)) foreach (MTrackDB::q(
-      "select name, deleted from components where compid in ($value)")
-      ->fetchAll() as $row) {
-    $c = $row['deleted'] ? '<del>' : '';
-    $c .= htmlentities($row['name'], ENT_QUOTES, 'utf-8');
-    $c .= $row['deleted'] ? '</del>' : '';
-    $res[] = $c;
-  }
-  return join(", ", $res);
-}
-
-function get_milestones_list($value)
-{
-  global $ABSWEB;
-
-  $res = array();
-  if (strlen($value)) foreach (MTrackDB::q(
-      "select name, completed, deleted from milestones where mid in ($value)")
-      ->fetchAll() as $row) {
-    if (strlen($row['completed'])) {
-      $row['deleted'] = 1;
-    }
-    $c = "<span class='milestone";
-    if ($row['deleted']) {
-      $c .= " completed";
-    }
-    $c .= "'><a href=\"{$ABSWEB}milestone.php/" .
-          urlencode($row['name']) . '">';
-    $c .= htmlentities($row['name'], ENT_QUOTES, 'utf-8');
-    $c .= "</a></span>";
-    $res[] = $c;
-  }
-  return join(", ", $res);
-}
-
-function get_keywords_list($value)
-{
-  $res = array();
-  if (strlen($value)) foreach (MTrackDB::q(
-      "select keyword from keywords where kid in ($value)")
-      ->fetchAll() as $row) {
-    $res[] = htmlentities($row['keyword'], ENT_QUOTES, 'utf-8');
-  }
-  return join(", ", $res);
-}
-
-if ($id == 'new') {
-  $changes = array();
-} else {
-  $changes = array();
-  $cids = array();
-  foreach (MTrackDB::q(
-        'select * from changes where object = ?
-        order by changedate asc',
-        "ticket:$issue->tid")->fetchAll(PDO::FETCH_OBJ) as $CS) {
-    $changes[$CS->cid] = $CS;
-    $cids[] = $CS->cid;
-  }
-  $cidlist = join(',', $cids);
-
-  $change_audit = array();
-  foreach (MTrackDB::q("select * from change_audit where cid in ($cidlist)")
-      ->fetchAll(PDO::FETCH_ASSOC) as $citem) {
-    $change_audit[$citem['cid']][] = $citem;
-  }
-
-  /* also need to include cases where the ticket was modified as a side-effect
-   * of other manipulations (such as milestones being closed and tickets being
-   * re-targeted.  Such manipulations do not directly reference this ticket,
-   * and so do not need to be included in the effort_audit array that is
-   * populated below. */
-
-  $tid = $issue->tid;
-  foreach (MTrackDB::q(
-    "select c.cid as cid, c.who as who, c.object as object, c.changedate as changedate, c.reason as reason, ca.fieldname as fieldname, ca.action as action, ca.oldvalue as oldvalue, ca.value as value from change_audit ca left join changes c on (ca.cid = c.cid) where ca.cid not in ($cidlist) and ca.fieldname like 'ticket:$tid:%'")
-    ->fetchAll(PDO::FETCH_OBJ) as $CS) {
-    if (!isset($changes[$CS->cid])) {
-      $changes[$CS->cid] = $CS;
-    }
-    $change_audit[$CS->cid][] = array(
-      'cid' => $CS->cid,
-      'fieldname' => $CS->fieldname,
-      'action' => $CS->action,
-      'oldvalue' => $CS->oldvalue,
-      'value' => $CS->value
-      );
-  }
-
-  $effort_audit = array();
-  foreach (MTrackDB::q(
-      "select * from effort where cid in ($cidlist) and tid=?", $issue->tid)
-      ->fetchAll(PDO::FETCH_ASSOC) as $eff) {
-    $effort_audit[$eff['cid']][] = $eff;
-  }
-}
-ksort($changes);
-
-$idno = 0;
-$events = array();
-
-function collapse_diff($diff)
-{
-  static $idnum = 1;
-  $id = 'diff_' . $idnum++;
-  return "<br>" .
-    "<button onclick='\$(&quot;#$id&quot;).toggle(); return false;'>Toggle diff</button>".
-    "<div id='$id' style='display:none'>" .
-    mtrack_diff($diff) . "</div>";
-}
-
-
- ///------------------loop -- out output events...
-
-foreach ($changes as $CS) {
-  $preamble = 0;
-  if ($idno == 0) {
-    $cid = "top";
-  } else {
-    $cid = "comment:$idno";
-  }
-  $idno++;
-
-  $who = $CS->who;
-  $timestamp = mtrack_date($CS->changedate, true);
-
-  $html = "<div class='ticketevent'><a class='pmark' href='#$cid'>#</a> <a name='$cid'>$timestamp</a> " .
-    mtrack_username($who, array('no_image' => true)) .
-    "</div>\n";
-
-  $html .= "<div class='ticketchangeinfo'>";
-  $html .= mtrack_username($who, array('no_name' => true, 'size' => 48));
-
-  if ($CS->cid == $issue->created) {
-    $html .= "<b>Opened</b><br>\n";
-  }
-
-  $comments = array();
-
-  if (isset($change_audit[$CS->cid]) && is_array($change_audit[$CS->cid]))
-  foreach ($change_audit[$CS->cid] as $citem) {
-    //print_r($citem);
-    list($tbl,,$field) = explode(':', $citem['fieldname'], 3);
-
-    if ($tbl != 'ticket') {
-      // can get here if we created a new keyword, for example
-      //var_dump($citem);
-      continue;
-    }
-    if ($field == '@comment') {
-      $comments[] = $citem['value'];
-      continue;
-    }
-
-    if ($field == '@components') {
-      $citem['value'] = get_components_list($citem['value']);
-    }
-    if ($field == '@milestones') {
-      $citem['value'] = get_milestones_list($citem['value']);
-    }
-    if ($field == '@keywords') {
-      $citem['value'] = get_keywords_list($citem['value']);
-    }
-    if ($field == 'spent') {
-      continue;
-    }
-    if ($field == 'estimated') {
-      if ($citem['value'] !== null) {
-        $citem['value'] += 0;
-      }
-      if ($citem['oldvalue'] !== null) {
-        $citem['oldvalue'] += 0;
-      }
-    }
-
-    if ($field[0] == '@') {
-      $main = isset($pseudo_fields[$field]) ? $pseudo_fields[$field] : '';
-      $field = substr($field, 1, -1);
-    } else {
-      $main = $issue->$field;
-    }
-
-    $f = MTrackTicket_CustomFields::getInstance()->fieldByName($field);
-    if ($f) {
-      $label = htmlentities($f->label, ENT_QUOTES, 'utf-8');
-    } else {
-      if ($field == 'attachment' && strlen($citem['oldvalue'])) {
-        $label = "Attachment: $citem[oldvalue]";
-      } else {
-        $label = ucfirst($field);
-      }
-    }
-
-    if ($citem['oldvalue'] == null) {
-      /* don't bother printing out a set if this is the initial thing
-       * and if the field values are currently the same */
-
-      if ($main != $citem['value'] || $cid != 'top') {
-
-        /* Special case for description; since it is multi-line and often
-         * very large, render it as a diff against the current ticket
-         * description field */
-        if ($field == 'description') {
-          if ($issue->description == $citem['value']) {
-            $html .= "<b>Description</b>: no longer empty; see above<br>";
-            continue;
-          }
-
-          $initial_lines = count(explode("\n", $issue->description));
-          $diff = mtrack_diff_strings($issue->description, $citem['value']);
-          $diff_add = 0;
-          $diff_rem = 0;
-          foreach (explode("\n", $diff) as $line) {
-            if (!strlen($line)) continue;
-            if ($line[0] == '-') {
-              $diff_rem++;
-            } else if ($line[0] == '+') {
-              $diff_add++;
-            }
-          }
-          if (abs($diff_add - $diff_rem) > $initial_lines / 2) {
-            $html .= "<b>initial $label</b><br>" .
-              MTrackWiki::format_to_html($citem['value']);
-          } else {
-            $diff = collapse_diff($diff);
-            $html .= "<b>initial $label</b> (diff to above):<br>$diff\n";
-          }
-        } else {
-          $html .= "<b>$label</b> $citem[value]<br>\n";
-        }
-      }
-    } elseif ($citem['action'] == 'changed') {
-      $lines = explode("\n", $citem['value'], 3);
-      if (count($lines) >= 2) {
-        $diff = mtrack_diff_strings($citem['oldvalue'], $citem['value']);
-        $diff = collapse_diff($diff);
-        $html .= "<b>$label</b> $citem[action]\n$diff\n";
-      } else {
-        $html .= "<b>$label</b> $citem[action] to $citem[value]<br>\n";
-      }
-    } else {
-      $html .= "<b>$label</b> $citem[action]<br>\n";
-    }
-  }
-
-  if (isset($effort_audit[$CS->cid]) && is_array($effort_audit[$CS->cid])) {
-    foreach ($effort_audit[$CS->cid] as $eff) {
-      $exp = (float)$eff['expended'];
-      if ($eff['expended'] != 0) {
-        $html .= "<b>spent</b> $exp hours<br>\n";
-        $preamble++;
-      }
-    }
-  }
-
-  if (count($comments)) {
-    if ($preamble) {
-      $html .= "<br>\n";
-      $preamble = 0;
-    }
-
-    foreach ($comments as $cid => $text) {
-        $M = array();
-       // var_dump($text);
-        if (preg_match('/\[changeset:([^,]+),([a-z0-9]+)\]/i', $text, $M)) {
-            // list the files that where changed...
-            //$html.= print_r($M, true);
-            $rp = '/' . $M[1] . '/' . $M[2];
-            $repo = MTrackSCM::factory($rp);
-            $cd =$repo->historyWithChangelog(null, 1, 'rev', $rp);
-            //print_r($cd);exit; 
-            $html .= MTrackWiki::format_to_html($cd->ent->changelog);
-            
-            
-            //echo '<PRE>'.print_R($cd);
-            
-            
-            if (is_array($cd->ent->files) && count($cd->ent->files)) {
-               // $html .= "<br><br><a href='${ABSWEB}changeset.php$path?fmt=diff'>Download diff</a>";
-                //$html .= "<div class='difffiles'>Affected files:<ul>";
-                $html .= "<div class='difffiles'><ul>";
-                foreach ($cd->ent->files as $id => $file) {
-                    $html .= "<li><a href='#d$id' 
-                            onclick=\"mtrack.showdiff('/{$M[1]}/$M[2]', $id, 'diff-$idno-$cid')\"><b>$file->status</b> $file->name</a></li>\n";
-                }
-                $html .=  "</ul></div>
-                    <div id=\"diff-$idno-$cid\"></div>";
-            }
-            
-            
-            //$html .= print_r($cd, true);
-            continue;
-        }
-        
-        $html .= MTrackWiki::format_to_html($text);
-
-      
-    }
-    
-    
-    
-  }
-
-  $html .= "</div>"; # ticketchangeinfo
-
-  $events[] = $html;
-}
-
-
-if (count($events) > 80 && !isset($_GET['all'])) {
-  $num_hidden = count($events) - 20;
-  $turl = $ABSWEB . 'ticket.php/' . $issue->nsident . '?all=1';
-  echo <<<HTML
-<br>
-<div id='show-overflow' class='ui-state-highlight ui-corner-all'>
-    <span class='ui-icon ui-icon-info'></span>
-    There are $num_hidden older comments that are not shown.
-    <a class='button' href='$turl'>Show hidden comments</button>
-</div>
-HTML;
-} else if (count($events) > 20 && !isset($_GET['all'])) {
-  $num_hidden = count($events) - 20;
-  echo <<<HTML
-<br>
-<div id='show-overflow' class='ui-state-highlight ui-corner-all'>
-    <span class='ui-icon ui-icon-info'></span>
-    There are $num_hidden older comments that are not shown.
-    <button id='button-show-overflow'>Show hidden comments</button>
-</div>
-<div id='ticketcommentsoverflow' style='display:none'>
-HTML;
-  while (count($events) > 20) {
-    echo array_shift($events);
-  }
-  echo <<<HTML
-</div>
-<script type='text/javascript'>
-$('#button-show-overflow').click(function() {
-  $('#show-overflow').hide('blind');
-  $('#ticketcommentsoverflow').show('clip');
-  return false;
-});
-</script>
-HTML;
-
-}
-while (count($events)) {
-  echo array_shift($events);
-}
-
-
-if ($id != 'new') {
-?>
-<br style="clear:both">
-<button id="bottom-comment-button" class='mtrack-make-comment'>Add Comment</button>
-<?php
-}
-
-?>
-</form>
-<div id="confirmCancelDialog" style="display:none"
-    title="Are you sure?">
-  You've entered information into the form.
-  If you cancel, you will not be able to get it back.
-</div>
-<div id="noCommentDialog" style="display:none"
-    title="Please enter comment">
-  It seems you have not made any changes to the ticket,
-  and haven't entered any comments.
-</div>
-<div id="noSummaryDialog" style="display:none"
-    title="Please enter summary">
-  It seems you haven't entered a summary for the ticket.
-</div>
-<script type='text/javascript'>
-formChanged = <?php echo $preview ? 'true' : 'false'; ?>;
-id = <?php echo json_encode($id) ?>;
-issue_tid_null = <?php echo json_encode($issue->tid == null) ?>;
-
-
-
-
-</script>
-<?php
-
-mtrack_foot();
-
-function mtrack_chg_status($rg, $name,$str, $sln = false, $sl=false, $issue=false) {
-  
-    return  mtrack_radio($rg,$name,   $_POST[$rg]) .
-        " <label for='$name'>$str</label>". 
-        ($sln ?  mtrack_select_box($sln, $sl, $issue->status) : '') .
-        "<br>\n" ;
-}
-
-
-function renderEditForm($issue, $params = array())
-{
-  global $id;
-  global $ABSWEB;
-  global $FIELDSET;
-
-  if (!isset($params['formname'])) {
-    $params['formname'] = 'tktedit';
-  } else if (!ctype_alpha($params['formname'])) {
-    throw new Exception("invalid form name");
-  }
-
-  /* compute allowed field values */
-  $allowed = array();
-
-  $C = new MTrackClassification;
-  $allowed['classification'] = $C->enumerate();
-
-  $P = new MTrackPriority;
-  $allowed['priority'] = $P->enumerate();
-
-  $S = new MTrackSeverity;
-  $allowed['severity'] = $S->enumerate();
-
-  $R = new MTrackResolution;
-  $allowed['resolution'] = $R->enumerate();
-
-  $r = array();
-  foreach (MTrackDB::q('
-        select c.compid, c.name, p.name 
-            from components c 
-                left join components_by_project cbp on (c.compid = cbp.compid) 
-                left join projects p on (cbp.projid = p.projid) 
-            where 
-                deleted <> 1 
-            order by 
-                c.name')
-      ->fetchAll(PDO::FETCH_NUM) as $row) {
-          
-    if (strlen($row[2])) {
-      $row[1] .= " ($row[2])";
-    }
-    $r[$row[0]] = $row[1];
-    
-  }
-  $allowed['component'] = $r;
-
-  $r = array();
-  foreach (MTrackDB::q(
-        'select mid, name from milestones where deleted <> 1
-        and completed is null order by (case when duedate is null then 1 else 0 end), duedate, name'
-        )->fetchAll(PDO::FETCH_NUM) as $row) {
-    $r[$row[0]] = $row[1];
-  }
-  foreach ($issue->getMilestones() as $mid => $name) {
-    if (!isset($r[$mid])) {
-      $r[$mid] = $name;
-    }
-  }
-  $allowed['milestone'] = $r;
-
-  // FIXME: workflow should be able to influence this list of users
-  $users = array();
-  $inactiveusers = array();
-  foreach (MTrackDB::q(
-      'select userid, fullname, active from userinfo order by userid'
-      )->fetchAll() as $row) {
-    if (strlen($row[1])) {
-      $disp = "$row[0] - $row[1]";
-    } else {
-      $disp = $row[0];
-    }
-    if ($row[2]) {
-      $users[$row[0]] = $disp;
-    } else {
-      $inactiveusers[$row[0]] = $disp;
-    }
-  }
-  $users[''] = 'nobody';
-  // allow for inactive users to show up if they're currently responsible
-  if (!isset($users[$issue->owner])) {
-    if (!isset($inactiveusers[$issue->owner])) {
-      $users[$issue->owner] = $issue->owner . ' (inactive)';
-    } else {
-      $users[$issue->owner] = $inactiveusers[$issue->owner] . ' (inactive)';
-    }
-  }
-  // last ditch to have it show the right info
-  if (!isset($users[$issue->owner])) {
-    $users[$issue->owner] = $issue->owner;
-  }
-  $allowed['owner'] = $users;
-
-  $html = "<input type='hidden' name='tid' value='" .
-    htmlentities($issue->tid === null ? 'new' : $issue->tid) . "'>\n";
-
-  /* render the form */
-  $col = 0;
-
-  foreach ($FIELDSET as $fsid => $fieldset) {
-    if (is_string($fsid)) {
-      $html .= "<fieldset id='$fsid'><legend>$fsid</legend>\n";
-    }
-
-    $html .= "<table class='fields'>";
-    $col = 0;
-    foreach ($fieldset as $propname => $info) {
-      if (isset($info['readonly'])) {
-        continue;
-      }
-      if (empty($info['ownrow'])) {
-        $info['ownrow'] = false;
-      }
-      $value = null;
-      switch ($propname) {
-        case 'keywords':
-          $value = join(' ', $issue->getKeywords());
-          break;
-        case 'milestone':
-          $value = $issue->getMilestones();
-          break;
-        case 'component':
-          $value = $issue->getComponents();
-          break;
-        case 'owner':
-          $value = $issue->owner;
-          if (!strlen($value)) {
-            $value = '';
-          }
-          break;
-        default:
-          if (isset($issue->$propname)) {
-            $value = $issue->$propname;
-          }
-      }
-      if (isset($info['condition']) && !$info['condition']) {
-        continue;
-      }
-
-      if (($info['ownrow'] && $col) || $col == 2) {
-        $html .= "</tr>\n";
-        $col = 0;
-      }
-      if ($col == 0) {
-        $html .= "<tr valign='top'>";
-      }
-      $col++;
-      if ($info['ownrow']) {
-        $html .= "<td colspan='4'>";
-      } else if ($info['type'] == 'multiselect') {
-        $html .= "<td colspan='2'>";
-      } else {
-        $html .= "<td>";
-      }
-
-      if ($value === null && isset($info['default'])) {
-        $value = $info['default'];
-      }
-
-      if ($info['type'] != 'multiselect') {
-        $html .= "<label for='$propname'>".
-          htmlentities($info['label'], ENT_QUOTES, 'utf-8').
-          ":</label>";
-      }
-
-      if ($info['ownrow']) {
-        $html .= "<br>\n";
-      } else if ($info['type'] != 'multiselect') {
-        $html .= "</td><td class='col$col'>";
-      }
-
-      switch ($info['type']) {
-        case 'text':
-          $size = empty($info['size']) ? "" : "size='$info[size]' ";
-          $html .= "<input id='$propname' name='$propname' ".
-            $size .
-            "value='".htmlentities($value, ENT_QUOTES, 'utf-8').
-            "'>";
-          break;
-
-        case 'multi':
-          $html .= "<textarea id='$propname' name='$propname' ".
-            "rows='$info[rows]' cols='$info[cols]' class='code'>".
-            htmlentities($value, ENT_QUOTES, 'utf-8').
-            "</textarea>\n";
-          break;
-
-        case 'wiki':
-          $srows = $info['rows'] + 1;
-          $html .= "<textarea id='$propname' name='$propname' ".
-            "style='height: {$srows}em' " .
-            "rows='$info[rows]' cols='$info[cols]' class='code wiki'>".
-            htmlentities($value, ENT_QUOTES, 'utf-8').
-            "</textarea>\n";
-          break;
-
-        case 'shortwiki':
-          $html .= "<textarea id='$propname' name='$propname' ".
-            "rows='$info[rows]' cols='$info[cols]' class='code wiki shortwiki'>"
-            . htmlentities($value, ENT_QUOTES, 'utf-8').
-            "</textarea>\n";
-          break;
-
-        case 'select':
-          if (isset($allowed[$propname])) {
-            $html .= mtrack_select_box($propname,
-                $allowed[$propname], $value);
-          } else {
-            $html .= mtrack_select_box($propname,
-                $info['options'], $value);
-          }
-          break;
-
-        case 'multiselect':
-          if (isset($allowed[$propname])) {
-            $html .= mtrack_multi_select_box($propname,
-                $info['label'] . " (select to add)",
-                $allowed[$propname], $value);
-          } else {
-            $html .= mtrack_multi_select_box($propname,
-                $info['label'] . " (select to add)",
-                $info['options'], $value);
-          }
-          break;
-      }
-
-      $html .= "</td>\n";
-
-      if ($info['ownrow']) {
-        $html .= "</tr>\n";
-        $col = 0;
-      }
-    }
-    $html .= "</table>\n";
-
-    if (is_string($fsid)) {
-      $html .= "</fieldset>\n";
-    }
-  }
-   $html .= "</div>";
-     $html .= "<div id='update-issue-desc' style='display:none'>";
-  $html .= "<fieldset id='action-container'><legend>Action - Issue is currently - {$issue->status}</legend>\n";
-
-  // FIXME: workflow inspired actions listed here
-  if (!isset($_POST['action'])) {
-    $_POST['action'] = 'none';
-  }
-  
-  
-  
-  if ($id != 'new') {
-    
-    $html .= mtrack_chg_status(
-        'action', 'none', 
-        "Leave status as " . ($issue->status == 'closed' ? $issue->resolution : $issue->status)
-    );
-         
-    if ($issue->status != 'closed') {
-        
-        
-       $html .= mtrack_chg_status( 'action', 'accept',   "Assign this ticket to ME");
-     // for coder's they can only change this ticke to certian states
-        $groups = MTrackAuth::getGroups(MTrackAuth::whoami());
-        //print_r($groups);
-        // Nasty - I really do not like the acl code in this ...
-         
-        $ST = new MTrackTicketState;
-        $ST = $ST->enumerate();
-        //print_r($ST);
-        unset($ST['closed']);
-         
-         
-        unset($ST[$issue->status]);
-       
-        if (count($ST)) {
-            foreach(array_keys($ST) as $s) {
-                $html .=   mtrack_chg_status ('action', 'change_' .$s, 'Change status to: <B>'.  $s. '</B>');
-            }
-            
-            //$html .=   mtrack_chg_status ('action', 'changestatus', 'Change status to:',   'status', $ST, $issue);
-        }
-        if (isset($groups['project:1:closer'])) {
-            $html .= mtrack_chg_status('action', 'fixed', 'Resolve as fixed');
-       
-            $R = new MTrackResolution;
-            $resolutions = $R->enumerate();
-            unset($resolutions['fixed']);
-            foreach(array_keys($resolutions) as $s) {
-                $html .=   mtrack_chg_status ('action', 'resolve_' .$s, 'Resolve as: <B>'.  $s. '</B>');
-            }
-           // $html .= mtrack_chg_status('action', 'resolve', 'Resolve as:', 'resolution', $resolutions, $issue );
-        } else {
-            // $html .= "<i>you must be in the closer group to close issues</i><br/>";
-        }
-
-    } else {
-      $html .= mtrack_radio('action', 'reopen', $_POST['action']);
-      $html .= " <label for='reopen'>Reopen ticket</label><br>\n";
-    }
-    $html .= "<br>\n";
-  }
-
-  $spent = empty($_POST['spent']) ? '' : htmlentities($_POST['spent'], ENT_QUOTES, 'utf-8');
-  if (!strlen($spent)) {
-    $spent = '0';
-  }
-  $html .= "<label for='spent'>Log time spent (hours)</label> ";
-  $html .= "<input type='text' name='spent' value='$spent'><br>\n";
-
-  if ($id != 'new') {
-    $html .= MTrackAttachment::renderDeleteList("ticket:$issue->tid");
-    $html .= <<<HTML
-  <br>
-  <label for='attachments[]'>Select file(s) to be attached</label>
-  <input type='file' class='multi' name='attachments[]'>
-HTML;
-
-  }
-  
-  $html .= "</fieldset>";
-  
-
-  
-  $html .= "<fieldset id='comment-container'><legend>Comment</legend>\n";
-
-  $html .= <<<HTML
-<textarea name='comment' id="comment"
-  class="wiki shortwiki" rows="5" cols="78">
-HTML;
-  if (isset($_POST['comment'])) {
-    $html .= htmlentities($_POST['comment'], ENT_QUOTES, 'utf-8');
-  }
-  $html .= "</textarea>";
-
-  $html .= "</fieldset>";
-  $html .= MTrackCaptcha::emit('ticket');
-
-
- $html .= "</div>";
-
-  $html .= <<<HTML
-    <div id='tkt-edit-button-block' class='button-float' style='display:none'>
-    <button class='mtrack-button-submit' type="submit" name="preview">Preview</button>
-    <button class='mtrack-button-submit' type="submit" name="apply">Submit changes</button>
-    <button class='mtrack-edit-cancel' type="submit" name="cancel">Cancel</button>
-HTML;
-
-  if ($id != 'new') {
-    $html .= <<<HTML
-<button class='mtrack-make-comment'>Add Comment / Update Status</button>
-HTML;
-  }
-  return $html;
-}