Move heads to their own class, get rid of old ref reading code
Move heads to their own class, get rid of old ref reading code

--- a/include/cache.cache_expire.php
+++ b/include/cache.cache_expire.php
@@ -6,8 +6,6 @@
  *
  *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
  */
-
-require_once('gitutil.git_read_refs.php');
 
 function cache_expire($expireall = false)
 {
@@ -21,12 +19,12 @@
 	if (!$gitphp_current_project)
 		return;
 
-	$headlist = git_read_refs("refs/heads");
+	$headlist = $gitphp_current_project->GetHeads();
 
 	if (count($headlist) > 0) {
-		$age = $headlist[0]['age'];
+		$age = $headlist[0]->GetCommit()->GetAge();
 
-		$tpl->clear_cache(null, sha1($project), null, $age);
+		$tpl->clear_cache(null, sha1($gitphp_current_project->GetProject()), null, $age);
 
 		$tpl->clear_cache('projectlist.tpl', sha1(serialize(GitPHP_ProjectList::GetInstance()->GetConfig())), null, $age);
 	}

--- a/include/display.git_heads.php
+++ b/include/display.git_heads.php
@@ -6,8 +6,6 @@
  *
  *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
  */
-
- require_once('gitutil.git_read_refs.php');
 
 function git_heads()
 {
@@ -21,8 +19,11 @@
 	if (!$tpl->is_cached('heads.tpl', $cachekey)) {
 		$head = $gitphp_current_project->GetHeadCommit()->GetHash();
 		$tpl->assign("head",$head);
-		$headlist = git_read_refs("refs/heads");
-		$tpl->assign("headlist",$headlist);
+
+		$headlist = $gitphp_current_project->GetHeads();
+		if (isset($headlist) && (count($headlist) > 0)) {
+			$tpl->assign("headlist",$headlist);
+		}
 	}
 	$tpl->display('heads.tpl', $cachekey);
 }

--- a/include/display.git_summary.php
+++ b/include/display.git_summary.php
@@ -11,7 +11,6 @@
  require_once(GITPHP_INCLUDEDIR . 'util.date_str.php');
  require_once(GITPHP_INCLUDEDIR . 'util.age_string.php');
  require_once(GITPHP_INCLUDEDIR . 'gitutil.git_read_revlist.php');
- require_once(GITPHP_INCLUDEDIR . 'gitutil.git_read_refs.php');
  require_once(GITPHP_INCLUDEDIR . 'gitutil.read_info_ref.php');
  require_once(GITPHP_INCLUDEDIR . 'git/Project.class.php');
 
@@ -68,7 +67,7 @@
 			$tpl->assign("taglist",$taglist);
 		}
 
-		$headlist = git_read_refs("refs/heads");
+		$headlist = $gitphp_current_project->GetHeads();
 		if (isset($headlist) && (count($headlist) > 0)) {
 			$tpl->assign("headlist",$headlist);
 		}

--- /dev/null
+++ b/include/git/Head.class.php
@@ -1,1 +1,88 @@
+<?php
+/**
+ * GitPHP Head
+ *
+ * Represents a single head
+ *
+ * @author Christopher Han <xiphux@gmail.com>
+ * @copyright Copyright (c) 2010 Christopher Han
+ * @package GitPHP
+ * @subpackage Git
+ */
 
+require_once(GITPHP_INCLUDEDIR . 'git/Ref.class.php');
+
+/**
+ * Head class
+ *
+ * @package GitPHP
+ * @subpackage Git
+ */
+class GitPHP_Head extends GitPHP_Ref
+{
+
+	/**
+	 * commit
+	 *
+	 * Stores the commit internally
+	 *
+	 * @access protected
+	 */
+	protected $commit;
+
+	/**
+	 * __construct
+	 *
+	 * Instantiates head
+	 *
+	 * @access public
+	 * @param mixed $project the project
+	 * @param string $head head name
+	 * @param string $headHash head hash
+	 * @return mixed head object
+	 * @throws Exception exception on invalid head or hash
+	 */
+	public function __construct($project, $head, $headHash = '')
+	{
+		parent::__construct($project, 'heads', $head, $headHash);
+	}
+
+	/**
+	 * GetCommit
+	 *
+	 * Gets the commit for this head
+	 *
+	 * @access public
+	 * @return mixed commit object for this tag
+	 */
+	public function GetCommit()
+	{
+		if (!$this->commit) {
+			$this->commit = $this->project->GetCommit($this->hash);
+		}
+
+		return $this->commit;
+	}
+	
+	/**
+	 * CompareAge
+	 *
+	 * Compares two heads by age
+	 *
+	 * @access public
+	 * @static
+	 * @param mixed $a first head
+	 * @param mixed $b second head
+	 * @return integer comparison result
+	 */
+	public static function CompareAge($a, $b)
+	{
+		$aObj = $a->GetCommit();
+		$bObj = $b->GetCommit();
+		if ($aObj->GetAge() === $bObj->GetAge())
+			return 0;
+		return ($aObj->GetAge() < $bObj->GetAge() ? -1 : 1);
+	}
+
+}
+

