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