Move projectlist classes to their own folder
[gitphp.git] / include / git / projectlist / ProjectListBase.class.php
blob:a/include/git/projectlist/ProjectListBase.class.php -> blob:b/include/git/projectlist/ProjectListBase.class.php
--- a/include/git/projectlist/ProjectListBase.class.php
+++ b/include/git/projectlist/ProjectListBase.class.php
@@ -1,83 +1,115 @@
 <?php
 /**
- * GitPHP ProjectListBase
- *
  * Base class that all projectlist classes extend
  *
  * @author Christopher Han <xiphux@gmail.com>
  * @copyright Copyright (c) 2010 Christopher Han
  * @package GitPHP
- * @subpackage Git
+ * @subpackage Git\ProjectList
  */
-
-require_once(GITPHP_GITOBJECTDIR . 'Project.class.php');
-require_once(GITPHP_GITOBJECTDIR . 'GitConfig.class.php');
-
-define('GITPHP_SORT_PROJECT', 'project');
-define('GITPHP_SORT_DESCRIPTION', 'descr');
-define('GITPHP_SORT_OWNER', 'owner');
-define('GITPHP_SORT_AGE', 'age');
-
-/**
- * ProjectListBase class
- *
- * @package GitPHP
- * @subpackage Git
- * @abstract
- */
-abstract class GitPHP_ProjectListBase implements Iterator
+abstract class GitPHP_ProjectListBase implements Iterator, GitPHP_Observable_Interface
 {
 	/**
-	 * projects
-	 *
-	 * Stores array of projects internally
-	 *
-	 * @access protected
+	 * Project name sort
+	 *
+	 * @var string
+	 */
+	const ProjectSort = 'project';
+
+	/**
+	 * Project description sort
+	 *
+	 * @var string
+	 */
+	const DescriptionSort = 'descr';
+
+	/**
+	 * Project owner sort
+	 *
+	 * @var string
+	 */
+	const OwnerSort = 'owner';
+
+	/**
+	 * Project age sort
+	 *
+	 * @var string
+	 */
+	const AgeSort = 'age';
+
+	/**
+	 * Project list
+	 *
+	 * @var GitPHP_Project[]
 	 */
 	protected $projects;
 
 	/**
-	 * projectsLoaded
-	 *
-	 * Stores whether the list of projects has been loaded
-	 *
-	 * @access protected
+	 * Whether the list of projects has been loaded
+	 *
+	 * @var boolean
 	 */
 	protected $projectsLoaded = false;
 
 	/**
-	 * projectConfig
-	 *
-	 * Stores the project configuration internally
-	 *
-	 * @access protected
+	 * The projectlist configuration
+	 *
+	 * @var string
 	 */
 	protected $projectConfig = null;
 
 	/**
-	 * projectSettings
-	 *
-	 * Stores the project settings internally
-	 *
-	 * @access protected
+	 * Project settings
+	 *
+	 * @var array
 	 */
 	protected $projectSettings = null;
 
 	/**
-	 * projectRoot
-	 *
-	 * Stores the project root internally
-	 *
-	 * @access protected
+	 * The project root
+	 *
+	 * @var string
 	 */
 	protected $projectRoot = null;
 
 	/**
-	 * __construct
-	 *
+	 * Object cache instance for all projects
+	 *
+	 * @var GitPHP_Cache
+	 */
+	protected $cache = null;
+
+	/**
+	 * Memory cache instance for all projects
+	 *
+	 * @var GitPHP_MemoryCache
+	 */
+	protected $memoryCache = null;
+
+	/**
+	 * Executable for all projects
+	 *
+	 * @var GitPHP_GitExe
+	 */
+	protected $exe = null;
+
+	/**
+	 * Config provider
+	 *
+	 * @var GitPHP_Config
+	 */
+	protected $config = null;
+
+	/**
+	 * Observers
+	 *
+	 * @var GitPHP_Observer_Interface[]
+	 */
+	protected $observers = array();
+
+	/**
 	 * Constructor
 	 *
-	 * @access public
 	 * @param string $projectRoot project root
 	 */
 	public function __construct($projectRoot)
@@ -85,23 +117,98 @@
 		$this->projects = array();
 		$this->projectRoot = GitPHP_Util::AddSlash($projectRoot);
 		if (empty($this->projectRoot)) {
-			throw new GitPHP_MessageException(__('A projectroot must be set in the config'), true, 500);
+			throw new GitPHP_MissingProjectrootException();
 		}
 		if (!is_dir($this->projectRoot)) {
-			throw new Exception(sprintf(__('%1$s is not a directory'), $this->projectRoot));
-		}
-
-	}
-
-	/**
-	 * HasProject
-	 *
-	 * Test if the projectlist contains
-	 * the given project
-	 *
-	 * @access public
+			throw new GitPHP_InvalidDirectoryConfigurationException($this->projectRoot);
+		}
+	}
+
+	/**
+	 * Get config provider
+	 *
+	 * @return GitPHP_Config
+	 */
+	public function GetConfig()
+	{
+		return $this->config;
+	}
+
+	/**
+	 * Set config provider
+	 *
+	 * @param GitPHP_Config $config config provider
+	 */
+	public function SetConfig($config)
+	{
+		$this->config = $config;
+	}
+
+	/**
+	 * Get memory cache instance
+	 *
+	 * @return GitPHP_MemoryCache|null
+	 */
+	public function GetMemoryCache()
+	{
+		return $this->memoryCache;
+	}
+
+	/**
+	 * Set memory cache instance
+	 *
+	 * @param GitPHP_MemoryCache|null $memoryCache memory cache instance
+	 */
+	public function SetMemoryCache($memoryCache)
+	{
+		$this->memoryCache = $memoryCache;
+	}
+
+	/**
+	 * Get object cache instance
+	 *
+	 * @return GitPHP_Cache|null object cache
+	 */
+	public function GetCache()
+	{
+		return $this->cache;
+	}
+
+	/**
+	 * Set object cache instance
+	 *
+	 * @param GitPHP_Cache|null $cache object cache instance
+	 */
+	public function SetCache($cache)
+	{
+		$this->cache = $cache;
+	}
+
+	/**
+	 * Get executable
+	 *
+	 * @return GitPHP_GitExe executable
+	 */
+	public function GetExe()
+	{
+		return $this->exe;
+	}
+
+	/**
+	 * Set executable
+	 *
+	 * @param GitPHP_GitExe $exe executable
+	 */
+	public function SetExe($exe)
+	{
+		$this->exe = $exe;
+	}
+
+	/**
+	 * Test if the projectlist contains the given project
+	 *
 	 * @return boolean true if project exists in list
-	 * @param string $project the project string to find
+	 * @param string $project the project to find
 	 */
 	public function HasProject($project)
 	{
@@ -112,12 +219,9 @@
 	}
 
 	/**
-	 * GetProject
-	 *
 	 * Gets a particular project
 	 *
-	 * @access public
-	 * @return mixed project object or null
+	 * @return GitPHP_Project|null project object or null
 	 * @param string $project the project to find
 	 */
 	public function GetProject($project)
