Update rss with validator recommendations
Update rss with validator recommendations

<?php <?php
/** /**
* Controller for displaying a project's feed * Controller for displaying a project's feed
* *
* @author Christopher Han <xiphux@gmail.com> * @author Christopher Han <xiphux@gmail.com>
* @author Christian Weiske <cweiske@cweiske.de> * @author Christian Weiske <cweiske@cweiske.de>
* @copyright Copyright (c) 2010 Christopher Han * @copyright Copyright (c) 2010 Christopher Han
* @package GitPHP * @package GitPHP
* @subpackage Controller * @subpackage Controller
*/ */
class GitPHP_Controller_Feed extends GitPHP_ControllerBase class GitPHP_Controller_Feed extends GitPHP_ControllerBase
{ {
/** /**
* Number of items to put in feed * Number of items to put in feed
* *
* @var int * @var int
*/ */
const FeedItemCount = 150; const FeedItemCount = 150;
   
/** /**
* Rss feed format * Rss feed format
* *
* @var string * @var string
*/ */
const RssFormat = 'rss'; const RssFormat = 'rss';
   
/** /**
* Atom feed format * Atom feed format
* *
* @var string * @var string
*/ */
const AtomFormat = 'atom'; const AtomFormat = 'atom';
   
/** /**
* Initialize controller * Initialize controller
*/ */
public function Initialize() public function Initialize()
{ {
parent::Initialize(); parent::Initialize();
$this->preserveWhitespace = true; $this->preserveWhitespace = true;
$this->DisableLogging(); $this->DisableLogging();
} }
   
/** /**
* Gets the template for this controller * Gets the template for this controller
* *
* @return string template filename * @return string template filename
*/ */
protected function GetTemplate() protected function GetTemplate()
{ {
if ($this->params['format'] == GitPHP_Controller_Feed::RssFormat) if ($this->params['format'] == GitPHP_Controller_Feed::RssFormat)
return 'rss.tpl'; return 'rss.tpl';
else if ($this->params['format'] == GitPHP_Controller_Feed::AtomFormat) else if ($this->params['format'] == GitPHP_Controller_Feed::AtomFormat)
return 'atom.tpl'; return 'atom.tpl';
} }
   
/** /**
* Gets the cache key for this controller * Gets the cache key for this controller
* *
* @return string cache key * @return string cache key
*/ */
protected function GetCacheKey() protected function GetCacheKey()
{ {
return ''; return '';
} }
   
/** /**
* 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 function GetName($local = false) public function GetName($local = false)
{ {
if ($this->params['format'] == GitPHP_Controller_Feed::RssFormat) { if ($this->params['format'] == GitPHP_Controller_Feed::RssFormat) {
if ($local && $this->resource) if ($local && $this->resource)
return $this->resource->translate('rss'); return $this->resource->translate('rss');
else else
return 'rss'; return 'rss';
} else if ($this->params['format'] == GitPHP_Controller_Feed::AtomFormat) { } else if ($this->params['format'] == GitPHP_Controller_Feed::AtomFormat) {
if ($local && $this->resource) if ($local && $this->resource)
return $this->resource->translate('atom'); return $this->resource->translate('atom');
else else
return 'atom'; return 'atom';
} }
} }
   
/** /**
* Loads headers for this template * Loads headers for this template
*/ */
protected function LoadHeaders() protected function LoadHeaders()
{ {
if ((!isset($this->params['format'])) || empty($this->params['format'])) { if ((!isset($this->params['format'])) || empty($this->params['format'])) {
throw new Exception('A feed format is required'); throw new Exception('A feed format is required');
} }
   
if ($this->params['format'] == GitPHP_Controller_Feed::RssFormat) { if ($this->params['format'] == GitPHP_Controller_Feed::RssFormat) {
$this->headers[] = "Content-type: text/xml; charset=UTF-8"; $this->headers[] = "Content-type: application/rss+xml; charset=UTF-8";
} else if ($this->params['format'] == GitPHP_Controller_Feed::AtomFormat) { } else if ($this->params['format'] == GitPHP_Controller_Feed::AtomFormat) {
$this->headers[] = "Content-type: application/atom+xml; charset=UTF-8"; $this->headers[] = "Content-type: application/atom+xml; charset=UTF-8";
} }
} }
   
/** /**
* Loads data for this template * Loads data for this template
*/ */
protected function LoadData() protected function LoadData()
{ {
$compat = $this->GetProject()->GetCompat(); $compat = $this->GetProject()->GetCompat();
$strategy = null; $strategy = null;
//if ($compat) { //if ($compat) {
$strategy = new GitPHP_LogLoad_Git($this->exe); $strategy = new GitPHP_LogLoad_Git($this->exe);
//} else { //} else {
// $strategy = new GitPHP_LogLoad_Raw(); // $strategy = new GitPHP_LogLoad_Raw();
//} //}
$log = new GitPHP_Log($this->GetProject(), $this->GetProject()->GetHeadCommit(), $strategy, GitPHP_Controller_Feed::FeedItemCount); $log = new GitPHP_Log($this->GetProject(), $this->GetProject()->GetHeadCommit(), $strategy, GitPHP_Controller_Feed::FeedItemCount);
$log->FilterOldCommits(48*60*60, 20); $log->FilterOldCommits(48*60*60, 20);
   
$this->tpl->assign('log', $log); $this->tpl->assign('log', $log);
   
$this->tpl->assign('gitexe', $this->exe); $this->tpl->assign('gitexe', $this->exe);
} }
   
} }
   
