Exemplo n.º 1
0
 /**
  * __construct
  *
  * Constructor
  *
  * @access public
  * @return mixed controller object
  * @throws Exception on invalid project
  */
 public function __construct()
 {
     require_once GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('smarty_prefix', 'lib/smarty/libs/')) . 'Smarty.class.php';
     $this->tpl = new Smarty();
     $this->tpl->error_reporting = E_ALL & ~E_NOTICE;
     $this->tpl->addPluginsDir(GITPHP_INCLUDEDIR . 'smartyplugins');
     if (GitPHP_Config::GetInstance()->GetValue('cache', false)) {
         $this->tpl->caching = Smarty::CACHING_LIFETIME_SAVED;
         if (GitPHP_Config::GetInstance()->HasKey('cachelifetime')) {
             $this->tpl->cache_lifetime = GitPHP_Config::GetInstance()->GetValue('cachelifetime');
         }
         $servers = GitPHP_Config::GetInstance()->GetValue('memcache', null);
         if (isset($servers) && is_array($servers) && count($servers) > 0) {
             $this->tpl->caching_type = 'memcache';
         }
     }
     if (isset($_GET['p'])) {
         $this->project = GitPHP_ProjectList::GetInstance()->GetProject(str_replace(chr(0), '', $_GET['p']));
         if (!$this->project) {
             throw new GitPHP_MessageException(sprintf(__('Invalid project %1$s'), $_GET['p']), true);
         }
     }
     if (isset($_GET['s'])) {
         $this->params['search'] = $_GET['s'];
     }
     if (isset($_GET['st'])) {
         $this->params['searchtype'] = $_GET['st'];
     }
     $this->ReadQuery();
 }
Exemplo n.º 2
0
 /**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     if (!($fp = fopen($this->projectConfig, 'r'))) {
         throw new Exception(sprintf(__('Failed to open project list file %1$s'), $this->projectConfig));
     }
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     while (!feof($fp) && ($line = fgets($fp))) {
         if (preg_match('/^([^\\s]+)(\\s.+)?$/', $line, $regs)) {
             if (is_file($projectRoot . $regs[1] . '/HEAD')) {
                 try {
                     $projObj = new GitPHP_Project($projectRoot, $regs[1]);
                     if (isset($regs[2]) && !empty($regs[2])) {
                         $projOwner = trim($regs[2]);
                         if (!empty($projOwner)) {
                             $projObj->SetOwner($projOwner);
                         }
                     }
                     $this->projects[$regs[1]] = $projObj;
                 } catch (Exception $e) {
                     GitPHP_Log::GetInstance()->Log($e->getMessage());
                 }
             } else {
                 GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $projectRoot . $regs[1]));
             }
         }
     }
     fclose($fp);
 }
Exemplo n.º 3
0
 /**
  * Constructor
  *
  * @param string $cacheDir cache dir
  * @param int $compressThreshold threshold to start compressing data at
  * @param boolean $igbinary whether to use igbinary, null to autodetect
  */
 public function __construct($cacheDir, $compressThreshold = 0, $igbinary = null)
 {
     if (file_exists($cacheDir)) {
         if (!is_dir($cacheDir)) {
             throw new Exception($cacheDir . ' exists but is not a directory');
         } else {
             if (!is_writable($cacheDir)) {
                 throw new Exception($cacheDir . ' is not writable');
             }
         }
     } else {
         if (!mkdir($cacheDir, 0777)) {
             throw new Exception($cacheDir . ' could not be created');
         }
         chmod($cacheDir, 0777);
     }
     $this->cacheDir = GitPHP_Util::AddSlash($cacheDir, true);
     if (!(is_int($compressThreshold) && $compressThreshold >= 0)) {
         throw new Exception('Invalid compression threshold');
     }
     $this->compressThreshold = $compressThreshold;
     if ($igbinary === null) {
         $this->igbinary = function_exists('igbinary_serialize');
     } else {
         if ($igbinary) {
             if (!function_exists('igbinary_serialize')) {
                 throw new Exception('Igbinary is not present');
             }
             $this->igbinary = $igbinary;
         }
     }
 }
 /**
  * Recursively searches for projects
  *
  * @param string $dir directory to recurse into
  */
 private function RecurseDir($dir)
 {
     if (!(is_dir($dir) && is_readable($dir))) {
         return;
     }
     $this->Log('Search directory', $dir);
     if ($dh = opendir($dir)) {
         $trimlen = strlen(GitPHP_Util::AddSlash($this->projectRoot)) + 1;
         while (($file = readdir($dh)) !== false) {
             $fullPath = $dir . '/' . $file;
             if (strpos($file, '.') !== 0 && is_dir($fullPath)) {
                 if (is_file($fullPath . '/HEAD')) {
                     $this->Log('Found project', $fullPath);
                     $projectPath = substr($fullPath, $trimlen);
                     if (!isset($this->projects[$projectPath])) {
                         $project = $this->LoadProject($projectPath);
                         if ($project) {
                             $this->projects[$projectPath] = $project;
                             unset($project);
                         }
                     }
                 } else {
                     $this->RecurseDir($fullPath);
                 }
             } else {
                 $this->Log('Skip', $fullPath);
             }
         }
         closedir($dh);
     }
 }
