Create projectlist classes
Create projectlist classes

--- a/include/Config.class.php
+++ b/include/Config.class.php
@@ -1,6 +1,7 @@
 <?php
 /**
- * GitPHP
+ * GitPHP Config
+ *
  * Configfile reader class
  *
  * @author Christopher Han <xiphux@gmail.com>

--- a/include/defs.constants.php
+++ b/include/defs.constants.php
@@ -15,5 +15,7 @@
 define("GITPHP_COMPRESS_GZ", 2);
 define("GITPHP_COMPRESS_ZIP", 3);
 
+define('GITPHP_NO_CATEGORY', 'none');
+
 ?>
 

--- a/include/git/Project.class.php
+++ b/include/git/Project.class.php
@@ -1,11 +1,13 @@
 <?php
 /**
- * GitPHP
- * Project class
+ * GitPHP Project
+ * 
+ * Represents a single git project
  *
  * @author Christopher Han <xiphux@gmail.com>
  * @copyright Copyright (c) 2010 Christopher Han
  * @package GitPHP
+ * @subpackage Git
  */
 
 require_once(GITPHP_INCLUDEDIR . 'defs.constants.php');
@@ -14,6 +16,7 @@
  * Project class
  *
  * @package GitPHP
+ * @subpackage Git
  */
 class GitPHP_Project
 {
@@ -63,6 +66,15 @@
 	 * @access protected
 	 */
 	protected $readDescription = false;
+
+	/**
+	 * category
+	 *
+	 * Stores the category internally
+	 *
+	 * @access protected
+	 */
+	protected $category = "";
 
 	/**
 	 * __construct
@@ -208,5 +220,31 @@
 	{
 	}
 
+	/**
+	 * GetCategory
+	 *
+	 * Gets the project's category
+	 *
+	 * @access public
+	 * @return string category
+	 */
+	public function GetCategory()
+	{
+		return $this->category;
+	}
+
+	/**
+	 * SetCategory
+	 * 
+	 * Sets the project's category
+	 *
+	 * @access public
+	 * @param string $category category
+	 */
+	public function SetCategory($category)
+	{
+		$this->category = $category;
+	}
+
 }
 

--- /dev/null
+++ b/include/git/ProjectList.class.php
@@ -1,1 +1,92 @@
+<?php
+/**
+ * GitPHP ProjectList
+ *
+ * Project list singleton instance and factory
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
 
+require_once(GITPHP_INCLUDEDIR . 'Config.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/ProjectListDirectory.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/ProjectListFile.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/ProjectListArray.class.php');
+
+/**
+ * ProjectList class
+ *
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_ProjectList
+{
+
+	/**
+	 * instance
+	 *
+	 * Stores the singleton instance of the projectlist
+	 *
+	 * @access protected
+	 * @static
+	 */
+	protected static $instance = null;
+
+	/**
+	 * GetInstance
+	 *
+	 * Returns the singleton instance
+	 *
+	 * @access public
+	 * @static
+	 * @return mixed instance of projectlist
+	 * @throws Exception if projectlist has not been instantiated yet
+	 */
+	public static function GetInstance()
+	{
+		if (!self::$instance) {
+			throw new Exception('ProjectList has not been instantiated.');
+		}
+
+		return self::$instance;
+	}
+
+	/**
+	 * Instantiate
+	 *
+	 * Instantiates the singleton instance
+	 *
+	 * @access private
+	 * @static
+	 * @param string $file config file with git projects
+	 * @throws Exception if there was an error reading the file
+	 */
+	public static function Instantiate($file = null)
+	{
+		if (self::$instance)
+			return;
+
+		if (!empty($file) && is_file($file) && include($file)) {
+			if (is_string($git_projects)) {
+				try {
+					self::$instance = new GitPHP_ProjectListFile($git_projects);
+					return;
+				} catch (Exception $e) {
+				}
+			} else if (is_array($git_projects)) {
+				try {
+					self::$instance = new GitPHP_ProjectListArray($git_projects);
+					return;
+				} catch (Exception $e) {
+				}
+			}
+		}
+
+		self::$instance = new GitPHP_ProjectListDirectory(GitPHP_Config::GetInstance()->GetValue('projectroot'));
+	}
+
+}
+
+