<?php <?php
/** /**
* Represents a single commit * Represents a single commit
* *
* @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 Git\Commit * @subpackage Git\Commit
*/ */
class GitPHP_Commit extends GitPHP_GitObject implements GitPHP_Observable_Interface, GitPHP_Cacheable_Interface class GitPHP_Commit extends GitPHP_GitObject implements GitPHP_Observable_Interface, GitPHP_Cacheable_Interface
{ {
   
/** /**
* Whether data for this commit has been read * Whether data for this commit has been read
* *
* @var boolean * @var boolean
*/ */
protected $dataRead = false; protected $dataRead = false;
   
/** /**
* Array of parent commits * Array of parent commits
* *
* @var string[] * @var string[]
*/ */
protected $parents = array(); protected $parents = array();
   
/** /**
* Tree hash for this commit * Tree hash for this commit
* *
* @var string * @var string
*/ */
protected $tree; protected $tree;
   
/** /**
* Author for this commit * Author for this commit
* *
* @var string * @var string
*/ */
protected $author; protected $author;
   
/** /**
* Author's epoch * Author's epoch
* *
* @var string * @var string
*/ */
protected $authorEpoch; protected $authorEpoch;
   
/** /**
* Author's timezone * Author's timezone
* *
* @var string * @var string
*/ */
protected $authorTimezone; protected $authorTimezone;
   
/** /**
* Committer for this commit * Committer for this commit
* *
* @var string * @var string
*/ */
protected $committer; protected $committer;
   
/** /**
* Committer's epoch * Committer's epoch
* *
* @var string * @var string
*/ */
protected $committerEpoch; protected $committerEpoch;
   
/** /**
* Committer's timezone * Committer's timezone
* *
* @var string * @var string
*/ */
protected $committerTimezone; protected $committerTimezone;
   
/** /**
* The commit title * The commit title
* *
* @var string * @var string
*/ */
protected $title; protected $title;
   
/** /**
* The commit comment * The commit comment
* *
* @var string * @var string
*/ */
protected $comment = array(); protected $comment = array();
   
/** /**
* Whether tree filenames have been read * Whether tree filenames have been read
* *
* @var boolean * @var boolean
*/ */
protected $readTree = false; protected $readTree = false;
   
/** /**
* The tag containing the changes in this commit * The tag containing the changes in this commit
* *
* @var string * @var string
*/ */
protected $containingTag = null; protected $containingTag = null;
   
/** /**
* Whether the containing tag has been looked up * Whether the containing tag has been looked up
* *
* @var boolean * @var boolean
*/ */
protected $containingTagRead = false; protected $containingTagRead = false;
   
/** /**
* Observers * Observers
* *
* @var array * @var array
*/ */
protected $observers = array(); protected $observers = array();
   
/** /**
* Data load strategy * Data load strategy
* *
* @var GitPHP_CommitLoadStrategy_Interface * @var GitPHP_CommitLoadStrategy_Interface
*/ */
protected $strategy; protected $strategy;
   
/** /**
* Instantiates object * Instantiates object
* *
* @param GitPHP_Project $project the project * @param GitPHP_Project $project the project
* @param string $hash object hash * @param string $hash object hash
* @param GitPHP_CommitLoadStrategy_Interface $strategy load strategy * @param GitPHP_CommitLoadStrategy_Interface $strategy load strategy
*/ */
public function __construct($project, $hash, GitPHP_CommitLoadStrategy_Interface $strategy) public function __construct($project, $hash, GitPHP_CommitLoadStrategy_Interface $strategy)
{ {
parent::__construct($project, $hash); parent::__construct($project, $hash);
   
if (!$strategy) if (!$strategy)
throw new Exception('Commit load strategy is required'); throw new Exception('Commit load strategy is required');
   
$this->SetStrategy($strategy); $this->SetStrategy($strategy);
} }
   
/** /**
* Set the load strategy * Set the load strategy
* *
* @param GitPHP_CommitLoadStrategy_Interface $strategy load strategy * @param GitPHP_CommitLoadStrategy_Interface $strategy load strategy
*/ */
public function SetStrategy(GitPHP_CommitLoadStrategy_Interface $strategy) public function SetStrategy(GitPHP_CommitLoadStrategy_Interface $strategy)
{ {
if (!$strategy) if (!$strategy)
return; return;
   
$this->strategy = $strategy; $this->strategy = $strategy;
} }
   
/** /**
* Gets the hash for this commit (overrides base) * Gets the hash for this commit (overrides base)
* *
* @param boolean $abbreviate true to abbreviate hash * @param boolean $abbreviate true to abbreviate hash
* @return string object hash * @return string object hash
*/ */
public function GetHash($abbreviate = false) public function GetHash($abbreviate = false)
{ {
if ($abbreviate && $this->strategy->LoadsAbbreviatedHash()) { if ($abbreviate && $this->strategy->LoadsAbbreviatedHash()) {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
} }
   
return parent::GetHash($abbreviate); return parent::GetHash($abbreviate);
} }
   
/** /**
* Gets the main parent of this commit * Gets the main parent of this commit
* *
* @return GitPHP_Commit|null commit object for parent * @return GitPHP_Commit|null commit object for parent
*/ */
public function GetParent() public function GetParent()
{ {
$hash = $this->GetParentHash(); $hash = $this->GetParentHash();
if ($hash) { if ($hash) {
return $this->GetProject()->GetCommit($hash); return $this->GetProject()->GetCommit($hash);
} }
   
return null; return null;
} }
   
/** /**
* Gets the hash of the main parent of this commit * Gets the hash of the main parent of this commit
* *
* @return string commit hash for parent * @return string commit hash for parent
*/ */
public function GetParentHash() public function GetParentHash()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
if (isset($this->parents[0])) if (isset($this->parents[0]))
return $this->parents[0]; return $this->parents[0];
   
return null; return null;
} }
   