--- a/include/git/Project.class.php
+++ b/include/git/Project.class.php
@@ -13,6 +13,7 @@
 require_once(GITPHP_INCLUDEDIR . 'defs.commands.php');
 require_once(GITPHP_INCLUDEDIR . 'git/GitExe.class.php');
 require_once(GITPHP_INCLUDEDIR . 'git/Commit.class.php');
+require_once(GITPHP_INCLUDEDIR . 'git/Head.class.php');
 require_once(GITPHP_INCLUDEDIR . 'git/Tag.class.php');
 
 /**
@@ -512,6 +513,8 @@
 	{
 		if (!$this->readHeads)
 			$this->ReadHeadList();
+
+		return $this->heads;
 	}
 
 	/**
@@ -524,6 +527,26 @@
 	protected function ReadHeadList()
 	{
 		$this->readHeads = true;
+
+		$exe = new GitPHP_GitExe($this);
+		$args = array();
+		$args[] = '--heads';
+		$ret = $exe->Execute(GIT_SHOW_REF, $args);
+		unset($exe);
+
+		$lines = explode("\n", $ret);
+
+		foreach ($lines as $line) {
+			if (preg_match('/^([0-9a-fA-F]{40}) refs\/heads\/(.+)$/', $line, $regs)) {
+				try {
+					$this->heads[] = new GitPHP_Head($this, $regs[2], $regs[1]);
+				} catch (Exception $e) {
+				}
+			}
+		}
+
+		usort($this->heads, array('GitPHP_Head', 'CompareAge'));
+
 	}
 
 

--- a/include/gitutil.git_get_type.php
+++ /dev/null
@@ -1,18 +1,1 @@
-<?php
-/*
- *  gitutil.git_get_type.php
- *  gitphp: A PHP git repository browser
- *  Component: Git utility - get type
- *
- *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
- */
 
-require_once('gitutil.git_cat_file.php');
-
-function git_get_type($hash)
-{
-	return trim(git_cat_file($hash,NULL,"-t"));
-}
-
-?>
-

--- a/include/gitutil.git_read_hash.php
+++ /dev/null
@@ -1,16 +1,1 @@
-<?php
-/*
- *  gitutil.git_read_hash.php
- *  gitphp: A PHP git repository browser
- *  Component: Git utility - read a hash
- *
- *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
- */
 
-function git_read_hash($path)
-{
-	return file_get_contents($path);
-}
-
-?>
-

--- a/include/gitutil.git_read_packed_refs.php
+++ /dev/null
@@ -1,46 +1,1 @@
-<?php
-/*
- *  gitutil.git_read_packed_refs.php
- *  gitphp: a PHP git repository browser
- *  Component: Git utility - read packed refs
- *
- *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
- */
 
- require_once('gitutil.git_read_hash.php');
-
-function git_read_packed_refs($refdir)
-{
-	global $gitphp_current_project;
-
-	if (!$gitphp_current_project)
-		return null;
-
-	$projectroot = GitPHP_Config::GetInstance()->GetValue('projectroot');
-	$project = $gitphp_current_project->GetProject();
-
-	if (!is_file($projectroot . $project . '/packed-refs'))
-		return null;
-
-	$refs = array();
-	$refs = explode("\n",git_read_hash($projectroot . $project . "/" . 'packed-refs'));
-	$reflist = array();
-
-	$dirlen = strlen($refdir);
-
-	foreach ($refs as $i) {
-		if (preg_match('/^([0-9a-f]{40}) (.+)$/i', trim($i), $regs)) {
-			if (strncmp($refdir, $regs[2], $dirlen) === 0) {
-				$regs[2] = substr($regs[2], $dirlen+1);
-				$refobj = git_read_ref($regs[1], $regs[2]);
-				if (isset($refobj))
-					$reflist[] = $refobj;
-			}
-		}
-	}
-
-	return $reflist;
-}
-
-?>
-

--- a/include/gitutil.git_read_ref.php
+++ /dev/null
@@ -1,67 +1,1 @@
-<?php
-/*
- *  gitutil.git_read_ref.php
- *  gitphp: A PHP git repository browser
- *  Component: Git utility - read single ref
- *
- *  Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
- */
 
