X-Git-Url: https://git.cweiske.de/phorkie.git/blobdiff_plain/882ce78e4fc3361288dbc3c453412556aa529c7d..808a3a5857c77ef99605fdfdde9b31b5c02e22c6:/src/phorkie/Repository.php diff --git a/src/phorkie/Repository.php b/src/phorkie/Repository.php index 46b2f65..013f017 100644 --- a/src/phorkie/Repository.php +++ b/src/phorkie/Repository.php @@ -32,6 +32,12 @@ class Repository */ public $hash; + /** + * Commit message of the last (or current) revision + * + * @var string + */ + public $message; /** @@ -56,6 +62,17 @@ class Repository $this->id = (int)$_GET['id']; $this->loadDirs(); $this->loadHash(); + $this->loadMessage(); + } + + public function loadById($id) + { + if (!is_numeric($id)) { + throw new Exception_Input('Paste ID not numeric'); + } + $this->id = (int)$id; + $this->loadDirs(); + $this->loadHash(); } protected function loadDirs() @@ -79,7 +96,6 @@ class Repository public function loadHash() { - return; if ($this->hash !== null) { return; } @@ -97,14 +113,32 @@ class Repository $this->hash = $output; } - public function loadById($id) + public function reloadHash() { - if (!is_numeric($id)) { - throw new Exception_Input('Paste ID not numeric'); + $this->hash = null; + return $this->loadHash(); + } + + /** + * Populates $this->message + * + * @return void + */ + public function loadMessage() + { + $rev = (isset($this->hash)) ? $this->hash : 'HEAD'; + $output = $this->getVc()->getCommand('log') + ->setOption('oneline') + ->addArgument('-1') + ->addArgument($rev) + ->execute(); + $output = trim($output); + if (strpos($output, ' ') > 0) { + $output = substr($output, strpos($output, ' '), strlen($output)); + $this->message = trim($output); + } else { + $this->message = "This commit message intentionally left blank."; } - $this->id = (int)$id; - $this->loadDirs(); - $this->loadHash(); } public function getVc() @@ -115,7 +149,7 @@ class Repository /** * Loads the list of files in this repository * - * @return File[] Array of files + * @return File[] Array of file objects */ public function getFiles() { @@ -127,6 +161,41 @@ class Repository return $arFiles; } + /** + * Decodes unicode characters in git filenames + * They begin and end with double quote characters, and may contain + * backslash + 3 letter octal code numbers representing the character. + * + * For example, + * > "t\303\244st.txt" + * means + * > täst.txt + * + * On the shell, you can pipe them into "printf" and have them decoded. + * + * @param string Encoded git file name + * + * @return string Decoded file name + */ + protected function decodeFileName($name) + { + $name = substr($name, 1, -1); + $name = str_replace('\"', '"', $name); + $name = preg_replace_callback( + '#\\\\[0-7]{3}#', + function ($ar) { + return chr(octdec(substr($ar[0], 1))); + }, + $name + ); + return $name; + } + + /** + * Return array with all file paths in this repository + * + * @return array + */ protected function getFilePaths() { if ($this->hash === null) { @@ -139,7 +208,13 @@ class Repository ->setOption('name-only') ->addArgument($hash) ->execute(); - return explode("\n", trim($output)); + $files = explode("\n", trim($output)); + foreach ($files as &$file) { + if ($file{0} == '"') { + $file = $this->decodeFileName($file); + } + } + return $files; } public function getFileByName($name, $bHasToExist = true) @@ -179,8 +254,13 @@ class Repository $db = new Database(); $db->getIndexer()->deleteRepo($this); - return Tools::recursiveDelete($this->workDir) + $bOk = Tools::recursiveDelete($this->workDir) && Tools::recursiveDelete($this->gitDir); + + $not = new Notificator(); + $not->delete($this); + + return $bOk; } public function getTitle() @@ -206,38 +286,82 @@ class Repository file_put_contents($this->gitDir . '/description', $description); } + /** + * @return array Array with keys "email" and "name" + */ + public function getOwner() + { + try { + $name = $this->getVc()->getCommand('config') + ->addArgument('owner.name')->execute(); + } catch (\VersionControl_Git_Exception $e) { + $name = $GLOBALS['phorkie']['auth']['anonymousName']; + } + try { + $email = $this->getVc()->getCommand('config') + ->addArgument('owner.email')->execute(); + } catch (\VersionControl_Git_Exception $e) { + $email = $GLOBALS['phorkie']['auth']['anonymousEmail']; + } + + return array('name' => trim($name), 'email' => trim($email)); + } + /** * Get a link to the repository * - * @param string $type Link type. Supported are: - * - "edit" - * - "delete" - * - "delete-confirm" - * - "display" - * - "fork" - * - "revision" - * @param string $option + * @param string $type Link type. Supported are: + * - "edit" + * - "delete" + * - "delete-confirm" + * - "display" + * - "embed" + * - "fork" + * - "revision" + * @param string $option Additional link option, e.g. revision number + * @param boolean $full Return full URL or normal relative * * @return string */ - public function getLink($type, $option = null) + public function getLink($type, $option = null, $full = false) { if ($type == 'edit') { - return '/' . $this->id . '/edit'; + $link = $this->id . '/edit'; + if ($option !== null) { + $link .= '/' . urlencode($option); + } } else if ($type == 'display') { - return '/' . $this->id; + $link = $this->id; } else if ($type == 'fork') { - return '/' . $this->id . '/fork'; + $link = $this->id . '/fork'; } else if ($type == 'doap') { - return '/' . $this->id . '/doap'; + $link = $this->id . '/doap'; } else if ($type == 'delete') { - return '/' . $this->id . '/delete'; + $link = $this->id . '/delete'; } else if ($type == 'delete-confirm') { - return '/' . $this->id . '/delete/confirm'; + $link = $this->id . '/delete/confirm'; + } else if ($type == 'embed') { + $link = $this->id . '/embed'; + } else if ($type == 'oembed-json') { + $link = 'oembed.php?format=json&url=' + . urlencode($this->getLink('display', null, true)); + } else if ($type == 'oembed-xml') { + $link = 'oembed.php?format=xml&url=' + . urlencode($this->getLink('display', null, true)); + } else if ($type == 'remotefork') { + return 'web+fork:' . $this->getLink('display', null, true); } else if ($type == 'revision') { - return '/' . $this->id . '/rev/' . $option; + $link = $this->id . '/rev/' . $option; + } else if ($type == 'linkback') { + $link = $this->id . '/linkback'; + } else { + throw new Exception('Unknown link type'); } - throw new Exception('Unknown link type'); + + if ($full) { + $link = Tools::fullUrl($link); + } + return $link; } public function getCloneURL($public = true) @@ -281,6 +405,13 @@ class Repository $commit->committerName = $arOutput[$current + 2]; $commit->committerEmail = $arOutput[$current + 3]; + if (substr($arOutput[$current + 4], 0, 1) != ' ') { + //commit without changed lines + $arCommits[] = $commit; + $current += 4; + continue; + } + $arLineParts = explode(' ', trim($arOutput[$current + 4])); $commit->filesChanged = $arLineParts[0]; $commit->linesAdded = $arLineParts[3]; @@ -295,6 +426,14 @@ class Repository return $arCommits; } + + /** + * @return Repository_ConnectionInfo + */ + public function getConnectionInfo() + { + return new Repository_ConnectionInfo($this); + } } ?>