@@ -129,7 +233,7 @@
 			return $this->projects[$project];
 
 		if (!$this->projectsLoaded) {
-			$projObj = $this->InstantiateProject($project);
+			$projObj = $this->LoadProject($project);
 			$this->projects[$project] = $projObj;
 			return $projObj;
 		}
@@ -138,15 +242,12 @@
 	}
 
 	/**
-	 * InstantiateProject
-	 *
-	 * Instantiates a project object
-	 *
-	 * @access protected
+	 * Loads a project
+	 *
 	 * @param string $proj project
-	 * @return mixed project object
-	 */
-	protected function InstantiateProject($proj)
+	 * @return return GitPHP_Project project object
+	 */
+	protected function LoadProject($proj)
 	{
 		$project = new GitPHP_Project(GitPHP_Util::AddSlash($this->projectRoot), $proj);
 
@@ -158,40 +259,88 @@
 			$this->ApplyProjectSettings($project, $this->projectSettings[$proj]);
 		}
 
+		$this->InjectProjectDependencies($project);
+
 		return $project;
 	}
 
 	/**
-	 * GetConfig
-	 *
+	 * Inject project dependency objects
+	 *
+	 * @param GitPHP_Project $project project object
+	 */
+	protected function InjectProjectDependencies($project)
+	{
+		if (!$project)
+			return;
+
+		$compat = $project->GetCompat();
+
+		$loader = null;
+		if ($compat) {
+			$project->SetStrategy(new GitPHP_ProjectLoad_Git($this->exe));
+		} else {
+			$loader = new GitPHP_GitObjectLoader($project);
+			$project->SetStrategy(new GitPHP_ProjectLoad_Raw($loader));
+		}
+
+		$headListStrategy = null;
+		if ($compat) {
+			$headListStrategy = new GitPHP_HeadListLoad_Git($this->exe);
+		} else {
+			$headListStrategy = new GitPHP_HeadListLoad_Raw();
+		}
+		$headList = new GitPHP_HeadList($project, $headListStrategy);
+		$project->SetHeadList($headList);
+
+		$tagListStrategy = null;
+		if ($compat) {
+			$tagListStrategy = new GitPHP_TagListLoad_Git($this->exe);
+		} else {
+			$tagListStrategy = new GitPHP_TagListLoad_Raw();
+		}
+		$tagList = new GitPHP_TagList($project, $tagListStrategy);
+		$project->SetTagList($tagList);
+
+		$manager = new GitPHP_GitObjectManager($project);
+		$manager->SetCompat($compat);
+		if (!$compat) {
+			$manager->SetObjectLoader($loader);
+		}
+		$manager->SetExe($this->exe);
+		if ($this->memoryCache) {
+			$manager->SetMemoryCache($this->memoryCache);
+		}
+		if ($this->cache) {
+			$manager->SetCache($this->cache);
+		}
+		$project->SetObjectManager($manager);
+	}
+
+	/**
 	 * Gets the config defined for this ProjectList
 	 *
-	 * @access public
-	 */
-	public function GetConfig()
+	 * @return mixed project config
+	 */
+	public function GetProjectListConfig()
 	{
 		return $this->projectConfig;
 	}
 
 	/**
-	 * GetSettings
-	 *
 	 * Gets the settings applied to this projectlist
 	 *
-	 * @access public
-	 */
-	public function GetSettings()
+	 * @return array
+	 */
+	public function GetProjectSettings()
 	{
 		return $this->projectSettings;
 	}
 
 	/**
-	 * ApplyGitConfig
-	 *
 	 * Reads the project's git config settings and applies them to the project
 	 *
-	 * @access protected
-	 * @param mixed $project project
+	 * @param GitPHP_Project $project project
 	 */
 	protected function ApplyGitConfig($project)
 	{
@@ -213,6 +362,8 @@
 
 		if ($config->HasValue('gitphp.description')) {
 			$project->SetDescription($config->GetValue('gitphp.description'));
+		} else if ($config->HasValue('gitweb.description')) {
+			$project->SetDescription($config->GetValue('gitweb.description'));
 		}
 
 		if ($config->HasValue('gitphp.category')) {
@@ -247,54 +398,56 @@
 			$project->SetAbbreviateLength($config->GetValue('core.abbrev'));
 		}
 
-	}
-
-	/**
-	 * ApplyGlobalConfig
-	 *
+		if ($config->HasValue('gitphp.allowedusers')) {
+			$project->SetAllowedUsers($config->GetValue('gitphp.allowedusers', true));
+		}
+
+	}
+
+	/**
 	 * Applies global config settings to a project
 	 *
-	 * @access protected
-	 * @param mixed $project project
+	 * @param GitPHP_Project $project project
 	 */
 	protected function ApplyGlobalConfig($project)
 	{
 		if (!$project)
 			return;
 
-		$config = GitPHP_Config::GetInstance();
-
-		if ($config->HasKey('cloneurl')) {
-			$project->SetCloneUrl(GitPHP_Util::AddSlash($config->GetValue('cloneurl'), false) . $project->GetProject());
-		}
-
-		if ($config->HasKey('pushurl')) {
-			$project->SetPushUrl(GitPHP_Util::AddSlash($config->GetValue('pushurl'), false) . $project->GetProject());
-		}
-
-		if ($config->HasKey('bugpattern')) {
-			$project->SetBugPattern($config->GetValue('bugpattern'));
-		}
-
-		if ($config->HasKey('bugurl')) {
-			$project->SetBugUrl($config->GetValue('bugurl'));
-		}
-
-		if ($config->HasKey('compat')) {
-			$project->SetCompat($config->GetValue('compat'));
-		}
-
-		if ($config->HasKey('uniqueabbrev')) {
-			$project->SetUniqueAbbreviation($config->GetValue('uniqueabbrev'));
-		}
-	}
-
-	/**
-	 * LoadProjects
-	 *
+		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);
+		}
+	}
+
+	/**
 	 * Loads all projects in the list
-	 *
-	 * @access public
 	 */
 	public function LoadProjects()
 	{
@@ -308,18 +461,27 @@
 	}
 
 	/**
-	 * PopulateProjects
-	 *
+	 * Filter projects by user access
+	 *
+	 * @param string $username username
+	 */
+	public function FilterByUser($username)
+	{
+		foreach ($this->projects as $path => $project) {
+			if (!$project->UserCanAccess($username))
+				unset($this->projects[$path]);
+		}
+	}
+
+	/**
 	 * Populates the internal list of projects
-	 *
-	 * @access protected
 	 */
 	abstract protected function PopulateProjects();
 
 	/**
-	 * rewind
-	 *
 	 * Rewinds the iterator
+	 *
+	 * @return GitPHP_Project
 	 */
 	function rewind()
 	{
@@ -327,9 +489,9 @@
 	}
 
 	/**
-	 * current
-	 *
 	 * Returns the current element in the array
+	 *
+	 * @return GitPHP_Project
 	 */
 	function current()
 	{
@@ -337,9 +499,9 @@
 	}
 
 	/**
-	 * key
-	 *
 	 * Returns the current key
+	 *
+	 * @return string
 	 */
 	function key()
 	{
@@ -347,9 +509,9 @@
 	}
 
 	/**
-	 * next
-	 * 
 	 * Advance the pointer
+	 *
+	 * @return GitPHP_Project
 	 */
 	function next()
 	{
@@ -357,9 +519,9 @@
 	}
 
 	/**
-	 * valid
-	 *
 	 * Test for a valid pointer
+	 *
+	 * @return boolean
 	 */
 	function valid()
 	{
@@ -367,26 +529,23 @@
 	}
 
 	/**
-	 * Sort
-	 *
 	 * Sorts the project list
 	 *
-	 * @access public
 	 * @param string $sortBy sort method
 	 */
