MTrackWeb/LinkHandler.php
[web.mtrack] / MTrackWeb / LinkHandler.php
1 <?php
2
3 /**
4  * This handles link creation for the wiki..
5  * 
6  * it get's registered by MTrackWeb as the link handler..
7  * 
8  */
9 require_once 'MTrack/Interface/WikiLinkHandler.php';
10
11
12 class MTrackWeb_LinkHandler implements MTrack_Interface_WikiLinkHandler
13 {
14     function MTrackWeb_LinkHandler()
15     {
16         $ff = HTML_FlexyFramework::get();
17         
18         $this->baseURL = $ff->cli ? $ff->MTrackCLI['baseURL'] : $ff->page->baseURL;
19         
20         
21     }
22     
23     /**
24      * opts
25      *  [display] = text to display
26      * 
27      */
28     function ticket($no, $extras=array())
29     {
30         
31         if ($no instanceof MTrackIssue) {
32             $tkt = $no;
33         } else if (is_string($no) || is_int($no)) {
34             static $cache = array();
35
36             if ($no[0] == '#') {
37                 $no = substr($no, 1);
38             }
39
40             if (!isset($cache[$no])) {
41                 $tkt = MTrackIssue::loadByNSIdent($no);
42                 if (!$tkt) {
43                     $tkt = MTrackIssue::loadById($no);
44                 }
45                 $cache[$no] = $tkt;
46             } else {
47                 $tkt = $cache[$no];
48             }
49         } else {
50             // FIXME: hinted data from reports
51             $tkt = new stdClass;
52             $tkt->tid = $no['ticket'];
53             $tkt->summary = $no['summary'];
54             $tkt->status = '';
55             
56             if (isset($no['state'])) {
57               $tkt->status = $no['state'];
58             } elseif (isset($no['status'])) {
59               $tkt->status = $no['status'];
60             } elseif (isset($no['__status__'])) {
61               $tkt->status = $no['__status__'];
62             }  
63             
64         }
65         if ($tkt == NULL) {
66             $tkt = new stdClass;
67             $tkt->tid = $no;
68             $tkt->summary = 'No such ticket';
69             $tkt->status = 'No such ticket';
70         }
71         $html = "<a class='ticketlink";
72         if ($tkt->status == 'closed') {
73             $html .= ' completed';
74         }
75         if (!empty($tkt->nsident)) {
76             $ident = $tkt->nsident;
77         } else {
78             $ident = $tkt->tid;
79         }
80         if (isset($extras['#'])) {
81             $anchor = '#' . $extras['#'];
82         } else {
83             $anchor = '';
84         }
85         $html .= "' href=\"{$this->baseURL}/Ticket/$ident$anchor\">";
86         if (isset($extras['display'])) {
87             $html .= htmlspecialchars($extras['display']);
88         } else {
89             $html .= '#' . htmlspecialchars($ident);
90         }
91         $html .= "</a>";
92         return $html;
93     }
94
95     function milestone(  $target, $label)
96     {
97         // silly but we assume target is urlencoded???...
98         $ms = MTrack_Milestone::loadByName($target);
99         
100         return  '<span class="milestone' .
101             (($ms->deleted || $ms->completed) ? ' completed' : '') .
102             '"><a href="'. $this->baseURL . '/Milestone/'. $target .'">'.
103                 htmlspecialchars(urldecode($target))  . 
104             '</a></span>';
105     }
106     
107     function help($target, $label, $anchor = '')  
108     {
109         // escape anchor???
110         
111         $target .= !empty($anchor) ? "#$anchor" : '';
112         
113         return '<a class="wikilink"
114             href="'.$this->baseURL . '/Help/' . htmlspecialchars($target) . 
115                 '">' . htmlspecialchars($label) . '</a>';
116     }
117     
118     function username($target, $opts=array())
119     {
120         if (is_object($target)) {
121             $person = $target;
122             $target = $person->id;
123         } else {
124             $person  = DB_DataObject::factory('Person');
125             $person->get($target);
126         }
127         
128         if (is_string($opts)) {
129             parse_str($opts, $opts);
130         }
131         
132         //print_R($person);
133         if (!$person->id) {
134             // we did not find the ysers...
135             // we currently ignore all the formating....
136             return '<a 
137                 href="'. $this->baseURL .'/User/'. urlencode($target) . '"  class="userlink">' . 
138                 htmlspecialchars($target). 
139                 '</a>';
140         }
141          /* WHY?
142           if (!ctype_alnum($username)) {
143             $target = "{$ABSWEB}user.php?user=" . urlencode($username);
144             if (isset($opts['edit'])) {
145               $target .= '&edit=1';
146             }
147           } 
148           */  
149         
150         
151         $open_a = 
152             '<a  title="' . htmlspecialchars($person->name) . '" 
153             href="' . 
154                 $this->baseURL .'/User/'.
155                     urlencode($person->id)  . 
156                     (empty($opts['edit']) ? '' : '?edit=1') .
157             '" 
158             class="userlink' . 
159                 (isset($opts['class']) ? ' ' . $opts['class'] : '') .
160             '">';
161         
162         $dispname = $person->name;
163         //$dispname = preg_match("/^([^+]*)(\+.*)?@(.*)$/", $target) ? $target : $person->id;
164         
165         
166         $size = empty($opts['size']) ? 24 : (int) $opts['size'];
167        // var_dump($opts);
168         $ret = 
169             (!empty($opts['no_image']) ? '' :  ($open_a . 
170                 '<img class="gravatar"
171                     width="' . $size . '" height="' . $size . '" 
172                     src="' . $this->baseURL . '/Avatar.png?u=' . 
173                         urlencode($person->id) . '&amp;s='. $size . '">
174                 </a>')) .
175             
176             // at this point the old code tries to chop it...
177             // I'm not sure that is a great idea....
178             (!empty($opts['no_name']) ? '' :  ($open_a .  htmlspecialchars($dispname) . '</a>')); 
179         //var_dump( htmlspecialchars($ret));
180         return $ret;
181     }
182                 
183     function browse($target, $label)
184     {
185         return  '<a href="'. $this->baseURL . '/Browse/'. htmlspecialchars($target) .'">'.
186                 htmlspecialchars($label)  . 
187             '</a></span>';
188     }
189     function log($target, $label) // what does this do...
190     {
191         return  '<a href="'. $this->baseURL . '/Log/'. htmlspecialchars($target) .'">'.
192                 htmlspecialchars($label)  . 
193             '</a>';
194     }
195     
196     function branch($branch, $repo = null)
197     {
198       return "<span class='branchname'>" . htmlspecialchars($branch) . "</span>";
199     }
200
201         
202       
203     
204     function changeset($cs, $repo = null)
205     {
206         $display =  substr($cs, 0, 12); 
207         if (empty($repo)) {
208             $repo = MTrack_Repo::loadByChangeSet($cs);
209         }
210         if (is_string($repo)) {
211             $repo = MTrack_Repo::loadByName($rep);
212         }
213         if (!is_a($repo, 'MTrack_Repo')) {
214             $repo = MTrack_Repo::defaultRepo();
215         }
216         $p = $repo->getBrowseRootName() . '/'. $cs;
217         
218         
219         return '<a class="changesetlink"
220             href="'. $this->baseURL . '/Changeset/'. htmlspecialchars($p) .'">[' .  substr($cs, 0, 12) . ']</a>';
221     }
222         
223         
224     function wiki($pagename, $extras = array())
225     {
226         return htmlspecialchars($pagename);
227         if ($pagename instanceof MTrack_Wiki_Item) {
228             $wiki = $pagename;
229         } else if (is_string($pagename)) {
230             $wiki =  new MTrack_Wiki_Item($pagename);
231             if (!$wiki->file) {
232                 $wiki = false;
233             }
234         } else {
235             // FIXME: hinted data from reports
236             throw new Exception("FIXME: wiki");
237         }
238         
239         if ($wiki) {
240             $pagename = $wiki->pagename;
241         }
242         $pagename .= empty( $extras['#']) ? '' : '#' . $extras['#'];
243         
244         return  '<a class="wikilink"  
245             href="'.$this->baseURL . '/Wiki/'. htmlspecialchars($pagename) .'">'.
246             htmlspecialchars(empty($extras['display']) ? $pagename :  $extras['display']) .     
247             '</a>';
248     }
249
250     // all these are prtty much the same..    
251     function query($target, $label) 
252     {
253         
254          return  '<a href="'. $this->baseURL . '/Query/'. htmlspecialchars($target) .'">'.
255                 htmlspecialchars($label)  . 
256             '</a>';
257     }
258     function report($target, $label) 
259     {
260         return  '<a href="'. $this->baseURL . '/Report/'. htmlspecialchars($target) .'">'.
261                 htmlspecialchars($label)  . 
262             '</a>';
263     }
264     
265     // technically not a link....
266     function date($tstring, $show_full = false)
267     {
268       /* database time is always relative to UTC */
269       $d = date_create($tstring, new DateTimeZone('UTC'));
270       if (!is_object($d)) {
271         throw new Exception("could not represent $tstring as a datetime object");
272       }
273       $iso8601 = $d->format(DateTime::W3C);
274       /* but we want to render relative to user prefs */
275       date_timezone_set($d, new DateTimeZone(date_default_timezone_get()));
276       $full = $d->format('D, M d Y H:i');
277
278       if (!$show_full) {
279             return "<abbr title=\"$iso8601\" class='timeinterval'>$full</abbr>";
280       }
281
282       return "<abbr title='$iso8601' class='timeinterval'>$full</abbr> <span class='fulldate'>$full</span>";
283     }
284     
285 }