<?php# vim:et:ts=3:sts=3:sw=3:fdm=marker:// WebSVN - Subversion repository viewing via the web using PHP// Copyright © 2004-2006 Tim Armes, Matt Sicker//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//// --//// listing.php//// Show the listing for the given repository/path/revisionrequire_once("include/setup.inc");require_once("include/svnlook.inc");require_once("include/utils.inc");require_once("include/template.inc");require_once("include/bugtraq.inc");function removeURLSeparator($url){return preg_replace('#(\?|&(amp;)?)$#', '', $url);}function fileLink($path, $file, $returnjoin = false){global $rep, $passrev, $showchanged, $config;if ($path == "" || $path{0} != "/")$ppath = "/".$path;else$ppath = $path;if ($ppath{strlen($ppath)-1} != "/")$ppath .= "/";if ($file{0} == "/")$pfile = substr($file, 1);else$pfile = $file;if ($returnjoin)return $ppath.$pfile;$isDir = $pfile{strlen($pfile) - 1} == "/";if ($passrev) $passrevstr = "rev=$passrev&"; else $passrevstr = "";if ($showchanged) $showchangedstr = "sc=$showchanged"; else $showchangedstr = "";if ($isDir){$url = $config->getURL($rep, $ppath.$pfile, "dir");// XHTML doesn't allow slashes in IDs ~J$id = str_replace('/', '_', $ppath.$pfile);$url = "<a id='$id' href=\"${url}$passrevstr$showchangedstr";$url = removeURLSeparator($url);if ($config->treeView) $url .= "#$id";$url .= "\">$pfile</a>";}else{$url = $config->getURL($rep, $ppath.$pfile, "file");$url .= $passrevstr.$showchangedstr;$url = removeURLSeparator($url);$url = "<a href=\"${url}\">$pfile</a>";}return $url;}function showDirFiles($svnrep, $subs, $level, $limit, $rev, $listing, $index, $treeview = true){global $rep, $passrev, $showchanged, $config, $lang;$path = "";if (!$treeview)$level = $limit;for ($n = 0; $n <= $level; $n++){$path .= $subs[$n]."/";}$contents = $svnrep->dirContents($path, $rev);// List each file in the current directory$loop = 0;$last_index = 0;$openDir = false;$fullaccess = $rep->hasReadAccess($path, false);foreach($contents as $file){$isDir = ($file{strlen($file) - 1} == "/"?1:0);$access = false;if ($isDir){if ($rep->hasReadAccess($path.$file, true)){$access = true;$openDir = (!strcmp($subs[$level+1]."/", $file) || !strcmp($subs[$level+1], $file));if ($openDir)$listing[$index]["filetype"] = "diropen";else$listing[$index]["filetype"] = "dir";if ($rep->isDownloadAllowed($path.$file)){$dlurl = $config->getURL($rep, $path.$file, "dl");$listing[$index]["fileviewdllink"] = "<a href=\"${dlurl}rev=$passrev&isdir=1\">${lang["TARBALL"]}</a>";}else$listing[$index]["fileviewdllink"] = " ";}}else{if ($fullaccess){$access = true;if ($level != $limit){// List directories only, skip all filescontinue;}$listing[$index]["fileviewdllink"] = " ";$listing[$index]["filetype"] = strrchr($file, ".");}}if ($access){$listing[$index]["rowparity"] = ($index % 2)?"1":"0";if ($treeview)$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"".fileLink($path, $file, true)."@$passrev\" onclick=\"checkCB(this)\" />";else$listing[$index]["compare_box"] = "";if ($openDir)$listing[$index]["filelink"] = "<b>".fileLink($path, $file)."</b>";else$listing[$index]["filelink"] = fileLink($path, $file);// The history command doesn't return with a trailing slash. We need to remember here if the// file is a directory or not!$listing[$index]["isDir"] = $isDir;if ($treeview)$listing[$index]["level"] = $level;else$listing[$index]["level"] = 0;$listing[$index]["node"] = 0; // t-node$fileurl = $config->getURL($rep, $path.$file, "log");$listing[$index]["fileviewloglink"] = "<a href=\"${fileurl}rev=$passrev&sc=$showchanged&isdir=$isDir\">${lang["VIEWLOG"]}</a>";$rssurl = $config->getURL($rep, $path.$file, "rss");if ($rep->getHideRss()){$listing[$index]["rsslink"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=$isDir\">${lang["RSSFEED"]}</a>";$listing[$index]["rssanchor"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=$isDir\">";}$index++;$loop++;$last_index = $index;if (($level != $limit) && ($isDir)){if (!strcmp($subs[$level + 1]."/", $file)){$listing = showDirFiles($svnrep, $subs, $level + 1, $limit, $rev, $listing, $index);$index = count($listing);}}}}if ($last_index != 0 && $treeview){$listing[$last_index - 1]["node"] = 1; // l-node}return $listing;}function showTreeDir($svnrep, $path, $rev, $listing){global $vars, $config;$subs = explode("/", $path);// For directory, the last element in the subs is empty.// For file, the last element in the subs is the file name.// Therefore, it is always count($subs) - 2$limit = count($subs) - 2;for ($n = 0; $n < $limit; $n++){$vars["last_i_node"][$n] = FALSE;}return showDirFiles($svnrep, $subs, 0, $limit, $rev, $listing, 0, $config->treeView);}// Make sure that we have a repositoryif (!isset($rep)){echo $lang["NOREP"];exit;}$svnrep = new SVNRepository($rep);// Revision info to pass along chain$passrev = $rev;// Get the directory contents of the given revision, or HEAD if not defined$contents = $svnrep->dirContents($path, @$rev);// If there's no revision info, go to the lastest revision for this path$history = $svnrep->getLog($path, "", "", false);if (!empty($history->entries[0]))$youngest = $history->entries[0]->rev;else$youngest = -1;// Unless otherwise specified, we get the log details of the latest changeif (empty($rev))$logrev = $youngest;else$logrev = $rev;if ($logrev != $youngest){$logEntry = $svnrep->getLog($path, $logrev, $logrev, false);$logEntry = $logEntry->entries[0];}else$logEntry = $history->entries[0];$headlog = $svnrep->getLog("/", "", "", true, 1);$headrev = $headlog->entries[0]->rev;// If we're not looking at a specific revision, get the HEAD revision number// (the revision of the rest of the tree display)if (empty($rev)){$rev = $headrev;}if ($path == "" || $path{0} != "/")$ppath = "/".$path;else$ppath = $path;$vars["repname"] = $rep->getDisplayName();$dirurl = $config->getURL($rep, $path, "dir");$logurl = $config->getURL($rep, $path, "log");$rssurl = $config->getURL($rep, $path, "rss");$dlurl = $config->getURL($rep, $path, "dl");$compurl = $config->getURL($rep, "/", "comp");if ($passrev != 0 && $passrev != $headrev && $youngest != -1)$vars["goyoungestlink"] = "<a href=\"${dirurl}opt=dir&sc=1\">${lang["GOYOUNGEST"]}</a>";else$vars["goyoungestlink"] = "";$bugtraq = new Bugtraq($rep, $svnrep, $ppath);$vars["action"] = "";$vars["rev"] = $rev;$vars["path"] = $ppath;$vars["lastchangedrev"] = $logrev;$vars["date"] = $logEntry->date;$vars["author"] = $logEntry->author;$vars["log"] = nl2br($bugtraq->replaceIDs(create_anchors($logEntry->msg)));if (!$showchanged){$vars["showchangeslink"] = "<a href=\"${dirurl}rev=$passrev&sc=1\">${lang["SHOWCHANGED"]}</a>";$vars["hidechangeslink"] = "";$vars["hidechanges"] = true;$vars["showchanges"] = false;}else{$vars["showchangeslink"] = "";$changes = $logEntry->mods;$firstAdded = true;$firstModded = true;$firstDeleted = true;$vars["newfilesbr"] = "";$vars["newfiles"] = "";$vars["changedfilesbr"] = "";$vars["changedfiles"] = "";$vars["deletedfilesbr"] = "";$vars["deletedfiles"] = "";foreach ($changes as $file){switch ($file->action){case "A":if (!$firstAdded) $vars["newfilesbr"] .= "<br />";$firstAdded = false;$vars["newfilesbr"] .= fileLink("", $file->path);$vars["newfiles"] .= " ".fileLink("", $file->path);break;case "M":if (!$firstModded) $vars["changedfilesbr"] .= "<br />";$firstModded = false;$vars["changedfilesbr"] .= fileLink("", $file->path);$vars["changedfiles"] .= " ".fileLink("", $file->path);break;case "D":if (!$firstDeleted) $vars["deletedfilesbr"] .= "<br />";$firstDeleted = false;$vars["deletedfilesbr"] .= $file->path;$vars["deletedfiles"] .= " ".$file->path;break;}}$vars["hidechangeslink"] = "<a href=\"${dirurl}rev=$passrev&sc=0\">${lang["HIDECHANGED"]}</a>";$vars["hidechanges"] = false;$vars["showchanges"] = true;}createDirLinks($rep, $ppath, $passrev, $showchanged);$vars["curdirloglink"] = "<a href=\"${logurl}rev=$passrev&sc=$showchanged&isdir=1\">${lang["VIEWLOG"]}</a>";if ($rev != $headrev){$history = $svnrep->getLog($path, $rev, "", false);}if (isset($history->entries[1]->rev)){$vars["curdircomplink"] = "<a href=\"${compurl}compare[]=".urlencode($history->entries[1]->path)."@".$history->entries[1]->rev."&compare[]=".urlencode($history->entries[0]->path)."@".$history->entries[0]->rev."\">${lang["DIFFPREV"]}</a>";}else{$vars["curdircomplink"] = "";}if ($rep->getHideRss()){$vars["curdirrsslink"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=1\">${lang["RSSFEED"]}</a>";$vars["curdirrsshref"] = "${rssurl}rev=$passrev&sc=$showchanged&isdir=1";$vars["curdirrssanchor"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=1\">";}// Set up the tarball link$subs = explode("/", $path);$level = count($subs) - 2;if ($rep->isDownloadAllowed($path))$vars["curdirdllink"] = "<a href=\"${dlurl}rev=$passrev&isdir=1\">${lang["TARBALL"]}</a>";else$vars["curdirdllink"] = "";$url = $config->getURL($rep, "/", "comp");$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">";$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />";$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>";$listing = array();$listing = showTreeDir($svnrep, $path, $rev, $listing);$vars["version"] = $version;if (!$rep->hasReadAccess($path, true))$vars["noaccess"] = true;if (!$rep->hasReadAccess($path, false))$vars["restricted"] = true;parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);parseTemplate($rep->getTemplatePath()."directory.tmpl", $vars, $listing);parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);?>