-	public function Sort($sortBy = GITPHP_SORT_PROJECT)
+	public function Sort($sortBy = GitPHP_ProjectListBase::ProjectSort)
 	{
 		switch ($sortBy) {
-			case GITPHP_SORT_DESCRIPTION:
+			case GitPHP_ProjectListBase::DescriptionSort:
 				uasort($this->projects, array('GitPHP_Project', 'CompareDescription'));
 				break;
-			case GITPHP_SORT_OWNER:
+			case GitPHP_ProjectListBase::OwnerSort:
 				uasort($this->projects, array('GitPHP_Project', 'CompareOwner'));
 				break;
-			case GITPHP_SORT_AGE:
+			case GitPHP_ProjectListBase::AgeSort:
 				uasort($this->projects, array('GitPHP_Project', 'CompareAge'));
 				break;
-			case GITPHP_SORT_PROJECT:
+			case GitPHP_ProjectListBase::ProjectSort:
 			default:
 				uasort($this->projects, array('GitPHP_Project', 'CompareProject'));
 				break;
@@ -394,11 +553,8 @@
 	}
 
 	/**
-	 * Count
-	 *
 	 * Gets the count of projects
 	 *
-	 * @access public
 	 * @return integer number of projects
 	 */
 	public function Count()
@@ -407,13 +563,10 @@
 	}
 
 	/**
-	 * Filter
-	 *
 	 * Returns a filtered list of projects
 	 *
-	 * @access public
-	 * @param string $filter filter pattern
-	 * @return array array of filtered projects
+	 * @param string $pattern filter pattern
+	 * @return GitPHP_Project[] array of filtered projects
 	 */
 	public function Filter($pattern = null)
 	{
@@ -434,12 +587,9 @@
 	}
 
 	/**
-	 * ApplyProjectSettings
-	 *
 	 * Applies override settings for a project
 	 *
-	 * @access protected
-	 * @param string $project the project object
+	 * @param GitPHP_Project $project the project object
 	 * @param array $projData project data array
 	 */
 	protected function ApplyProjectSettings($project, $projData)
