Start adding basic login infrastructure (still needs styling)
Start adding basic login infrastructure (still needs styling)

/* /*
* gitphp.css * gitphp.css
* *
* GitPHP layout functional stylesheet * GitPHP layout functional stylesheet
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2006-2011 Christopher Han * @copyright Copyright (c) 2006-2011 Christopher Han
* @package GitPHP * @package GitPHP
*/ */
   
   
/* /*
* Base styles * Base styles
*/ */
.monospace { .monospace {
font-family: monospace; font-family: monospace;
} }
   
table { table {
border-spacing: 0px; border-spacing: 0px;
} }
   
   
/* /*
* Title bar * Title bar
* (main header with commit message) * (main header with commit message)
*/ */
div.title a.title { div.title a.title {
display: block; display: block;
} }
   
/* /*
* Project list * Project list
*/ */
.projectList .projectRow .projectOwner { .projectList .projectRow .projectOwner {
white-space: nowrap; white-space: nowrap;
} }
   
.projectList .projectRow .projectAge { .projectList .projectRow .projectAge {
white-space: nowrap; white-space: nowrap;
} }
   
.projectList .projectRow .link { .projectList .projectRow .link {
white-space: nowrap; white-space: nowrap;
} }
   
   
/* /*
* Full log view * Full log view
*/ */
div.log_body { div.log_body {
padding: 8px 8px 8px 150px; padding: 8px 8px 8px 150px;
} }
span.age { span.age {
position: relative; position: relative;
float: left; float: left;
width: 142px; width: 142px;
} }
div.log_link { div.log_link {
margin: -5px 0px; margin: -5px 0px;
padding: 0px 8px; padding: 0px 8px;
position: relative; position: relative;
float: left; float: left;
width: 136px; width: 136px;
} }
   
   
/* /*
* Diff display * Diff display
*/ */
.pre { .pre {
white-space: pre; white-space: pre;
} }
   
   
/* /*
* Search box * Search box
*/ */
div.search { div.search {
margin: 4px 8px; margin: 4px 8px;
position: absolute; position: absolute;
top: 56px; top: 56px;
right: 12px right: 12px
} }
   
   
/* /*
* Badges * Badges
*/ */
a.rss_logo { a.rss_logo {
float: right; float: right;
} }
   
   
/* /*
* Language selector * Language selector
*/ */
div.lang_select { div.lang_select {
width: 300px; width: 300px;
float: right; float: right;
text-align: right; text-align: right;
padding-right: 10px; padding-right: 10px;
} }
   
   
/* /*
* Blob/blame display * Blob/blame display
*/ */
table.code td.num { table.code td.num {
white-space: pre; white-space: pre;
} }
   
table.code td.codeline { table.code td.codeline {
white-space: pre; white-space: pre;
} }
   
table.code td.author, table.code td.date { table.code td.author, table.code td.date {
white-space: nowrap; white-space: nowrap;
} }
   
   
/* /*
* Blob view * Blob view
*/ */
td#blameData { td#blameData {
white-space: nowrap; white-space: nowrap;
} }
   
/* /*
* File search view * File search view
*/ */
span.matchline { span.matchline {
white-space: pre; white-space: pre;
} }
   
/* /*
* side-by-side-diff diff * side-by-side-diff diff
*/ */
table.diffTable { table.diffTable {
width: 100%; width: 100%;
white-space: pre-wrap; white-space: pre-wrap;
} }
   
table.diffTable td { table.diffTable td {
width: 50%; width: 50%;
} }
   
/* /*
* side-by-side commitdiff * side-by-side commitdiff
*/ */
div.commitDiffSBS div.SBSTOC .showAll div.commitDiffSBS div.SBSTOC .showAll
{ {
display: none; display: none;
} }
   
  /*
  * login link
  */
  div.login {
  float: right;
  }
   
   
/* /*
* Geshi styles * Geshi styles
* These are generated by Geshi, don't change them * These are generated by Geshi, don't change them
*/ */
#blobData .de1, #blobData .de2 { #blobData .de1, #blobData .de2 {
font: normal normal 1em/1.2em monospace; font: normal normal 1em/1.2em monospace;
margin: 0; margin: 0;
padding: 0; padding: 0;
background: none; background: none;
vertical-align: top; vertical-align: top;
} }
   
#blobData { #blobData {
font-family: monospace; font-family: monospace;
} }
   
#blobData li, #blobData .li1 { #blobData li, #blobData .li1 {
font-weight: normal; font-weight: normal;
vertical-align: top; vertical-align: top;
} }
   
<?php <?php
/** /**
* Base class that all controllers extend * Base class that all controllers extend
* *
* @author Christopher Han <xiphux@gmail.com * @author Christopher Han <xiphux@gmail.com
* @copyright Copyright (c) 2010 Christopher Han * @copyright Copyright (c) 2010 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Controller * @subpackage Controller
*/ */
abstract class GitPHP_ControllerBase abstract class GitPHP_ControllerBase
{ {
   
/** /**
* Config handler instance * Config handler instance
* *
* @var GitPHP_Config * @var GitPHP_Config
*/ */
protected $config; protected $config;
   
/** /**
* User list instance * User list instance
* *
* @var GitPHP_UserList * @var GitPHP_UserList
*/ */
protected $userList; protected $userList;
   
/** /**
* Resource handler instance * Resource handler instance
* *
* @var GitPHP_Resource * @var GitPHP_Resource
*/ */
protected $resource; protected $resource;
   
/** /**
* Smarty instance * Smarty instance
* *
* @var Smarty * @var Smarty
*/ */
protected $tpl; protected $tpl;
   
/** /**
* Project list * Project list
* *
* @var GitPHP_ProjectListBase * @var GitPHP_ProjectListBase
*/ */
protected $projectList; protected $projectList;
   
/** /**
* Current project * Current project
* *
* @var GitPHP_Project * @var GitPHP_Project
*/ */
protected $project; protected $project;
   
/** /**
* Flag if this is a multi project controller * Flag if this is a multi project controller
* *
* @var boolean * @var boolean
*/ */
protected $multiProject; protected $multiProject;
   
/** /**
* Parameters * Parameters
* *
* @var array * @var array
*/ */
protected $params = array(); protected $params = array();
   
/** /**
* HTTP Headers * HTTP Headers
* *
* @var string[] * @var string[]
*/ */
protected $headers = array(); protected $headers = array();
   
/** /**
* Flag to preserve whitespace in output (for non-html output) * Flag to preserve whitespace in output (for non-html output)
* *
* @var boolean * @var boolean
*/ */
protected $preserveWhitespace = false; protected $preserveWhitespace = false;
   
/** /**
* Logger instance * Logger instance
* *
* @var GitPHP_DebugLog * @var GitPHP_DebugLog
*/ */
protected $log; protected $log;
   
/** /**
* Git executable instance * Git executable instance
* *
* @var GitPHP_GitExe * @var GitPHP_GitExe
*/ */
protected $exe; protected $exe;
   
/** /**
* Url router instance * Url router instance
* *
* @var GitPHP_Router * @var GitPHP_Router
*/ */
protected $router; protected $router;
   
/** /**
* Initialize controller * Initialize controller
*/ */
public function Initialize() public function Initialize()
{ {
$this->InitializeConfig(); $this->InitializeConfig();
   
$this->InitializeResource(); $this->InitializeResource();
   
$this->InitializeUserList(); $this->InitializeUserList();
   
$this->EnableLogging(); $this->EnableLogging();
   
$this->InitializeGitExe(); $this->InitializeGitExe();
   
$this->InitializeProjectList(); $this->InitializeProjectList();
   
$this->InitializeSmarty(); $this->InitializeSmarty();
   
if ($this->multiProject) { if ($this->multiProject) {
$this->projectList->LoadProjects(); $this->projectList->LoadProjects();
} }
   
if (!empty($this->params['project'])) { if (!empty($this->params['project'])) {
$project = $this->projectList->GetProject($this->params['project']); $project = $this->projectList->GetProject($this->params['project']);
if (!$project) { if (!$project) {
throw new GitPHP_InvalidProjectParameterException($this->params['project']); throw new GitPHP_InvalidProjectParameterException($this->params['project']);
} }
$this->project = $project->GetProject(); $this->project = $project->GetProject();
} }
   
if (!($this->project || $this->multiProject)) { if (!($this->project || $this->multiProject)) {
throw new GitPHP_MissingProjectParameterException(); throw new GitPHP_MissingProjectParameterException();
} }
} }
   
/** /**
* Initialize config * Initialize config
*/ */
protected function InitializeConfig() protected function InitializeConfig()
{ {
$this->config = new GitPHP_Config(); $this->config = new GitPHP_Config();
$this->config->LoadConfig(GITPHP_CONFIGDIR . 'gitphp.conf.php'); $this->config->LoadConfig(GITPHP_CONFIGDIR . 'gitphp.conf.php');
} }
   
/** /**
* Initialize resource manager * Initialize resource manager
*/ */
protected function InitializeResource() protected function InitializeResource()
{ {
$locale = null; $locale = null;
   
$baseurl = GitPHP_Util::BaseUrl(); $baseurl = GitPHP_Util::BaseUrl();
   
if (!empty($this->params['lang'])) { if (!empty($this->params['lang'])) {
/* /*
* User picked something * User picked something
*/ */
setcookie(GitPHP_Resource::LocaleCookie, $this->params['lang'], time()+GitPHP_Resource::LocaleCookieLifetime, $baseurl); setcookie(GitPHP_Resource::LocaleCookie, $this->params['lang'], time()+GitPHP_Resource::LocaleCookieLifetime, $baseurl);
$locale = $this->params['lang']; $locale = $this->params['lang'];
} else if (!empty($_COOKIE[GitPHP_Resource::LocaleCookie])) { } else if (!empty($_COOKIE[GitPHP_Resource::LocaleCookie])) {
/** /**
* Returning user with a preference * Returning user with a preference
*/ */
$locale = $_COOKIE[GITPHP_Resource::LocaleCookie]; $locale = $_COOKIE[GITPHP_Resource::LocaleCookie];
} else { } else {
/* /*
* User's first time here, try by HTTP_ACCEPT_LANGUAGE * User's first time here, try by HTTP_ACCEPT_LANGUAGE
*/ */
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$httpAcceptLang = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); $httpAcceptLang = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$locale = GitPHP_Resource::FindPreferredLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']); $locale = GitPHP_Resource::FindPreferredLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']);
if (!empty($locale)) { if (!empty($locale)) {
setcookie(GitPHP_Resource::LocaleCookie, $locale, time()+GitPHP_Resource::LocaleCookieLifetime, $baseurl); setcookie(GitPHP_Resource::LocaleCookie, $locale, time()+GitPHP_Resource::LocaleCookieLifetime, $baseurl);
} }
} }
} }
   