Exemplo n.º 5
0
 /**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     foreach ($this->projectConfig as $proj => $projData) {
         try {
             if (is_string($projData)) {
                 // Just flat array of project paths
                 $projObj = new GitPHP_Project($projectRoot, $projData);
                 $this->projects[$projData] = $projObj;
             } else {
                 if (is_array($projData)) {
                     if (is_string($proj) && !empty($proj)) {
                         // Project key pointing to data array
                         $projObj = new GitPHP_Project($projectRoot, $proj);
                         $this->projects[$proj] = $projObj;
                         $this->ApplyProjectSettings($proj, $projData);
                     } else {
                         if (isset($projData['project'])) {
                             // List of data arrays with projects inside
                             $projObj = new GitPHP_Project($projectRoot, $projData['project']);
                             $this->projects[$projData['project']] = $projObj;
                             $this->ApplyProjectSettings(null, $projData);
                         }
                     }
                 }
             }
         } catch (Exception $e) {
             GitPHP_Log::GetInstance()->Log($e->getMessage());
         }
     }
 }
 /**
  * __construct
  *
  * constructor
  *
  * @param string $projectDir directory to search
  * @throws Exception if parameter is not a directory
  * @access public
  */
 public function __construct($projectDir)
 {
     if (!is_dir($projectDir)) {
         throw new Exception(sprintf(__('%1$s is not a directory'), $projectDir));
     }
     $this->projectDir = GitPHP_Util::AddSlash($projectDir);
     parent::__construct();
 }
Exemplo n.º 7
0
 public function testAddSlashWin()
 {
     if (!GitPHP_Util::IsWindows()) {
         $this->markTestSkipped();
     }
     $this->assertEquals('path\\with\\backslash\\', GitPHP_Util::AddSlash('path\\with\\backslash\\', true));
     $this->assertEquals('path\\without\\backslash\\', GitPHP_Util::AddSlash('path\\without\\backslash', true));
     $this->assertEquals('path\\with\\slash/', GitPHP_Util::AddSlash('path\\with\\slash/', true));
     $this->assertEquals('/path/with/colon:', GitPHP_Util::AddSlash('/path/with/colon:', true));
     $this->assertEquals('\\', GitPHP_Util::AddSlash('\\', true));
     $this->assertEquals('/', GitPHP_Util::AddSlash('/', true));
 }
 /**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     $use_errors = libxml_use_internal_errors(true);
     $xml = simplexml_load_file($this->projectConfig);
     libxml_clear_errors();
     libxml_use_internal_errors($use_errors);
     if (!$xml) {
         throw new Exception(sprintf('Could not load SCM manager config %1$s', $this->projectConfig));
     }
     foreach ($xml->repositories->repository as $repository) {
         if ($repository->type != 'git') {
             GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $repository->name));
             continue;
         }
         if ($repository->public != 'true') {
             GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not public', $repository->name));
             continue;
         }
         $projName = trim($repository->name);
         if (empty($projName)) {
             continue;
         }
         if (is_file($projectRoot . $projName . '/HEAD')) {
             try {
                 $projObj = new GitPHP_Project($projectRoot, $projName);
                 $projOwner = trim($repository->contact);
                 if (!empty($projOwner)) {
                     $projObj->SetOwner($projOwner);
                 }
                 $projDesc = trim($repository->description);
                 if (!empty($projDesc)) {
                     $projObj->SetDescription($projDesc);
                 }
                 $this->projects[$projName] = $projObj;
             } catch (Exception $e) {
                 GitPHP_Log::GetInstance()->Log($e->getMessage());
             }
         } else {
             GitPHP_Log::GetInstance()->Log(sprintf('%1$s is not a git project', $projName));
         }
     }
 }
Exemplo n.º 9
0
/**
 * scripturl smarty function
 *
 * @param array $params function parameters
 * @param mixed $smarty smarty object
 * @return string script url
 */