/** /**
* Gets an array of parent objects for this commit * Gets an array of parent objects for this commit
* *
* @return GitPHP_Commit[] array of commit objects * @return GitPHP_Commit[] array of commit objects
*/ */
public function GetParents() public function GetParents()
{ {
$parenthashes = $this->GetParentHashes(); $parenthashes = $this->GetParentHashes();
   
$parents = array(); $parents = array();
foreach ($parenthashes as $parent) { foreach ($parenthashes as $parent) {
$parents[] = $this->GetProject()->GetCommit($parent); $parents[] = $this->GetProject()->GetCommit($parent);
} }
   
return $parents; return $parents;
} }
   
/** /**
* Gets an array of parent hashes for this commit * Gets an array of parent hashes for this commit
* *
* @return string[] array of hashes * @return string[] array of hashes
*/ */
public function GetParentHashes() public function GetParentHashes()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
$parents = $this->parents; $parents = $this->parents;
return $parents; return $parents;
} }
   
/** /**
* Gets the tree for this commit * Gets the tree for this commit
* *
* @return GitPHP_Tree tree object * @return GitPHP_Tree tree object
*/ */
public function GetTree() public function GetTree()
{ {
$treehash = $this->GetTreeHash(); $treehash = $this->GetTreeHash();
   
if (empty($treehash)) if (empty($treehash))
return null; return null;
   
$tree = $this->GetProject()->GetObjectManager()->GetTree($treehash); $tree = $this->GetProject()->GetObjectManager()->GetTree($treehash);
if ($tree) { if ($tree) {
$tree->SetCommitHash($this->hash); $tree->SetCommitHash($this->hash);
$tree->SetPath(null); $tree->SetPath(null);
} }
   
return $tree; return $tree;
} }
   