if (empty($locale) && $this->config) { if (empty($locale) && $this->config) {
/* /*
* No preference, fall back on setting * No preference, fall back on setting
*/ */
$locale = $this->config->GetValue('locale'); $locale = $this->config->GetValue('locale');
} }
   
if (!empty($locale) && ($locale != 'en_US')) { if (!empty($locale) && ($locale != 'en_US')) {
try { try {
$this->resource = new GitPHP_Resource($locale); $this->resource = new GitPHP_Resource($locale);
} catch (Exception $e) { } catch (Exception $e) {
} }
} }
} }
   
/** /**
* Initialize user list * Initialize user list
*/ */
public function InitializeUserList() public function InitializeUserList()
{ {
$this->userList = new GitPHP_UserList(); $this->userList = new GitPHP_UserList();
$this->userList->LoadUsers(GITPHP_CONFIGDIR . 'users.conf.php'); $this->userList->LoadUsers(GITPHP_CONFIGDIR . 'users.conf.php');
  if ($this->userList->GetCount() > 0) {
  if (!isset($_SESSION))
  session_start();
  }
} }
   
/** /**
* Initialize executable * Initialize executable
* *
* @param boolean $validate whether the exe should be validated * @param boolean $validate whether the exe should be validated
*/ */
protected function InitializeGitExe($validate = true) protected function InitializeGitExe($validate = true)
{ {
$this->exe = new GitPHP_GitExe($this->config->GetValue('gitbin')); $this->exe = new GitPHP_GitExe($this->config->GetValue('gitbin'));
if ($this->log) if ($this->log)
$this->exe->AddObserver($this->log); $this->exe->AddObserver($this->log);
if ($validate && !$this->exe->Valid()) { if ($validate && !$this->exe->Valid()) {
throw new GitPHP_InvalidGitExecutableException($this->exe->GetBinary()); throw new GitPHP_InvalidGitExecutableException($this->exe->GetBinary());
} }
} }
   
/** /**
* Initialize project list * Initialize project list
*/ */
protected function InitializeProjectList() protected function InitializeProjectList()
{ {
if (file_exists(GITPHP_CONFIGDIR . 'projects.conf.php')) { if (file_exists(GITPHP_CONFIGDIR . 'projects.conf.php')) {
$this->projectList = GitPHP_ProjectList::Instantiate($this->config, GITPHP_CONFIGDIR . 'projects.conf.php', false); $this->projectList = GitPHP_ProjectList::Instantiate($this->config, GITPHP_CONFIGDIR . 'projects.conf.php', false);
} else { } else {
$this->projectList = GitPHP_ProjectList::Instantiate($this->config, GITPHP_CONFIGDIR . 'gitphp.conf.php', true); $this->projectList = GitPHP_ProjectList::Instantiate($this->config, GITPHP_CONFIGDIR . 'gitphp.conf.php', true);
} }
   
$this->projectList->SetMemoryCache(new GitPHP_MemoryCache($this->config->GetValue('objectmemory'))); $this->projectList->SetMemoryCache(new GitPHP_MemoryCache($this->config->GetValue('objectmemory')));
if ($this->config->GetValue('objectcache')) { if ($this->config->GetValue('objectcache')) {
$strategy = null; $strategy = null;
$servers = $this->config->GetValue('memcache'); $servers = $this->config->GetValue('memcache');
if ($servers) { if ($servers) {
if (class_exists('Memcached')) { if (class_exists('Memcached')) {
$strategy = new GitPHP_Cache_Memcached($servers); $strategy = new GitPHP_Cache_Memcached($servers);
} else if (class_exists('Memcache')) { } else if (class_exists('Memcache')) {
$strategy = new GitPHP_Cache_Memcache($servers); $strategy = new GitPHP_Cache_Memcache($servers);
} else { } else {
throw new GitPHP_MissingMemcacheException(); throw new GitPHP_MissingMemcacheException();
} }
} else { } else {
$strategy = new GitPHP_Cache_File(GITPHP_CACHEDIR . 'objects', $this->config->GetValue('objectcachecompress')); $strategy = new GitPHP_Cache_File(GITPHP_CACHEDIR . 'objects', $this->config->GetValue('objectcachecompress'));
} }
$cache = new GitPHP_Cache($strategy); $cache = new GitPHP_Cache($strategy);
$cache->SetLifetime($this->config->GetValue('objectcachelifetime')); $cache->SetLifetime($this->config->GetValue('objectcachelifetime'));
$this->projectList->SetCache($cache); $this->projectList->SetCache($cache);
} }
   
$this->projectList->SetExe($this->exe); $this->projectList->SetExe($this->exe);
   
if ($this->log) if ($this->log)
$this->projectList->AddObserver($this->log); $this->projectList->AddObserver($this->log);
   
} }
   
/** /**
* Initialize smarty * Initialize smarty
*/ */
protected function InitializeSmarty() protected function InitializeSmarty()
{ {
require_once(GITPHP_SMARTYDIR . 'Smarty.class.php'); require_once(GITPHP_SMARTYDIR . 'Smarty.class.php');
$this->tpl = new Smarty; $this->tpl = new Smarty;
$this->tpl->error_reporting = E_ALL & ~E_NOTICE; $this->tpl->error_reporting = E_ALL & ~E_NOTICE;
$this->tpl->merge_compiled_includes = true; $this->tpl->merge_compiled_includes = true;
$this->tpl->addPluginsDir(GITPHP_INCLUDEDIR . 'smartyplugins'); $this->tpl->addPluginsDir(GITPHP_INCLUDEDIR . 'smartyplugins');
   
if ($this->config->GetValue('cache')) { if ($this->config->GetValue('cache')) {
$cacheDir = GITPHP_CACHEDIR . 'templates'; $cacheDir = GITPHP_CACHEDIR . 'templates';
   
if (file_exists($cacheDir)) { if (file_exists($cacheDir)) {
if (!is_dir($cacheDir)) { if (!is_dir($cacheDir)) {
throw new Exception($cacheDir . ' exists but is not a directory'); throw new Exception($cacheDir . ' exists but is not a directory');
} else if (!is_writable($cacheDir)) { } else if (!is_writable($cacheDir)) {
throw new Exception($cacheDir . ' is not writable'); throw new Exception($cacheDir . ' is not writable');
} }
} else { } else {
if (!mkdir($cacheDir, 0777)) if (!mkdir($cacheDir, 0777))
throw new Exception($cacheDir . ' could not be created'); throw new Exception($cacheDir . ' could not be created');
chmod($cacheDir, 0777); chmod($cacheDir, 0777);
} }
$this->tpl->setCacheDir($cacheDir); $this->tpl->setCacheDir($cacheDir);
   
$this->tpl->caching = Smarty::CACHING_LIFETIME_SAVED; $this->tpl->caching = Smarty::CACHING_LIFETIME_SAVED;
if ($this->config->HasKey('cachelifetime')) { if ($this->config->HasKey('cachelifetime')) {
$this->tpl->cache_lifetime = $this->config->GetValue('cachelifetime'); $this->tpl->cache_lifetime = $this->config->GetValue('cachelifetime');
} }
   
$servers = $this->config->GetValue('memcache'); $servers = $this->config->GetValue('memcache');
if (isset($servers) && is_array($servers) && (count($servers) > 0)) { if (isset($servers) && is_array($servers) && (count($servers) > 0)) {
$this->tpl->registerCacheResource('memcache', new GitPHP_CacheResource_Memcache($servers)); $this->tpl->registerCacheResource('memcache', new GitPHP_CacheResource_Memcache($servers));
$this->tpl->caching_type = 'memcache'; $this->tpl->caching_type = 'memcache';
} }
   
} }
   
} }
   
/** /**
* Set router instance * Set router instance
* *
* @param GitPHP_Router $router router * @param GitPHP_Router $router router
*/ */
public function SetRouter($router) public function SetRouter($router)
{ {
$this->router = $router; $this->router = $router;
} }
   
/** /**
* Get config instance * Get config instance
* *
* @return GitPHP_Config * @return GitPHP_Config
*/ */
public function GetConfig() public function GetConfig()
{ {
return $this->config; return $this->config;
} }
   
/** /**
* Get log instance * Get log instance
* *
* @return GitPHP_DebugLog * @return GitPHP_DebugLog
*/ */
public function GetLog() public function GetLog()
{ {
return $this->log; return $this->log;
} }
   