--- /dev/null
+++ b/include/git/ProjectListArray.class.php
@@ -1,1 +1,72 @@
+<?php
+/**
+ * GitPHP ProjectListArray
+ *
+ * Lists all projects in a multidimensional array
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
 
+require_once(GITPHP_INCLUDEDIR . 'defs.constants.php');
+require_once(GITPHP_INCLUDEDIR . 'git/ProjectListBase.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/Project.class.php');
+
+/**
+ * ProjectListArray class
+ *
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_ProjectListArray extends GitPHP_ProjectListBase
+{
+
+	/**
+	 * __construct
+	 *
+	 * constructor
+	 *
+	 * @param mixed $projectArray array to read
+	 * @throws Exception if parameter is not an array
+	 * @access public
+	 */
+	public function __construct($projectArray)
+	{
+		if (!is_array($projectArray)) {
+			throw new Exception('An array of projects is required.');
+		}
+
+		$this->projectConfig = $projectArray;
+
+		parent::__construct();
+	}
+
+	/**
+	 * PopulateProjects
+	 *
+	 * Populates the internal list of projects
+	 *
+	 * @access protected
+	 * @throws Exception if file cannot be read
+	 */
+	protected function PopulateProjects()
+	{
+		foreach ($this->projectConfig as $cat => $plist) {
+			if (is_array($plist)) {
+				foreach ($plist as $pname => $ppath) {
+					try {
+						$projObj = new GitPHP_Project($ppath);
+						if ($cat != GITPHP_NO_CATEGORY)
+							$projObj->SetCategory($cat);
+						$this->projects[] = $projObj;
+					} catch (Exception $e) {
+					}
+				}
+			}
+		}
+	}
+
+}
+

--- /dev/null
+++ b/include/git/ProjectListBase.class.php
@@ -1,1 +1,113 @@
+<?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
+ */
 
+/**
+ * ProjectListBase class
+ *
+ * @package GitPHP
+ * @subpackage Git
+ * @abstract
+ */
+abstract class GitPHP_ProjectListBase
+{
+	/**
+	 * projects
+	 *
+	 * Stores array of projects internally
+	 *
+	 * @access protected
+	 */
+	protected $projects;
+
+	/**
+	 * projectConfig
+	 *
+	 * Stores the project configuration internally
+	 *
+	 * @access protected
+	 */
+	protected $projectConfig = null;
+
+	/**
+	 * __construct
+	 *
+	 * Constructor
+	 *
+	 * @access public
+	 */
+	public function __construct()
+	{
+		$this->projects = array();
+		$this->PopulateProjects();
+	}
+
+	/**
+	 * HasProject
+	 *
+	 * Test if the projectlist contains
+	 * the given project
+	 *
+	 * @access public
+	 * @return boolean true if project exists in list
+	 * @param string $project the project string to find
+	 */
+	public function HasProject($project)
+	{
+		return ($this->GetProject($project) !== null);
+	}
+
+	/**
+	 * GetProject
+	 *
+	 * Gets a particular project
+	 *
+	 * @access public
+	 * @return mixed project object or null
+	 * @param string $project the project to find
+	 */
+	public function GetProject($project)
+	{
+		if (empty($project))
+			return null;
+
+		foreach ($this->projects as $projObj) {
+			if ($projObj->GetProject() == $project) {
+				return $projObj;
+			}
+		}
+
+		return null;
+	}
+
+	/**
+	 * GetConfig
+	 *
+	 * Gets the config defined for this ProjectList
+	 *
+	 * @access public
+	 */
+	public function GetConfig()
+	{
+		return $this->projectConfig;
+	}
+
+	/**
+	 * PopulateProjects
+	 *
+	 * Populates the internal list of projects
+	 *
+	 * @access protected
+	 */
+	abstract protected function PopulateProjects();
+
+}
+

--- /dev/null
+++ b/include/git/ProjectListDirectory.class.php
@@ -1,1 +1,99 @@
+<?php
+/**
+ * GitPHP ProjectListDirectory
+ *
+ * Lists all projects in a given directory
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
 
+require_once(GITPHP_INCLUDEDIR . 'Config.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/ProjectListBase.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/Project.class.php');
+
+/**
+ * ProjectListDirectory class
+ *
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_ProjectListDirectory extends GitPHP_ProjectListBase
+{
+	
+	/**
+	 * projectDir
+	 *
+	 * Stores projectlist directory internally
+	 *
+	 * @access protected
+	 */
+	protected $projectDir;
+
+	/**
+	 * __construct
+	 *
+	 * constructor
+	 *
+	 * @param string $projectDir directory to search
+	 * @throws Exception if parameter is not a directory
+	 * @access public
+	 */
+	public function __construct($projectDir)
+	{
+		if (!is_dir($projectDir)) {
+			throw new Exception($projectDir . ' is not a directory.');
+		}
+
+		$this->projectDir = $projectDir;
+
+		parent::__construct();
+	}
+
+	/**
+	 * PopulateProjects
+	 *
+	 * Populates the internal list of projects
+	 *
+	 * @access protected
+	 */
+	protected function PopulateProjects()
+	{
+		$this->RecurseDir($this->projectDir);
+	}
+
+	/**
+	 * RecurseDir
+	 *
+	 * Recursively searches for projects
+	 *
+	 * @param string $dir directory to recurse into
+	 */
+	private function RecurseDir($dir)
+	{
+		if (!is_dir($dir))
+			return;
+
+		if ($dh = opendir($dir)) {
+			while (($file = readdir($dh)) !== false) {
+				$fullPath = $dir . '/' . $file;
+				if ((strpos($file, '.') !== 0) && is_dir($fullPath)) {
+					if (is_file($fullPath . '/HEAD')) {
+						$projectPath = substr($fullPath, strlen(GitPHP_Config::GetInstance()->GetValue('projectroot')) + 1);
+						try {
+							$this->projects[] = new GitPHP_Project($projectPath);
+						} catch (Exception $e) {
+						}
+					} else {
+						$this->RecurseDir($fullPath);
+					}
+				}
+			}
+			closedir($dh);
+		}
+	}
+
+}
+