@@ -474,17 +624,17 @@
 		if (isset($projData['website']) && is_string($projData['website'])) {
 			$project->SetWebsite($projData['website']);
 		}
-	}
-
-	/**
-	 * SetSettings
-	 *
+		if (!empty($projData['allowedusers'])) {
+			$project->SetAllowedUsers($projData['allowedusers']);
+		}
+	}
+
+	/**
 	 * Sets a list of settings for the project list
 	 *
-	 * @access protected
 	 * @param array $settings the array of settings
 	 */
-	public function SetSettings($settings)
+	public function SetProjectSettings($settings)
 	{
 		if ((!$settings) || (count($settings) < 1))
 			return;
@@ -495,11 +645,7 @@
 	}
 
 	/**
-	 * ApplySettings
-	 *
 	 * Applies project settings to project list
-	 *
-	 * @access protected
 	 */
 	protected function ApplySettings()
 	{
@@ -523,5 +669,54 @@
 		}
 	}
 
+	/**
+	 * Add a new observer
+	 *
+	 * @param GitPHP_Observer_Interface $observer observer
+	 */
+	public function AddObserver($observer)
+	{
+		if (!$observer)
+			return;
+
+		if (array_search($observer, $this->observers) !== false)
+			return;
+
+		$this->observers[] = $observer;
+	}
+
+	/**
+	 * Remove an observer
+	 *
+	 * @param GitPHP_Observer_Interface $observer observer
+	 */
+	public function RemoveObserver($observer)
+	{
+		if (!$observer)
+			return;
+
+		$key = array_search($observer, $this->observers);
+
+		if ($key === false)
+			return;
+
+		unset($this->observers[$key]);
+	}
+
+	/**
+	 * Log a message to observers
+	 *
+	 * @param string $message message
+	 */
+	protected function Log($message)
+	{
+		if (empty($message))
+			return;
+
+		foreach ($this->observers as $observer) {
+			$observer->ObjectChanged($this, GitPHP_Observer_Interface::LoggableChange, array($message));
+		}
+	}
+
 }
 

comments