1: <?php
2: /**
3: * Git directory class that stores information about the files in a single
4: * directory in the repository.
5: *
6: * Copyright 2008-2012 Horde LLC (http://www.horde.org/)
7: *
8: * See the enclosed file COPYING for license information (LGPL). If you
9: * did not receive this file, see http://www.horde.org/licenses/lgpl21.
10: *
11: * @author Chuck Hagenbuch <chuck@horde.org>
12: * @author Michael Slusarz <slusarz@horde.org>
13: * @author Jan Schneider <jan@horde.org>
14: * @package Vcs
15: */
16: class Horde_Vcs_Directory_Git extends Horde_Vcs_Directory_Base
17: {
18: /**
19: * The current branch.
20: *
21: * @var string
22: */
23: protected $_branch;
24:
25: /**
26: * Constructor.
27: *
28: * @todo Throw exception if not a valid directory (ls-tree doesn't really
29: * list directory contents, but all objects matching a pattern, so it
30: * returns an empty list when used with non-existant directories.
31: *
32: * @param Horde_Vcs_Base $rep A repository object.
33: * @param string $dn Path to the directory.
34: * @param array $opts Any additional options:
35: * - 'rev': (string) Generate directory list for
36: * a certain branch or revision.
37: *
38: * @throws Horde_Vcs_Exception
39: */
40: public function __construct(Horde_Vcs_Base $rep, $dn, $opts = array())
41: {
42: parent::__construct($rep, $dn, $opts);
43:
44: $this->_branch = empty($opts['rev'])
45: ? $rep->getDefaultBranch()
46: : $opts['rev'];
47:
48: // @TODO See if we have a valid cache of the tree at this revision
49:
50: $dir = $this->_dirName;
51: if (substr($dir, 0, 1) == '/') {
52: $dir = (string)substr($dir, 1);
53: }
54: if (strlen($dir) && substr($dir, -1) != '/') {
55: $dir .= '/';
56: }
57:
58: list($stream, $result) = $rep->runCommand(
59: 'ls-tree --full-name ' . escapeshellarg($this->_branch)
60: . ' ' . escapeshellarg($dir));
61:
62: /* Create two arrays - one of all the files, and the other of all the
63: * dirs. */
64: while (!feof($result)) {
65: $line = rtrim(fgets($result));
66: if (!strlen($line)) {
67: continue;
68: }
69:
70: list(, $type, , $file) = preg_split('/\s+/', $line, -1,
71: PREG_SPLIT_NO_EMPTY);
72: $file = preg_replace('/\\\\(\d+)/e', 'chr(0$1)', $file);
73: $file = str_replace(array('\\t', '\\n', '\\\\'),
74: array("\t", "\n", '\\'),
75: $file);
76: $file = trim($file, '"');
77: if ($type == 'tree') {
78: $this->_dirs[] = basename($file);
79: } else {
80: $this->_files[] = $rep->getFile(
81: $file,
82: array('branch' => $this->_branch));
83: }
84: }
85: fclose($result);
86: proc_close($stream);
87: }
88:
89: /**
90: * Returns a list of all branches in this directory.
91: *
92: * @return array A branch list.
93: */
94: public function getBranches()
95: {
96: $blist = array_keys($this->_rep->getBranchList());
97: if (!in_array($this->_branch, $blist)) {
98: $blist[] = $this->_branch;
99: }
100: return $blist;
101: }
102: }