--- /dev/null
+++ b/include/git/ProjectListFile.class.php
@@ -1,1 +1,84 @@
+<?php
+/**
+ * GitPHP ProjectListFile
+ *
+ * Lists all projects in a given file
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
 
+require_once(GITPHP_INCLUDEDIR . 'Config.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/ProjectListBase.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/Project.class.php');
+
+/**
+ * ProjectListFile class
+ *
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_ProjectListFile extends GitPHP_ProjectListBase
+{
+	
+	/**
+	 * __construct
+	 *
+	 * constructor
+	 *
+	 * @param string $projectFile file to read
+	 * @throws Exception if parameter is not a readable file
+	 * @access public
+	 */
+	public function __construct($projectFile)
+	{
+		if (!(is_string($projectFile) && is_file($projectFile))) {
+			throw new Exception($projectFile . ' is not a file.');
+		}
+
+		$this->projectConfig = $projectFile;
+
+		parent::__construct();
+	}
+
+	/**
+	 * PopulateProjects
+	 *
+	 * Populates the internal list of projects
+	 *
+	 * @access protected
+	 * @throws Exception if file cannot be read
+	 */
+	protected function PopulateProjects()
+	{
+		if (!($fp = fopen($this->projectConfig, 'r'))) {
+			throw new Exception('Failed to open project list file ' . $this->projectConfig . '.');
+		}
+
+		$projectRoot = GitPHP_Config::GetInstance()->GetValue('projectroot');
+
+		while (!feof($fp) && ($line = fgets($fp))) {
+			$pinfo = explode(' ', $line);
+			$ppath = trim($pinfo[0]);
+			if (is_file($projectRoot . $ppath . '/HEAD')) {
+				try {
+					$projObj = new GitPHP_Project($ppath);
+					if (isset($pinfo[1])) {
+						$projOwner = trim($pinfo[1]);
+						if (!empty($projOwner)) {
+							$projObj->SetOwner($projOwner);
+						}
+					}
+					$this->projects[] = $projObj;
+				} catch (Exception $e) {
+				}
+			}
+		}
+
+		fclose($fp);
+	}
+
+}
+

--- a/include/gitutil.git_project_info.php
+++ b/include/gitutil.git_project_info.php
@@ -9,11 +9,10 @@
 
  require_once(GITPHP_INCLUDEDIR . 'gitutil.git_read_head.php');
  require_once(GITPHP_INCLUDEDIR . 'gitutil.git_read_commit.php');
