From: Chris Han Date: Sat, 18 Aug 2012 04:11:27 +0000 Subject: Implement pagination interface on history X-Git-Url: https://git.razvi.ro/?p=gitphp.git&a=commitdiff&h=b0707c01bcd72c950ec9d8f8d591968d5e7c78cb --- Implement pagination interface on history --- --- a/include/controller/Controller_History.class.php +++ b/include/controller/Controller_History.class.php @@ -71,7 +71,7 @@ $blob->SetPath($this->params['file']); $this->tpl->assign('blob', $blob); - $history = new GitPHP_FileHistory($this->GetProject(), $co, $this->params['file'], $this->exe); + $history = new GitPHP_FileHistory($this->GetProject(), $this->params['file'], $this->exe, $co); $this->tpl->assign('history', $history); } --- a/include/git/FileHistory.class.php +++ b/include/git/FileHistory.class.php @@ -7,35 +7,49 @@ * @package GitPHP * @subpackage Git */ -class GitPHP_FileHistory implements Iterator +class GitPHP_FileHistory implements Iterator, GitPHP_Pagination_Interface { /** * The project * * @var GitPHP_Project */ - protected $project; - - /** - * The commit hash + protected $project = null; + + /** + * History + * + * @var GitPHP_FileDiff[] + */ + protected $history = array(); + + /** + * The path * * @var string */ - protected $commitHash; - - /** - * The path + protected $path; + + /** + * The limit of objects to load + * + * @var int + */ + protected $limit = 50; + + /** + * The number of objects to skip + * + * @var int + */ + protected $skip = 0; + + /** + * The hash to walk back from * * @var string */ - protected $path; - - /** - * The history - * - * @var GitPHP_FileDiff[] - */ - protected $history = array(); + protected $hash = false; /** * Whether data has been loaded @@ -55,35 +69,49 @@ * Constructor * * @param GitPHP_Project $project project - * @param GitPHP_Commit $commit commit to start history from * @param string $path file path to trace history of * @param GitPHP_GitExe $exe git exe - */ - public function __construct($project, $commit, $path, $exe) - { - if (!$project) + * @param GitPHP_Commit $head commit to start history from + */ + public function __construct($project, $path, $exe, $head = null, $limit = 0, $skip = 0) + { + if (!$project) { throw new Exception('Project is required'); - - if (!$commit) - throw new Exception('Commit is required'); - + } + + $this->project = $project; + $this->limit = $limit; + $this->skip = $skip; + + if (!$head) + $head = $this->project->GetHeadCommit(); + + if ($head) { + $this->hash = $head->GetHash(); + } if (empty($path)) throw new Exception('Path is required'); if (!$exe) throw new Exception('Git exe is required'); - $this->project = $project; - - $this->commitHash = $commit->GetHash(); - $this->path = $path; $this->exe = $exe; } /** - * Gets the project for this file history + * Gets the path for this file history + * + * @return string path + */ + public function GetPath() + { + return $this->path; + } + + /** + * Gets the project * * @return GitPHP_Project project */ @@ -93,47 +121,160 @@ } /** - * Gets the commit for this file history - * - * @return GitPHP_Commit commit - */ - public function GetCommit() - { - return $this->project->GetCommit($this->commitHash); - } - - /** - * Gets the path for this file history - * - * @return string path - */ - public function GetPath() - { - return $this->path; - } - - /** - * Gets the history - * - * @return GitPHP_FileDiff[] history data - */ - public function GetHistory() - { - if (!$this->dataLoaded) - $this->LoadData(); - - return $this->history; + * Gets the count + * + * @return int count + */ + public function GetCount() + { + if (!$this->dataLoaded) { + $this->LoadData(); + } + + return count($this->history); + } + + /** + * Gets the limit + * + * @return int limit + */ + public function GetLimit() + { + return $this->limit; + } + + /** + * Sets the limit + * + * @param int $limit limit + */ + public function SetLimit($limit) + { + if ($this->limit == $limit) + return; + + if ($this->dataLoaded) { + if (($limit < $this->limit) && ($limit > 0)) { + /* want less data, just trim the array */ + $this->history = array_slice($this->history, 0, $limit); + } else if (($limit > $this->limit) || ($limit < 1)) { + /* want more data, have to reload */ + $this->Clear(); + } + } + + $this->limit = $limit; + } + + /** + * Gets the skip number + * + * @return int skip number + */ + public function GetSkip() + { + return $this->skip; + } + + /** + * Sets the skip number + * + * @param int $skip skip number + */ + public function SetSkip($skip) + { + if ($skip == $this->skip) + return; + + if ($this->dataLoaded) { + $this->Clear(); + } + + $this->skip = $skip; + } + + /** + * Gets the head this log will walk from + * + * @return GitPHP_Commit head commit + */ + public function GetHead() + { + return $this->project->GetCommit($this->hash); + } + + /** + * Sets the head this log will walk from + * + * @param GitPHP_Commit $head head commit + */ + public function SetHead($head) + { + if ($head) + $this->SetHeadHash($head->GetHash()); + else + $this->SetHeadHash(null); + } + + /** + * Gets the head hash this log will walk from + * + * @return string hash + */ + public function GetHeadHash() + { + return $this->hash; + } + + /** + * Sets the head hash this log will walk from + * + * @param string $hash head commit hash + */ + public function SetHeadHash($hash) + { + if (empty($hash)) { + $head = $this->project->GetHeadCommit(); + if ($head) + $hash = $head->GetHash(); + } + + if ($hash != $this->hash) { + $this->Clear(); + $this->hash = $hash; + } } /** * Loads the history data */ - private function LoadData() + protected function LoadData() { $this->dataLoaded = true; $args = array(); - $args[] = $this->commitHash; + $args[] = $this->hash; + + $canSkip = true; + if ($this->skip > 0) + $canSkip = $this->exe->CanSkip(); + + if ($canSkip) { + if ($this->limit > 0) { + $args[] = '--max-count=' . $this->limit; + } + if ($this->skip > 0) { + $args[] = '--skip=' . $skip; + } + } else { + if ($this->limit > 0) { + $args[] = '--max-count=' . ($this->limit + $this->skip); + } + } + + $args[] = '--'; + $args[] = $this->path; $args[] = '|'; $args[] = $this->exe->GetBinary(); $args[] = '--git-dir=' . $this->project->GetPath(); @@ -160,12 +301,18 @@ } } + if (($this->skip > 0) && (!$canSkip)) { + if ($this->limit > 0) { + $this->history = array_slice($this->history, $this->skip, $this->limit); + } else { + $this->history = array_slice($this->history, $this->skip); + } + } + } /** * Rewinds the iterator - * - * @return GitPHP_FileDiff */ function rewind() { @@ -179,7 +326,7 @@ /** * Returns the current revision * - * @return GitPHP_FileDiff + * @return GitPHP_Commit */ function current() { @@ -192,8 +339,6 @@ /** * Returns the current key - * - * @return int */ function key() { @@ -206,8 +351,6 @@ /** * Advance the pointer - * - * @return GitPHP_FileDiff|boolean */ function next() { @@ -232,5 +375,18 @@ return key($this->history) !== null; } + /** + * Clears the loaded data + */ + public function Clear() + { + if (!$this->dataLoaded) + return; + + $this->history = array(); + reset($this->history); + + $this->dataLoaded = false; + } }