/** /**
* Enable logging * Enable logging
*/ */
public function EnableLogging() public function EnableLogging()
{ {
if ($this->log) if ($this->log)
return; return;
   
$debug = $this->config->GetValue('debug'); $debug = $this->config->GetValue('debug');
if ($debug) { if ($debug) {
$this->log = new GitPHP_DebugLog($debug, $this->config->GetValue('benchmark')); $this->log = new GitPHP_DebugLog($debug, $this->config->GetValue('benchmark'));
$this->log->SetStartTime(GITPHP_START_TIME); $this->log->SetStartTime(GITPHP_START_TIME);
$this->log->SetStartMemory(GITPHP_START_MEM); $this->log->SetStartMemory(GITPHP_START_MEM);
if ($this->exe) if ($this->exe)
$this->exe->AddObserver($this->log); $this->exe->AddObserver($this->log);
if ($this->projectList) if ($this->projectList)
$this->projectList->AddObserver($this->log); $this->projectList->AddObserver($this->log);
} }
} }
   
/** /**
* Disable logging * Disable logging
*/ */
protected function DisableLogging() protected function DisableLogging()
{ {
if (!$this->log) if (!$this->log)
return; return;
   
$this->projectList->RemoveObserver($this->log); $this->projectList->RemoveObserver($this->log);
$this->exe->RemoveObserver($this->log); $this->exe->RemoveObserver($this->log);
   
$this->log->SetEnabled(false); $this->log->SetEnabled(false);
   
$this->log = null; $this->log = null;
} }
   
/** /**
* Gets the project for this controller * Gets the project for this controller
* *
* @return GitPHP_Project|null project * @return GitPHP_Project|null project
*/ */
public function GetProject() public function GetProject()
{ {
if ($this->project) if ($this->project)
return $this->projectList->GetProject($this->project); return $this->projectList->GetProject($this->project);
return null; return null;
} }
   
/** /**
* Gets the template for this controller * Gets the template for this controller
* *
* @return string template filename * @return string template filename
*/ */
protected abstract function GetTemplate(); protected abstract function GetTemplate();
   
/** /**
* Gets the cache key for this controller * Gets the cache key for this controller
* *
* @return string cache key * @return string cache key
*/ */
protected abstract function GetCacheKey(); protected abstract function GetCacheKey();
   
/** /**
* Get the prefix for all cache keys * Get the prefix for all cache keys
* *
* @param boolean $projectKeys include project-specific key pieces * @param boolean $projectKeys include project-specific key pieces
* @return string cache key prefix * @return string cache key prefix
*/ */
private function GetCacheKeyPrefix($projectKeys = true) private function GetCacheKeyPrefix($projectKeys = true)
{ {
if ($this->resource) if ($this->resource)
$cacheKeyPrefix = $this->resource->GetLocale(); $cacheKeyPrefix = $this->resource->GetLocale();
else else
$cacheKeyPrefix = 'en_US'; $cacheKeyPrefix = 'en_US';
   
if ($this->projectList) { if ($this->projectList) {
$cacheKeyPrefix .= '|' . sha1(serialize($this->projectList->GetProjectListConfig())) . '|' . sha1(serialize($this->projectList->GetProjectSettings())); $cacheKeyPrefix .= '|' . sha1(serialize($this->projectList->GetProjectListConfig())) . '|' . sha1(serialize($this->projectList->GetProjectSettings()));
} }
if ($this->project && $projectKeys) { if ($this->project && $projectKeys) {
$cacheKeyPrefix .= '|' . sha1($this->project); $cacheKeyPrefix .= '|' . sha1($this->project);
} }
return $cacheKeyPrefix; return $cacheKeyPrefix;
} }
   
/** /**
* Get the full cache key * Get the full cache key
* *
* @return string full cache key * @return string full cache key
*/ */
protected function GetFullCacheKey() protected function GetFullCacheKey()
{ {
$cacheKey = $this->GetCacheKeyPrefix(); $cacheKey = $this->GetCacheKeyPrefix();
   
$subCacheKey = $this->GetCacheKey(); $subCacheKey = $this->GetCacheKey();
   
if (!empty($subCacheKey)) if (!empty($subCacheKey))
$cacheKey .= '|' . $subCacheKey; $cacheKey .= '|' . $subCacheKey;
   
if (strlen($cacheKey) > 100) { if (strlen($cacheKey) > 100) {
$cacheKey = sha1($cacheKey); $cacheKey = sha1($cacheKey);
} }
   
return $cacheKey; return $cacheKey;
} }
   
/** /**
* Gets the name of this controller's action * Gets the name of this controller's action
* *
* @param boolean $local true if caller wants the localized action name * @param boolean $local true if caller wants the localized action name
* @return string action name * @return string action name
*/ */
public abstract function GetName($local = false); public abstract function GetName($local = false);
   
/** /**
* Set a parameter * Set a parameter
* *
* @param string $key key to set * @param string $key key to set
* @param mixed $value value to set * @param mixed $value value to set
*/ */
public function SetParam($key, $value) public function SetParam($key, $value)
{ {
if (empty($key)) if (empty($key))
return; return;
   
if (empty($value)) if (empty($value))
unset($this->params[$key]); unset($this->params[$key]);
   
if (is_string($value)) if (is_string($value))
$value = str_replace(chr(0), '', $value); $value = str_replace(chr(0), '', $value);
   
$this->params[$key] = $value; $this->params[$key] = $value;
} }
   
/** /**
* Loads headers for this template * Loads headers for this template
*/ */
protected function LoadHeaders() protected function LoadHeaders()
{ {
$this->headers[] = 'Content-Type: text/html; charset=UTF-8'; $this->headers[] = 'Content-Type: text/html; charset=UTF-8';
} }
   
/** /**
* Loads data for this template * Loads data for this template
*/ */
protected abstract function LoadData(); protected abstract function LoadData();
   
/** /**
* Loads common data used by all templates * Loads common data used by all templates
*/ */
private function LoadCommonData() private function LoadCommonData()
{ {
global $gitphp_version, $gitphp_appstring; global $gitphp_version, $gitphp_appstring;
   
$this->tpl->assign('version', $gitphp_version); $this->tpl->assign('version', $gitphp_version);
   
$stylesheet = $this->config->GetValue('stylesheet'); $stylesheet = $this->config->GetValue('stylesheet');
if ($stylesheet == 'gitphp.css') { if ($stylesheet == 'gitphp.css') {
// backwards compatibility // backwards compatibility
$stylesheet = 'gitphpskin.css'; $stylesheet = 'gitphpskin.css';
} }
$this->tpl->assign('stylesheet', preg_replace('/\.css$/', '', $stylesheet)); $this->tpl->assign('stylesheet', preg_replace('/\.css$/', '', $stylesheet));
   
$this->tpl->assign('javascript', $this->config->GetValue('javascript')); $this->tpl->assign('javascript', $this->config->GetValue('javascript'));
$this->tpl->assign('googlejs', $this->config->GetValue('googlejs')); $this->tpl->assign('googlejs', $this->config->GetValue('googlejs'));
if ($this->config->HasKey('title')) { if ($this->config->HasKey('title')) {
$this->tpl->assign('pagetitle', $this->config->GetValue('title')); $this->tpl->assign('pagetitle', $this->config->GetValue('title'));
} else { } else {
$this->tpl->assign('pagetitle', $gitphp_appstring); $this->tpl->assign('pagetitle', $gitphp_appstring);
} }
if ($this->config->HasKey('homelink')) { if ($this->config->HasKey('homelink')) {
$this->tpl->assign('homelink', $this->config->GetValue('homelink')); $this->tpl->assign('homelink', $this->config->GetValue('homelink'));
} else { } else {
if ($this->resource) if ($this->resource)
$this->tpl->assign('homelink', $this->resource->translate('projects')); $this->tpl->assign('homelink', $this->resource->translate('projects'));
else else
$this->tpl->assign('homelink', 'projects'); $this->tpl->assign('homelink', 'projects');
} }
$this->tpl->assign('action', $this->GetName()); $this->tpl->assign('action', $this->GetName());
$this->tpl->assign('actionlocal', $this->GetName(true)); $this->tpl->assign('actionlocal', $this->GetName(true));
if ($this->project) if ($this->project)
$this->tpl->assign('project', $this->GetProject()); $this->tpl->assign('project', $this->GetProject());
if ($this->config->GetValue('search')) if ($this->config->GetValue('search'))
$this->tpl->assign('enablesearch', true); $this->tpl->assign('enablesearch', true);
if ($this->config->GetValue('filesearch')) if ($this->config->GetValue('filesearch'))
$this->tpl->assign('filesearch', true); $this->tpl->assign('filesearch', true);
if (isset($this->params['search'])) if (isset($this->params['search']))
$this->tpl->assign('search', $this->params['search']); $this->tpl->assign('search', $this->params['search']);
if (isset($this->params['searchtype'])) if (isset($this->params['searchtype']))
$this->tpl->assign('searchtype', $this->params['searchtype']); $this->tpl->assign('searchtype', $this->params['searchtype']);
if ($this->resource) { if ($this->resource) {
$this->tpl->assign('currentlocale', $this->resource->GetLocale()); $this->tpl->assign('currentlocale', $this->resource->GetLocale());
$this->tpl->assign('currentprimarylocale', $this->resource->GetPrimaryLocale()); $this->tpl->assign('currentprimarylocale', $this->resource->GetPrimaryLocale());
$this->tpl->assign('resource', $this->resource); $this->tpl->assign('resource', $this->resource);
} else { } else {
$this->tpl->assign('currentlocale', 'en_US'); $this->tpl->assign('currentlocale', 'en_US');
$this->tpl->assign('currentprimarylocale', 'en'); $this->tpl->assign('currentprimarylocale', 'en');
} }
$this->tpl->assign('supportedlocales', GitPHP_Resource::SupportedLocales(true)); $this->tpl->assign('supportedlocales', GitPHP_Resource::SupportedLocales(true));
if ($this->config->GetValue('graphs')) if ($this->config->GetValue('graphs'))
$this->tpl->assign('enablegraphs', true); $this->tpl->assign('enablegraphs', true);
   
$this->tpl->assign('baseurl', GitPHP_Util::BaseUrl()); $this->tpl->assign('baseurl', GitPHP_Util::BaseUrl());
   
$requesturl = $_SERVER['REQUEST_URI']; $requesturl = $_SERVER['REQUEST_URI'];
$querypos = strpos($requesturl, '?'); $querypos = strpos($requesturl, '?');
if ($querypos !== false) if ($querypos !== false)
$requesturl = substr($requesturl, 0, $querypos); $requesturl = substr($requesturl, 0, $querypos);
$this->tpl->assign('requesturl', $requesturl); $this->tpl->assign('requesturl', $requesturl);
if ($this->router) { if ($this->router) {
$this->router->SetCleanUrl($this->config->GetValue('cleanurl') ? true : false); $this->router->SetCleanUrl($this->config->GetValue('cleanurl') ? true : false);
$this->router->SetAbbreviate($this->config->GetValue('abbreviateurl') ? true : false); $this->router->SetAbbreviate($this->config->GetValue('abbreviateurl') ? true : false);
if ($this->config->HasKey('self')) { if ($this->config->HasKey('self')) {
$this->router->SetBaseUrl($this->config->GetValue('self')); $this->router->SetBaseUrl($this->config->GetValue('self'));
} }
$this->tpl->assign('router', $this->router); $this->tpl->assign('router', $this->router);
} }
   
$getvars = explode('&', $_SERVER['QUERY_STRING']); $getvars = explode('&', $_SERVER['QUERY_STRING']);
$getvarsmapped = array(); $getvarsmapped = array();
foreach ($getvars as $varstr) { foreach ($getvars as $varstr) {
$eqpos = strpos($varstr, '='); $eqpos = strpos($varstr, '=');
if ($eqpos > 0) { if ($eqpos > 0) {
$var = substr($varstr, 0, $eqpos); $var = substr($varstr, 0, $eqpos);
$val = substr($varstr, $eqpos + 1); $val = substr($varstr, $eqpos + 1);
if (!(empty($var) || empty($val) || ($var == 'q'))) { if (!(empty($var) || empty($val) || ($var == 'q'))) {
$getvarsmapped[$var] = urldecode($val); $getvarsmapped[$var] = urldecode($val);
} }
} }
} }
$this->tpl->assign('requestvars', $getvarsmapped); $this->tpl->assign('requestvars', $getvarsmapped);
   
$this->tpl->assign('snapshotformats', GitPHP_Archive::SupportedFormats()); $this->tpl->assign('snapshotformats', GitPHP_Archive::SupportedFormats());
   
  if ($this->userList && ($this->userList->GetCount() > 0)) {
  $this->tpl->assign('loginenabled', true);
  if (!empty($_SESSION['gitphpuser'])) {
  $user = $this->userList->GetUser($_SESSION['gitphpuser']);
  if ($user) {
  $this->tpl->assign('loggedinuser', $user->GetUsername());
  }
  }
  }
} }
   