function smarty_function_scripturl($params, &$smarty)
{
    if (GitPHP_Config::GetInstance()->HasKey('self')) {
        $selfurl = GitPHP_Config::GetInstance()->GetValue('self');
        if (!empty($selfurl)) {
            if (substr($selfurl, -4) != '.php') {
                $selfurl = GitPHP_Util::AddSlash($selfurl);
            }
            return $selfurl;
        }
    }
    if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
        $scriptstr = 'https://';
    } else {
        $scriptstr = 'http://';
    }
    $scriptstr .= $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
    return $scriptstr;
}
 /**
  * PopulateProjects
  *
  * Populates the internal list of projects
  *
  * @access protected
  * @throws Exception if file cannot be read
  */
 protected function PopulateProjects()
 {
     $projectRoot = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('projectroot'));
     foreach ($this->projectConfig as $cat => $plist) {
         if (is_array($plist)) {
             foreach ($plist as $pname => $ppath) {
                 try {
                     $projObj = new GitPHP_Project($projectRoot, $ppath);
                     if ($cat != GITPHP_NO_CATEGORY) {
                         $projObj->SetCategory($cat);
                     }
                     $this->projects[$ppath] = $projObj;
                 } catch (Exception $e) {
                     GitPHP_Log::GetInstance()->Log($e->getMessage());
                 }
             }
         }
     }
 }
Exemplo n.º 11
0
 /**
  * Loads a project
  *
  * @param string $proj project
  * @return GitPHP_Project project object
  */
 protected function LoadProject($proj)
 {
     if (!$this->fileRead) {
         $this->ReadFile();
     }
     $found = false;
     $owner = null;
     foreach ($this->fileContents as $lineData) {
         if (isset($lineData['project']) && $lineData['project'] == $proj) {
             $projectRoot = GitPHP_Util::AddSlash($this->projectRoot);
             if (is_file($projectRoot . $proj . '/HEAD')) {
                 $found = true;
                 if (isset($lineData['owner'])) {
                     $owner = $lineData['owner'];
                 }
             } else {
                 $this->Log('Invalid project', $projectRoot . $proj);
             }
             break;
         }
     }
     if (!$found) {
         return null;
     }
     $projectObj = new GitPHP_Project($this->projectRoot, $proj);
     $this->ApplyGlobalConfig($projectObj);
     $this->ApplyGitConfig($projectObj);
     if (!empty($owner)) {
         $projectObj->SetOwner($owner);
     }
     if ($this->projectSettings && isset($this->projectSettings[$proj])) {
         $this->ApplyProjectSettings($projectObj, $this->projectSettings[$proj]);
     }
     $this->InjectProjectDependencies($projectObj);
     return $projectObj;
 }
Exemplo n.º 12
0
 /**
  * Class constructor
  *
  * @param string $projectRoot project root
  * @param string $project project
  * @param GitPHP_ProjectLoadStrategy_Interface $strategy load strategy
  */
 public function __construct($projectRoot, $project, GitPHP_ProjectLoadStrategy_Interface $strategy = null)
 {
     $this->projectRoot = GitPHP_Util::AddSlash($projectRoot);
     $this->SetProject($project);
     if ($strategy) {
         $this->SetStrategy($strategy);
     }
 }
