1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
5 // partly - event.toHTML is borked... - we should use templating for this..
6 require_once 'MTrackWeb/Ticket.php';
8 class MTrackWeb_Events extends MTrackWeb_Ticket
19 $this->id = $pi ? $pi: (isset($_GET['id']) ? $_GET['id'] : 0);
20 $this->id = (int) $this->id ;
27 $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
28 $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit'] : 100;
32 DB_DataObject::debugLevel(1);
33 $d = DB_DataObject::factory('mtrack_change');
34 $d->ontable = 'mtrack_ticket';
36 $d->orderBy('changedate ASC'); // last first?
37 $d->limit ($start, $limit);
41 $this->events = array();
43 $this->events[$d->id] = clone($d);
46 $d = DB_DataObject::factory('mtrack_change_audit');
47 $d->whereAddIn('change_id', array_keys($this->events), 'int');
51 $this->events[$d->change_id]->audit[] = clone($d);
55 foreach($this->events as $id=>$c) {
56 echo $this->eventToHtml($c);
59 //$this->renderEvents();
62 function eventToHtml($e)
69 $cid = "comment:{$e->id}";
71 // tidied up by jquery..
72 $timestamp = $this->link->date($e->changedate, false);
77 // default is that something changed..
83 $comment_fields = array();
86 if (!empty($e->reason)) {
87 $comments[] = $e->reason;
88 $type = 'Comment added';
89 $comment_title = array_shift(explode("\n", $e->reason));
93 foreach ($e->audit as $citem) {
97 $ar = explode(':', $citem->fieldname, 3);
98 if (count($ar) != 3) {
102 list($tbl,,$field) = $ar;
104 if ($tbl != 'ticket') {
105 // can get here if we created a new keyword, for example
112 case 'spent': //?? ignore why?
118 $comment_fields[] = $field;
119 $ar = MTrackComponent::loadByIds($citem->value);
120 $ar = array_map( function($e) { return $e->toHtml(); }, $ar);
121 $citem->value = join(', ', $ar);
127 $comment_fields[] = $field;
128 $citem->value = $e->get_milestones_list($citem->value);
134 $comment_fields[] = $field;
135 $ar = MTrackKeyword::loadByIds($citem->value);
136 $ar = array_map( function($e) { return $e->toHtml(); }, $ar);
137 $citem->value = join(', ', $ar);
141 $comment_fields[] = $field;
142 if ($citem->value !== null) {
145 if ($citem->oldvalue !== null) {
146 $citem->oldvalue += 0;
151 $comment_fields[] = $field;
152 if ($field[0] == '@') {
153 $main = isset($pseudo_fields[$field]) ? $pseudo_fields[$field] : '';
154 $field = substr($field, 1, -1);
156 $main = $e->issue->$field;
164 // $label = htmlentities($f->label, ENT_QUOTES, 'utf-8');
166 if ($field == 'attachment' && strlen($citem->oldvalue)) {
167 $label = "Attachment: $citem[oldvalue]";
169 $label = ucfirst($field);
173 /* what does this do.. why not used set/changed/deleted etc..
174 if ($citem->oldvalue == null) {
175 // don't bother printing out a set if this is the initial thing
176 // and if the field values are currently the same
178 if ($main != $citem['value'] || $e->change_id != 'top') {
180 // Special case for description; since it is multi-line and often
181 // very large, render it as a diff against the current ticket
183 if ($field == 'description') {
184 if ($this->issue->description == $citem['value']) {
185 $comment_body .= "<b>Description</b>: no longer empty; see above<br>";
189 $initial_lines = count(explode("\n", $this->issue->description));
190 $diff = $this->diff_strings($this->issue->description, $citem['value']);
193 foreach (explode("\n", $diff) as $line) {
194 if (!strlen($line)) continue;
195 if ($line[0] == '-') {
197 } else if ($line[0] == '+') {
201 if (abs($diff_add - $diff_rem) > $initial_lines / 2) {
202 $comment_body .= "<b>initial $label</b><br>" .
203 MTrack_Wiki::format_to_html($citem['value']);
205 $diff = $this->collapse_diff($diff);
206 $comment_body .= "<b>initial $label</b> (diff to above):<br>$diff\n";
209 $comment_body .= "<b>$label</b> $citem[value]<br>\n";
215 if ($citem->action == 'changed') {
216 $lines = explode("\n", $citem->value, 3);
217 if (count($lines) >= 2) {
218 $diff = $this->diff_strings($citem->oldvalue, $citem->value);
219 $diff = $this->collapse_diff($diff);
220 $comment_body .= "<b>$label</b> $citem[action]\n$diff\n";
222 $comment_body .= "<b>$label</b> $citem[action] to $citem[value]<br>\n";
227 $comment_body .= "<b>$label</b> $citem[action]<br>\n";
231 $commit_info = array();
232 if ($comment_title &&
233 preg_match('/\(In \[changeset:([^,]+),([a-z0-9]+)\]\)(.*)$/i', $comment_title, $commit_info)) {
237 $comment_title = '<a class="changesetlink" href="'. $GLOBALS['ABSWEB'] . 'changeset.php/'.
238 $commit_info[1].'/'.$commit_info[2]. '">[' . $commit_info[2] . ']</a>'.$commit_info[3];
242 if ($this->id == $this->issue->created) {
244 $comment_title = 'Issue Created';
252 <div class="ticketevent">
253 <span class="ticketevent-expand" id="ticketevent-expand-' . $this->cid . '">+ ' . $type.'</span>
254 <a class="pmark" href="#'.$cid.'">#'.$this->cid.'</a>
256 <span class="ticketevent-expand" id="ticketevent-expand-title-' . $this->cid . '">' .
257 (strlen($comment_title) ? $comment_title : implode(', ', $comment_fields)) . '
260 <span style="float:right">' .
261 $link->username($this->who, array('no_image' => true, 'fullname' => true)) . '
262 - <a name="'.$cid.'">'.$timestamp.'</a>
266 <div class="ticketchangeinfo" id="ticketchangeinfo-' . $this->cid . '">' .
267 $link->username($this->who, array('no_name' => true, 'size' => 48));
272 foreach ($this->effort as $eff) {
273 $exp = (float)$eff['expended'];
274 if ($eff['expended'] != 0) {
275 $comment_body .= "<b>spent</b> $exp hours<br>\n";
286 foreach ($comments as $cid => $text) {
287 // look for changesets in the comments..
288 // and display them as expandable linsk..
289 $html .= MTrack_Wiki::format_to_html($text);
298 // list the files that where changed...
299 //$html.= print_r($M, true);
300 $rp = '/' . $commit_info[1] . '/' . $commit_info[2];
302 $repo = MTrackSCM::factory($rp);
303 $cd = $repo->historyWithChangelog(null, 1, 'rev', $rp);
307 if (!is_array($cd->ent->files) || !count($cd->ent->files)) {
311 $num = count(array_keys($cd->ent->files));
318 $file_summary = array();
319 foreach($map as $k=>$v) {
322 foreach ($cd->ent->files as $id => $file) {
325 $type = isset($map[$file->status]) ? $map[$file->status] : '??? '. $file->status;
329 // will bork on unknown...
336 <div class="ticketevent ticketevent-fileitem">
337 <span class="ticketevent-expand" id="ticketevent-expand-' . $this->cid . '.' . $id .'">+ ' . $type.'</span>
338 <span title="' . $fullrp . '?part=' . $id. '" class="ticketevent-expand" id="ticketevent-expand-title-' . $this->cid . '.' . $id . '">' .
339 $file->nameToHtml() . '
341 <span title="' . $fullrp . '?part=' . $id. '" class="ticketevent-expand-diff changesetlink">[View Diff]</span>
342 <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View File]</span>
343 <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View History]</span>
345 <div class="ticketchangeinfo" id="ticketchangeinfo-' . $this->cid . '.' . $id . '"></div>
354 foreach($summary as $k=>$v) {
358 $ar[] = $v . ' ' . $k;
361 <div class="ticketevent ticketevent-fileitem">
362 <span class="ticketevent-expand" id="ticketevent-expand-' . $this->cid . '.0">+ MULTIPLE FILES: </span>
363 <span title="' . $fullrp . '?part=' . 0 . '" class="ticketevent-expand" id="ticketevent-expand-title-' . $this->cid . '.' . $id . '">' .
364 implode(', ', $ar) . '
366 <span title="' . $fullrp . '" class="ticketevent-expand-diff changesetlink">[View Diff]</span>
367 <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View File]</span>
368 <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View History]</span>
370 <div class="ticketchangeinfo" id="ticketchangeinfo-' . $this->cid . '"></div>
375 //$html .= print_r($cd, true);
386 function collapse_diff($diff)
389 require_once 'MTrackWeb/Changeset.php';
390 $cs = new MTrackWeb_Changeset();
391 $id = 'diff_' . $idnum++;
393 "<button onclick='\$("#$id").toggle(); return false;'>Toggle diff</button>".
394 "<div id='$id' style='display:none'>" .
395 $cs->diff($diff) . "</div>";
398 function diff_strings($before, $now)
401 $tempdir = sys_get_temp_dir();
402 $afile = tempnam($tempdir, "mtrack");
403 $bfile = tempnam($tempdir, "mtrack");
404 file_put_contents($afile, $before);
405 file_put_contents($bfile, $now);
406 static $diff = false;
408 require_once 'System.php';
409 $diff= System::which('diff');
411 if (PHP_OS == 'SunOS') {
412 // TODO: make an option to allow use of gnu diff on solaris
413 $diff = shell_exec("$diff -u $afile $bfile");
414 $diff = str_replace($afile, 'before', $diff);
415 $diff = str_replace($bfile, 'now', $diff);
417 $diff = shell_exec("$diff --label before --label now -u $afile $bfile");
421 $diff = htmlentities($diff, ENT_COMPAT, 'utf-8');