/** /**
* Renders any special headers * Renders any special headers
*/ */
public function RenderHeaders() public function RenderHeaders()
{ {
$this->LoadHeaders(); $this->LoadHeaders();
   
if (count($this->headers) > 0) { if (count($this->headers) > 0) {
$hascontenttype = false; $hascontenttype = false;
foreach ($this->headers as $hdr) { foreach ($this->headers as $hdr) {
if (empty($hdr)) if (empty($hdr))
continue; continue;
   
if (strncmp($hdr, 'Content-Type:', 13) === 0) { if (strncmp($hdr, 'Content-Type:', 13) === 0) {
if ($hascontenttype) if ($hascontenttype)
throw new Exception('Duplicate Content-Type header'); throw new Exception('Duplicate Content-Type header');
$hascontenttype = true; $hascontenttype = true;
} }
header($hdr); header($hdr);
} }
} }
} }
   
/** /**
* Renders the output * Renders the output
*/ */
public function Render() public function Render()
{ {
if (($this->config->GetValue('cache') == true) && ($this->config->GetValue('cacheexpire') === true)) if (($this->config->GetValue('cache') == true) && ($this->config->GetValue('cacheexpire') === true))
$this->CacheExpire(); $this->CacheExpire();
   
if (!$this->tpl->isCached($this->GetTemplate(), $this->GetFullCacheKey())) { if (!$this->tpl->isCached($this->GetTemplate(), $this->GetFullCacheKey())) {
$this->tpl->clearAllAssign(); $this->tpl->clearAllAssign();
if ($this->log && $this->log->GetBenchmark()) if ($this->log && $this->log->GetBenchmark())
$this->log->Log("Data load begin"); $this->log->Log("Data load begin");
$this->LoadCommonData(); $this->LoadCommonData();
$this->LoadData(); $this->LoadData();
if ($this->log && $this->log->GetBenchmark()) if ($this->log && $this->log->GetBenchmark())
$this->log->Log("Data load end"); $this->log->Log("Data load end");
} }
   
if (!$this->preserveWhitespace) { if (!$this->preserveWhitespace) {
//$this->tpl->loadFilter('output', 'trimwhitespace'); //$this->tpl->loadFilter('output', 'trimwhitespace');
} }
   
if ($this->log && $this->log->GetBenchmark()) if ($this->log && $this->log->GetBenchmark())
$this->log->Log("Smarty render begin"); $this->log->Log("Smarty render begin");
$this->tpl->display($this->GetTemplate(), $this->GetFullCacheKey()); $this->tpl->display($this->GetTemplate(), $this->GetFullCacheKey());
if ($this->log && $this->log->GetBenchmark()) if ($this->log && $this->log->GetBenchmark())
$this->log->Log("Smarty render end"); $this->log->Log("Smarty render end");
   
$this->tpl->clearAllAssign(); $this->tpl->clearAllAssign();
   
if ($this->log) if ($this->log && $this->projectList)
$this->log->Log('MemoryCache count: ' . $this->projectList->GetMemoryCache()->GetCount()); $this->log->Log('MemoryCache count: ' . $this->projectList->GetMemoryCache()->GetCount());
} }
   
/** /**
* Expires the cache * Expires the cache
* *
* @param boolean $expireAll expire the whole cache * @param boolean $expireAll expire the whole cache
*/ */
public function CacheExpire($expireAll = false) public function CacheExpire($expireAll = false)
{ {
if ($expireAll) { if ($expireAll) {
$this->tpl->clearAllCache(); $this->tpl->clearAllCache();
return; return;
} }
   
if (!$this->project) if (!$this->project)
return; return;
   
$epoch = $this->GetProject()->GetEpoch(); $epoch = $this->GetProject()->GetEpoch();
if (empty($epoch)) if (empty($epoch))
return; return;
   
$age = $this->GetProject()->GetAge(); $age = $this->GetProject()->GetAge();
   
$this->tpl->clearCache(null, $this->GetCacheKeyPrefix(), null, $age); $this->tpl->clearCache(null, $this->GetCacheKeyPrefix(), null, $age);
$this->tpl->clearCache('projectlist.tpl', $this->GetCacheKeyPrefix(false), null, $age); $this->tpl->clearCache('projectlist.tpl', $this->GetCacheKeyPrefix(false), null, $age);
} }
   
} }
   
  <?php
  /**
  * Controller for login
  *
  * @author Christopher Han <xiphux@gmail.com>
  * @copyright Copyright (c) 2012 Christopher Han
  * @package GitPHP
  * @subpackage Controller
  */
  class GitPHP_Controller_Login extends GitPHP_ControllerBase
  {
  /**
  * Flag whether login was successful
  *
  * @var boolean|null
  */
  protected $loginSuccess = null;
 
  /**
  * Initialize controller
  */
  public function Initialize()
  {
  $this->InitializeConfig();
 
  $this->InitializeResource();
 
  $this->InitializeUserList();
 
  $this->EnableLogging();
 
  $this->InitializeSmarty();
  }
 
  /**
  * Gets the template for this controller
  *
  * @return string template filename
  */
  protected function GetTemplate()
  {
  return 'login.tpl';
  }
 
  /**
  * Gets the cache key for this controller
  *
  * @return string cache key
  */
  protected function GetCacheKey()
  {
  $key = (isset($this->params['username']) ? $this->params['username'] : '') . '|' . (isset($this->params['password']) ? $this->params['password'] : '');
  if (!empty($key))
  $key = sha1($key);
  return $key;
  }
 
  /**
  * Gets the name of this controller's action
  *
  * @param boolean $local true if caller wants the localized action name
  * @return string action name
  */
  public function GetName($local = false)
  {
  if ($local && $this->resource) {
  return $this->resource->translate('login');
  }
  return 'login';
  }
 
  /**
  * Loads headers for this template
  */
  protected function LoadHeaders()
  {
  if (!empty($_SESSION['gitphpuser'])) {
  $user = $this->userList->GetUser($_SESSION['gitphpuser']);
  if ($user) {
  $this->headers[] = 'Location: ' . $this->router->GetUrl(array(), true);
  $this->loginSuccess = true;
  } else {
  unset($_SESSION['gitphpuser']);
  }
  }
 
  if (!(empty($this->params['username']) || empty($this->params['password']))) {
  $user = $this->userList->GetUser($this->params['username']);
  if ($user && ($this->params['password'] === $user->GetPassword())) {
  $_SESSION['gitphpuser'] = $user->GetUsername();
  $this->headers[] = 'Location: ' . $this->router->GetUrl(array(), true);
  $this->loginSuccess = true;
  } else {
  $this->loginSuccess = false;
  }
  }
  }
 
  /**
  * Loads data for this template
  */
  protected function LoadData()
  {
  if ($this->loginSuccess === false) {
  $this->tpl->assign('loginerror', 'Invalid username or password');
  }
  }
 
  /**
  * Renders the output
  */
  public function Render()
  {
  if ($this->loginSuccess === true)
  return; // logged in and redirected, don't render
 
  return parent::Render();
  }
 
  }
 
  <?php
  /**
  * Controller for logout
  *
  * @author Christopher Han <xiphux@gmail.com>
  * @copyright Copyright (c) 2012 Christopher Han
  * @package GitPHP
  * @subpackage Controller
  */
  class GitPHP_Controller_Logout extends GitPHP_ControllerBase
  {
  /**
  * Initialize controller
  */
  public function Initialize()
  {
  $this->InitializeUserList();
  }
 
  /**
  * Gets the template for this controller
  *
  * @return string template filename
  */
  protected function GetTemplate()
  {
  }
 
  /**
  * Gets the cache key for this controller
  *
  * @return string cache key
  */
  protected function GetCacheKey()
  {
  }
 
  /**
  * Gets the name of this controller's action
  *
  * @param boolean $local true if caller wants the localized action name
  * @return string action name
  */
  public function GetName($local = false)
  {
  return 'logout';
  }
 
  /**
  * Loads headers for this template
  */
  protected function LoadHeaders()
  {
  if (!empty($_SESSION['gitphpuser'])) {
  unset($_SESSION['gitphpuser']);
  }
  $this->headers[] = 'Location: ' . $this->router->GetUrl(array(), true);
  }
 
  /**
  * Loads data for this template
  */
  protected function LoadData()
  {
  }
 
  /**
  * Renders the output
  */
  public function Render()
  {
  }
 
  }
 