- require_once('util.age_string.php');
- require_once('gitutil.git_get_type.php');
- require_once('gitutil.git_read_tag.php');
-
- function git_read_ref($ref_id, $ref_file)
- {
- 	global $gitphp_current_project;
-
-	if (!$gitphp_current_project)
-		return null;
-
-	$projectroot = GitPHP_Config::GetInstance()->GetValue('projectroot');
-	$project = $gitphp_current_project->GetProject();
-
-	$type = git_get_type($ref_id);
-
-	if (!$type)
-		return null;
-
-	$ref_item = array();
-	$ref_item['type'] = $type;
-	$ref_item['id'] = $ref_id;
-	$ref_item['epoch'] = 0;
-	$ref_item['age_string'] = "unknown";
-
-	if ($type == "tag") {
-		$tag = git_read_tag($ref_id);
-		$ref_item['comment'] = $tag['comment'];
-		if ($tag['type'] == "commit") {
-			$co = $gitphp_current_project->GetCommit($tag['object']);
-			$ref_item['epoch'] = $co->GetCommitterEpoch();
-			$ref_item['age_string'] = age_string($co->GetAge());
-			$ref_item['age'] = $co->GetAge();
-		} else if (isset($tag['epoch'])) {
-			$age = time() - $tag['epoch'];
-			$ref_item['epoch'] = $tag['epoch'];
-			$ref_item['age_string'] = age_string($age);
-			$ref_item['age'] = $age;
-		}
-		$ref_item['reftype'] = $tag['type'];
-		$ref_item['name'] = $tag['name'];
-		$ref_item['refid'] = $tag['object'];
-	} else if ($type == "commit") {
-		$co = $gitphp_current_project->GetCommit($ref_id);
-		$ref_item['reftype'] = "commit";
-		$ref_item['name'] = $ref_file;
-		$ref_item['title'] = $co->GetTitle();
-		$ref_item['refid'] = $ref_id;
-		$ref_item['epoch'] = $co->GetCommitterEpoch();
-		$ref_item['age_string'] = age_string($co->GetAge());
-		$ref_item['age'] = $co->GetAge();
-	}
-
-	return $ref_item;
- }
-
-?>
-

--- a/include/gitutil.git_read_refs.php
+++ /dev/null
@@ -1,74 +1,1 @@
-<?php
-/*
- *  gitutil.git_read_refs.php
- *  gitphp: A PHP git repository browser
- *  Component: Git utility - read refs
- *
- *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
- */
 
- require_once('util.epochcmp.php');
- require_once('gitutil.git_read_hash.php');
- require_once('gitutil.git_read_ref.php');
- require_once('gitutil.git_read_packed_refs.php');
-
-function git_read_refs($refdir)
-{
-	global $gitphp_current_project;
-
-	if (!$gitphp_current_project)
-		return null;
-
-	$projectroot = GitPHP_Config::GetInstance()->GetValue('projectroot');
-	$project = $gitphp_current_project->GetProject();
-
-	if (!is_dir($projectroot . $project . "/" . $refdir))
-		return null;
-	$refs = array();
-	if ($dh = opendir($projectroot . $project . "/" . $refdir)) {
-		while (($dir = readdir($dh)) !== false) {
-			if (strpos($dir,'.') !== 0) {
-				if (is_dir($projectroot . $project . "/" . $refdir . "/" . $dir)) {
-					if ($dh2 = opendir($projectroot . $project . "/" . $refdir . "/" . $dir)) {
-						while (($dir2 = readdir($dh2)) !== false) {
-							if (strpos($dir2,'.') !== 0)
-								$refs[] = $dir . "/" . $dir2;
-						}
-						closedir($dh2);
-					}
-				}
-				$refs[] = $dir;
-			}
-		}
-		closedir($dh);
-	} else
-		return null;
-	$reflist = array();
-	foreach ($refs as $i => $ref_file) {
-		$ref_id = git_read_hash($projectroot . $project . "/" . $refdir . "/" . $ref_file);
-		$refobj = git_read_ref($ref_id, $ref_file);
-		if (isset($refobj))
-			$reflist[] = $refobj;
-	}
-
-	$packedrefs = git_read_packed_refs($refdir);
-	if (isset($packedrefs) && count($packedrefs) > 0) {
-		foreach ($packedrefs as $packedref) {
-			$found = false;
-			foreach ($reflist as $ref) {
-				if (strcmp($ref["name"], $packedref["name"]) === 0) {
-					$found = true;
-					break;
-				}
-			}
-			if (!$found)
-				$reflist[] = $packedref;
-		}
-	}
-
-	usort($reflist,"epochcmp");
-	return $reflist;
-}
-
-?>
-

--- a/include/gitutil.git_read_tag.php
+++ /dev/null
@@ -1,46 +1,1 @@
-<?php
-/*
- *  gitutil.git_read_tag.php
- *  gitphp: A PHP git repository browser
- *  Component: Git utility - read tag
- *
- *  Copyright (C) 2008 Christopher Han <xiphux@gmail.com>
- */
 