- require_once(GITPHP_INCLUDEDIR . 'git/Project.class.php');
 
 function git_project_info($projectroot,$project)
 {
-	$projectObj = new GitPHP_Project($project);
+	$projectObj = GitPHP_ProjectList::GetInstance()->GetProject($project);
 
 	$projinfo = array();
 	$projinfo["project"] = $project;

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -27,7 +27,6 @@
  /*
   * Configuration
   */
- require_once(GITPHP_CONFIGDIR . 'gitphp.conf.php');
  require_once(GITPHP_INCLUDEDIR . 'Config.class.php');
  try {
  	GitPHP_Config::GetInstance()->LoadConfig(GITPHP_CONFIGDIR . 'gitphp.conf.php.example');
@@ -35,39 +34,17 @@
  }
  GitPHP_Config::GetInstance()->LoadConfig(GITPHP_CONFIGDIR . 'gitphp.conf.php');
 
+ /**
+  * Project list
+  */
+ require_once(GITPHP_INCLUDEDIR . 'git/ProjectList.class.php');
+ GitPHP_ProjectList::Instantiate(GITPHP_CONFIGDIR . 'gitphp.conf.php');
 
  $project = null;
 
  if (isset($_GET['p'])) {
- 	$fullpath = realpath(GitPHP_Config::GetInstance()->GetValue('projectroot') . $_GET['p']);
-	$realprojroot = realpath(GitPHP_Config::GetInstance()->GetValue('projectroot'));
-	$pathpiece = substr($fullpath, 0, strlen($realprojroot));
-	if (strcmp($pathpiece, $realprojroot) === 0) {
-		if (is_string($git_projects) && is_file($git_projects)) {
-			if ($fp = fopen($git_projects, 'r')) {
-				while (!feof($fp) && ($line = fgets($fp))) {
-					$pinfo = explode(' ', $line);
-					$ppath = trim($pinfo[0]);
-					if ($ppath == $_GET['p']) {
-						$project = $_GET['p'];
-						break;
-					}
-				}
-				fclose($fp);
-			}
-		} else if (is_array($git_projects)) {
-			foreach ($git_projects as $category) {
-				if (array_search($_GET['p'], $category)) {
-					$project = $_GET['p'];
-					break;
-				}
-			}
-		} else {
-			$project = $_GET['p'];
-		}
-		if (isset($project))
-			$project = str_replace(chr(0), '', $project);
-	}
+ 	if (GitPHP_ProjectList::GetInstance()->HasProject($_GET['p']))
+		$project = str_replace(chr(0), '', $_GET['p']);
  }
 
  $extraoutput = FALSE;
@@ -103,7 +80,7 @@
 		$tpl->cache_lifetime = GitPHP_Config::GetInstance()->GetValue('cachelifetime');
 	if (GitPHP_Config::GetInstance()->GetValue('cacheexpire', true) === false) {
 		require_once(GITPHP_INCLUDEDIR . 'cache.cache_expire.php');
-		cache_expire(GitPHP_Config::GetInstance()->GetValue('projectroot'), $project, (isset($git_projects) ? $git_projects : null));
+		cache_expire(GitPHP_Config::GetInstance()->GetValue('projectroot'), $project, GitPHP_ProjectList::GetInstance()->GetConfig());
 	}
  }
 
@@ -116,8 +93,7 @@
  if ($project) {
 	$tpl->assign("validproject",TRUE);
 	$tpl->assign("project",$project);
-	require_once(GITPHP_INCLUDEDIR . 'git/Project.class.php');
-	$projectObj = new GitPHP_Project($project);
+	$projectObj = GitPHP_ProjectList::GetInstance()->GetProject($project);
 	$tpl->assign("projectdescription", $projectObj->GetDescription());
 	if (isset($_GET['a'])) {
 		$tpl->assign("action",$_GET['a']);
@@ -147,10 +123,10 @@
 	git_message("Cache expired");
  } else if (isset($_GET['a']) && $_GET['a'] == "opml") {
 	require_once(GITPHP_INCLUDEDIR . 'display.git_opml.php');
-	git_opml(GitPHP_Config::GetInstance()->GetValue('projectroot'), (isset($git_projects) ? $git_projects : null));
+	git_opml(GitPHP_Config::GetInstance()->GetValue('projectroot'), GitPHP_ProjectList::GetInstance()->GetConfig());
  } else if (isset($_GET['a']) && $_GET['a'] == "project_index") {
 	require_once(GITPHP_INCLUDEDIR . 'display.git_project_index.php');
-	git_project_index(GitPHP_Config::GetInstance()->GetValue('projectroot'),(isset($git_projects) ? $git_projects : null));
+	git_project_index(GitPHP_Config::GetInstance()->GetValue('projectroot'), GitPHP_ProjectList::GetInstance()->GetConfig());
  } else if ($project) {
  	if (!is_dir(GitPHP_Config::GetInstance()->GetValue('projectroot') . $project)) {
 		$tpl->assign("validproject",FALSE);
@@ -257,7 +233,7 @@
 	}
  } else {
 	require_once(GITPHP_INCLUDEDIR . 'display.git_project_list.php');
-	git_project_list(GitPHP_Config::GetInstance()->GetValue('projectroot'), (isset($git_projects) ? $git_projects : null), (isset($_GET['o']) ? $_GET['o'] : "project"));
+	git_project_list(GitPHP_Config::GetInstance()->GetValue('projectroot'), GitPHP_ProjectList::GetInstance()->GetConfig(), (isset($_GET['o']) ? $_GET['o'] : "project"));
  }
 
  if (GitPHP_Config::GetInstance()->GetValue('debug', false) && $extraoutput)

comments