Don't reference resource singleton in agestring function
[gitphp.git] / include / controller / ControllerBase.class.php
blob:a/include/controller/ControllerBase.class.php -> blob:b/include/controller/ControllerBase.class.php
--- a/include/controller/ControllerBase.class.php
+++ b/include/controller/ControllerBase.class.php
@@ -18,6 +18,20 @@
 	protected $config;
 
 	/**
+	 * User list instance
+	 *
+	 * @var GitPHP_UserList
+	 */
+	protected $userList;
+
+	/**
+	 * Resource handler instance
+	 *
+	 * @var GitPHP_Resource
+	 */
+	protected $resource;
+
+	/**
 	 * Smarty instance
 	 *
 	 * @var Smarty
@@ -81,11 +95,22 @@
 	protected $exe;
 
 	/**
-	 * Constructor
-	 */
-	public function __construct()
-	{
-		$this->config = GitPHP_Config::GetInstance();
+	 * Url router instance
+	 *
+	 * @var GitPHP_Router
+	 */
+	protected $router;
+
+	/**
+	 * Initialize controller
+	 */
+	public function Initialize()
+	{
+		$this->InitializeConfig();
+
+		$this->InitializeResource();
+
+		$this->InitializeUserList();
 
 		$this->EnableLogging();
 
@@ -99,24 +124,87 @@
 			$this->projectList->LoadProjects();
 		}
 
-		if (isset($_GET['p'])) {
-			$project = $this->projectList->GetProject(str_replace(chr(0), '', $_GET['p']));
+		if (!empty($this->params['project'])) {
+			$project = $this->projectList->GetProject($this->params['project']);
 			if (!$project) {
-				throw new GitPHP_MessageException(sprintf(__('Invalid project %1$s'), $_GET['p']), true);
+				throw new GitPHP_InvalidProjectParameterException($this->params['project']);
 			}
 			$this->project = $project->GetProject();
 		}
 
 		if (!($this->project || $this->multiProject)) {
-			throw new GitPHP_MessageException(__('Project is required'), true);
-		}
-
-		if (isset($_GET['s']))
-			$this->params['search'] = $_GET['s'];
-		if (isset($_GET['st']))
-			$this->params['searchtype'] = $_GET['st'];
-
-		$this->ReadQuery();
+			throw new GitPHP_MissingProjectParameterException();
+		}
+	}
+
+	/**
+	 * Initialize config
+	 */
+	protected function InitializeConfig()
+	{
+		$this->config = new GitPHP_Config();
+		$this->config->LoadConfig(GITPHP_CONFIGDIR . 'gitphp.conf.php');
+	}
+
+	/**
+	 * Initialize resource manager
+	 */
+	protected function InitializeResource()
+	{
+		$locale = null;
+
+		$baseurl = GitPHP_Util::BaseUrl();
+
+		if (!empty($this->params['lang'])) {
+			/*
+			 * User picked something
+			 */
+			setcookie(GitPHP_Resource::LocaleCookie, $this->params['lang'], time()+GitPHP_Resource::LocaleCookieLifetime, $baseurl);
+			$locale = $this->params['lang'];
+		} else if (!empty($_COOKIE[GitPHP_Resource::LocaleCookie])) {
+			/**
+			 * Returning user with a preference
+			 */
+			$locale = $_COOKIE[GITPHP_Resource::LocaleCookie];
+		} else {
+			/*
+			 * User's first time here, try by HTTP_ACCEPT_LANGUAGE
+			 */
+			if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
+				$httpAcceptLang = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
+				$locale = GitPHP_Resource::FindPreferredLocale($_SERVER['HTTP_ACCEPT_LANGUAGE']);
+				if (!empty($locale)) {
+					setcookie(GitPHP_Resource::LocaleCookie, $locale, time()+GitPHP_Resource::LocaleCookieLifetime, $baseurl);
+				}
+			}
+		}
+
+		if (empty($locale) && $this->config) {
+			/*
+			 * No preference, fall back on setting
+			 */
+			$locale = $this->config->GetValue('locale');
+		}
+
+		if (!empty($locale) && ($locale != 'en_US')) {
+			try {
+				$this->resource = new GitPHP_Resource($locale);
+			} catch (Exception $e) {
+			}
+		}
+	}
+
+	/**
+	 * Initialize user list
+	 */
+	public function InitializeUserList()
+	{
+		$this->userList = new GitPHP_UserList();
+		$this->userList->LoadUsers(GITPHP_CONFIGDIR . 'users.conf.php');
+		if ($this->userList->GetCount() > 0) {
+			if (!isset($_SESSION))
+				session_start();
+		}
 	}
 
 	/**
@@ -130,7 +218,7 @@
 		if ($this->log)
 			$this->exe->AddObserver($this->log);
 		if ($validate && !$this->exe->Valid()) {
-			throw new GitPHP_MessageException(sprintf(__('Could not run the git executable "%1$s".  You may need to set the "%2$s" config value.'), $this->exe->GetBinary(), 'gitbin'), true, 500);
+			throw new GitPHP_InvalidGitExecutableException($this->exe->GetBinary());
 		}
 	}
 
@@ -140,9 +228,29 @@
 	protected function InitializeProjectList()
 	{
 		if (file_exists(GITPHP_CONFIGDIR . 'projects.conf.php')) {
-			$this->projectList = GitPHP_ProjectList::Instantiate(GITPHP_CONFIGDIR . 'projects.conf.php', false);
+			$this->projectList = GitPHP_ProjectList::Instantiate($this->config, GITPHP_CONFIGDIR . 'projects.conf.php', false);
 		} else {
-			$this->projectList = GitPHP_ProjectList::Instantiate(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')));
+		if ($this->config->GetValue('objectcache')) {
+			$strategy = null;
+			$servers = $this->config->GetValue('memcache');
+			if ($servers) {
+				if (class_exists('Memcached')) {
+					$strategy = new GitPHP_Cache_Memcached($servers);
+				} else if (class_exists('Memcache')) {
+					$strategy = new GitPHP_Cache_Memcache($servers);
+				} else {
+					throw new GitPHP_MissingMemcacheException();
+				}
+			} else {
+				$strategy = new GitPHP_Cache_File(GITPHP_CACHEDIR . 'objects', $this->config->GetValue('objectcachecompress'));
+			}
+			$cache = new GitPHP_Cache($strategy);
+			$cache->SetLifetime($this->config->GetValue('objectcachelifetime'));
+			$this->projectList->SetCache($cache);
 		}
 
 		$this->projectList->SetExe($this->exe);
@@ -164,6 +272,21 @@
 		$this->tpl->addPluginsDir(GITPHP_INCLUDEDIR . 'smartyplugins');
 
 		if ($this->config->GetValue('cache')) {
+			$cacheDir = GITPHP_CACHEDIR . 'templates';
+
+			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->tpl->setCacheDir($cacheDir);
+
 			$this->tpl->caching = Smarty::CACHING_LIFETIME_SAVED;
 			if ($this->config->HasKey('cachelifetime')) {
 				$this->tpl->cache_lifetime = $this->config->GetValue('cachelifetime');
@@ -177,6 +300,26 @@
 
 		}
 
+	}
+
+	/**
+	 * Set router instance
+	 *
+	 * @param GitPHP_Router $router router
+	 */
+	public function SetRouter($router)
+	{
+		$this->router = $router;
+	}
+
+	/**
+	 * Get config instance
+	 *
+	 * @return GitPHP_Config
+	 */
+	public function GetConfig()
+	{
+		return $this->config;
 	}
 
 	/**
@@ -259,10 +402,13 @@
 	 */
 	private function GetCacheKeyPrefix($projectKeys = true)
 	{
-		$cacheKeyPrefix = GitPHP_Resource::GetLocale();
+		if ($this->resource)
+			$cacheKeyPrefix = $this->resource->GetLocale();
+		else
+			$cacheKeyPrefix = 'en_US';
 
 		if ($this->projectList) {
-			$cacheKeyPrefix .= '|' . sha1(serialize($this->projectList->GetConfig())) . '|' . sha1(serialize($this->projectList->GetSettings()));
+			$cacheKeyPrefix .= '|' . sha1(serialize($this->projectList->GetProjectListConfig())) . '|' . sha1(serialize($this->projectList->GetProjectSettings()));
 		}
 		if ($this->project && $projectKeys) {
 			$cacheKeyPrefix .= '|' . sha1($this->project);
@@ -301,11 +447,6 @@
 	public abstract function GetName($local = false);
 
 	/**
-	 * Read query into parameters
-	 */
-	protected abstract function ReadQuery();
-
-	/**
 	 * Set a parameter
 	 *
 	 * @param string $key key to set
@@ -319,6 +460,9 @@
 		if (empty($value))
 			unset($this->params[$key]);
 
+		if (is_string($value))
+			$value = str_replace(chr(0), '', $value);
+
 		$this->params[$key] = $value;
 	}
 
@@ -327,6 +471,7 @@
 	 */
 	protected function LoadHeaders()
 	{
+		$this->headers[] = 'Content-Type: text/html; charset=UTF-8';
 	}
 
 	/**
@@ -360,7 +505,10 @@
 		if ($this->config->HasKey('homelink')) {
 			$this->tpl->assign('homelink', $this->config->GetValue('homelink'));
 		} else {
-			$this->tpl->assign('homelink', __('projects'));
+			if ($this->resource)
+				$this->tpl->assign('homelink', $this->resource->translate('projects'));
+			else
+				$this->tpl->assign('homelink', 'projects');
 		}
 		$this->tpl->assign('action', $this->GetName());
 		$this->tpl->assign('actionlocal', $this->GetName(true));
@@ -374,29 +522,34 @@
 			$this->tpl->assign('search', $this->params['search']);
 		if (isset($this->params['searchtype']))
 			$this->tpl->assign('searchtype', $this->params['searchtype']);
-		$this->tpl->assign('currentlocale', GitPHP_Resource::GetLocale());
-		$this->tpl->assign('resource', GitPHP_Resource::GetInstance());
-		$this->tpl->assign('supportedlocales', GitPHP_Resource::SupportedLocales($this->config->GetValue('debug')));
-
-		$scripturl = $_SERVER['SCRIPT_NAME'];
-		$fullscripturl = '';
-		if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on'))
-			$fullscripturl = 'https://';
-		else
-			$fullscripturl = 'http://';
-		$fullscripturl .= $_SERVER['HTTP_HOST'] . $scripturl;
-
-		if ($this->config->HasKey('self')) {
-			$selfurl = $this->config->GetValue('self');
-			if (!empty($selfurl)) {
-				if (substr($selfurl, -4) != '.php') {
-					$selfurl = GitPHP_Util::AddSlash($selfurl);
-				}
-				$fullscripturl = $selfurl;
-			}
-		}
-		$this->tpl->assign('scripturl', $scripturl);
-		$this->tpl->assign('fullscripturl', $fullscripturl);
+		if ($this->resource) {
+			$this->tpl->assign('currentlocale', $this->resource->GetLocale());
+			$this->tpl->assign('currentprimarylocale', $this->resource->GetPrimaryLocale());
+			$this->tpl->assign('resource', $this->resource);
+		} else {
+			$this->tpl->assign('currentlocale', 'en_US');
+			$this->tpl->assign('currentprimarylocale', 'en');
+		}
+		$this->tpl->assign('supportedlocales', GitPHP_Resource::SupportedLocales(true));
+		if ($this->config->GetValue('graphs'))
+			$this->tpl->assign('enablegraphs', true);
+
+		$this->tpl->assign('baseurl', GitPHP_Util::BaseUrl());
+
+		$requesturl = $_SERVER['REQUEST_URI'];
+		$querypos = strpos($requesturl, '?');
+		if ($querypos !== false)
+			$requesturl = substr($requesturl, 0, $querypos);
+		$this->tpl->assign('requesturl', $requesturl);
+		
+		if ($this->router) {
+			$this->router->SetCleanUrl($this->config->GetValue('cleanurl') ? true : false);
+			$this->router->SetAbbreviate($this->config->GetValue('abbreviateurl') ? true : false);
+			if ($this->config->HasKey('self')) {
+				$this->router->SetBaseUrl($this->config->GetValue('self'));
+			}
+			$this->tpl->assign('router', $this->router);
+		}
 
 		$getvars = explode('&', $_SERVER['QUERY_STRING']);
 		$getvarsmapped = array();
@@ -405,7 +558,7 @@
 			if ($eqpos > 0) {
 				$var = substr($varstr, 0, $eqpos);
 				$val = substr($varstr, $eqpos + 1);
-				if (!(empty($var) || empty($val))) {
+				if (!(empty($var) || empty($val) || ($var == 'q'))) {
 					$getvarsmapped[$var] = urldecode($val);
 				}
 			}
@@ -413,6 +566,16 @@
 		$this->tpl->assign('requestvars', $getvarsmapped);
 
 		$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());
+				}
+			}
+		}
 	}
 
 	/**
@@ -423,7 +586,16 @@
 		$this->LoadHeaders();
 
 		if (count($this->headers) > 0) {
+			$hascontenttype = false;
 			foreach ($this->headers as $hdr) {
+				if (empty($hdr))
+					continue;
+
+				if (strncmp($hdr, 'Content-Type:', 13) === 0) {
+					if ($hascontenttype)
+						throw new Exception('Duplicate Content-Type header');
+					$hascontenttype = true;
+				}
 				header($hdr);
 			}
 		}
@@ -459,7 +631,7 @@
 
 		$this->tpl->clearAllAssign();
 
-		if ($this->log)
+		if ($this->log && $this->projectList)
 			$this->log->Log('MemoryCache count: ' . $this->projectList->GetMemoryCache()->GetCount());
 	}
 

comments