<?php <?php
/** /**
* Request router * Request router
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2010 Christopher Han * @copyright Copyright (c) 2010 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Router * @subpackage Router
*/ */
class GitPHP_Router class GitPHP_Router
{ {
   
/** /**
* Route map * Route map
* *
* @var array * @var array
*/ */
protected $routes = array(); protected $routes = array();
   
/** /**
* Query parameter map * Query parameter map
* *
* @var array * @var array
*/ */
protected $queryParameters = array(); protected $queryParameters = array();
   
/** /**
* Clean url flag * Clean url flag
* *
* @var boolean * @var boolean
*/ */
protected $cleanurl = false; protected $cleanurl = false;
   
/** /**
* Abbreviate hashes flag * Abbreviate hashes flag
* *
* @var boolean * @var boolean
*/ */
protected $abbreviate = false; protected $abbreviate = false;
   
/** /**
* Base url * Base url
* *
* @var string * @var string
*/ */
protected $baseurl; protected $baseurl;
   
/** /**
* Full url * Full url
* *
* @var string * @var string
*/ */
protected $fullurl; protected $fullurl;
   
/** /**
* Constructor * Constructor
* *
* @param boolean $cleanurl true to generate clean urls * @param boolean $cleanurl true to generate clean urls
* @param boolean $abbreviate true to abbreviate hashes * @param boolean $abbreviate true to abbreviate hashes
*/ */
public function __construct($cleanurl = false, $abbreviate = false) public function __construct($cleanurl = false, $abbreviate = false)
{ {
$this->cleanurl = $cleanurl; $this->cleanurl = $cleanurl;
$this->abbreviate = $abbreviate; $this->abbreviate = $abbreviate;
   
$this->baseurl = GitPHP_Util::BaseUrl(); $this->baseurl = GitPHP_Util::BaseUrl();
if (empty($this->baseurl)) if (empty($this->baseurl))
$this->baseurl = '/'; $this->baseurl = '/';
$this->fullurl = GitPHP_Util::BaseUrl(true); $this->fullurl = GitPHP_Util::BaseUrl(true);
   
$this->InitializeRoutes(); $this->InitializeRoutes();
$this->InitializeQueryParameters(); $this->InitializeQueryParameters();
} }
   
/** /**
* Get clean url setting * Get clean url setting
* *
* @return boolean * @return boolean
*/ */
public function GetCleanUrl() public function GetCleanUrl()
{ {
return $this->cleanurl; return $this->cleanurl;
} }
   
/** /**
* Set clean url setting * Set clean url setting
* *
* @param boolean $cleanurl true to generate clean urls * @param boolean $cleanurl true to generate clean urls
*/ */
public function SetCleanUrl($cleanurl) public function SetCleanUrl($cleanurl)
{ {
$this->cleanurl = $cleanurl; $this->cleanurl = $cleanurl;
} }
   
/** /**
* Get abbreviate hash setting * Get abbreviate hash setting
* *
* @return boolean * @return boolean
*/ */
public function GetAbbreviate() public function GetAbbreviate()
{ {
return $this->abbreviate; return $this->abbreviate;
} }
   
/** /**
* Set abbreviate hash setting * Set abbreviate hash setting
* *
* @param boolean $abbreviate abbreviate * @param boolean $abbreviate abbreviate
*/ */
public function SetAbbreviate($abbreviate) public function SetAbbreviate($abbreviate)
{ {
$this->abbreviate = $abbreviate; $this->abbreviate = $abbreviate;
} }
   
/** /**
* Get base url * Get base url
* *
* @param boolean $full true to return full base url (include protocol and hostname) * @param boolean $full true to return full base url (include protocol and hostname)
* @return string base url * @return string base url
*/ */
public function GetBaseUrl($full = false) public function GetBaseUrl($full = false)
{ {
if ($full) if ($full)
return $this->fullurl; return $this->fullurl;
   
return $this->baseurl; return $this->baseurl;
} }
   
/** /**
* Set base url * Set base url
* *
* @param string $baseurl base url * @param string $baseurl base url
*/ */
public function SetBaseUrl($baseurl) public function SetBaseUrl($baseurl)
{ {
$this->baseurl = $baseurl; $this->baseurl = $baseurl;
$this->fullurl = $baseurl; $this->fullurl = $baseurl;
} }
   
/** /**
* Initialize route map * Initialize route map
*/ */
private function InitializeRoutes() private function InitializeRoutes()
{ {
// project view // project view
$projectroute = new GitPHP_Route('projects/:project', array( $projectroute = new GitPHP_Route('projects/:project', array(
'project' => '[^\?]+' 'project' => '[^\?]+'
)); ));
   
// project-specific action with hash and output method // project-specific action with hash and output method
$this->routes[] = new GitPHP_Route(':action/:hash/:output', array( $this->routes[] = new GitPHP_Route(':action/:hash/:output', array(
'action' => 'blobs', 'action' => 'blobs',
'hash' => '[0-9A-Fa-f]{4,40}|HEAD', 'hash' => '[0-9A-Fa-f]{4,40}|HEAD',
'output' => 'plain' 'output' => 'plain'
), array(), $projectroute); ), array(), $projectroute);
   
// project-specific action with hash // project-specific action with hash
$this->routes[] = new GitPHP_Route(':action/:hash', array( $this->routes[] = new GitPHP_Route(':action/:hash', array(
'action' => 'commits|trees|blobs|search|snapshot|commitdiff|blobdiff|blame', 'action' => 'commits|trees|blobs|search|snapshot|commitdiff|blobdiff|blame',
'hash' => '[0-9A-Fa-f]{4,40}|HEAD' 'hash' => '[0-9A-Fa-f]{4,40}|HEAD'
), array(), $projectroute); ), array(), $projectroute);
   
// project-specific action with hash or ref // project-specific action with hash or ref
$this->routes[] = new GitPHP_Route(':action/:hash', array( $this->routes[] = new GitPHP_Route(':action/:hash', array(
'action' => 'shortlog|log', 'action' => 'shortlog|log',
'hash' => '[^\?]+' 'hash' => '[^\?]+'
), array(), $projectroute); ), array(), $projectroute);
   
// map heads to shortlog // map heads to shortlog
$this->routes[] = new GitPHP_Route(':action/:hash', array( $this->routes[] = new GitPHP_Route(':action/:hash', array(
'action' => 'heads', 'action' => 'heads',
'hash' => '[^\?]+' 'hash' => '[^\?]+'
), array( ), array(
'action' => 'shortlog' 'action' => 'shortlog'
), $projectroute); ), $projectroute);
   
// project-specific graphs // project-specific graphs
$this->routes[] = new GitPHP_Route(':action/:graphtype', array( $this->routes[] = new GitPHP_Route(':action/:graphtype', array(
'action' => 'graphs', 'action' => 'graphs',
'graphtype' => '[a-z]+' 'graphtype' => '[a-z]+'
), array(), $projectroute); ), array(), $projectroute);
   
// project-specific tag // project-specific tag
$this->routes[] = new GitPHP_Route(':action/:tag', array( $this->routes[] = new GitPHP_Route(':action/:tag', array(
'action' => 'tags', 'action' => 'tags',
'tag' => '[^\?]+' 'tag' => '[^\?]+'
), array(), $projectroute); ), array(), $projectroute);
   
$formats = GitPHP_Archive::SupportedFormats(); $formats = GitPHP_Archive::SupportedFormats();
if (count($formats) > 0) { if (count($formats) > 0) {
$formatconstraint = implode("|", array_keys($formats)); $formatconstraint = implode("|", array_keys($formats));
// project specific snapshot format with hash // project specific snapshot format with hash
$this->routes[] = new GitPHP_Route(':format/:hash', array( $this->routes[] = new GitPHP_Route(':format/:hash', array(
'format' => $formatconstraint, 'format' => $formatconstraint,
'hash' => '[0-9A-Fa-f]{4,40}|HEAD' 'hash' => '[0-9A-Fa-f]{4,40}|HEAD'
), array( ), array(
'action' => 'snapshot' 'action' => 'snapshot'
), $projectroute); ), $projectroute);
   
// project specific snapshot format // project specific snapshot format
$this->routes[] = new GitPHP_Route(':format', array( $this->routes[] = new GitPHP_Route(':format', array(
'format' => $formatconstraint 'format' => $formatconstraint
), array( ), array(
'action' => 'snapshot' 'action' => 'snapshot'
), $projectroute); ), $projectroute);
} }
   
// project-specific action only // project-specific action only
$this->routes[] = new GitPHP_Route(':action', array( $this->routes[] = new GitPHP_Route(':action', array(
'action' => 'tags|heads|shortlog|log|search|atom|rss|snapshot|commits|graphs|trees|blobs|history|commitdiff|blobdiff' 'action' => 'tags|heads|shortlog|log|search|atom|rss|snapshot|commits|graphs|trees|blobs|history|commitdiff|blobdiff'
), array(), $projectroute); ), array(), $projectroute);
   
$this->routes[] = $projectroute; $this->routes[] = $projectroute;
   
// non-project action // non-project action
$this->routes[] = new GitPHP_Route(':action', array( $this->routes[] = new GitPHP_Route(':action', array(
'action' => 'opml|projectindex' 'action' => 'opml|projectindex|login|logout'
)); ));
   
usort($this->routes, array('GitPHP_Route', 'CompareRoute')); usort($this->routes, array('GitPHP_Route', 'CompareRoute'));
} }
   
/** /**
* Initialize query parameter map * Initialize query parameter map
*/ */
private function InitializeQueryParameters() private function InitializeQueryParameters()
{ {
$this->queryParameters = array( $this->queryParameters = array(
'project' => 'p', 'project' => 'p',
'action' => 'a', 'action' => 'a',
'hash' => 'h', 'hash' => 'h',
'hashbase' => 'hb', 'hashbase' => 'hb',
'hashparent' => 'hp', 'hashparent' => 'hp',
'graphtype' => 'g', 'graphtype' => 'g',
'output' => 'o', 'output' => 'o',
'format' => 'fmt', 'format' => 'fmt',
'tag' => 't', 'tag' => 't',
'page' => 'pg', 'page' => 'pg',
'search' => 's', 'search' => 's',
'searchtype' => 'st', 'searchtype' => 'st',
'diffmode' => 'd', 'diffmode' => 'd',
'file' => 'f', 'file' => 'f',
'mark' => 'm', 'mark' => 'm',
'prefix' => 'prefix', 'prefix' => 'prefix',
'sort' => 'sort', 'sort' => 'sort',
'lang' => 'l' 'lang' => 'l'
); );
} }
   
/** /**
* Convert a parameter array to a query variable array * Convert a parameter array to a query variable array
* *
* @param array $params parameter array * @param array $params parameter array
* @return array query variable array * @return array query variable array
*/ */
private function ParameterArrayToQueryVarArray($params) private function ParameterArrayToQueryVarArray($params)
{ {
$queryvars = array(); $queryvars = array();
   
if (count($params) < 1) if (count($params) < 1)
return $queryvars; return $queryvars;
   
foreach ($params as $param => $val) { foreach ($params as $param => $val) {
   
if (empty($val)) if (empty($val))
continue; continue;
   
if (empty($this->queryParameters[$param])) if (empty($this->queryParameters[$param]))
continue; continue;
   
$queryvar = $this->queryParameters[$param]; $queryvar = $this->queryParameters[$param];
   
if (!empty($queryvar)) if (!empty($queryvar))
$queryvars[$queryvar] = $val; $queryvars[$queryvar] = $val;
} }
   
return $queryvars; return $queryvars;
} }
   
/** /**
* Convert a query variable array to a parameter array * Convert a query variable array to a parameter array
* *
* @param array $queryvars query variable array * @param array $queryvars query variable array
* @return array parameter array * @return array parameter array
*/ */
private function QueryVarArrayToParameterArray($queryvars) private function QueryVarArrayToParameterArray($queryvars)
{ {
$params = array(); $params = array();
   
if (count($queryvars) < 1) if (count($queryvars) < 1)
return $params; return $params;
   
foreach ($queryvars as $var => $val) { foreach ($queryvars as $var => $val) {
   
if (empty($val)) if (empty($val))
continue; continue;
   
$param = array_search($var, $this->queryParameters); $param = array_search($var, $this->queryParameters);
   
if (!empty($param)) if (!empty($param))
$params[$param] = $val; $params[$param] = $val;
} }
   
return $params; return $params;
} }
   
/** /**
* Build route from url parameters * Build route from url parameters
* *
* @param array $urlparams url parameters * @param array $urlparams url parameters
*/ */
private function BuildRoute($urlparams) private function BuildRoute($urlparams)
{ {
foreach ($this->routes as $route) { foreach ($this->routes as $route) {
   
if (!$route->Valid($urlparams)) if (!$route->Valid($urlparams))
continue; continue;
   
$path = $route->Build($urlparams); $path = $route->Build($urlparams);
$usedparams = $route->GetUsedParameters(); $usedparams = $route->GetUsedParameters();
   
return array($path, $usedparams); return array($path, $usedparams);
} }
   
return array(null, array()); return array(null, array());
} }
   
/** /**
* Find route matching query * Find route matching query
* *
* @param string $query query * @param string $query query
* @return array query parameters * @return array query parameters
*/ */
private function FindRoute($query) private function FindRoute($query)
{ {
if (empty($query)) if (empty($query))
return array(); return array();
   
foreach ($this->routes as $route) { foreach ($this->routes as $route) {
   
$params = $route->Match($query); $params = $route->Match($query);
if ($params === false) if ($params === false)
continue; continue;
   
return $params; return $params;
} }
   
return array(); return array();
} }
   
/** /**
* Gets a controller for an action * Gets a controller for an action
* *
* @return mixed controller object * @return mixed controller object
*/ */
public function GetController() public function GetController()
{ {
$params = $this->QueryVarArrayToParameterArray($_GET); $params = $this->QueryVarArrayToParameterArray($_GET);
   
if (!empty($_GET['q'])) { if (!empty($_GET['q'])) {
$restparams = GitPHP_Router::ReadCleanUrl($_SERVER['REQUEST_URI']); $restparams = GitPHP_Router::ReadCleanUrl($_SERVER['REQUEST_URI']);
if (count($restparams) > 0) if (count($restparams) > 0)
$params = array_merge($params, $restparams); $params = array_merge($params, $restparams);
} }
   
$controller = null; $controller = null;
   
$action = null; $action = null;
if (!empty($params['action'])) if (!empty($params['action']))
$action = $params['action']; $action = $params['action'];
   
switch ($action) { switch ($action) {
   
   
case 'search': case 'search':
$controller = new GitPHP_Controller_Search(); $controller = new GitPHP_Controller_Search();
break; break;
   
   
case 'commitdiff': case 'commitdiff':
case 'commitdiff_plain': case 'commitdiff_plain':
$controller = new GitPHP_Controller_Commitdiff(); $controller = new GitPHP_Controller_Commitdiff();
if ($action === 'commitdiff_plain') if ($action === 'commitdiff_plain')
$controller->SetParam('output', 'plain'); $controller->SetParam('output', 'plain');
break; break;
   
   
case 'blobdiff': case 'blobdiff':
case 'blobdiff_plain': case 'blobdiff_plain':
$controller = new GitPHP_Controller_Blobdiff(); $controller = new GitPHP_Controller_Blobdiff();
if ($action === 'blobdiff_plain') if ($action === 'blobdiff_plain')
$controller->SetParam('output', 'plain'); $controller->SetParam('output', 'plain');
break; break;
   
   
case 'history': case 'history':
$controller = new GitPHP_Controller_History(); $controller = new GitPHP_Controller_History();
break; break;
   
   
case 'shortlog': case 'shortlog':
case 'log': case 'log':
$controller = new GitPHP_Controller_Log(); $controller = new GitPHP_Controller_Log();
if ($action === 'shortlog') if ($action === 'shortlog')
$controller->SetParam('short', true); $controller->SetParam('short', true);
break; break;
   
   
case 'snapshot': case 'snapshot':
$controller = new GitPHP_Controller_Snapshot(); $controller = new GitPHP_Controller_Snapshot();
break; break;
   
   
case 'tree': case 'tree':
case 'trees': case 'trees':
$controller = new GitPHP_Controller_Tree(); $controller = new GitPHP_Controller_Tree();
break; break;
   
   
case 'tags': case 'tags':
if (empty($params['tag'])) { if (empty($params['tag'])) {
$controller = new GitPHP_Controller_Tags(); $controller = new GitPHP_Controller_Tags();
break; break;
} }
case 'tag': case 'tag':
$controller = new GitPHP_Controller_Tag(); $controller = new GitPHP_Controller_Tag();
break; break;
   
   
case 'heads': case 'heads':
$controller = new GitPHP_Controller_Heads(); $controller = new GitPHP_Controller_Heads();
break; break;
   
   
case 'blame': case 'blame':
$controller = new GitPHP_Controller_Blame(); $controller = new GitPHP_Controller_Blame();
break; break;
   
   
case 'blob': case 'blob':
case 'blobs': case 'blobs':
case 'blob_plain': case 'blob_plain':
$controller = new GitPHP_Controller_Blob(); $controller = new GitPHP_Controller_Blob();
if ($action === 'blob_plain') if ($action === 'blob_plain')
$controller->SetParam('output', 'plain'); $controller->SetParam('output', 'plain');
break; break;
   
   
case 'atom': case 'atom':
case 'rss': case 'rss':
$controller = new GitPHP_Controller_Feed(); $controller = new GitPHP_Controller_Feed();
if ($action == 'rss') if ($action == 'rss')
$controller->SetParam('format', GitPHP_Controller_Feed::RssFormat); $controller->SetParam('format', GitPHP_Controller_Feed::RssFormat);
else if ($action == 'atom') else if ($action == 'atom')
$controller->SetParam('format', GitPHP_Controller_Feed::AtomFormat); $controller->SetParam('format', GitPHP_Controller_Feed::AtomFormat);
break; break;
   
   
case 'commit': case 'commit':
case 'commits': case 'commits':
$controller = new GitPHP_Controller_Commit(); $controller = new GitPHP_Controller_Commit();
break; break;
   
   
case 'summary': case 'summary':
$controller = new GitPHP_Controller_Project(); $controller = new GitPHP_Controller_Project();
break; break;
   
   
case 'project_index': case 'project_index':
case 'projectindex': case 'projectindex':
$controller = new GitPHP_Controller_ProjectList(); $controller = new GitPHP_Controller_ProjectList();
$controller->SetParam('txt', true); $controller->SetParam('txt', true);
break; break;
   
   
case 'opml': case 'opml':
$controller = new GitPHP_Controller_ProjectList(); $controller = new GitPHP_Controller_ProjectList();
$controller->SetParam('opml', true); $controller->SetParam('opml', true);
break; break;
   
   
  case 'login':
  $controller = new GitPHP_Controller_Login();
  if (!empty($_POST['username']))
  $controller->SetParam('username', $_POST['username']);
  if (!empty($_POST['password']))
  $controller->SetParam('password', $_POST['password']);
  break;
   
  case 'logout':
  $controller = new GitPHP_Controller_Logout();
  break;
   
   
case 'graph': case 'graph':
case 'graphs': case 'graphs':
//$controller = new GitPHP_Controller_Graph(); //$controller = new GitPHP_Controller_Graph();
//break; //break;
case 'graphdata': case 'graphdata':
//$controller = new GitPHP_Controller_GraphData(); //$controller = new GitPHP_Controller_GraphData();
//break; //break;
default: default:
if (!empty($params['project'])) { if (!empty($params['project'])) {
$controller = new GitPHP_Controller_Project(); $controller = new GitPHP_Controller_Project();
} else { } else {
$controller = new GitPHP_Controller_ProjectList(); $controller = new GitPHP_Controller_ProjectList();
} }
} }
   
foreach ($params as $paramname => $paramval) { foreach ($params as $paramname => $paramval) {
if ($paramname !== 'action') if ($paramname !== 'action')
$controller->SetParam($paramname, $paramval); $controller->SetParam($paramname, $paramval);
} }
   
$controller->SetRouter($this); $controller->SetRouter($this);
   
return $controller; return $controller;
} }
   
/** /**
* Get message controller * Get message controller
* *
* @return GitPHP_ControllerBase * @return GitPHP_ControllerBase
*/ */
public function GetMessageController() public function GetMessageController()
{ {
$params = $this->QueryVarArrayToParameterArray($_GET); $params = $this->QueryVarArrayToParameterArray($_GET);
   
if (!empty($_GET['q'])) { if (!empty($_GET['q'])) {
$restparams = GitPHP_Router::ReadCleanUrl($_SERVER['REQUEST_URI']); $restparams = GitPHP_Router::ReadCleanUrl($_SERVER['REQUEST_URI']);
if (count($restparams) > 0) if (count($restparams) > 0)
$params = array_merge($params, $restparams); $params = array_merge($params, $restparams);
} }
   
$controller = new GitPHP_Controller_Message(); $controller = new GitPHP_Controller_Message();
   
foreach ($params as $paramname => $paramval) { foreach ($params as $paramname => $paramval) {
if ($paramname !== 'action') if ($paramname !== 'action')
$controller->SetParam($paramname, $paramval); $controller->SetParam($paramname, $paramval);
} }
   
$controller->SetRouter($this); $controller->SetRouter($this);
   
return $controller; return $controller;
} }
   
/** /**
* Read a rest-style clean url * Read a rest-style clean url
* *
* @param string $url url * @param string $url url
* @return array request parameters from url * @return array request parameters from url
*/ */
private function ReadCleanUrl($url) private function ReadCleanUrl($url)
{ {
$querypos = strpos($url, '?'); $querypos = strpos($url, '?');
if ($querypos !== false) if ($querypos !== false)
$url = substr($url, 0, $querypos); $url = substr($url, 0, $querypos);
   
$url = rtrim($url, "/"); $url = rtrim($url, "/");
   
$baseurl = GitPHP_Util::AddSlash(GitPHP_Util::BaseUrl(), false); $baseurl = GitPHP_Util::AddSlash(GitPHP_Util::BaseUrl(), false);
if (empty($baseurl)) if (empty($baseurl))
$baseurl = '/'; $baseurl = '/';
   
if (strncmp($baseurl, $url, strlen($baseurl)) === 0) if (strncmp($baseurl, $url, strlen($baseurl)) === 0)
$url = substr($url, strlen($baseurl)); $url = substr($url, strlen($baseurl));
   
return $this->FindRoute($url); return $this->FindRoute($url);
} }
   
/** /**
* Generate a url * Generate a url
* *
* @param array $params request parameters * @param array $params request parameters
* @param boolean $full true to get full url (include protocol and hostname) * @param boolean $full true to get full url (include protocol and hostname)
*/ */
public function GetUrl($params = array(), $full = false) public function GetUrl($params = array(), $full = false)
{ {
if ($full) if ($full)
$baseurl = $this->fullurl; $baseurl = $this->fullurl;
else else
$baseurl = $this->baseurl; $baseurl = $this->baseurl;
   
if ($this->cleanurl) { if ($this->cleanurl) {
if (substr_compare($baseurl, 'index.php', -9) === 0) { if (substr_compare($baseurl, 'index.php', -9) === 0) {
$baseurl = dirname($baseurl); $baseurl = dirname($baseurl);
} }
$baseurl = GitPHP_Util::AddSlash($baseurl, false); $baseurl = GitPHP_Util::AddSlash($baseurl, false);
} else { } else {
if (substr_compare($baseurl, 'index.php', -9) !== 0) { if (substr_compare($baseurl, 'index.php', -9) !== 0) {
$baseurl = GitPHP_Util::AddSlash($baseurl, false); $baseurl = GitPHP_Util::AddSlash($baseurl, false);
} }
} }
   
if (count($params) < 1) if (count($params) < 1)
return $baseurl; return $baseurl;
   
$abbreviate = $this->abbreviate; $abbreviate = $this->abbreviate;
if ($abbreviate && !empty($params['project']) && ($params['project'] instanceof GitPHP_Project)) { if ($abbreviate && !empty($params['project']) && ($params['project'] instanceof GitPHP_Project)) {
if ($params['project']->GetCompat()) if ($params['project']->GetCompat())
$abbreviate = false; $abbreviate = false;
} }
   
foreach ($params as $paramname => $paramval) { foreach ($params as $paramname => $paramval) {
switch ($paramname) { switch ($paramname) {
case 'hash': case 'hash':
case 'hashbase': case 'hashbase':
case 'hashparent': case 'hashparent':
case 'mark': case 'mark':
$params[$paramname] = GitPHP_Router::GetHash($paramval, $abbreviate); $params[$paramname] = GitPHP_Router::GetHash($paramval, $abbreviate);
break; break;
case 'tag': case 'tag':
$params[$paramname] = GitPHP_Router::GetTag($paramval); $params[$paramname] = GitPHP_Router::GetTag($paramval);
break; break;
case 'project': case 'project':
$params[$paramname] = GitPHP_Router::GetProject($paramval); $params[$paramname] = GitPHP_Router::GetProject($paramval);
break; break;
} }
} }
   
if ($this->cleanurl) { if ($this->cleanurl) {
   
if (!empty($params['action'])) { if (!empty($params['action'])) {
switch ($params['action']) { switch ($params['action']) {
case 'blob': case 'blob':
case 'commit': case 'commit':
case 'tree': case 'tree':
case 'graph': case 'graph':
case 'tag': case 'tag':
// these actions are plural in clean urls // these actions are plural in clean urls
$params['action'] = $params['action'] . 's'; $params['action'] = $params['action'] . 's';
break; break;
} }
} }
   
list($queryurl, $exclude) = $this->BuildRoute($params); list($queryurl, $exclude) = $this->BuildRoute($params);
$baseurl .= $queryurl; $baseurl .= $queryurl;
   
foreach ($exclude as $excludeparam) { foreach ($exclude as $excludeparam) {
unset($params[$excludeparam]); unset($params[$excludeparam]);
} }
} }
   
$querystr = GitPHP_Router::GetQueryString($params); $querystr = GitPHP_Router::GetQueryString($params);
   
if (empty($querystr)) if (empty($querystr))
return $baseurl; return $baseurl;
   
return $baseurl . '?' . $querystr; return $baseurl . '?' . $querystr;
} }
   
/** /**
* Gets query parameters for a url * Gets query parameters for a url
* *
* @param array $params query parameters * @param array $params query parameters
* @return string query string * @return string query string
*/ */
private function GetQueryString($params = array()) private function GetQueryString($params = array())
{ {
if (count($params) < 1) if (count($params) < 1)
return null; return null;
   
$query = $this->ParameterArrayToQueryVarArray($params); $query = $this->ParameterArrayToQueryVarArray($params);
   
if (count($query) < 1) if (count($query) < 1)
return null; return null;
   
$querystr = null; $querystr = null;
   
foreach ($query as $var => $val) { foreach ($query as $var => $val) {
if (empty($val)) if (empty($val))
continue; continue;
if (!empty($querystr)) if (!empty($querystr))
$querystr .= '&'; $querystr .= '&';
$querystr .= $var . '=' . rawurlencode($val); $querystr .= $var . '=' . rawurlencode($val);
} }
   
return $querystr; return $querystr;
} }
   
/** /**
* Gets a hash for a string or hash-identified object * Gets a hash for a string or hash-identified object
* *
* @param string|GitPHP_GitObject $value string or hashed object * @param string|GitPHP_GitObject $value string or hashed object
* @param boolean $abbreviate true to abbreviate hash * @param boolean $abbreviate true to abbreviate hash
* @return string hash * @return string hash
*/ */
private static function GetHash($value, $abbreviate = false) private static function GetHash($value, $abbreviate = false)
{ {
if ($value instanceof GitPHP_GitObject) if ($value instanceof GitPHP_GitObject)
return $value->GetHash($abbreviate); return $value->GetHash($abbreviate);
else if (is_string($value)) else if (is_string($value))
return $value; return $value;
   
return null; return null;
} }
   
/** /**
* Gets an identifier for a tag * Gets an identifier for a tag
* *
* @param string|GitPHP_Tag $value string or tag * @param string|GitPHP_Tag $value string or tag
* @return string hash * @return string hash
*/ */
private static function GetTag($value) private static function GetTag($value)
{ {
if ($value instanceof GitPHP_Tag) if ($value instanceof GitPHP_Tag)
return $value->GetName(); return $value->GetName();
else if (is_string($value)) else if (is_string($value))
return $value; return $value;
return null; return null;
} }
   
/** /**
* Gets a project identifier for a project * Gets a project identifier for a project
* *
* @param string|GitPHP_Project $value string or project * @param string|GitPHP_Project $value string or project
* @return string identifier * @return string identifier
*/ */
private static function GetProject($value) private static function GetProject($value)
{ {
if ($value instanceof GitPHP_Project) { if ($value instanceof GitPHP_Project) {
return $value->GetProject(); return $value->GetProject();
} else if (is_string($project)) { } else if (is_string($project)) {
return $value; return $value;
} }
} }
   
} }
   
  {*
  * Login template
  *
  * @author Christopher Han <xiphux@gmail.com>
  * @copyright Copyright (c) 2012 Christopher Han
  * @package GitPHP
  * @subpackage Template
  *}
  {extends file='main.tpl'}
 
  {block name=header}
  <a href="{geturl}">{if $homelink}{$homelink}{else}{t}projects{/t}{/if}</a> / {if $actionlocal}{$actionlocal}{/if}
  {/block}
 
  {block name=main}
  {if $loginerror}
  <div class="loginerror">
  {$loginerror}
  </div>
  {/if}
  <form method="post" action="{geturl action=login}">
  <table>
  <tr>
  <td><label for="username">Username:</label></td>
  <td><input type="text" name="username" {if $username}value="{$username}"{/if} /></td>
  </tr>
  <tr>
  <td><label for="password">Password:</label></td>
  <td><input type="password" name="password" /></td>
  </tr>
  <tr>
  <td></td>
  <td><input type="submit" value="Login" /></td>
  </tr>
  </table>
  </form>
  {/block}
 