Exemplo n.º 13
0
 /**
  * CreateSmarty
  *
  * Instantiates Smarty cache
  *
  * @access private
  */
 private function CreateSmarty()
 {
     if ($this->tpl) {
         return;
     }
     require_once GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('smarty_prefix', 'lib/smarty/libs/')) . 'Smarty.class.php';
     $this->tpl = new Smarty();
     $this->tpl->addPluginsDir(GITPHP_INCLUDEDIR . 'smartyplugins');
     $this->tpl->caching = Smarty::CACHING_LIFETIME_SAVED;
     $servers = GitPHP_Config::GetInstance()->GetValue('memcache', null);
     if (isset($servers) && is_array($servers) && count($servers) > 0) {
         $this->tpl->caching_type = 'memcache';
     }
 }
Exemplo n.º 14
0
 /**
  * LoadData
  *
  * Loads data for this template
  *
  * @access protected
  */
 protected function LoadData()
 {
     $head = $this->project->GetHeadCommit();
     $this->tpl->assign('head', $head);
     $commit = $this->project->GetCommit($this->params['hashbase']);
     $this->tpl->assign('commit', $commit);
     if (!isset($this->params['hash']) && isset($this->params['file'])) {
         $this->params['hash'] = $commit->PathToHash($this->params['file']);
     }
     $blob = $this->project->GetBlob($this->params['hash']);
     if ($this->params['file']) {
         $blob->SetPath($this->params['file']);
     }
     $blob->SetCommit($commit);
     $this->tpl->assign('blob', $blob);
     $blame = $blob->GetBlame();
     $this->tpl->assign('blame', $blob->GetBlame());
     if (isset($this->params['js']) && $this->params['js']) {
         return;
     }
     $this->tpl->assign('tree', $commit->GetTree());
     if (GitPHP_Config::GetInstance()->GetValue('geshi', true)) {
         include_once GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('geshiroot', 'lib/geshi/')) . "geshi.php";
         if (class_exists('GeSHi')) {
             $geshi = new GeSHi("", 'php');
             if ($geshi) {
                 $lang = $geshi->get_language_name_from_extension(substr(strrchr($blob->GetName(), '.'), 1));
                 if (!empty($lang)) {
                     $geshi->enable_classes();
                     $geshi->enable_strict_mode(GESHI_MAYBE);
                     $geshi->set_source($blob->GetData());
                     $geshi->set_language($lang);
                     $geshi->set_header_type(GESHI_HEADER_PRE_TABLE);
                     $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
                     $output = $geshi->parse_code();
                     $bodystart = strpos($output, '<td');
                     $bodyend = strrpos($output, '</tr>');
                     if ($bodystart !== false && $bodyend !== false) {
                         $geshihead = substr($output, 0, $bodystart);
                         $geshifoot = substr($output, $bodyend);
                         $geshibody = substr($output, $bodystart, $bodyend);
                         $this->tpl->assign('geshihead', $geshihead);
                         $this->tpl->assign('geshibody', $geshibody);
                         $this->tpl->assign('geshifoot', $geshifoot);
                         $this->tpl->assign('geshicss', $geshi->get_stylesheet());
                         $this->tpl->assign('geshi', true);
                     }
                 }
             }
         }
     }
 }
Exemplo n.º 15
0
 /**
  * Loads a project
  *
  * @param string $proj project
  * @return GitPHP_Project project object
  */
 protected function LoadProject($proj)
 {
     if (!$this->fileRead) {
         $this->ReadFile();
     }
     $data = null;
     $found = false;
     foreach ($this->fileContents as $projData) {
         if (isset($projData) && $proj == $projData['name']) {
             $data = $projData;
             $found = true;
             break;
         }
     }
     if (!$found) {
         return null;
     }
     if (!(isset($data['type']) && $data['type'] == 'git')) {
         $this->Log('Invalid project', $proj);
         return null;
     }
     if (!(isset($data['public']) && $data['public'] == true)) {
         $this->Log('Private project', $proj);
         return null;
     }
     if (!is_file(GitPHP_Util::AddSlash($this->projectRoot) . $proj . '/HEAD')) {
         $this->Log('Invalid project', $proj);
     }
     $projectObj = new GitPHP_Project($this->projectRoot, $proj);
     $this->ApplyGlobalConfig($projectObj);
     $this->ApplyGitConfig($projectObj);
     if (isset($data['owner']) && !empty($data['owner'])) {
         $projectObj->SetOwner($data['owner']);
     }
     if (isset($data['description']) && !empty($data['description'])) {
         $projectObj->SetDescription($data['description']);
     }
     if ($this->projectSettings && isset($this->projectSettings[$proj])) {
         $this->ApplyProjectSettings($projectObj, $this->projectSettings[$proj]);
     }
     $this->InjectProjectDependencies($projectObj);
     return $projectObj;
 }