/** /**
* Gets the tree hash for this commit * Gets the tree hash for this commit
* *
* @return string tree hash * @return string tree hash
*/ */
public function GetTreeHash() public function GetTreeHash()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return $this->tree; return $this->tree;
} }
   
/** /**
* Gets the author for this commit * Gets the author for this commit
* *
* @return string author * @return string author
*/ */
public function GetAuthor() public function GetAuthor()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return $this->author; return $this->author;
} }
   
/** /**
* Gets the author's name only * Gets the author's name only
* *
* @return string author name * @return string author name
*/ */
public function GetAuthorName() public function GetAuthorName()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return preg_replace('/ <.*/', '', $this->author); return preg_replace('/ <.*/', '', $this->author);
} }
   
/** /**
  * Gets the author's email only
  *
  * @return string author email
  */
  public function GetAuthorEmail()
  {
  if (!$this->dataRead)
  $this->ReadData();
   
  if (preg_match('/ <(.*)>$/', $this->author, $regs)) {
  return $regs[1];
  }
  }
   
  /**
* Gets the author's epoch * Gets the author's epoch
* *
* @return string author epoch * @return string author epoch
*/ */
public function GetAuthorEpoch() public function GetAuthorEpoch()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return $this->authorEpoch; return $this->authorEpoch;
} }
   
/** /**
* Gets the author's local epoch * Gets the author's local epoch
* *
* @return string author local epoch * @return string author local epoch
*/ */
public function GetAuthorLocalEpoch() public function GetAuthorLocalEpoch()
{ {
$epoch = $this->GetAuthorEpoch(); $epoch = $this->GetAuthorEpoch();
$tz = $this->GetAuthorTimezone(); $tz = $this->GetAuthorTimezone();
if (preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $tz, $regs)) { if (preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $tz, $regs)) {
$local = $epoch + ((((int)$regs[1]) + ($regs[2]/60)) * 3600); $local = $epoch + ((((int)$regs[1]) + ($regs[2]/60)) * 3600);
return $local; return $local;
} }
return $epoch; return $epoch;
} }
   
/** /**
* Gets the author's timezone * Gets the author's timezone
* *
* @param boolean $separator true to return with separator * @param boolean $separator true to return with separator
* @return string author timezone * @return string author timezone
*/ */
public function GetAuthorTimezone($separator = false) public function GetAuthorTimezone($separator = false)
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
if ($separator && preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $this->authorTimezone, $regs)) { if ($separator && preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $this->authorTimezone, $regs)) {
return $regs[1] . ':' . $regs[2]; return $regs[1] . ':' . $regs[2];
} }
   
return $this->authorTimezone; return $this->authorTimezone;
} }
   
/** /**
* Gets the author for this commit * Gets the author for this commit
* *
* @return string author * @return string author
*/ */
public function GetCommitter() public function GetCommitter()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return $this->committer; return $this->committer;
} }
   
