MTrackWeb/Events.php
[web.mtrack] / MTrackWeb / Events.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3  
4 // is this working ???
5 // partly - event.toHTML is borked... - we should use templating for this..
6 require_once 'MTrackWeb/Ticket.php';
7
8 class MTrackWeb_Events extends MTrackWeb_Ticket
9 {
10     var $id; // 0 = new
11     var $issue = false;
12     var $preview;
13     var $error;
14     var $editable;
15     var $tid = 0;
16     
17     function get($pi=0)
18     {
19         $this->id = $pi ?  $pi: (isset($_GET['id']) ? $_GET['id'] : 0);
20         $this->id  = (int) $this->id ;
21         $this->loadIssue();
22         
23         if (!$this->issue) {
24             $this->jerr( "OPPS");
25         }
26  
27         $start = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
28         $limit = isset($_REQUEST['limit']) ? (int) $_REQUEST['limit'] : 100;
29         
30         // fetch all the 
31         
32         DB_DataObject::debugLevel(1);
33         $d = DB_DataObject::factory('mtrack_change');
34         $d->ontable = 'mtrack_ticket';
35         $d->onid = $this->id;
36         $d->orderBy('changedate ASC'); // last first?
37         $d->limit ($start, $limit);
38         $d->audit = array();
39         $d->find();
40         
41         $this->events = array();
42         while ($d->fetch()) {
43             $this->events[$d->id] = clone($d);
44         }
45         
46         $d = DB_DataObject::factory('mtrack_change_audit');
47         $d->whereAddIn('change_id', array_keys($this->events), 'int');
48         $d->find();
49         
50         while ($d->fetch()) {
51             $this->events[$d->change_id]->audit[] = clone($d);
52         }
53         
54           
55         foreach($this->events as $c) {
56             echo $this->eventToHtml($c);
57         }
58         exit;
59         //$this->renderEvents();
60     }
61     
62     function eventToHtml($e)
63     {
64         
65     
66         
67         $preamble = 0;
68         
69         $cid = "comment:{$e->change_id}";
70         
71         // tidied up by jquery..
72         $timestamp = $link->date($e->changedate, false);
73          
74   
75         $comments = array();
76
77         // default is that something changed..
78         $type = 'Changed';
79         
80         $comment_body = '';
81         
82         $comment_title = '';
83         $comment_fields = array();
84         
85         foreach ($e->audit as $citem) {
86                 //print_r($citem);
87             $main = false;
88             
89             $ar = explode(':', $citem['fieldname'], 3);
90             if (count($ar) != 3) {
91                 continue;
92             }
93             list($tbl,,$field) = $ar;
94
95             if ($tbl != 'ticket') {
96                 // can get here if we created a new keyword, for example
97                 //var_dump($citem);
98                 continue;
99             }
100                 
101             switch($field) {
102                 case '@comment':
103                     $comments[] = $citem['value'];
104                     $type = 'Comment added';
105                     $comment_title = array_shift(explode("\n", $citem['value']));
106                     continue;
107                
108                case 'spent':
109                     continue;
110                     
111                     
112              
113                 case '@components': 
114                     $comment_fields[] = $field;
115                     $ar = MTrackComponent::loadByIds($citem['value']);
116                     $ar = array_map( function($e) { return  $e->toHtml(); }, $ar); 
117                     $citem['value'] = join(', ', $ar);
118                     
119                     
120                     break;
121                 
122                 case '@milestones': 
123                     $comment_fields[] = $field;
124                     $citem['value'] = $e->get_milestones_list($citem['value']);
125                     break;
126                 
127                 case '@keywords':
128                 
129                 
130                     $comment_fields[] = $field;
131                     $ar = MTrackKeyword::loadByIds($citem['value']);
132                     $ar = array_map( function($e) { return  $e->toHtml(); }, $ar); 
133                     $citem['value'] = join(', ', $ar);
134                     break;
135                     
136                 case  'estimated': 
137                     $comment_fields[] = $field;
138                     if ($citem['value'] !== null) {
139                         $citem['value'] += 0;
140                     }
141                     if ($citem['oldvalue'] !== null) {
142                         $citem['oldvalue'] += 0;
143                     }
144                     break;
145                 
146                 default:
147                     $comment_fields[] = $field;
148                     if ($field[0] == '@') {
149                         $main = isset($pseudo_fields[$field]) ? $pseudo_fields[$field] : '';
150                         $field = substr($field, 1, -1);
151                     } else {
152                         $main = $e->issue->$field;
153                     }
154
155             }
156
157                  
158             require_once 'MTrack/Ticket_CustomFields.php';
159             $f = MTrackTicket_CustomFields::getInstance()->fieldByName($field);
160                 
161                 
162                 
163             if ($f) {
164                 $label = htmlentities($f->label, ENT_QUOTES, 'utf-8');
165             } else {
166                 if ($field == 'attachment' && strlen($citem['oldvalue'])) {
167                     $label = "Attachment: $citem[oldvalue]";
168                 } else {
169                     $label = ucfirst($field);
170                 }
171             }
172
173             if ($citem['oldvalue'] == null) {
174                   /* don't bother printing out a set if this is the initial thing
175                    * and if the field values are currently the same */
176
177                 if ($main != $citem['value'] || $e->change_id != 'top') {
178
179                         /* Special case for description; since it is multi-line and often
180                          * very large, render it as a diff against the current ticket
181                          * description field */
182                     if ($field == 'description') {
183                         if ($this->issue->description == $citem['value']) {
184                             $comment_body .= "<b>Description</b>: no longer empty; see above<br>";
185                             continue;
186                         }
187
188                         $initial_lines = count(explode("\n", $this->issue->description));
189                         $diff = $this->diff_strings($this->issue->description, $citem['value']);
190                         $diff_add = 0;
191                         $diff_rem = 0;
192                         foreach (explode("\n", $diff) as $line) {
193                                 if (!strlen($line)) continue;
194                                 if ($line[0] == '-') {
195                                   $diff_rem++;
196                                 } else if ($line[0] == '+') {
197                                   $diff_add++;
198                                 }
199                         }
200                         if (abs($diff_add - $diff_rem) > $initial_lines / 2) {
201                             $comment_body .= "<b>initial $label</b><br>" .
202                                     MTrack_Wiki::format_to_html($citem['value']);
203                         } else {
204                                 $diff = $this->collapse_diff($diff);
205                                 $comment_body .= "<b>initial $label</b> (diff to above):<br>$diff\n";
206                         }
207                     } else {
208                           $comment_body .= "<b>$label</b> $citem[value]<br>\n";
209                     }
210                 }
211                 continue;
212             } 
213             
214             if ($citem['action'] == 'changed') {
215                 $lines = explode("\n", $citem['value'], 3);
216                 if (count($lines) >= 2) {
217                     $diff = $this->diff_strings($citem['oldvalue'], $citem['value']);
218                     $diff = $this->collapse_diff($diff);
219                     $comment_body .= "<b>$label</b> $citem[action]\n$diff\n";
220                 } else {
221                     $comment_body .= "<b>$label</b> $citem[action] to $citem[value]<br>\n";
222                 }
223                 continue;
224             } 
225             
226             $comment_body .= "<b>$label</b> $citem[action]<br>\n";
227             
228         }
229         
230         $commit_info = array();
231         if ($comment_title && 
232             preg_match('/\(In \[changeset:([^,]+),([a-z0-9]+)\]\)(.*)$/i', $comment_title, $commit_info)) {
233             $type = 'Commit';
234             
235             
236             $comment_title = '<a class="changesetlink" href="'. $GLOBALS['ABSWEB'] . 'changeset.php/'. 
237                 $commit_info[1].'/'.$commit_info[2]. '">[' . $commit_info[2] . ']</a>'.$commit_info[3];
238             
239             
240         }
241         if ($this->cid == $this->issue->created) {
242             $type = 'Created';
243             $comment_title = 'Issue Created';
244         }
245         
246         
247         
248         
249       
250         $html = '
251             <div class="ticketevent">
252                 <span class="ticketevent-expand" id="ticketevent-expand-' . $this->cid . '">+ ' . $type.'</span> 
253                 <a class="pmark" href="#'.$cid.'">#'.$this->cid.'</a> 
254                 
255                 <span class="ticketevent-expand" id="ticketevent-expand-title-' . $this->cid . '">' .
256                 (strlen($comment_title) ? $comment_title : implode(', ', $comment_fields)) . '
257                 </span>
258                 
259                 <span style="float:right">' . 
260                     $link->username($this->who, array('no_image' => true, 'fullname' => true))  . '
261                     -  <a name="'.$cid.'">'.$timestamp.'</a> 
262                 </span>
263                 
264             </div>
265             <div class="ticketchangeinfo" id="ticketchangeinfo-' . $this->cid . '">' . 
266                $link->username($this->who, array('no_name' => true, 'size' => 48));
267                    
268               
269               
270          
271         foreach ($this->effort as $eff) {
272             $exp = (float)$eff['expended'];
273             if ($eff['expended'] != 0) {
274                 $comment_body .= "<b>spent</b> $exp hours<br>\n";
275                 $preamble++;
276             }
277         }
278      
279  
280         if ($preamble) {
281             $html .= "<br>\n";
282             $preamble = 0;
283         }
284         
285         foreach ($comments as $cid => $text) {
286             // look for changesets in the comments..
287             // and display them as expandable linsk..
288             $html .= MTrack_Wiki::format_to_html($text);
289         }
290         
291         
292         $html .= '</div>';
293         
294         
295         
296         if ($commit_info) {
297             // list the files that where changed...
298             //$html.= print_r($M, true);
299             $rp = '/' . $commit_info[1] . '/' . $commit_info[2];
300             $fullrp = $rp;
301             $repo = MTrackSCM::factory($rp);
302             $cd = $repo->historyWithChangelog(null, 1, 'rev', $rp);
303             //print_r($cd);exit; 
304             
305             
306             if (!is_array($cd->ent->files) || !count($cd->ent->files)) {
307                 return $html;
308             }
309             
310             $num = count(array_keys($cd->ent->files));
311             $map = array(
312                 'D' => 'DELETED',
313                 'M' => 'MODIFIED',
314                 'A' => 'ADDED'
315             );
316             
317             $file_summary = array();
318             foreach($map as $k=>$v) {
319                 $summary[$v] = 0;
320             }
321             foreach ($cd->ent->files as $id => $file) {
322                
323                 
324                 $type = isset($map[$file->status])  ? $map[$file->status] : '??? '. $file->status;
325                 
326                 if ($num > 10) 
327                 {
328                     // will bork on unknown...
329                     $summary[$type]++;
330                     continue;
331                 }
332                 
333                 
334             $html .= '
335                 <div class="ticketevent ticketevent-fileitem">
336                     <span class="ticketevent-expand" id="ticketevent-expand-' . $this->cid . '.' . $id .'">+ ' . $type.'</span> 
337                     <span title="' . $fullrp . '?part=' . $id. '"  class="ticketevent-expand" id="ticketevent-expand-title-' . $this->cid . '.' . $id . '">' .
338                     $file->nameToHtml() . '
339                     </span>
340                     <span title="' . $fullrp . '?part=' . $id. '"  class="ticketevent-expand-diff changesetlink">[View Diff]</span> 
341                     <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View File]</span>
342                     <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View History]</span>
343                 </div>
344                 <div class="ticketchangeinfo" id="ticketchangeinfo-' . $this->cid . '.' . $id  . '"></div>
345         ';            
346                 
347                 
348                
349             }
350             
351             if ($num>  10) {
352                 $ar = array();
353                 foreach($summary as $k=>$v) {
354                     if (empty($v)) {
355                         continue;
356                     }
357                     $ar[] = $v . ' ' . $k;
358                 }
359                 $html .= '
360                 <div class="ticketevent ticketevent-fileitem">
361                     <span class="ticketevent-expand" id="ticketevent-expand-' . $this->cid . '.0">+ MULTIPLE FILES: </span>
362                     <span title="' . $fullrp . '?part=' . 0 . '"  class="ticketevent-expand" id="ticketevent-expand-title-' . $this->cid . '.' . $id . '">' .
363                     implode(', ', $ar) . '
364                     </span>
365                     <span title="' . $fullrp . '"  class="ticketevent-expand-diff changesetlink">[View Diff]</span> 
366                     <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View File]</span>
367                     <span title="' . $fullrp . '" class="ticketevent-expand-view changesetlink">[View History]</span>
368                 </div>
369                 <div class="ticketchangeinfo" id="ticketchangeinfo-' . $this->cid . '"></div>
370         ';            
371                 
372             }
373             
374             //$html .= print_r($cd, true);
375              
376         }
377         
378          
379         return $html ;
380                 
381                 
382     }
383     
384       
385 }