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 // log.php
24 //
25 // Show the logs for the given path
26  
27 require_once("include/setup.inc");
28 require_once("include/svnlook.inc");
29 require_once("include/utils.inc");
30 require_once("include/template.inc");
31 require_once("include/bugtraq.inc");
32  
33 $page = (int)@$_REQUEST["page"];
34 $all = (@$_REQUEST["all"] == 1)?1:0;
35 $isDir = (@$_REQUEST["isdir"] == 1)?1:0;
36 $dosearch = (@$_REQUEST["logsearch"] == 1)?1:0;
37 $search = trim(@$_REQUEST["search"]);
38 $words = preg_split('#\s+#', $search);
39 $fromRev = (int)@$_REQUEST["fr"];
40 $startrev = strtoupper(trim(@$_REQUEST["sr"]));
41 $endrev = strtoupper(trim(@$_REQUEST["er"]));
42 $max = @$_REQUEST["max"];
43  
44 // Max number of results to find at a time
45 $numSearchResults = 15;
46  
47 if ($search == "")
48 $dosearch = false;
49  
50 // removeAccents
51 //
52 // Remove all the accents from a string. This function doesn't seem
53 // ideal, but expecting everyone to install 'unac' seems a little
54 // excessive as well...
55  
56 function removeAccents($string)
57 {
58 return strtr($string,
59 "ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ",
60 "AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn");
61 }
62  
63 // Normalise the search words
64 foreach ($words as $index => $word)
65 {
66 $words[$index] = strtolower(removeAccents($word));
67  
68 // Remove empty string introduced by multiple spaces
69 if (empty($words[$index]))
70 unset($words[$index]);
71 }
72  
73 if (empty($page)) $page = 1;
74  
75 // If searching, display all the results
76 $all = (bool) $dosearch;
77  
78 $maxperpage = 20;
79  
80 // Make sure that we have a repository
81 if (!isset($rep))
82 {
83 echo $lang["NOREP"];
84 exit;
85 }
86  
87 $svnrep = new SVNRepository($rep);
88  
89 $passrev = $rev;
90  
91 // If there's no revision info, go to the lastest revision for this path
92 $history = $svnrep->getLog($path, "", "", true);
93 $youngest = $history->entries[0]->rev;
94  
95 if (empty($rev))
96 $rev = $youngest;
97  
98 // make sure path is prefixed by a /
99 $ppath = $path;
100 if ($path == "" || $path{0} != "/")
101 $ppath = "/".$path;
102  
103 $vars["action"] = $lang["LOG"];
104 $vars["repname"] = $rep->getDisplayName();
105 $vars["rev"] = $rev;
106 $vars["path"] = $ppath;
107  
108 createDirLinks($rep, $ppath, $passrev, $showchanged);
109  
110 $logurl = $config->getURL($rep, $path, "log");
111  
112 if ($rev != $youngest)
113 $vars["goyoungestlink"] = "<a href=\"${logurl}sc=1\">${lang["GOYOUNGEST"]}</a>";
114 else
115 $vars["goyoungestlink"] = "";
116  
117 // We get the bugtraq variable just once based on the HEAD
118 $bugtraq = new Bugtraq($rep, $svnrep, $ppath);
119  
120 if ($startrev != "HEAD") $startrev = (int)$startrev;
121 if (empty($startrev)) $startrev = $rev;
122 if (empty($endrev)) $endrev = 1;
123  
124 if (empty($_REQUEST["max"]))
125 {
126 if (empty($_REQUEST["logsearch"]))
127 $max = 30;
128 else
129 $max = 0;
130 }
131 else
132 {
133 $max = (int)$max;
134 if ($max < 0) $max = 30;
135 }
136  
137 $history = $svnrep->getLog($path, $startrev, $endrev, true, $max);
138 $vars["logsearch_moreresultslink"] = "";
139 $vars["pagelinks"] = "";
140 $vars["showalllink"] = "";
141 $listing = array();
142  
143 if (!empty($history))
144 {
145 // Get the number of separate revisions
146 $revisions = count($history->entries);
147  
148 if ($all)
149 {
150 $firstrevindex = 0;
151 $lastrevindex = $revisions - 1;
152 $pages = 1;
153 }
154 else
155 {
156 // Calculate the number of pages
157 $pages = floor($revisions / $maxperpage);
158 if (($revisions % $maxperpage) > 0) $pages++;
159  
160 if ($page > $pages) $page = $pages;
161  
162 // Word out where to start and stop
163 $firstrevindex = ($page - 1) * $maxperpage;
164 $lastrevindex = $firstrevindex + $maxperpage - 1;
165 if ($lastrevindex > $revisions - 1) $lastrevindex = $revisions - 1;
166 }
167  
168 $history = $svnrep->getLog($path, $history->entries[$firstrevindex ]->rev, $history->entries[$lastrevindex]->rev, false, 0);
169  
170 $row = 0;
171 $index = 0;
172 $listing = array();
173 $found = false;
174  
175 foreach ($history->entries as $r)
176 {
177 // Assume a good match
178 $match = true;
179 $thisrev = $r->rev;
180  
181 // Check the log for the search words, if searching
182 if ($dosearch)
183 {
184 if ((empty($fromRev) || $fromRev > $thisrev))
185 {
186 // Turn all the HTML entities into real characters.
187  
188 // Make sure that each word in the search in also in the log
189 foreach($words as $word)
190 {
191 if (strpos(strtolower(removeAccents($r->msg)), $word) === false)
192 {
193 $match = false;
194 break;
195 }
196 }
197  
198 if ($match)
199 {
200 $numSearchResults--;
201 $found = true;
202 }
203 }
204 else
205 $match = false;
206 }
207  
208 if ($match)
209 {
210 // Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!)
211 $rpath = $r->path;
212  
213 if (empty($rpath))
214 $rpath = "/";
215 else if ($isDir && $rpath{strlen($rpath) - 1} != "/")
216 $rpath .= "/";
217  
218 // Find the parent path (or the whole path if it's already a directory)
219 $pos = strrpos($rpath, "/");
220 $parent = substr($rpath, 0, $pos + 1);
221  
222 $url = $config->getURL($rep, $parent, "dir");
223 $listing[$index]["revlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=1\">$thisrev</a>";
224  
225 if ($isDir)
226 {
227 $listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$parent@$thisrev\" onclick=\"checkCB(this)\" />";
228 $url = $config->getURL($rep, $rpath, "dir");
229 $listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=$showchanged\">$rpath</a>";
230 }
231 else
232 {
233 $listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$rpath@$thisrev\" onclick=\"checkCB(this)\" />";
234 $url = $config->getURL($rep, $rpath, "file");
235 $listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&amp;sc=$showchanged\">$rpath</a>";
236 }
237  
238 $listing[$index]["revauthor"] = $r->author;
239 $listing[$index]["revage"] = $r->age;
240 $listing[$index]["revlog"] = nl2br($bugtraq->replaceIDs(create_anchors($r->msg)));
241 $listing[$index]["rowparity"] = "$row";
242  
243 $row = 1 - $row;
244 $index++;
245 }
246  
247 // If we've reached the search limit, stop here...
248 if (!$numSearchResults)
249 {
250 $url = $config->getURL($rep, $path, "log");
251 $vars["logsearch_moreresultslink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;isdir=$isDir&amp;logsearch=1&amp;search=$search&amp;fr=$thisrev\">${lang["MORERESULTS"]}</a>";
252 break;
253 }
254 }
255  
256 $vars["logsearch_resultsfound"] = true;
257  
258 if ($dosearch && !$found)
259 {
260 if ($fromRev == 0)
261 {
262 $vars["logsearch_nomatches"] = true;
263 $vars["logsearch_resultsfound"] = false;
264 }
265 else
266 $vars["logsearch_nomorematches"] = true;
267 }
268 else if ($dosearch && $numSearchResults > 0)
269 {
270 $vars["logsearch_nomorematches"] = true;
271 }
272  
273 // Work out the paging options
274  
275 if ($pages > 1)
276 {
277 $prev = $page - 1;
278 $next = $page + 1;
279 echo "<p><center>";
280  
281 if ($page > 1) $vars["pagelinks"] .= "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$prev\"><&nbsp;${lang["PREV"]}</a> ";
282 for ($p = 1; $p <= $pages; $p++)
283 {
284 if ($p != $page)
285 $vars["pagelinks"].= "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$p\">$p</a> ";
286 else
287 $vars["pagelinks"] .= "<b>$p </b>";
288 }
289 if ($page < $pages) $vars["pagelinks"] .=" <a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;max=$max&amp;page=$next\">${lang["NEXT"]}&nbsp;></a>";
290  
291 $vars["showalllink"] = "<a href=\"${logurl}rev=$rev&amp;sr=$startrev&amp;er=$endrev&amp;sc=$showchanged&amp;all=1&amp;max=$max\">${lang["SHOWALL"]}</a>";
292 echo "</center>";
293 }
294 }
295  
296 // Create the project change combo box
297  
298 $url = $config->getURL($rep, $path, "log");
299 # XXX: forms don't have the name attribute, but _everything_ has the id attribute,
300 # so what you're trying to do (if anything?) should be done via that ~J
301 $vars["logsearch_form"] = "<form action=\"$url\" method=\"post\" name=\"logsearchform\">";
302  
303 $vars["logsearch_startbox"] = "<input name=\"sr\" size=\"5\" value=\"$startrev\" />";
304 $vars["logsearch_endbox" ] = "<input name=\"er\" size=\"5\" value=\"$endrev\" />";
305 $vars["logsearch_maxbox" ] = "<input name=\"max\" size=\"5\" value=\"".($max==0?"":$max)."\" />";
306 $vars["logsearch_inputbox"] = "<input name=\"search\" value=\"$search\" />";
307  
308 $vars["logsearch_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\" />";
309 $vars["logsearch_endform"] = "<input type=\"hidden\" name=\"logsearch\" value=\"1\" />".
310 "<input type=\"hidden\" name=\"op\" value=\"log\" />".
311 "<input type=\"hidden\" name=\"rev\" value=\"$rev\" />".
312 "<input type=\"hidden\" name=\"sc\" value=\"$showchanged\" />".
313 "<input type=\"hidden\" name=\"isdir\" value=\"$isDir\" />".
314 "</form>";
315  
316 $url = $config->getURL($rep, $path, "log");
317 $vars["logsearch_clearloglink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;isdir=$isDir\">${lang["CLEARLOG"]}</a>";
318  
319 $url = $config->getURL($rep, "/", "comp");
320 $vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";
321 $vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREREVS"]}\" />";
322 $vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";
323  
324 $vars["version"] = $version;
325  
326 if (!$rep->hasReadAccess($path, false))
327 $vars["noaccess"] = true;
328  
329 parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
330 parseTemplate($rep->getTemplatePath()."log.tmpl", $vars, $listing);
331 parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
332  
333 ?>