{* {*
* Main * Main
* *
* Main page template * Main page template
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @copyright Copyright (c) 2011 Christopher Han * @copyright Copyright (c) 2011 Christopher Han
* @packge GitPHP * @packge GitPHP
* @subpackage Template * @subpackage Template
*} *}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{$currentprimarylocale}"> <html lang="{$currentprimarylocale}">
<!-- gitphp web interface {$version}, (C) 2006-2011 Christopher Han <xiphux@gmail.com> --> <!-- gitphp web interface {$version}, (C) 2006-2011 Christopher Han <xiphux@gmail.com> -->
<head> <head>
<title> <title>
{block name=title} {block name=title}
{$pagetitle} {$pagetitle}
{/block} {/block}
</title> </title>
{block name=feeds} {block name=feeds}
{/block} {/block}
{block name=links} {block name=links}
{/block} {/block}
{if file_exists('css/gitphp.min.css')} {if file_exists('css/gitphp.min.css')}
<link rel="stylesheet" href="{$baseurl}/css/gitphp.min.css" type="text/css" /> <link rel="stylesheet" href="{$baseurl}/css/gitphp.min.css" type="text/css" />
{else} {else}
<link rel="stylesheet" href="{$baseurl}/css/gitphp.css" type="text/css" /> <link rel="stylesheet" href="{$baseurl}/css/gitphp.css" type="text/css" />
{/if} {/if}
{if file_exists("css/$stylesheet.min.css")} {if file_exists("css/$stylesheet.min.css")}
<link rel="stylesheet" href="{$baseurl}/css/{$stylesheet}.min.css" type="text/css" /> <link rel="stylesheet" href="{$baseurl}/css/{$stylesheet}.min.css" type="text/css" />
{else} {else}
<link rel="stylesheet" href="{$baseurl}/css/{$stylesheet}.css" type="text/css" /> <link rel="stylesheet" href="{$baseurl}/css/{$stylesheet}.css" type="text/css" />
{/if} {/if}
<link rel="stylesheet" href="{$baseurl}/css/ext/jquery.qtip.min.css" type="text/css" /> <link rel="stylesheet" href="{$baseurl}/css/ext/jquery.qtip.min.css" type="text/css" />
{block name=css} {block name=css}
{/block} {/block}
{if $javascript} {if $javascript}
<script type="text/javascript"> <script type="text/javascript">
var require = { var require = {
baseUrl: '{$baseurl}/js', baseUrl: '{$baseurl}/js',
paths: { paths: {
jquery: [ jquery: [
{if $googlejs} {if $googlejs}
'https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min', 'https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min',
{/if} {/if}
'ext/jquery-1.8.1.min' 'ext/jquery-1.8.1.min'
], ],
d3: 'ext/d3.v2.min', d3: 'ext/d3.v2.min',
qtip: 'ext/jquery.qtip.min', qtip: 'ext/jquery.qtip.min',
modernizr: 'ext/modernizr.custom' modernizr: 'ext/modernizr.custom'
}, },
config: { config: {
'modules/snapshotformats': { 'modules/snapshotformats': {
formats: { formats: {
{foreach from=$snapshotformats key=format item=extension name=formats} {foreach from=$snapshotformats key=format item=extension name=formats}
"{$format}": "{$extension}"{if !$smarty.foreach.formats.last},{/if} "{$format}": "{$extension}"{if !$smarty.foreach.formats.last},{/if}
{/foreach} {/foreach}
} }
}, },
{if $project} {if $project}
'modules/getproject': { 'modules/getproject': {
project: '{$project->GetProject()}' project: '{$project->GetProject()}'
}, },
{/if} {/if}
'modules/geturl': { 'modules/geturl': {
baseurl: '{$baseurl}/' baseurl: '{$baseurl}/'
}, },
'modules/resources': { 'modules/resources': {
resources: { resources: {
Loading: "{t escape='js'}Loading…{/t}", Loading: "{t escape='js'}Loading…{/t}",
LoadingBlameData: "{t escape='js'}Loading blame data…{/t}", LoadingBlameData: "{t escape='js'}Loading blame data…{/t}",
Snapshot: "{t escape='js'}snapshot{/t}", Snapshot: "{t escape='js'}snapshot{/t}",
NoMatchesFound: '{t escape=no}No matches found for "%1"{/t}' NoMatchesFound: '{t escape=no}No matches found for "%1"{/t}'
} }
} }
} }
}; };
{block name=javascript} {block name=javascript}
{if file_exists('js/common.min.js')} {if file_exists('js/common.min.js')}
require.paths.common = 'common.min'; require.paths.common = 'common.min';
{/if} {/if}
require.deps = ['common']; require.deps = ['common'];
{/block} {/block}
</script> </script>
<script type="text/javascript" src="{$baseurl}/js/ext/require.js"></script> <script type="text/javascript" src="{$baseurl}/js/ext/require.js"></script>
{/if} {/if}
</head> </head>
<body> <body>
  {if $loginenabled}
  <div class="login">
  {if $loggedinuser}
  <a href="{geturl action=logout}" />logout</a>
  {else}
  <a href="{geturl action=login}" />login</a>
  {/if}
  </div>
  {/if}