Exemplo n.º 16
0
 /**
  * Applies global config settings to a project
  *
  * @param GitPHP_Project $project project
  */
 protected function ApplyGlobalConfig($project)
 {
     if (!$project) {
         return;
     }
     if (!$this->config) {
         return;
     }
     if ($this->config->GetValue('cloneurl')) {
         $project->SetCloneUrl(GitPHP_Util::AddSlash($this->config->GetValue('cloneurl'), false) . $project->GetProject());
     }
     if ($this->config->GetValue('pushurl')) {
         $project->SetPushUrl(GitPHP_Util::AddSlash($this->config->GetValue('pushurl'), false) . $project->GetProject());
     }
     if ($this->config->GetValue('bugpattern')) {
         $project->SetBugPattern($this->config->GetValue('bugpattern'));
     }
     if ($this->config->GetValue('bugurl')) {
         $project->SetBugUrl($this->config->GetValue('bugurl'));
     }
     if ($this->config->HasKey('compat')) {
         $project->SetCompat($this->config->GetValue('compat'));
     }
     if ($this->config->HasKey('uniqueabbrev')) {
         $project->SetUniqueAbbreviation($this->config->GetValue('uniqueabbrev'));
     }
     if ($this->config->GetValue('abbreviateurl')) {
         $project->SetUniqueAbbreviation(true);
     }
 }
Exemplo n.º 17
0
 /**
  * __construct
  *
  * Constructor
  *
  * @access public
  */
 public function __construct()
 {
     $this->dir = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('gittmp'));
     if (empty($this->dir)) {
         $this->dir = GitPHP_TmpDir::SystemTmpDir();
     }
     if (empty($this->dir)) {
         throw new Exception(__('No tmpdir defined'));
     }
     if (file_exists($this->dir)) {
         if (is_dir($this->dir)) {
             if (!is_writeable($this->dir)) {
                 throw new Exception(sprintf(__('Specified tmpdir %1$s is not writable'), $this->dir));
             }
         } else {
             throw new Exception(sprintf(__('Specified tmpdir %1$s is not a directory'), $this->dir));
         }
     } else {
         if (!mkdir($this->dir, 0700)) {
             throw new Exception(sprintf(__('Could not create tmpdir %1$s'), $this->dir));
         }
     }
 }
Exemplo n.º 18
0
 /**
  * LoadData
  *
  * Loads data for this template
  *
  * @access protected
  */
 protected function LoadData()
 {
     $commit = $this->project->GetCommit($this->params['hashbase']);
     $this->tpl->assign('commit', $commit);
     if (!isset($this->params['hash']) && isset($this->params['file'])) {
         $this->params['hash'] = $commit->PathToHash($this->params['file']);
     }
     $blob = $this->project->GetBlob($this->params['hash']);
     if (!empty($this->params['file'])) {
         $blob->SetPath($this->params['file']);
     }
     $blob->SetCommit($commit);
     $this->tpl->assign('blob', $blob);
     if (isset($this->params['plain']) && $this->params['plain']) {
         return;
     }
     $head = $this->project->GetHeadCommit();
     $this->tpl->assign('head', $head);
     $this->tpl->assign('tree', $commit->GetTree());
     if (GitPHP_Config::GetInstance()->GetValue('filemimetype', true)) {
         $mime = $blob->FileMime();
         if ($mime) {
             $mimetype = strtok($mime, '/');
             if ($mimetype == 'image') {
                 $this->tpl->assign('datatag', true);
                 $this->tpl->assign('mime', $mime);
                 $this->tpl->assign('data', base64_encode($blob->GetData()));
                 return;
             }
         }
     }
     if (GitPHP_Config::GetInstance()->GetValue('geshi', true)) {
         include_once GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('geshiroot', 'lib/geshi/')) . "geshi.php";
         if (class_exists('GeSHi')) {
             $geshi = new GeSHi("", 'php');
             if ($geshi) {
                 $lang = $geshi->get_language_name_from_extension(substr(strrchr($blob->GetName(), '.'), 1));
                 if (!empty($lang)) {
                     $geshi->enable_classes();
                     $geshi->enable_strict_mode(GESHI_MAYBE);
                     $geshi->set_source($blob->GetData());
                     $geshi->set_language($lang);
                     $geshi->set_header_type(GESHI_HEADER_PRE_TABLE);
                     $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS);
                     $geshi->set_overall_id('blobData');
                     $this->tpl->assign('geshiout', $geshi->parse_code());
                     $this->tpl->assign('geshicss', $geshi->get_stylesheet());
                     $this->tpl->assign('geshi', true);
                     return;
                 }
             }
         }
     }
     $this->tpl->assign('bloblines', $blob->GetData(true));
 }
