/** * Display a file using appropriate highlighting * * @return void */ public function showAction() { include_once 'geshi/geshi.php'; $this->view->project = $this->_project; $config = new USVN_Config_Ini(USVN_CONFIG_FILE, USVN_CONFIG_SECTION); $project_name = str_replace(USVN_URL_SEP, '/', $this->_project->name); $svn_file_path = $this->getRequest()->getParam('file'); $this->view->path = $svn_file_path; $local_file_path = USVN_SVNUtils::getRepositoryPath($config->subversion->path . "/svn/" . $project_name . "/" . $svn_file_path); $file_ext = pathinfo($svn_file_path, PATHINFO_EXTENSION); $revision = $this->getRequest()->getParam('rev'); $file_rev = ''; if (!empty($revision)) { if (is_numeric($revision) && $revision > 0) { $cmd = USVN_SVNUtils::svnCommand("log --non-interactive --revision {$revision} --quiet {$local_file_path}"); $verif = USVN_ConsoleUtils::runCmdCaptureMessageUnsafe($cmd, $return); if (!$return) { $this->view->revision = $revision; $file_rev = '--revision ' . $revision; } } } if (empty($file_rev)) { $cmd = USVN_SVNUtils::svnCommand("info {$local_file_path}"); $infos = USVN_ConsoleUtils::runCmdCaptureMessageUnsafe($cmd, $return); if (preg_match_all('#^([^:]+): (.*)$#m', $infos, $tmp)) { $infos = array(); foreach ($tmp[1] as $k => $v) { $infos[$v] = $tmp[2][$k]; } $this->view->revision = $infos['Last Changed Rev']; if ($revision) { $this->view->message = T_("The requested revision does not exist. Switching to the last changed revision."); } } } $cmd = USVN_SVNUtils::svnCommand("log --non-interactive --quiet {$local_file_path}"); $revs = USVN_ConsoleUtils::runCmdCaptureMessageUnsafe($cmd, $return); if (preg_match_all('#^r([0-9]+) \\|#m', $revs, $tmp)) { $revs = array(); $this->view->prev_revision = NULL; $this->view->next_revision = NULL; foreach ($tmp[1] as $k => $rev) { if ($this->view->prev_revision === NULL && intval($rev) < intval($this->view->revision)) { $this->view->prev_revision = $rev; } if ($rev > $this->view->revision) { $this->view->next_revision = $rev; } $revs[] = $rev; } $this->view->select_revisions = $revs; } $cmd = USVN_SVNUtils::svnCommand("cat --non-interactive {$file_rev} {$local_file_path}"); $source = USVN_ConsoleUtils::runCmdCaptureMessageUnsafe($cmd, $return); if ($return) { throw new USVN_Exception(T_("Can't read from subversion repository.\nCommand:\n%s\n\nError:\n%s"), $cmd, $message); } else { $this->view->color_view = $this->getRequest()->getParam('color'); $this->view->diff_view = $this->getRequest()->getParam('diff'); $this->view->diff_revision = $this->getRequest()->getParam('drev'); if ($this->view->diff_revision >= $this->view->revision) { $this->view->diff_revision = $this->view->prev_revision; } if ($this->getRequest()->getParam('post') === NULL) { $this->view->color_view = 1; } $geshi = new Geshi(); $lang_name = $geshi->get_language_name_from_extension($file_ext); $this->view->language = $lang_name; $geshi->set_language($this->view->color_view ? $lang_name : NULL, true); $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS); if ($this->view->diff_view && ($this->view->diff_revision || $this->view->prev_revision)) { $d_revs = ($this->view->diff_revision ? $this->view->diff_revision : $this->view->prev_revision) . ':' . $this->view->revision; $cmd = USVN_SVNUtils::svnCommand("diff --non-interactive --revision {$d_revs} {$local_file_path}"); $diff = USVN_ConsoleUtils::runCmdCaptureMessageUnsafe($cmd, $return); if ($return) { $this->view->message = T_('The requested diff revision does not exist.'); } else { $new_source = array(); $source = explode("\n", $source); array_pop($source); // Skip the final "\n" $diff = explode("\n", $diff); array_pop($diff); // Skip the final "\n" $source_line = NULL; $count_line = 0; $diff_lines = array(); while (($line = array_shift($diff)) !== NULL) { $line = trim($line); if (preg_match('#^@@ \\-[0-9,]+ \\+([0-9]+),[0-9]+ @@$#', $line, $tmp)) { if ($source_line === NULL) { $source_line = 1; } while (intval($source_line) < intval($tmp[1])) { array_push($new_source, array_shift($source)); $source_line++; $count_line++; } continue; } if ($source_line !== NULL) { $diff_char = substr($line, 0, 1); if ($diff_char == '\\') { continue; } elseif ($diff_char == '-') { array_push($new_source, substr($line, 1)); $diff_lines[$count_line] = '-'; } else { if ($diff_char == '+') { $diff_lines[$count_line] = '+'; } array_push($new_source, array_shift($source)); $source_line++; } $count_line++; } } if (count($source)) { $new_source = array_merge($new_source, $source); } $source = implode("\n", $new_source); unset($new_source); $this->view->diff_lines = $diff_lines; } } $geshi->set_source($source); $geshi->set_header_type(GESHI_HEADER_DIV); $this->view->highlighted_source = $geshi->parse_code(); if ($this->view->diff_view) { if (preg_match('#^<div ([^>]*)><ol>(.*)</ol></div>(\\s*)$#s', $this->view->highlighted_source, $tmp)) { $this->view->diff_div = $tmp[1]; $this->view->highlighted_source = $tmp[2]; } } } }