/** /**
* Gets the author's name only * Gets the author's name only
* *
* @return string author name * @return string author name
*/ */
public function GetCommitterName() public function GetCommitterName()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return preg_replace('/ <.*/', '', $this->committer); return preg_replace('/ <.*/', '', $this->committer);
  }
   
  /**
  * Gets the committer's email only
  *
  * @return string committer email
  */
  public function GetCommitterEmail()
  {
  if (!$this->dataRead)
  $this->ReadData();
   
  if (preg_match('/ <(.*)>$/', $this->committer, $regs)) {
  return $regs[1];
  }
} }
   
/** /**
* Gets the committer's epoch * Gets the committer's epoch
* *
* @return string committer epoch * @return string committer epoch
*/ */
public function GetCommitterEpoch() public function GetCommitterEpoch()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return $this->committerEpoch; return $this->committerEpoch;
} }
   
/** /**
* Gets the committer's local epoch * Gets the committer's local epoch
* *
* @return string committer local epoch * @return string committer local epoch
*/ */
public function GetCommitterLocalEpoch() public function GetCommitterLocalEpoch()
{ {
$epoch = $this->GetCommitterEpoch(); $epoch = $this->GetCommitterEpoch();
$tz = $this->GetCommitterTimezone(); $tz = $this->GetCommitterTimezone();
if (preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $tz, $regs)) { if (preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $tz, $regs)) {
$local = $epoch + ((((int)$regs[1]) + ($regs[2]/60)) * 3600); $local = $epoch + ((((int)$regs[1]) + ($regs[2]/60)) * 3600);
return $local; return $local;
} }
return $epoch; return $epoch;
} }
   
/** /**
* Gets the author's timezone * Gets the author's timezone
* *
* @param boolean $separator true to return with separator * @param boolean $separator true to return with separator
* @return string author timezone * @return string author timezone
*/ */
public function GetCommitterTimezone($separator = false) public function GetCommitterTimezone($separator = false)
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
if ($separator && preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $this->committerTimezone, $regs)) { if ($separator && preg_match('/^([+\-][0-9][0-9])([0-9][0-9])$/', $this->committerTimezone, $regs)) {
return $regs[1] . ':' . $regs[2]; return $regs[1] . ':' . $regs[2];
} }
   
return $this->committerTimezone; return $this->committerTimezone;
} }
   
/** /**
* Gets the commit title * Gets the commit title
* *
* @param integer $trim length to trim to (0 for no trim) * @param integer $trim length to trim to (0 for no trim)
* @return string title * @return string title
*/ */
public function GetTitle($trim = 0) public function GetTitle($trim = 0)
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
if ($trim > 0) { if ($trim > 0) {
if (function_exists('mb_strimwidth')) { if (function_exists('mb_strimwidth')) {
return mb_strimwidth($this->title, 0, $trim, '…'); return mb_strimwidth($this->title, 0, $trim, '…');
} else if (strlen($this->title) > $trim) { } else if (strlen($this->title) > $trim) {
return substr($this->title, 0, $trim) . '…'; return substr($this->title, 0, $trim) . '…';
} }
} }
   
return $this->title; return $this->title;
} }
   
/** /**
* Gets the lines of comment * Gets the lines of comment
* *
* @return string[] lines of comment * @return string[] lines of comment
*/ */
public function GetComment() public function GetComment()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return $this->comment; return $this->comment;
} }
   
/** /**
* Gets the lines of the comment matching the given pattern * Gets the lines of the comment matching the given pattern
* *
* @param string $pattern pattern to find * @param string $pattern pattern to find
* @return string[] matching lines of comment * @return string[] matching lines of comment
*/ */
public function SearchComment($pattern) public function SearchComment($pattern)
{ {
if (empty($pattern)) if (empty($pattern))
return $this->GetComment(); return $this->GetComment();
   
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return preg_grep('/' . $pattern . '/i', $this->comment); return preg_grep('/' . $pattern . '/i', $this->comment);
} }
   