<div class="page_header"> <div class="page_header">
{if $supportedlocales} {if $supportedlocales}
<div class="lang_select"> <div class="lang_select">
<form action="{$requesturl}" method="get" id="frmLangSelect"> <form action="{$requesturl}" method="get" id="frmLangSelect">
<div> <div>
{foreach from=$requestvars key=var item=val} {foreach from=$requestvars key=var item=val}
{if $var != "l"} {if $var != "l"}
<input type="hidden" name="{$var}" value="{$val|escape}" /> <input type="hidden" name="{$var}" value="{$val|escape}" />
{/if} {/if}
{/foreach} {/foreach}
<label for="selLang">{t}language:{/t}</label> <label for="selLang">{t}language:{/t}</label>
<select name="l" id="selLang"> <select name="l" id="selLang">
{foreach from=$supportedlocales key=locale item=language} {foreach from=$supportedlocales key=locale item=language}
<option {if $locale == $currentlocale}selected="selected"{/if} value="{$locale}">{if $language}{$language} ({$locale}){else}{$locale}{/if}</option> <option {if $locale == $currentlocale}selected="selected"{/if} value="{$locale}">{if $language}{$language} ({$locale}){else}{$locale}{/if}</option>
{/foreach} {/foreach}
</select> </select>
<input type="submit" value="{t}set{/t}" id="btnLangSet" /> <input type="submit" value="{t}set{/t}" id="btnLangSet" />
</div> </div>
</form> </form>
</div> </div>
{/if} {/if}
{block name=header} {block name=header}
<a href="{geturl}">{if $homelink}{$homelink}{else}{t}projects{/t}{/if}</a> / <a href="{geturl}">{if $homelink}{$homelink}{else}{t}projects{/t}{/if}</a> /
{/block} {/block}
</div> </div>
{block name=main} {block name=main}
   
{/block} {/block}
<div class="page_footer"> <div class="page_footer">
{block name=footer} {block name=footer}
{/block} {/block}
</div> </div>
<div class="attr_footer"> <div class="attr_footer">
<a href="http://www.gitphp.org/" target="_blank">GitPHP by Chris Han</a> <a href="http://www.gitphp.org/" target="_blank">GitPHP by Chris Han</a>
</div> </div>
</body> </body>
</html> </html>
   
comments