Rev Author Line No. Line
4988 kaklik 1 <?php
2 // WebSVN - Subversion repository viewing via the web using PHP
3 // Copyright (C) 2004-2006 Tim Armes
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 //
19 // --
20 //
21 // search.php
22 //
23 // Show the search listing for the given term in repository/path/revision
24  
25 require_once 'include/setup.php';
26 require_once 'include/svnlook.php';
27 require_once 'include/utils.php';
28 require_once 'include/template.php';
29 require_once 'include/bugtraq.php';
30  
31 function removeURLSeparator($url)
32 {
33 return preg_replace('#(\?|&(amp;)?)$#', '', $url);
34 }
35  
36 function urlForPath($fullpath, $passRevString)
37 {
38 global $config, $rep;
39  
40 $isDir = $fullpath[strlen($fullpath) - 1] == '/';
41  
42 if ($isDir)
43 {
44 if ($config->treeView)
45 {
46 $url = $config->getURL($rep, $fullpath, 'dir').$passRevString;
47 $id = anchorForPath($fullpath);
48 $url .= '#'.$id.'" id="'.$id;
49 }
50 else
51 {
52 $url = $config->getURL($rep, $fullpath, 'dir').$passRevString;
53 }
54 }
55 else
56 {
57 $url = $config->getURL($rep, $fullpath, 'file').$passRevString;
58 }
59  
60 return removeURLSeparator($url);
61 }
62  
63 function showSearchResults($svnrep, $path, $searchstring, $rev, $peg, $listing, $index=0, $treeview = true)
64 {
65  
66 global $config, $lang, $rep, $passrev, $peg, $passRevString;
67  
68 // List each file in the current directory
69 $loop = 0;
70 $last_index = 0;
71 $accessToThisDir = $rep->hasReadAccess($path, false);
72  
73 $openDir = false;
74 $logList = $svnrep->getListSearch($path, $searchstring, $rev, $peg);
75  
76 if (!$logList)
77 {
78 return $listing;
79 }
80  
81 $downloadRevAndPeg = createRevAndPegString($rev, $peg ? $peg : $rev);
82  
83 foreach ($logList->entries as $entry)
84 {
85 $isDir = $entry->isdir;
86 $file = $entry->file;
87 $isDirString = ($isDir) ? 'isdir=1&amp;' : '';
88  
89 // Only list files/directories that are not designated as off-limits
90 $access = ($isDir) ? $rep->hasReadAccess($path.$file, false)
91 : $accessToThisDir;
92  
93 if (!$access)
94 {
95 continue;
96 }
97  
98 $listvar = &$listing[$index];
99 $listvar['rowparity'] = $index % 2;
100  
101 if ($isDir)
102 {
103 $listvar['filetype'] = ($openDir) ? 'diropen' : 'dir';
104 $openDir = true;
105 }
106 else
107 {
108 $listvar['filetype'] = strtolower(strrchr($file, '.'));
109 $openDir = false;
110 }
111  
112 $listvar['isDir'] = $isDir;
113 $listvar['openDir'] = $openDir;
114 $listvar['path'] = str_replace('%2F', '/', rawurlencode($path.$file));
115  
116 $tempelements = explode('/',$file);
117  
118 if ($tempelements[count($tempelements)-1] === "")
119 {
120 $lastindexfile = count($tempelements)-1 - 1;
121 $listvar['node'] = $lastindexfile; // t-node
122 $listvar['level'] = ($treeview) ? $lastindexfile : 0;
123 $listvar['filename'] = escape($tempelements[$lastindexfile]);
124 }
125 else
126 {
127 $lastindexfile = count($tempelements)-1;
128 $listvar['node'] = $lastindexfile; // t-node
129 $listvar['level'] = ($treeview) ? $lastindexfile : 0;
130 $listvar['filename'] = escape($tempelements[$lastindexfile]);
131 }
132  
133 for ($j=1;$j<=$lastindexfile;$j++)
134 {
135 $listvar['last_i_node'][$j] = false;
136 }
137  
138 if ($isDir)
139 {
140 $listvar['fileurl'] = urlForPath($path.$file, $passRevString);
141 }
142 else
143 {
144 $listvar['fileurl'] = urlForPath($path.$file, createDifferentRevAndPegString($passrev, $peg));
145 }
146  
147 $listvar['filelink'] = '<a href="'.$listvar['fileurl'].'">'.$listvar['filename'].'</a>';
148  
149 if ($isDir)
150 {
151 $listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.$passRevString;
152 }
153 else
154 {
155 $listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.createDifferentRevAndPegString($passrev, $peg);
156 }
157  
158 if ($treeview)
159 {
160 $listvar['compare_box'] = '<input type="checkbox" name="compare[]" value="'.escape($path.$file).'@'.$passrev.'" onclick="enforceOnlyTwoChecked(this)" />';
161 }
162  
163 if ($config->showLastModInListing())
164 {
165 $listvar['committime'] = $entry->committime;
166 $listvar['revision'] = $entry->rev;
167 $listvar['author'] = $entry->author;
168 $listvar['age'] = $entry->age;
169 $listvar['date'] = $entry->date;
170 $listvar['revurl'] = $config->getURL($rep, $path.$file, 'revision').$isDirString.createRevAndPegString($entry->rev, $peg ? $peg : $rev);
171 }
172  
173 if ($rep->isDownloadAllowed($path.$file))
174 {
175 $downloadurl = $config->getURL($rep, $path.$file, 'dl').$isDirString.$downloadRevAndPeg;
176  
177 if ($isDir)
178 {
179 $listvar['downloadurl'] = $downloadurl;
180 $listvar['downloadplainurl'] = '';
181 }
182 else
183 {
184 $listvar['downloadplainurl'] = $downloadurl;
185 $listvar['downloadurl'] = '';
186 }
187 }
188 else
189 {
190 $listvar['downloadplainurl'] = '';
191 $listvar['downloadurl'] = '';
192 }
193  
194 if ($rep->isRssEnabled())
195 {
196 // RSS should always point to the latest revision, so don't include rev
197 $listvar['rssurl'] = $config->getURL($rep, $path.$file, 'rss').$isDirString.createRevAndPegString('', $peg);
198 }
199  
200 $loop++;
201 $index++;
202 $last_index = $index;
203 }
204  
205 return $listing;
206 }
207  
208 // Make sure that we have a repository
209 if (!$rep)
210 {
211 renderTemplate404('directory','NOREP');
212 }
213  
214 $svnrep = new SVNRepository($rep);
215  
216 if (!empty($rev))
217 {
218 $info = $svnrep->getInfo($path, $rev, $peg);
219  
220 if ($info)
221 {
222 $path = $info->path;
223 $peg = (int)$info->rev;
224 }
225 }
226  
227 $history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg);
228  
229 if (!$history)
230 {
231 unset($vars['error']);
232 $history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg);
233 if (!$history)
234 {
235 renderTemplate404('directory','NOPATH');
236 }
237 }
238  
239 $youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : 0;
240  
241 // Unless otherwise specified, we get the log details of the latest change
242 $lastChangedRev = ($passrev) ? $passrev : $youngest;
243  
244 if ($lastChangedRev != $youngest)
245 {
246 $history = $svnrep->getLog($path, $lastChangedRev, 1, false, 2, $peg);
247 }
248  
249 $logEntry = ($history && isset($history->entries[0])) ? $history->entries[0] : 0;
250  
251 $headlog = $svnrep->getLog('/', '', '', true, 1);
252 $headrev = ($headlog && isset($headlog->entries[0])) ? $headlog->entries[0]->rev : 0;
253  
254 // If we're not looking at a specific revision, get the HEAD revision number
255 // (the revision of the rest of the tree display)
256  
257 if (empty($rev))
258 {
259 $rev = $headrev;
260 }
261  
262 if ($path == '' || $path[0] != '/')
263 {
264 $ppath = '/'.$path;
265 }
266 else
267 {
268 $ppath = $path;
269 }
270  
271 createPathLinks($rep, $ppath, $passrev, $peg);
272 $passRevString = createRevAndPegString($passrev, $peg);
273 $isDirString = 'isdir=1&amp;';
274  
275 $revurl = $config->getURL($rep, $path != '/' ? $path : '', 'dir');
276 $revurlSuffix = $path != '/' ? '#'.anchorForPath($path) : '';
277  
278 if ($rev < $youngest)
279 {
280 if ($path == '/')
281 {
282 $vars['goyoungesturl'] = $config->getURL($rep, '', 'dir');
283 }
284 else
285 {
286 $vars['goyoungesturl'] = $config->getURL($rep, $path, 'dir').createRevAndPegString($youngest, $peg ? $peg: $rev).$revurlSuffix;
287 }
288  
289 $vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>';
290  
291 $history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg);
292  
293 if (isset($history2->entries[1]))
294 {
295 $nextRev = $history2->entries[1]->rev;
296 if ($nextRev != $youngest)
297 {
298 $vars['nextrev'] = $nextRev;
299 $vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg).$revurlSuffix;
300 }
301 }
302  
303 unset($vars['error']);
304 }
305  
306 if (isset($history->entries[1]))
307 {
308 $prevRev = $history->entries[1]->rev;
309 $prevPath = $history->entries[1]->path;
310 $vars['prevrev'] = $prevRev;
311 $vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg).$revurlSuffix;
312 }
313  
314 $bugtraq = new Bugtraq($rep, $svnrep, $ppath);
315  
316 $vars['action'] = '';
317 $vars['rev'] = $rev;
318 $vars['peg'] = $peg;
319 $vars['path'] = str_replace('%2F', '/', rawurlencode($ppath));
320 $vars['safepath'] = escape($ppath);
321 $vars['lastchangedrev'] = $lastChangedRev;
322  
323 if ($logEntry)
324 {
325 $vars['date'] = $logEntry->date;
326 $vars['age'] = datetimeFormatDuration(time() - strtotime($logEntry->date));
327 $vars['author'] = $logEntry->author;
328 $vars['log'] = nl2br($bugtraq->replaceIDs(create_anchors(xml_entities($logEntry->msg))));
329 }
330  
331 $vars['revurl'] = $config->getURL($rep, ($path == '/' ? '' : $path), 'revision').$isDirString.$passRevString;
332 $vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>';
333  
334 if ($history && count($history->entries) > 1)
335 {
336 $vars['compareurl'] = $config->getURL($rep, '', 'comp').'compare[]='.rawurlencode($history->entries[1]->path).'@'.$history->entries[1]->rev. '&amp;compare[]='.rawurlencode($history->entries[0]->path).'@'.$history->entries[0]->rev;
337 $vars['comparelink'] = '<a href="'.$vars['compareurl'].'">'.$lang['DIFFPREV'].'</a>';
338 }
339  
340 $vars['logurl'] = $config->getURL($rep, $path, 'log').$isDirString.$passRevString;
341 $vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>';
342  
343 if ($rep->isRssEnabled())
344 {
345 $vars['rssurl'] = $config->getURL($rep, $path, 'rss').$isDirString.createRevAndPegString('', $peg);
346 $vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>';
347 }
348  
349 // Set up the tarball link
350 $subs = explode('/', $path);
351 $level = count($subs) - 2;
352 if ($rep->isDownloadAllowed($path) && !isset($vars['warning']))
353 {
354 $vars['downloadurl'] = $config->getURL($rep, $path, 'dl').$isDirString.$passRevString;
355 }
356  
357 $vars['compare_form'] = '<form method="get" action="'.$config->getURL($rep, '', 'comp').'" id="compare">';
358  
359 if ($config->multiViews)
360 {
361 $vars['compare_form'] .= '<input type="hidden" name="op" value="comp"/>';
362 }
363 else
364 {
365 $vars['compare_form'] .= '<input type="hidden" name="repname" value="'.$repname.'" />';
366 }
367  
368 $vars['compare_submit'] = '<input type="submit" value="'.$lang['COMPAREPATHS'].'" />';
369 $vars['compare_endform'] = '</form>';
370  
371 $vars['showlastmod'] = $config->showLastModInListing();
372  
373 if (empty($_GET["search"]))
374 {
375 $vars['warning'] = $lang['NOSEARCHTERM'];
376 createSearchSelectionForm();
377 }
378 else
379 {
380 createSearchSelectionForm();
381 $vars['compare_box'] = '';
382 $listing = showSearchResults($svnrep, $path, $_GET["search"], $rev, $peg, array(),0,$config->treeView);
383 }
384  
385 if (!$rep->hasReadAccess($path))
386 {
387 $vars['error'] = $lang['NOACCESS'];
388 sendHeaderForbidden();
389 }
390  
391 $vars['restricted'] = !$rep->hasReadAccess($path, false);
392  
393 renderTemplate('directory');