/** /**
* Gets the age of the commit * Gets the age of the commit
* *
* @return string age * @return string age
*/ */
public function GetAge() public function GetAge()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
if (!empty($this->committerEpoch)) if (!empty($this->committerEpoch))
return time() - $this->committerEpoch; return time() - $this->committerEpoch;
   
return ''; return '';
} }
   
/** /**
* Returns whether this is a merge commit * Returns whether this is a merge commit
* *
* @return boolean true if merge commit * @return boolean true if merge commit
*/ */
public function IsMergeCommit() public function IsMergeCommit()
{ {
if (!$this->dataRead) if (!$this->dataRead)
$this->ReadData(); $this->ReadData();
   
return count($this->parents) > 1; return count($this->parents) > 1;
} }
   
/** /**
* Read the data for the commit * Read the data for the commit
*/ */
protected function ReadData() protected function ReadData()
{ {
$this->dataRead = true; $this->dataRead = true;
   
list( list(
$abbreviatedHash, $abbreviatedHash,
$this->tree, $this->tree,
$this->parents, $this->parents,
$this->author, $this->author,
$this->authorEpoch, $this->authorEpoch,
$this->authorTimezone, $this->authorTimezone,
$this->committer, $this->committer,
$this->committerEpoch, $this->committerEpoch,
$this->committerTimezone, $this->committerTimezone,
$this->title, $this->title,
$this->comment $this->comment
) = $this->strategy->Load($this); ) = $this->strategy->Load($this);
   
if (!empty($abbreviatedHash)) { if (!empty($abbreviatedHash)) {
$this->abbreviatedHash = $abbreviatedHash; $this->abbreviatedHash = $abbreviatedHash;
$this->abbreviatedHashLoaded = true; $this->abbreviatedHashLoaded = true;
} }
   
foreach ($this->observers as $observer) { foreach ($this->observers as $observer) {
$observer->ObjectChanged($this, GitPHP_Observer_Interface::CacheableDataChange); $observer->ObjectChanged($this, GitPHP_Observer_Interface::CacheableDataChange);
} }
} }
   
/** /**
* Gets heads that point to this commit * Gets heads that point to this commit
* *
* @return GitPHP_Head[] array of heads * @return GitPHP_Head[] array of heads
*/ */
public function GetHeads() public function GetHeads()
{ {
return $this->GetProject()->GetHeadList()->GetCommitHeads($this); return $this->GetProject()->GetHeadList()->GetCommitHeads($this);
} }
   
/** /**
* Gets tags that point to this commit * Gets tags that point to this commit
* *
* @return GitPHP_Tag[] array of tags * @return GitPHP_Tag[] array of tags
*/ */
public function GetTags() public function GetTags()
{ {
return $this->GetProject()->GetTagList()->GetCommitTags($this); return $this->GetProject()->GetTagList()->GetCommitTags($this);
} }
   
/** /**
* Gets the tag that contains the changes in this commit * Gets the tag that contains the changes in this commit
* *
* @return GitPHP_Tag tag object * @return GitPHP_Tag tag object
*/ */
public function GetContainingTag() public function GetContainingTag()
{ {
$tag = $this->GetContainingTagName(); $tag = $this->GetContainingTagName();
   
if (empty($tag)) if (empty($tag))
return null; return null;
   
return $this->GetProject()->GetTagList()->GetTag($tag); return $this->GetProject()->GetTagList()->GetTag($tag);
} }
   
/** /**
* Gets the name of the tag that contains the changes in this commit * Gets the name of the tag that contains the changes in this commit
* *
* @return string tag name * @return string tag name
*/ */
public function GetContainingTagName() public function GetContainingTagName()
{ {
if (!$this->containingTagRead) if (!$this->containingTagRead)
$this->ReadContainingTag(); $this->ReadContainingTag();
   
return $this->containingTag; return $this->containingTag;
} }
   