- require_once('gitutil.git_cat_file.php');
-
-function git_read_tag($tag_id)
-{
-	$tag = array();
-	$tagout = git_cat_file($tag_id, NULL, "tag");
-	$tag['id'] = $tag_id;
-	$comment = array();
-	$tok = strtok($tagout,"\n");
-	while ($tok !== false) {
-		if (preg_match("/^object ([0-9a-fA-F]{40})$/",$tok,$regs))
-			$tag['object'] = $regs[1];
-		else if (preg_match("/^type (.+)$/",$tok,$regs))
-			$tag['type'] = $regs[1];
-		else if (preg_match("/^tag (.+)$/",$tok,$regs))
-			$tag['name'] = $regs[1];
-		else if (preg_match("/^tagger (.*) ([0-9]+) (.*)$/",$tok,$regs)) {
-			$tag['author'] = $regs[1];
-			$tag['epoch'] = $regs[2];
-			$tag['tz'] = $regs[3];
-		} else {
-			while ($tok !== false) {
-				$comment[] = $tok;
-				$tok = strtok("\n");
-			}
-			break;
-		}
-		$tok = strtok("\n");
-	}
-	$tag['comment'] = $comment;
-	if (!isset($tag['name']))
-		return null;
-	return $tag;
-}
-
-?>
-

file:a/index.php -> file:b/index.php
--- a/index.php
+++ b/index.php
@@ -89,7 +89,7 @@
  	$tpl->caching = 2;
 	if (GitPHP_Config::GetInstance()->HasKey('cachelifetime'))
 		$tpl->cache_lifetime = GitPHP_Config::GetInstance()->GetValue('cachelifetime');
-	if (GitPHP_Config::GetInstance()->GetValue('cacheexpire', true) === false) {
+	if (GitPHP_Config::GetInstance()->GetValue('cacheexpire', true) === true) {
 		require_once(GITPHP_INCLUDEDIR . 'cache.cache_expire.php');
 		cache_expire();
 	}
@@ -104,8 +104,7 @@
  if ($project) {
 	$tpl->assign("validproject",TRUE);
 	$tpl->assign("project",$project);
-	$projectObj = GitPHP_ProjectList::GetInstance()->GetProject($project);
-	$tpl->assign("projectdescription", $projectObj->GetDescription());
+	$tpl->assign("projectdescription", $gitphp_current_project->GetDescription());
 	if (isset($_GET['a'])) {
 		$tpl->assign("action",$_GET['a']);
 		$tpl->assign("validaction", TRUE);

--- a/templates/heads.tpl
+++ b/templates/heads.tpl
@@ -19,10 +19,11 @@
  <table cellspacing="0">
    {* Loop and display each head *}
    {foreach from=$headlist item=head}
+     {assign var=commit value=$head->GetCommit()}
      <tr class="{cycle values="light,dark"}">
-       <td><i>{$head.age_string}</i></td>
-       <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head.name}" class="list"><b>{$head.name}</b></a></td>
-       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head.name}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$head.name}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$head.name}&hb={$head.name}">tree</a></td>
+       <td><em>{$commit->GetAge()|agestring}</em></td>
+       <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head->GetName()}" class="list"><strong>{$head->GetName()}</strong></a></td>
+       <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$head->GetName()}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$head->GetName()}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$head->GetName()}&hb={$commit->GetHash()}">tree</a></td>
      </tr>
    {/foreach}
  </table>

--- a/templates/project.tpl
+++ b/templates/project.tpl
@@ -96,9 +96,10 @@
          {if $smarty.section.head.index == 16}
            <td><a href="{$SCRIPT_NAME}?p={$project}&a=heads">...</a></td>
          {else}
-           <td><em>{$headlist[head].age_string}</em></td>
-           <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head].name}" class="list"><strong>{$headlist[head].name}</strong></td>
-           <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head].name}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$headlist[head].name}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$headlist[head].name}&hb={$headlist[head].name}">tree</a></td>
+	   {assign var=commit value=$headlist[head]->GetCommit()}
+           <td><em>{$commit->GetAge()|agestring}</em></td>
+           <td><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head]->GetName()}" class="list"><strong>{$headlist[head]->GetName()}</strong></td>
+           <td class="link"><a href="{$SCRIPT_NAME}?p={$project}&a=shortlog&h=refs/heads/{$headlist[head]->GetName()}">shortlog</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=log&h=refs/heads/{$headlist[head]->GetName()}">log</a> | <a href="{$SCRIPT_NAME}?p={$project}&a=tree&h=refs/heads/{$headlist[head]->GetName()}&hb={$commit->GetHash()}">tree</a></td>
          {/if}
        </tr>
      {/section}

comments