<?php// WebSVN - Subversion repository viewing via the web using PHP// Copyright (C) 2004-2006 Tim Armes//// 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//// --//// configclass.php//// General class for handling configuration optionsrequire_once 'include/command.php';require_once 'include/authz.php';require_once 'include/version.php';// Auxillary functions used to sort repositories by name/group// {{{ cmpReps($a, $b)function cmpReps($a, $b) {// First, sort by group$g = strcasecmp((string) $a->group, (string) $b->group);if ($g) return $g;// Same group? Sort by namereturn strcasecmp($a->name, $b->name);}// }}}// {{{ cmpGroups($a, $b)function cmpGroups($a, $b) {$g = strcasecmp((string) $a->group, (string) $b->group);if ($g) return $g;return 0;}// }}}// {{{ mergesort(&$array, [$cmp_function])function mergesort(&$array, $cmp_function = 'strcmp') {// Arrays of size < 2 require no actionif (count($array) < 2) return;// Split the array in half$halfway = count($array) / 2;$array1 = array_slice($array, 0, $halfway);$array2 = array_slice($array, $halfway);// Recurse to sort the two halvesmergesort($array1, $cmp_function);mergesort($array2, $cmp_function);// If all of $array1 is <= all of $array2, just append them.if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) {$array = array_merge($array1, $array2);return;}// Merge the two sorted arrays into a single sorted array$array = array();$array1count = count($array1);$array2count = count($array2);$ptr1 = 0;$ptr2 = 0;while ($ptr1 < $array1count && $ptr2 < $array2count) {if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) {$array[] = $array1[$ptr1++];} else {$array[] = $array2[$ptr2++];}}// Merge the remainderwhile ($ptr1 < $array1count) $array[] = $array1[$ptr1++];while ($ptr2 < $array2count) $array[] = $array2[$ptr2++];return;}// }}}// A Repository parent path configuration classclass ParentPath {// {{{ Propertiesvar $path;var $group;var $pattern;var $skipAlreadyAdded;var $clientRootURL;// }}}// {{{ __construct($path [, $group [, $pattern [, $skipAlreadyAdded [, $clientRootURL]]]])function __construct($path, $group = null, $pattern = false, $skipAlreadyAdded = true, $clientRootURL = '') {$this->path = $path;$this->group = $group;$this->pattern = $pattern;$this->skipAlreadyAdded = $skipAlreadyAdded;$this->clientRootURL = rtrim($clientRootURL, '/');}// }}}// {{{ findRepository($name)// look for a repository with $namefunction &findRepository($name) {global $config;if ($this->group != null) {$prefix = $this->group.'.';if (substr($name, 0, strlen($prefix)) == $prefix) {$name = substr($name, strlen($prefix));} else {$null = null;return $null;}}// is there a directory named $name?$fullpath = $this->path.DIRECTORY_SEPARATOR.$name;if (is_dir($fullpath) && is_readable($fullpath)) {// And that contains a db directory (in an attempt to not include non svn repositories.$dbfullpath = $fullpath.DIRECTORY_SEPARATOR.'db';if (is_dir($dbfullpath) && is_readable($dbfullpath)) {// And matches the pattern if specifiedif ($this->pattern === false || preg_match($this->pattern, $name)) {$url = $config->fileUrlPrefix.$fullpath;$url = str_replace(DIRECTORY_SEPARATOR, '/', $url);if ($url[ strlen($url) - 1 ] == '/') {$url = substr($url, 0, -1);}if (!in_array($url, $config->_excluded, true)) {$clientRootURL = ($this->clientRootURL) ? $this->clientRootURL.'/'.$name : '';$rep = new Repository($name, $name, $url, $this->group, null, null, null, $clientRootURL);return $rep;}}}}$null = null;return $null;}// }}}// {{{ getRepositories()// return all repositories in the parent path matching patternfunction &getRepositories() {global $config;$repos = array();$handle = @opendir($this->path);if (!$handle) return $repos;// For each file...while (false !== ($name = readdir($handle))) {$fullpath = $this->path.DIRECTORY_SEPARATOR.$name;if ($name[0] != '.' && is_dir($fullpath) && is_readable($fullpath)) {// And that contains a db directory (in an attempt to not include non svn repositories.$dbfullpath = $fullpath.DIRECTORY_SEPARATOR.'db';if (is_dir($dbfullpath) && is_readable($dbfullpath)) {// And matches the pattern if specifiedif ($this->pattern === false || preg_match($this->pattern, $name)) {$url = $config->fileUrlPrefix.$fullpath;$url = str_replace(DIRECTORY_SEPARATOR, '/', $url);if ($url[strlen($url) - 1] == '/') {$url = substr($url, 0, -1);}$clientRootURL = ($this->clientRootURL) ? $this->clientRootURL.'/'.$name : '';$repos[] = new Repository($name, $name, $url, $this->group, null, null, null, $clientRootURL);}}}}closedir($handle);// Sort the repositories into alphabetical orderif (!empty($repos)) {usort($repos, 'cmpReps');}return $repos;}// }}}// {{{ getSkipAlreadyAdded()// Return if we should skip already added repos for this parent path.function getSkipAlreadyAdded() {return $this->skipAlreadyAdded;}// }}}}// A Repository configuration classclass Repository {// {{{ Propertiesvar $name;var $svnName;var $path;var $subpath;var $group;var $username = null;var $password = null;var $clientRootURL;// Local configuration options must start off unsetvar $allowDownload;var $minDownloadLevel;var $allowedExceptions = array();var $disallowedExceptions = array();var $logsShowChanges;var $rss;var $rssCaching;var $rssMaxEntries;var $spaces;var $ignoreSvnMimeTypes;var $ignoreWebSVNContentTypes;var $bugtraq;var $bugtraqProperties;var $authz = null;var $templatePath = false;// }}}// {{{ __construct($name, $svnName, $serverRootURL [, $group [, $username [, $password [, $clientRootURL]]]])function __construct($name, $svnName, $serverRootURL, $group = null, $username = null, $password = null, $subpath = null, $clientRootURL = null) {$this->name = $name;$this->svnName = $svnName;$this->path = $serverRootURL;$this->subpath = $subpath;$this->group = $group;$this->username = $username;$this->password = $password;$this->clientRootURL = rtrim($clientRootURL, '/');}// }}}// {{{ getDisplayName()function getDisplayName() {if (!empty($this->group)) {return $this->group.'.'.$this->name;}return $this->name;}// }}}// {{{ svnCredentialsfunction svnCredentials() {$params = '';if ($this->username !== null && $this->username !== '') {$params .= ' --username '.quote($this->username);}if ($this->password !== null) {$params .= ' --password '.quote($this->password);}return $params;}// }}}// Local configuration accessorsfunction setLogsShowChanges($enabled = true) {$this->logsShowChanges = $enabled;}function logsShowChanges() {global $config;if (isset($this->logsShowChanges))return $this->logsShowChanges;elsereturn $config->logsShowChanges();}// {{{ RSS Feedfunction setRssEnabled($enabled) {$this->rss = $enabled;}function isRssEnabled() {global $config;if (isset($this->rss))return $this->rss;elsereturn $config->isRssEnabled();}function setRssCachingEnabled($enabled = true) {$this->rssCaching = $enabled;}function isRssCachingEnabled() {global $config;if (isset($this->rssCaching))return $this->rssCaching;elsereturn $config->isRssCachingEnabled();}function setRssMaxEntries($max) {$this->rssMaxEntries = $max;}function getRssMaxEntries() {global $config;if (isset($this->rssMaxEntries))return $this->rssMaxEntries;elsereturn $config->getRssMaxEntries();}// }}}// {{{ Downloadfunction allowDownload() {$this->allowDownload = true;}function disallowDownload() {$this->allowDownload = false;}function getAllowDownload() {global $config;if (isset($this->allowDownload)) {return $this->allowDownload;}return $config->getAllowDownload();}function setMinDownloadLevel($level) {$this->minDownloadLevel = $level;}function getMinDownloadLevel() {global $config;if (isset($this->minDownloadLevel)) {return $this->minDownloadLevel;}return $config->getMinDownloadLevel();}function addAllowedDownloadException($path) {if ($path[strlen($path) - 1] != '/') $path .= '/';$this->allowedExceptions[] = $path;}function addDisallowedDownloadException($path) {if ($path[strlen($path) - 1] != '/') $path .= '/';$this->disallowedExceptions[] = $path;}function isDownloadAllowed($path) {global $config;// Check global download optionif (!$this->getAllowDownload()) {return false;}// Check with access moduleif (!$this->hasUnrestrictedReadAccess($path)) {return false;}$subs = explode('/', $path);$level = count($subs) - 2;if ($level >= $this->getMinDownloadLevel()) {// Level OK, search for disallowed exceptionsif ($config->findException($path, $this->disallowedExceptions)) {return false;}if ($config->findException($path, $config->disallowedExceptions)) {return false;}return true;} else {// Level not OK, search for disallowed exceptionsif ($config->findException($path, $this->allowedExceptions)) {return true;}if ($config->findException($path, $config->allowedExceptions)) {return true;}return false;}}// }}}// {{{ Templatesfunction setTemplatePath($path) {$this->templatePath = $path;}function getTemplatePath() {global $config;if (!empty($this->templatePath)) {return $this->templatePath;}return $config->getTemplatePath();}// }}}// {{{ Tab expansionfunction expandTabsBy($sp) {$this->spaces = $sp;}function getExpandTabsBy() {global $config;if (isset($this->spaces)) {return $this->spaces;}return $config->getExpandTabsBy();}// }}}// {{{ MIME-Type Handingfunction ignoreSvnMimeTypes() {$this->ignoreSvnMimeTypes = true;}function useSvnMimeTypes() {$this->ignoreSvnMimeTypes = false;}function getIgnoreSvnMimeTypes() {global $config;if (isset($this->ignoreSvnMimeTypes)) {return $this->ignoreSvnMimeTypes;}return $config->getIgnoreSvnMimeTypes();}function ignoreWebSVNContentTypes() {$this->ignoreWebSVNContentTypes = true;}function useWebSVNContentTypes() {$this->ignoreWebSVNContentTypes = false;}function getIgnoreWebSVNContentTypes() {global $config;if (isset($this->ignoreWebSVNContentTypes)) {return $this->ignoreWebSVNContentTypes;}return $config->getIgnoreWebSVNContentTypes();}// }}}// {{{ Bugtraq issue trackingfunction setBugtraqEnabled($enabled) {$this->bugtraq = $enabled;}function isBugtraqEnabled() {global $config;if (isset($this->bugtraq))return $this->bugtraq;elsereturn $config->isBugtraqEnabled();}function setBugtraqProperties($properties) {$this->bugtraqProperties = $properties;}function getBugtraqProperties() {global $config;if (isset($this->bugtraqProperties))return $this->bugtraqProperties;elsereturn $config->getBugtraqProperties();}// }}}// {{{ Authorizationfunction useAccessFile($file) {if (is_readable($file)) {if ($this->authz === null) {$this->authz = new Authorization();}$this->authz->addAccessFile($file);} else {die('Unable to read access file "'.$file.'"');}}function &getAuthz() {global $config;$a = null;if ($this->authz !== null) {$a =& $this->authz;} else {$a =& $config->getAuthz();}return $a;}function _getPathWithSubIf($pathWoSub) {if (!$this->subpath) {return $pathWoSub;}return '/' . $this->subpath . $pathWoSub;}function hasReadAccess($pathWoSub, $checkSubDirs = false) {$path = $this->_getPathWithSubIf($pathWoSub);$a =& $this->getAuthz();if (!empty($a)) {return $a->hasReadAccess($this->svnName, $path, $checkSubDirs);}// No access file - free access...return true;}function hasLogReadAccess($pathWithSub) {$path = $pathWithSub;$a =& $this->getAuthz();if (!empty($a)) {return $a->hasReadAccess($this->svnName, $path, false);}// No access file - free access...return true;}function hasUnrestrictedReadAccess($pathWoSub) {$path = $this->_getPathWithSubIf($pathWoSub);$a =& $this->getAuthz();if (!empty($a)) {return $a->hasUnrestrictedReadAccess($this->svnName, $path);}// No access file - free access...return true;}// }}}}// The general configuration classclass WebSvnConfig {// {{{ Properties// Tool path locationsvar $_svnCommandPath = '';var $_svnConfigDir = '/tmp/websvn';var $_svnTrustServerCert = false;var $svn = 'svn --non-interactive --config-dir /tmp/websvn';var $svnAuthz = 'svnauthz accessof';var $diff = 'diff';var $enscript = 'enscript -q';var $sed = 'sed';var $gzip = 'gzip';var $tar = 'tar';var $zip = 'zip';var $locale = '';// different modes for file and directory downloadvar $defaultFileDlMode = 'plain';var $defaultDirectoryDlMode = 'gzip';var $validFileDlModes = array( 'gzip', 'zip', 'plain' );var $validDirectoryDlModes = array( 'gzip', 'zip' );// Other configuration itemsvar $treeView = true;var $flatIndex = true;var $openTree = false;var $alphabetic = false;var $showLastModInIndex = true;var $showLastModInListing = true;var $showAgeInsteadOfDate = true;var $_showRepositorySelectionForm = true;var $_ignoreWhitespacesInDiff = false;var $serverIsWindows = false;var $multiViews = false;var $multiViewsIndex = 'browse';var $useEnscript = false;var $useEnscriptBefore_1_6_3 = false;var $useGeshi = false;var $geshiScript = 'geshi.php';var $useParsedown = false;var $parsedownScript = 'Parsedown.php';var $inlineMimeTypes = array();var $allowDownload = false;var $tempDir = '';var $minDownloadLevel = 0;var $allowedExceptions = array();var $disallowedExceptions = array();var $logsShowChanges = false;var $rss = true;var $rssCaching = false;var $rssMaxEntries = 40;var $spaces = 8;var $bugtraq = false;var $bugtraqProperties = null;var $authz = null;var $blockRobots = false;var $loadAllRepos = false;var $templatePaths = array();var $userTemplate = false;var $ignoreSvnMimeTypes = false;var $ignoreWebSVNContentTypes = false;var $subversionVersion = '';var $subversionMajorVersion = '';var $subversionMinorVersion = '';var $defaultLanguage = 'en';var $ignoreAcceptedLanguages = false;var $quote = "'";var $pathSeparator = ':';var $fileUrlPrefix = 'file://';var $breadcrumbRepoRootAsRepo = false;var $_repositories = array();var $_parentPaths = array(); // parent paths to loadvar $_parentPathsLoaded = false;var $_excluded = array();// }}}// {{{ __construct()function __construct() {}// }}}// {{{ Repository configurationfunction addRepository($name, $serverRootURL, $group = null, $username = null, $password = null, $clientRootURL = null) {$this->addRepositorySubpath($name, $serverRootURL, null, $group, $username, $password, $clientRootURL);}function addRepositorySubpath($name, $serverRootURL, $subpath, $group = null, $username = null, $password = null, $clientRootURL = null) {if (DIRECTORY_SEPARATOR != '/') {$serverRootURL = str_replace(DIRECTORY_SEPARATOR, '/', $serverRootURL);if ($subpath !== null) {$subpath = str_replace(DIRECTORY_SEPARATOR, '/', $subpath);}}$serverRootURL = trim($serverRootURL, '/');$svnName = substr($serverRootURL, strrpos($serverRootURL, '/') + 1);$this->_repositories[] = new Repository($name, $svnName, $serverRootURL, $group, $username, $password, $subpath, $clientRootURL);}// Automatically set up the repositories based on a parent pathfunction parentPath($path, $group = null, $pattern = false, $skipAlreadyAdded = true, $clientRootURL = '') {$this->_parentPaths[] = new ParentPath($path, $group, $pattern, $skipAlreadyAdded, $clientRootURL);}function addExcludedPath($path) {$url = $this->fileUrlPrefix.$path;$url = str_replace(DIRECTORY_SEPARATOR, '/', $url);if ($url[strlen($url) - 1] == '/') {$url = substr($url, 0, -1);}$this->_excluded[] = $url;}function getRepositories() {// lazily load parent pathsif ($this->_parentPathsLoaded) return $this->_repositories;$this->_parentPathsLoaded = true;foreach ($this->_parentPaths as $parentPath) {$parentRepos = $parentPath->getRepositories();foreach ($parentRepos as $repo) {if (!$parentPath->getSkipAlreadyAdded()) {$this->_repositories[] = $repo;} else {// we have to check if we already have a repo with the same svn name$duplicate = false;foreach ($this->_repositories as $knownRepos) {if ($knownRepos->path == $repo->path && $knownRepos->subpath == $repo->subpath) {$duplicate = true;break;}}if (!$duplicate && !in_array($repo->path, $this->_excluded, true)) {$this->_repositories[] = $repo;}}}}return $this->_repositories;}function &findRepository($name) {// first look in the "normal repositories"foreach ($this->_repositories as $index => $rep) {if (strcmp($rep->getDisplayName(), $name) == 0) {$repref =& $this->_repositories[$index];return $repref;}}// now if the parent repos have not already been loaded// check themif (!$this->_parentPathsLoaded) {foreach ($this->_parentPaths as $parentPath) {$repref =& $parentPath->findRepository($name);if ($repref != null) {$this->_repositories[] = $repref;return $repref;}}}// Hack to return a string by reference; value retrieved at setup.php:414$str = 'Unable to find repository "'.escape($name).'".';$error =& $str;return $error;}// }}}// {{{ setServerIsWindows//// The server is running on Windowsfunction setServerIsWindows() {$this->serverIsWindows = true;// On Windows machines, use double quotes around command line parameters$this->quote = '"';// On Windows, semicolon separates path entries in a list rather than colon.$this->pathSeparator = ';';$this->fileUrlPrefix = 'file:///';}// }}}// {{{ MultiViews// useMultiViews//// Use MultiViews to access the repositoryfunction useMultiViews($multiViewsIndex = 'browse') {$this->multiViews = true;$this->multiViewsIndex = $multiViewsIndex;}function getUseMultiViews() {return $this->multiViews;}function getMultiViewsIndex() {return $this->multiViewsIndex;}// }}}// {{{ Enscript// useEnscript//// Use Enscript to colourise listingsfunction useEnscript($before_1_6_3 = false) {$this->useEnscript = true;$this->useEnscriptBefore_1_6_3 = $before_1_6_3;}function getUseEnscript() {return $this->useEnscript;}function getUseEnscriptBefore_1_6_3() {return $this->useEnscriptBefore_1_6_3;}// }}}// {{{ GeSHifunction setGeshiPath($path) {$this->_setPath($this->geshiScript, $path, 'geshi.php');}function getGeshiScript() {return $this->geshiScript;}// useGeshi//// Use GeSHi to colourise listingsfunction useGeshi() {$this->useGeshi = true;}function getUseGeshi() {return $this->useGeshi;}// }}}// {{{ Parsedownfunction setParsedownPath($path) {$this->_setPath($this->parsedownScript, $path, 'Parsedown.php');}function getParsedownScript() {return $this->parsedownScript;}// useParsedown//// Use Parsedown to render README.mdfunction useParsedown() {$this->useParsedown = true;}function getUseParsedown() {return $this->useParsedown;}// }}}// {{{ Inline MIME Types// inlineMimeTypes//// Specify MIME types to display inline in WebSVN pagesfunction addInlineMimeType($type) {if (!in_array($type, $this->inlineMimeTypes)) {$this->inlineMimeTypes[] = $type;}}// }}}// {{{ Show changed files by default on log.phpfunction setLogsShowChanges($enabled = true, $myrep = 0) {if (empty($myrep)) {$this->logsShowChanges = $enabled;} else {$repo =& $this->findRepository($myrep);$repo->logsShowChanges = $enabled;}}function logsShowChanges() {return $this->logsShowChanges;}// }}}// {{{ RSSfunction setRssEnabled($enabled = true, $myrep = 0) {if (empty($myrep)) {$this->rss = $enabled;} else {$repo =& $this->findRepository($myrep);$repo->setRssEnabled($enabled);}}function isRssEnabled() {return $this->rss;}function setRssCachingEnabled($enabled = true, $myrep = 0) {if (empty($myrep)) {$this->rssCaching = true;} else {$repo =& $this->findRepository($myrep);$repo->setRssCachingEnabled($enabled);}}function isRssCachingEnabled() {return $this->rssCaching;}// Maximum number of entries in RSS feedfunction setRssMaxEntries($max, $myrep = 0) {if (empty($myrep)) {$this->rssMaxEntries = $max;} else {$repo =& $this->findRepository($myrep);$repo->setRssMaxEntries($max);}}function getRssMaxEntries() {return $this->rssMaxEntries;}function getHideRSS() {return $this->rss;}// cacheRSS//// Enable caching of RSS feedsfunction enableRSSCaching($myrep = 0) {if (empty($myrep)) {$this->rssCaching = true;} else {$repo =& $this->findRepository($myrep);$repo->enableRSSCaching();}}function getRSSCaching() {return $this->rssCaching;}// }}}// {{{ Downloads// allowDownload//// Allow download of tarballsfunction allowDownload($myrep = 0) {if (empty($myrep)) {$this->allowDownload = true;} else {$repo =& $this->findRepository($myrep);$repo->allowDownload();}}function disallowDownload($myrep = 0) {if (empty($myrep)) {$this->allowDownload = false;} else {$repo =& $this->findRepository($myrep);$repo->disallowDownload();}}function getAllowDownload() {return $this->allowDownload;}function setTempDir($tempDir) {$this->tempDir = $tempDir;}function getTempDir() {if (empty($this->tempDir)) {$this->tempDir = sys_get_temp_dir();}return $this->tempDir;}function setMinDownloadLevel($level, $myrep = 0) {if (empty($myrep)) {$this->minDownloadLevel = $level;} else {$repo =& $this->findRepository($myrep);$repo->setMinDownloadLevel($level);}}function getMinDownloadLevel() {return $this->minDownloadLevel;}function addAllowedDownloadException($path, $myrep = 0) {if ($path[strlen($path) - 1] != '/') {$path .= '/';}if (empty($myrep)) {$this->allowedExceptions[] = $path;} else {$repo =& $this->findRepository($myrep);$repo->addAllowedDownloadException($path);}}function addDisallowedDownloadException($path, $myrep = 0) {if ($path[strlen($path) - 1] != '/') {$path .= '/';}if (empty($myrep)) {$this->disallowedExceptions[] = $path;} else {$repo =& $this->findRepository($myrep);$repo->addDisallowedDownloadException($path);}}function findException($path, $exceptions) {foreach ($exceptions as $key => $exc) {if (strncmp($exc, $path, strlen($exc)) == 0) {return true;}}return false;}// }}}// {{{ getURL//// Get the URL to a path name based on the current configfunction getURL($rep, $path, $op) {list($base, $params) = $this->getUrlParts($rep, $path, $op);$url = $base.'?';foreach ($params as $k => $v) {$url .= $k.'='.rawurlencode($v).'&';}return $url;}// }}}// {{{ getUrlParts//// Get the URL and parameters for a path name based on the current configfunction getUrlParts($rep, $path, $op) {$params = array();if ($this->multiViews) {$url = $_SERVER['SCRIPT_NAME'];if (preg_match('|\.php$|i', $url)) {// remove the .php extension$url = substr($url, 0, -4);}if ($path && $path[0] != '/') {$path = '/'.$path;}if (substr($url, -5) == 'index') {$url = substr($url, 0, -5).$this->multiViewsIndex;}if ($op == 'index') {$url .= '/';} else if (is_object($rep)) {$url .= '/'.$rep->getDisplayName().str_replace('%2F', '/', rawurlencode($path ?? ''));if ($op && $op != 'dir' && $op != 'file') {$params['op'] = $op;}}} else {switch ($op) {case 'index':$url = '.';break;case 'dir':$url = 'listing.php';break;case 'revision':$url = 'revision.php';break;case 'file':$url = 'filedetails.php';break;case 'log':$url = 'log.php';break;case 'diff':$url = 'diff.php';break;case 'blame':$url = 'blame.php';break;case 'form':$url = 'form.php';break;case 'rss':$url = 'rss.php';break;case 'dl':$url = 'dl.php';break;case 'comp':$url = 'comp.php';break;case 'search':$url = 'search.php';break;}if (is_object($rep) && $op != 'index') {$params['repname'] = $rep->getDisplayName();}if (!empty($path)) {$params['path'] = $path;}}return array($url, $params);}// }}}// {{{ Paths and Commands// setPath//// Set the location of the given pathfunction _setPath(&$var, $path, $name, $params = '') {if ($path == '') {// Search in system search path. No check for existence possible$var = $name;} else {$lastchar = substr($path, -1, 1);$isDir = ($lastchar == DIRECTORY_SEPARATOR || $lastchar == '/' || $lastchar == '\\');if (!$isDir) $path .= DIRECTORY_SEPARATOR;if (($this->serverIsWindows && !file_exists($path.$name.'.exe')) || (!$this->serverIsWindows && !file_exists($path.$name))) {echo 'Unable to find "'.$name.'" tool at location "'.$path.$name.'"';exit;}// On a windows machine we need to put quotes around the// entire command to allow for spaces in the pathif ($this->serverIsWindows) {$var = '"'.$path.$name.'"';} else {$var = $path.$name;}}// Append parametersif ($params != '') $var .= ' '.$params;}// Define directory path to use for --config-dir parameterfunction setSvnConfigDir($path) {$this->_svnConfigDir = $path;$this->_updateSvnCommand();}// Define flag to use --trust-server-cert parameterfunction setTrustServerCert() {$this->_svnTrustServerCert = true;$this->_updateSvnCommand();}// Define the location of the svn command (e.g. '/usr/bin')function setSvnCommandPath($path) {$this->_svnCommandPath = $path;$this->_updateSvnCommand();}// Define the location of the svnauthz command (e.g. '/usr/bin')function setSvnAuthzCommandPath($path) {$this->_setPath($this->svnAuthz, $path, 'svnauthz', 'accessof');}function _updateSvnCommand() {$this->_setPath($this->svn, $this->_svnCommandPath, 'svn', '--non-interactive --config-dir '.$this->_svnConfigDir.($this->_svnTrustServerCert ? ' --trust-server-cert' : ''));}function getSvnCommand() {return $this->svn;}function getSvnAuthzCommand() {return $this->svnAuthz;}// setDiffPath//// Define the location of the diff commandfunction setDiffPath($path) {$this->_setPath($this->diff, $path, 'diff');}function getDiffCommand() {return $this->diff;}// setEnscriptPath//// Define the location of the enscript commandfunction setEnscriptPath($path) {$this->_setPath($this->enscript, $path, 'enscript', '-q');}function getEnscriptCommand() {return $this->enscript;}// setSedPath//// Define the location of the sed commandfunction setSedPath($path) {$this->_setPath($this->sed, $path, 'sed');}function getSedCommand() {return $this->sed;}// setTarPath//// Define the location of the tar commandfunction setTarPath($path) {$this->_setPath($this->tar, $path, 'tar');}function getTarCommand() {return $this->tar;}// setGzipPath//// Define the location of the GZip commandfunction setGzipPath($path) {$this->_setPath($this->gzip, $path, 'gzip');}function getGzipCommand() {return $this->gzip;}// setZipPath//// Define the location of the zip commandfunction setZipPath($path) {$this->_setPath($this->zip, $path, 'zip');}function getZipPath() {return $this->zip;}// setLocale//// Set the locale for PHP and all spawned processesfunction setLocale($locale) {$this->locale = $locale;}function getLocale() {return $this->locale;}// setDefaultFileDlMode//// Define the default file download mode - one of [gzip, zip, plain]function setDefaultFileDlMode($dlmode) {if (in_array($dlmode, $this->validFileDlModes)) {$this->defaultFileDlMode = $dlmode;} else {echo 'Setting default file download mode to an invalid value "'.$dlmode.'"';exit;}}function getDefaultFileDlMode() {return $this->defaultFileDlMode;}// setDefaultDirectoryDlMode//// Define the default directory download mode - one of [gzip, zip]function setDefaultDirectoryDlMode($dlmode) {if (in_array($dlmode, $this->validDirectoryDlModes)) {$this->defaultDirectoryDlMode = $dlmode;} else {echo 'Setting default directory download mode to an invalid value "'.$dlmode.'"';exit;}}function setDefaultFolderDlMode($dlmode) {$this->setDefaultDirectoryDlMode($dlmode);}function getDefaultDirectoryDlMode() {return $this->defaultDirectoryDlMode;}function getDefaultFolderDlMode() {return $this->getDefaultDirectoryDlMode();}// Templatesfunction addTemplatePath($path) {$lastchar = substr($path, -1, 1);if ($lastchar != '/' && $lastchar != '\\') {$path .= DIRECTORY_SEPARATOR;}if (!in_array($path, $this->templatePaths)) {$this->templatePaths[] = $path;}}function setTemplatePath($path, $myrep = null) {$lastchar = substr($path, -1, 1);if ($lastchar != '/' && $lastchar != '\\') {$path .= DIRECTORY_SEPARATOR;}if ($myrep !== null) {// fixed template for specific repository$repo =& $this->findRepository($myrep);$repo->setTemplatePath($path);} else {// for backward compatibilityif (in_array($path, $this->templatePaths)) {array_splice($this->templatePaths, array_search($path, $this->templatePaths), 1);}array_unshift($this->templatePaths, $path);}}function getTemplatePath() {if (count($this->templatePaths) == 0) {echo 'No template path added in config file';exit;}if ($this->userTemplate !== false)return $this->userTemplate;elsereturn $this->templatePaths[0];}// }}}function setDefaultLanguage($language) {$this->defaultLanguage = $language;}function getDefaultLanguage() {return $this->defaultLanguage;}function ignoreUserAcceptedLanguages() {$this->ignoreAcceptedLanguages = true;}function useAcceptedLanguages() {return !$this->ignoreAcceptedLanguages;}// {{{ Tab expansion functionsfunction expandTabsBy($sp, $myrep = 0) {if (empty($myrep)) {$this->spaces = $sp;} else {$repo =& $this->findRepository($myrep);$repo->expandTabsBy($sp);}}function getExpandTabsBy() {return $this->spaces;}// }}}// {{{ Bugtraq issue trackingfunction setBugtraqEnabled($enabled, $myrep = 0) {if (empty($myrep)) {$this->bugtraq = $enabled;} else {$repo =& $this->findRepository($myrep);$repo->setBugtraqEnabled($enabled);}}function isBugtraqEnabled() {return $this->bugtraq;}function setBugtraqProperties($message, $logregex, $url, $append = true, $myrep = null) {$properties = array();$properties['bugtraq:message'] = $message;$properties['bugtraq:logregex'] = $logregex;$properties['bugtraq:url'] = $url;$properties['bugtraq:append'] = (bool)$append;if ($myrep === null) {$this->bugtraqProperties = $properties;} else {$repo =& $this->findRepository($myrep);$repo->setBugtraqProperties($properties);}}function getBugtraqProperties() {return $this->bugtraqProperties;}// }}}// {{{ Misc settingsfunction ignoreSvnMimeTypes() {$this->ignoreSvnMimeTypes = true;}function getIgnoreSvnMimeTypes() {return $this->ignoreSvnMimeTypes;}function ignoreWebSVNContentTypes() {$this->ignoreWebSVNContentTypes = true;}function getIgnoreWebSVNContentTypes() {return $this->ignoreWebSVNContentTypes;}function useAccessFile($file, $myrep = 0) {if (empty($myrep)) {if (is_readable($file)) {if ($this->authz === null) {$this->authz = new Authorization();}$this->authz->addAccessFile($file);} else {echo 'Unable to read access file "'.$file.'"';exit;}} else {$repo =& $this->findRepository($myrep);$repo->useAccessFile($file);}}function &getAuthz() {return $this->authz;}function areRobotsBlocked() {return $this->blockRobots;}function setBlockRobots($value = true) {$this->blockRobots = $value;}function useTreeView() {$this->treeView = true;}function getUseTreeView() {return $this->treeView;}function useFlatView() {$this->treeView = false;}function useTreeIndex($open) {$this->flatIndex = false;$this->openTree = $open;}function getUseFlatIndex() {return $this->flatIndex;}function getOpenTree() {return $this->openTree;}function setLoadAllRepos($flag) {$this->loadAllRepos = $flag;}function showLoadAllRepos() {return $this->loadAllRepos;}function setAlphabeticOrder($flag) {$this->alphabetic = $flag;}function isAlphabeticOrder() {return $this->alphabetic;}function showLastModInIndex() {return $this->showLastModInIndex;}function setShowLastModInIndex($show) {$this->showLastModInIndex = $show;}function showLastModInListing() {return $this->showLastModInListing;}function setShowLastModInListing($show) {$this->showLastModInListing = $show;}function showAgeInsteadOfDate() {return $this->showAgeInsteadOfDate;}function setShowAgeInsteadOfDate($show) {$this->showAgeInsteadOfDate = $show;}function showRepositorySelectionForm() {return $this->_showRepositorySelectionForm;}function setShowRepositorySelectionForm($show) {$this->_showRepositorySelectionForm = $show;}function getIgnoreWhitespacesInDiff() {return $this->_ignoreWhitespacesInDiff;}function setIgnoreWhitespacesInDiff($ignore) {$this->_ignoreWhitespacesInDiff = $ignore;}// Methods for storing version information for the command-line svn toolfunction setSubversionVersion($subversionVersion) {$this->subversionVersion = $subversionVersion;}function getSubversionVersion() {return $this->subversionVersion;}function setSubversionMajorVersion($subversionMajorVersion) {$this->subversionMajorVersion = $subversionMajorVersion;}function getSubversionMajorVersion() {return $this->subversionMajorVersion;}function setSubversionMinorVersion($subversionMinorVersion) {$this->subversionMinorVersion = $subversionMinorVersion;}function getSubversionMinorVersion() {return $this->subversionMinorVersion;}// }}}// {{{ Sort the repostories//// This function sorts the repositories by group name. The contents of the// group are left in there original order, which will either be sorted if the// group was added using the parentPath function, or defined for the order in// which the repositories were included in the user's config file.//// Note that as of PHP 4.0.6 the usort command no longer preserves the order// of items that are considered equal (in our case, part of the same group).// The mergesort function preserves this order.function sortByGroup() {if (!empty($this->_repositories)) {mergesort($this->_repositories, 'cmpGroups');}}// }}}// {{{ Change the name of the breadcrumb root-phrase to that of the current repo?function setBreadcrumbRepoRootAsRepo($newValue) {$this->breadcrumbRepoRootAsRepo = $newValue;}function getBreadcrumbRepoRootAsRepo() {return $this->breadcrumbRepoRootAsRepo;}// }}}}