8 * Repository ID (number in repositories directory)
15 * Full path to the .git repository
22 * Full path to the work tree directory
29 * Revision of the repository that shall be shown
36 * Commit message of the last (or current) revision
44 * Load Repository data from GET-Request
48 * @throws Exception When something is wrong
50 public function loadFromRequest()
52 if (!isset($_GET['id'])) {
53 throw new Exception_Input('Paste ID missing');
55 if (!is_numeric($_GET['id'])) {
56 throw new Exception_Input('Paste ID not numeric');
58 if (isset($_GET['rev'])) {
59 $this->hash = $_GET['rev'];
62 $this->id = (int)$_GET['id'];
68 protected function loadDirs()
70 $gitDir = $GLOBALS['phorkie']['cfg']['gitdir'] . '/' . $this->id . '.git';
71 if (!is_dir($gitDir)) {
72 throw new Exception_NotFound(
73 sprintf('Paste %d .git dir not found', $this->id)
76 $this->gitDir = $gitDir;
78 $workDir = $GLOBALS['phorkie']['cfg']['workdir'] . '/' . $this->id;
79 if (!is_dir($workDir)) {
80 throw new Exception_NotFound(
81 sprintf('Paste %d work dir not found', $this->id)
84 $this->workDir = $workDir;
87 public function loadHash()
90 if ($this->hash !== null) {
94 $output = $this->getVc()->getCommand('log')
95 ->setOption('pretty', 'format:%H')
96 ->setOption('max-count', 1)
98 $output = trim($output);
99 if (strlen($output) !== 40) {
101 'Loading commit hash failed: ' . $output
104 $this->hash = $output;
107 public function loadMessage()
109 $rev = (isset($this->hash)) ? $this->hash : 'HEAD';
110 $output = $this->getVc()->getCommand('log')
111 ->setOption('oneline')
115 $output = trim($output);
116 if (strpos($output, ' ') > 0) {
117 $output = substr($output, strpos($output, ' '), strlen($output));
118 $this->message = trim($output);
120 $this->message = "This commit message intentionally left blank.";
124 public function loadById($id)
126 if (!is_numeric($id)) {
127 throw new Exception_Input('Paste ID not numeric');
129 $this->id = (int)$id;
134 public function getVc()
136 return new \VersionControl_Git($this->gitDir);
140 * Loads the list of files in this repository
142 * @return File[] Array of files
144 public function getFiles()
146 $files = $this->getFilePaths();
148 foreach ($files as $name) {
149 $arFiles[] = new File($name, $this);
154 protected function getFilePaths()
156 if ($this->hash === null) {
161 $output = $this->getVc()->getCommand('ls-tree')
163 ->setOption('name-only')
166 return explode("\n", trim($output));
169 public function getFileByName($name, $bHasToExist = true)
171 $name = Tools::sanitizeFilename($name);
173 throw new Exception_Input('Empty file name given');
177 $files = $this->getFilePaths();
178 if (array_search($name, $files) === false) {
179 throw new Exception_Input('File does not exist');
182 return new File($name, $this);
185 public function hasFile($name)
188 $this->getFileByName($name);
189 } catch (Exception $e) {
196 * Permanently deletes the paste repository without any way to get
199 * @return boolean True if all went well, false if not
201 public function delete()
203 $db = new Database();
204 $db->getIndexer()->deleteRepo($this);
206 return Tools::recursiveDelete($this->workDir)
207 && Tools::recursiveDelete($this->gitDir);
210 public function getTitle()
212 $desc = $this->getDescription();
213 if (trim($desc) != '') {
217 return 'paste #' . $this->id;
220 public function getDescription()
222 if (!is_readable($this->gitDir . '/description')) {
225 return file_get_contents($this->gitDir . '/description');
228 public function setDescription($description)
230 file_put_contents($this->gitDir . '/description', $description);
234 * Get a link to the repository
236 * @param string $type Link type. Supported are:
243 * @param string $option
247 public function getLink($type, $option = null)
249 if ($type == 'edit') {
250 return '/' . $this->id . '/edit';
251 } else if ($type == 'display') {
252 return '/' . $this->id;
253 } else if ($type == 'fork') {
254 return '/' . $this->id . '/fork';
255 } else if ($type == 'delete') {
256 return '/' . $this->id . '/delete';
257 } else if ($type == 'delete-confirm') {
258 return '/' . $this->id . '/delete/confirm';
259 } else if ($type == 'revision') {
260 return '/' . $this->id . '/rev/' . $option;
262 throw new Exception('Unknown link type');
265 public function getCloneURL($public = true)
267 $var = $public ? 'public' : 'private';
268 if (isset($GLOBALS['phorkie']['cfg']['git'][$var])) {
269 return $GLOBALS['phorkie']['cfg']['git'][$var] . $this->id . '.git';
275 * Returns the history of the repository.
276 * We don't use VersionControl_Git's rev list fetcher since it does not
277 * give us separate email addresses and names, and it does not give us
278 * the amount of changed (added/deleted) lines.
280 * @return array Array of history objects
282 public function getHistory()
284 $output = $this->getVc()->getCommand('log')
285 ->setOption('pretty', 'format:commit %H%n%at%n%an%n%ae')
286 ->setOption('max-count', 10)
287 ->setOption('shortstat')
290 $arCommits = array();
291 $arOutput = explode("\n", $output);
292 $lines = count($arOutput);
294 while ($current < $lines) {
295 $commit = new Repository_Commit();
296 list($name,$commit->hash) = explode(' ', $arOutput[$current]);
297 if ($name !== 'commit') {
299 'Git log output format not as expected: ' . $arOutput[$current]
302 $commit->committerTime = $arOutput[$current + 1];
303 $commit->committerName = $arOutput[$current + 2];
304 $commit->committerEmail = $arOutput[$current + 3];
306 $arLineParts = explode(' ', trim($arOutput[$current + 4]));
307 $commit->filesChanged = $arLineParts[0];
308 $commit->linesAdded = $arLineParts[3];
309 if (isset($arLineParts[5])) {
310 $commit->linesDeleted = $arLineParts[5];
315 $arCommits[] = $commit;