/** /**
* Looks up the tag that contains the changes in this commit * Looks up the tag that contains the changes in this commit
*/ */
public function ReadContainingTag() public function ReadContainingTag()
{ {
$this->containingTagRead = true; $this->containingTagRead = true;
   
$this->containingTag = $this->strategy->LoadContainingTag($this); $this->containingTag = $this->strategy->LoadContainingTag($this);
} }
   
/** /**
* Diffs this commit with its immediate parent * Diffs this commit with its immediate parent
* *
* @param GitPHP_GitExe $exe git executable * @param GitPHP_GitExe $exe git executable
* @return GitPHP_TreeDiff Tree diff * @return GitPHP_TreeDiff Tree diff
*/ */
public function DiffToParent($exe) public function DiffToParent($exe)
{ {
return new GitPHP_TreeDiff($this->GetProject(), $exe, $this->hash); return new GitPHP_TreeDiff($this->GetProject(), $exe, $this->hash);
} }
   
/** /**
* Add a new observer * Add a new observer
* *
* @param GitPHP_Observer_Interface $observer observer * @param GitPHP_Observer_Interface $observer observer
*/ */
public function AddObserver($observer) public function AddObserver($observer)
{ {
if (!$observer) if (!$observer)
return; return;
   
if (array_search($observer, $this->observers) !== false) if (array_search($observer, $this->observers) !== false)
return; return;
   
$this->observers[] = $observer; $this->observers[] = $observer;
} }
   
/** /**
* Remove an observer * Remove an observer
* *
* @param GitPHP_Observer_Interface $observer observer * @param GitPHP_Observer_Interface $observer observer
*/ */
public function RemoveObserver($observer) public function RemoveObserver($observer)
{ {
if (!$observer) if (!$observer)
return; return;
   
$key = array_search($observer, $this->observers); $key = array_search($observer, $this->observers);
   
if ($key === false) if ($key === false)
return; return;
   
unset($this->observers[$key]); unset($this->observers[$key]);
} }
   
/** /**
* Called to prepare the object for serialization * Called to prepare the object for serialization
* *
* @return string[] list of properties to serialize * @return string[] list of properties to serialize
*/ */
public function __sleep() public function __sleep()
{ {
$properties = array('dataRead', 'parents', 'tree', 'author', 'authorEpoch', 'authorTimezone', 'committer', 'committerEpoch', 'committerTimezone', 'title', 'comment', 'readTree'); $properties = array('dataRead', 'parents', 'tree', 'author', 'authorEpoch', 'authorTimezone', 'committer', 'committerEpoch', 'committerTimezone', 'title', 'comment', 'readTree');
return array_merge($properties, parent::__sleep()); return array_merge($properties, parent::__sleep());
} }
   
/** /**
* Gets the cache key to use for this object * Gets the cache key to use for this object
* *
* @return string cache key * @return string cache key
*/ */
public function GetCacheKey() public function GetCacheKey()
{ {
return GitPHP_Commit::CacheKey($this->project->GetProject(), $this->hash); return GitPHP_Commit::CacheKey($this->project->GetProject(), $this->hash);
} }
   
/** /**
* Compares two commits by age * Compares two commits by age
* *
* @param GitPHP_Commit $a first commit * @param GitPHP_Commit $a first commit
* @param GitPHP_Commit $b second commit * @param GitPHP_Commit $b second commit
* @return integer comparison result * @return integer comparison result
*/ */
public static function CompareAge($a, $b) public static function CompareAge($a, $b)
{ {
if ($a->GetAge() === $b->GetAge()) { if ($a->GetAge() === $b->GetAge()) {
// fall back on author epoch // fall back on author epoch
return 0 - GitPHP_Commit::CompareAuthorEpoch($a, $b); return 0 - GitPHP_Commit::CompareAuthorEpoch($a, $b);
} }
return ($a->GetAge() < $b->GetAge() ? -1 : 1); return ($a->GetAge() < $b->GetAge() ? -1 : 1);
} }
   
