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