Rev Author Line No. Line
185 miho 1 <?php
2 # vim:et:ts=3:sts=3:sw=3:fdm=marker:
3  
4 // WebSVN - Subversion repository viewing via the web using PHP
5 // Copyright © 2004-2006 Tim Armes, Matt Sicker
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 //
21 // --
22 //
23 // utils.inc
24 //
25 // General utility commands
26  
27 // {{{ createDirLinks
28 //
29 // Create a list of links to the current path that'll be available from the template
30  
31 function createDirLinks($rep, $path, $rev, $showchanged)
32 {
33 global $vars, $config;
34  
35 $subs = explode('/', htmlentities($path));
36 $sofar = "";
37 $count = count($subs);
38 $vars["curdirlinks"] = "";
39  
40 // The number of links depends on the last item. It's empty if
41 // we're looing at a directory, and full if it's a file
42 if (empty($subs[$count - 1]))
43 {
44 $limit = $count - 2;
45 $dir = true;
46 }
47 else
48 {
49 $limit = $count - 1;
50 $dir = false;
51 }
52  
53 for ($n = 0; $n < $limit; $n++)
54 {
55 $sofar .= html_entity_decode($subs[$n])."/";
56 $sofarurl = $config->getURL($rep, $sofar, "dir");
57 $vars["curdirlinks"] .= "[<a href=\"${sofarurl}rev=$rev&amp;sc=$showchanged\">".$subs[$n]."/]</a> ";
58 }
59  
60 if ($dir)
61 {
62 $vars["curdirlinks"] .= "[<b>".html_entity_decode($subs[$n])."</b>/]";
63 }
64 else
65 {
66 $vars["curdirlinks"] .= "[<b>".html_entity_decode($subs[$n])."</b>]";
67 }
68 }
69  
70 // }}}
71  
72 // {{{ create_anchors
73 //
74 // Create links out of http:// and mailto: tags
75  
76 # TODO: the target="_blank" nonsense should be optional (or specified by the template)
77 function create_anchors($text)
78 {
79 $ret = $text;
80  
81 // Match correctly formed URLs that aren't already links
82 $ret = preg_replace("#\b(?<!href=\")([a-z]+?)://(\S*)([\w/]+)#i",
83 "<a href=\"\\1://\\2\\3\" target=\"_blank\">\\1://\\2\\3</a>",
84 $ret);
85  
86 // Now match anything beginning with www, as long as it's not //www since they were matched above
87 $ret = preg_replace("#\b(?<!//)www\.(\S*)([\w/]+)#i",
88 "<a href=\"http://www.\\1\\2\" target=\"_blank\">www.\\1\\2</a>",
89 $ret);
90  
91 // Match email addresses
92 $ret = preg_replace("#\b([\w\-_.]+)@([\w\-.]+)\b#i",
93 "<a href=\"mailto:\\1@\\2\">\\1@\\2</a>",
94 $ret);
95  
96 return ($ret);
97 }
98  
99 // }}}
100  
101 // {{{ getFullURL
102  
103 function getFullURL($loc)
104 {
105 $protocol = 'http';
106  
107 if (isset($_SERVER["HTTPS"]) && (strtolower($_SERVER["HTTPS"]) != "off"))
108 {
109 $protocol = "https";
110 }
111  
112 $port = ":".$_SERVER["SERVER_PORT"];
113 if ((":80" == $port && "http" == $protocol) ||
114 (":443" == $port && "https" == $protocol))
115 {
116 $port = "";
117 }
118  
119 if (isset($_SERVER["HTTP_HOST"]))
120 {
121 $host = $_SERVER["HTTP_HOST"];
122 }
123 else if (isset($_SERVER["SERVER_NAME"]))
124 {
125 $host = $_SERVER["SERVER_NAME"].$port;
126 }
127 else if (isset($_SERVER["SERVER_ADDR"]))
128 {
129 $host = $_SERVER["SERVER_ADDR"].$port;
130 }
131 else
132 {
133 print "Unable to redirect";
134 exit;
135 }
136  
137 $url = $protocol . "://" . $host . $loc;
138  
139 return $url;
140 }
141  
142 // }}}
143  
144 // {{{ hardspace
145 //
146 // Replace the spaces at the front of a line with hard spaces
147  
148 # XXX: this is an unnecessary function; you can prevent whitespace from being
149 # trimmed via CSS (use the "white-space: pre;" properties). ~J
150 # in the meantime, here's an improved function (does nothing)
151  
152 function hardspace($s)
153 {
154 return '<code>' . expandTabs($s) . '</code>';
155 }
156  
157 // }}}
158  
159 // {{{ expandTabs
160  
161 /**
162 * Expands the tabs in a line that may or may not include HTML.
163 *
164 * Enscript generates code with HTML, so we need to take that into account.
165 *
166 * @param string $s Line of possibly HTML-encoded text to expand
167 * @param int $tabwidth Tab width, -1 to use repository's default, 0 to collapse
168 * all tabs.
169 * @return string The expanded line.
170 * @since 2.1
171 */
172  
173 function expandTabs($s, $tabwidth = -1)
174 {
175 global $rep;
176  
177 if ($tabwidth == -1)
178 $tabwidth = $rep->getExpandTabsBy();
179 $pos = 0;
180  
181 // Parse the string into chunks that are either 1 of: HTML tag, tab char, run of any other stuff
182 $chunks = preg_split("/((?:<.+?>)|(?:&.+?;)|(?:\t))/", $s, -1, PREG_SPLIT_DELIM_CAPTURE);
183  
184 // Count the sizes of the chunks and replace tabs as we go
185 for ($i = 0; $i < count($chunks); $i++)
186 {
187 # make sure we're not dealing with an empty string
188 if (empty($chunks[$i])) continue;
189 switch ($chunks[$i]{0})
190 {
191 case '<': // HTML tag : ignore its width by doing nothing
192 break;
193  
194 case '&': // HTML entity: count its width as 1 char
195 $pos += 1;
196 break;
197  
198 case "\t": // Tab char: replace it with a run of spaces between length tabwidth and 1
199 $tabsize = $tabwidth - ($pos % $tabwidth);
200 $chunks[$i] = str_repeat(' ', $tabsize);
201 $pos += $tabsize;
202 break;
203  
204 default: // Anything else: just keep track of its width
205 $pos += strlen($chunks[$i]);
206 break;
207 }
208 }
209  
210 // Put the chunks back together and we've got the original line, detabbed.
211 return join('', $chunks);
212 }
213  
214 // }}}
215  
216 // {{{ datetimeFormatDuration
217 //
218 // Formats a duration of seconds for display.
219 //
220 // $seconds the number of seconds until something
221 // $nbsp true if spaces should be replaced by nbsp
222 // $skipSeconds true if seconds should be omitted
223 //
224 // return the formatted duration (e.g. @c "8h 6m 1s")
225  
226 function datetimeFormatDuration($seconds, $nbsp = false, $skipSeconds = false)
227 {
228 global $lang;
229  
230 if ($seconds < 0)
231 {
232 $seconds = -$seconds;
233 $neg = true;
234 }
235 else
236 $neg = false;
237  
238 $qty = array();
239  
240 $qty[] = (int)($seconds / (60 * 60 * 24));
241 $seconds %= 60 * 60 * 24;
242  
243 $qty[] = (int)($seconds / (60 * 60));
244 $seconds %= 60 * 60;
245  
246 $qty[] = (int)($seconds / 60);
247 $qty[] = (int)($seconds % 60);
248  
249 $text = "";
250 $names = $lang["DAYLETTER"].$lang["HOURLETTER"].$lang["MINUTELETTER"];
251 if (!$skipSeconds) $names .= $lang["SECONDLETTER"];
252  
253 $any = false;
254 for ($i = 0; $i < strlen($names); $i++)
255 // If a "higher valued" time slot had a value or this time slot
256 // has a value or this is the very last entry (i.e. all values
257 // are 0 and we still want to print seconds)
258 if ($any || $qty[$i] || $i == sizeof($qty) - 1)
259 {
260 $any = true;
261  
262 if ($i)
263 $text .= sprintf("%2d", $qty[$i]);
264 else
265 $text .= $qty[$i];
266  
267 $text .= "{$names{$i}} ";
268 }
269  
270 $text = trim($text);
271 if ($neg)
272 $text = "-$text";
273  
274 return $nbsp ? str_replace(" ", "&nbsp;", $text) : $text;
275 }
276  
277 // }}}
278  
279 // {{{ getParameterisedSelfUrl
280 //
281 // Get the relative URL (PHP_SELF) with GET and POST data
282  
283 function getParameterisedSelfUrl($params = true)
284 {
285 global $config;
286  
287 $url = null;
288  
289 if ($config->multiViews)
290 {
291 // Get rid of the file's name
292 $url = preg_replace('/\.php/', '', $_SERVER['PHP_SELF'], 1);
293 }
294 else
295 {
296 $url = basename($_SERVER['PHP_SELF']);
297  
298 // Sometimes the .php isn't on the end. Damn strange...
299 if (strchr($url, '.') === false)
300 $url .= '.php';
301 }
302  
303 if ($params)
304 {
305 $arr = $_GET + $_POST;
306 # XXX: the point of HTTP POST is that URIs have a set size limit, so POST
307 # data is typically too large to bother with; why include it?
308 $url .= '?'.htmlentities(http_build_query($arr));
309 }
310  
311 return $url;
312 }
313  
314 // }}}
315  
316 // {{{ getUserLanguage
317  
318 function getUserLanguage() {
319 $languages = !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : 'en';
320 if (strpos($languages, ',') === false) return $languages; # only one specified
321 # split off the languages into an array of languages and q-values
322 $qvals = array();
323 $langs = array();
324 preg_match_all('#(\S+?)\s*(?:;q=([01](?:\.\d{1,3})?))?\s*,\s*#', $languages, $qvals, PREG_SET_ORDER);
325 foreach ($qvals as $q) {
326 $langs[] = array (
327 $q[1],
328 floatval(!empty($q[2]) ? $q[2] : 1.0)
329 );
330 }
331 # XXX: now, we should loop through our available languages and choose an
332 # appropriate one for the user
333 # note that we shouldn't match the region unless we have a specific region
334 # to use (e.g. zh-CN vs. zh-TW)
335 # FIXME: see above; otherwise, this function doesn't really do anything
336 }
337  
338 // }}}
339  
340 ?>