/** /**
* Compares two commits by author epoch * Compares two commits by author epoch
* *
* @param GitPHP_Commit $a first commit * @param GitPHP_Commit $a first commit
* @param GitPHP_Commit $b second commit * @param GitPHP_Commit $b second commit
* @return integer comparison result * @return integer comparison result
*/ */
public static function CompareAuthorEpoch($a, $b) public static function CompareAuthorEpoch($a, $b)
{ {
if ($a->GetAuthorEpoch() === $b->GetAuthorEpoch()) { if ($a->GetAuthorEpoch() === $b->GetAuthorEpoch()) {
return 0; return 0;
} }
return ($a->GetAuthorEpoch() < $b->GetAuthorEpoch() ? -1 : 1); return ($a->GetAuthorEpoch() < $b->GetAuthorEpoch() ? -1 : 1);
} }
   
/** /**
* Generates a commit cache key * Generates a commit cache key
* *
* @param string $proj project * @param string $proj project
* @param string $hash hash * @param string $hash hash
* @return string cache key * @return string cache key
*/ */
public static function CacheKey($proj, $hash) public static function CacheKey($proj, $hash)
{ {
return 'project|' . $proj . '|commit|' . $hash; return 'project|' . $proj . '|commit|' . $hash;
} }
   
} }
   
{* {*
* rss.tpl * rss.tpl
* gitphp: A PHP git repository browser * gitphp: A PHP git repository browser
* Component: RSS template * Component: RSS template
* *
* Copyright (C) 2009 Christopher Han <xiphux@gmail.com> * Copyright (C) 2009 Christopher Han <xiphux@gmail.com>
*} *}
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel> <channel>
<title>{$project->GetProject()}</title> <title>{$project->GetProject()}</title>
<link>{geturl fullurl=true project=$project}</link> <link>{geturl fullurl=true project=$project}</link>
  <atom:link rel="self" href="{geturl fullurl=true project=$project action=rss}" type="application/rss+xml" />
<description>{$project->GetProject()} log</description> <description>{$project->GetProject()} log</description>
<language>en</language> <language>en</language>
   
{foreach from=$log item=logitem} {foreach from=$log item=logitem}
<item> <item>
<title>{$logitem->GetCommitterEpoch()|date_format:"%d %b %R"} - {$logitem->GetTitle()|escape:'html'}</title> <title>{$logitem->GetCommitterEpoch()|date_format:"%d %b %R"} - {$logitem->GetTitle()|escape:'html'}</title>
<author>{$logitem->GetAuthor()|escape:'html'}</author> <author>{$logitem->GetAuthorEmail()|escape:'html'} ({$logitem->GetAuthorName()|escape:'html'})</author>
<pubDate>{$logitem->GetCommitterEpoch()|date_format:"%a, %d %b %Y %H:%M:%S %z"}</pubDate> <pubDate>{$logitem->GetCommitterEpoch()|date_format:"%a, %d %b %Y %H:%M:%S %z"}</pubDate>
<guid isPermaLink="true">{geturl fullurl=true project=$project action=commit hash=$logitem}</guid> <guid isPermaLink="true">{geturl fullurl=true project=$project action=commit hash=$logitem}</guid>
<link>{geturl fullurl=true project=$project action=commit hash=$logitem}</link> <link>{geturl fullurl=true project=$project action=commit hash=$logitem}</link>
<description>{$logitem->GetTitle()|escape:'html'}</description> <description>{$logitem->GetTitle()|escape:'html'}</description>
<content:encoded> <content:encoded>
<![CDATA[ <![CDATA[
{foreach from=$logitem->GetComment() item=line} {foreach from=$logitem->GetComment() item=line}
{$line}<br /> {$line}<br />
{/foreach} {/foreach}
{foreach from=$logitem->DiffToParent($gitexe) item=diffline} {foreach from=$logitem->DiffToParent($gitexe) item=diffline}
{$diffline->GetToFile()}<br /> {$diffline->GetToFile()}<br />
{/foreach} {/foreach}
]]> ]]>
</content:encoded> </content:encoded>
</item> </item>
{/foreach} {/foreach}
   
</channel> </channel>
</rss> </rss>
   
comments