Exemplo n.º 19
0
 /**
  * GetPushUrl
  *
  * Gets the push URL for this repository, if specified
  *
  * @access public
  * @return string push url
  */
 public function GetPushUrl()
 {
     if ($this->pushUrl !== null) {
         return $this->pushUrl;
     }
     if ($this->GetConfig()->HasValue('gitphp.pushurl')) {
         return $this->GetConfig()->GetValue('gitphp.pushurl');
     }
     $pushurl = GitPHP_Util::AddSlash(GitPHP_Config::GetInstance()->GetValue('pushurl', ''), false);
     if (!empty($pushurl)) {
         $pushurl .= $this->project;
     }
     return $pushurl;
 }
Exemplo n.º 20
0
 /**
  * Generate a url
  *
  * @param array $params request parameters
  * @param boolean $full true to get full url (include protocol and hostname)
  */
 public function GetUrl($params = array(), $full = false)
 {
     if ($full) {
         $baseurl = $this->fullurl;
     } else {
         $baseurl = $this->baseurl;
     }
     if ($this->cleanurl) {
         if (substr_compare($baseurl, 'index.php', -9) === 0) {
             $baseurl = dirname($baseurl);
         }
         $baseurl = GitPHP_Util::AddSlash($baseurl, false);
     } else {
         if (substr_compare($baseurl, 'index.php', -9) !== 0) {
             $baseurl = GitPHP_Util::AddSlash($baseurl, false);
         }
     }
     if (count($params) < 1) {
         return $baseurl;
     }
     $abbreviate = $this->abbreviate;
     if ($abbreviate && !empty($params['project']) && $params['project'] instanceof GitPHP_Project) {
         if ($params['project']->GetCompat()) {
             $abbreviate = false;
         }
     }
     foreach ($params as $paramname => $paramval) {
         switch ($paramname) {
             case 'hash':
             case 'hashbase':
             case 'hashparent':
             case 'mark':
                 $params[$paramname] = GitPHP_Router::GetHash($paramval, $abbreviate);
                 break;
             case 'tag':
                 $params[$paramname] = GitPHP_Router::GetTag($paramval);
                 break;
             case 'project':
                 $params[$paramname] = GitPHP_Router::GetProject($paramval);
                 break;
         }
     }
     if ($this->cleanurl) {
         if (!empty($params['action'])) {
             switch ($params['action']) {
                 case 'blob':
                 case 'commit':
                 case 'tree':
                 case 'graph':
                 case 'tag':
                     // these actions are plural in clean urls
                     $params['action'] = $params['action'] . 's';
                     break;
             }
         }
         list($queryurl, $exclude) = $this->BuildRoute($params);
         $baseurl .= $queryurl;
         foreach ($exclude as $excludeparam) {
             unset($params[$excludeparam]);
         }
     }
     $querystr = GitPHP_Router::GetQueryString($params);
     if (empty($querystr)) {
         return $baseurl;
     }
     return $baseurl . '?' . $querystr;
 }