1: <?php
  2:   3:   4:   5:   6:   7:   8: 
  9: class Horde_Vcs_File_Svn extends Horde_Vcs_File_Base
 10: {
 11:      12:  13:  14:  15: 
 16:     protected $_driver = 'Svn';
 17: 
 18:      19:  20: 
 21:     protected $_logpipe;
 22: 
 23:     protected function _init()
 24:     {
 25:         $cmd = $this->_rep->getCommand() . ' log -v '
 26:             . escapeshellarg($this->getPath()) . ' 2>&1';
 27:         $this->_logpipe = popen($cmd, 'r');
 28:         if (!$this->_logpipe) {
 29:             throw new Horde_Vcs_Exception('Failed to execute svn log: ' . $cmd);
 30:         }
 31: 
 32:         $header = fgets($this->_logpipe);
 33:         if (!strspn($header, '-')) {
 34:             throw new Horde_Vcs_Exception('Error executing svn log: ' . $header);
 35:         }
 36: 
 37:         while (!feof($this->_logpipe)) {
 38:             try {
 39:                 $log = $this->_getLog();
 40:                 $rev = $log->getRevision();
 41:                 $this->_logs[$rev] = $log;
 42:                 $this->_revs[] = $rev;
 43:             } catch (Horde_Vcs_Exception $e) {}
 44:         }
 45: 
 46:         pclose($this->_logpipe);
 47:     }
 48: 
 49:      50:  51:  52:  53:  54:  55:  56:  57: 
 58:     public function parseLog($parse_files = true)
 59:     {
 60:         $line = fgets($this->_logpipe);
 61:         if (feof($this->_logpipe) || !$line) {
 62:             throw new Horde_Vcs_Exception('No more data');
 63:         }
 64: 
 65:         if (preg_match('/^r([0-9]*) \| (.*?) \| (.*) \(.*\) \| ([0-9]*) lines?$/', $line, $matches)) {
 66:             $rev = $matches[1];
 67:             $author = $matches[2];
 68:             $date = strtotime($matches[3]);
 69:             $size = $matches[4];
 70:         } else {
 71:             throw new Horde_Vcs_Exception('Unknown log format: ' . $line);
 72:         }
 73: 
 74:         fgets($this->_logpipe);
 75: 
 76:         $files = array();
 77:         if ($parse_files) {
 78:             while (($line = trim(fgets($this->_logpipe))) != '') {
 79:                 list($mode, $file) = explode(' ', trim($line));
 80:                 $files[ltrim($file, '/')] = array('status' => $mode);
 81:             }
 82:         }
 83: 
 84:         $log = '';
 85:         for ($i = 0; $i != $size; ++$i) {
 86:             $log .= rtrim(fgets($this->_logpipe)) . "\n";
 87:         }
 88:         $log = rtrim($log);
 89: 
 90:         fgets($this->_logpipe);
 91: 
 92:         return array($rev, $author, $log, $date, $size, $files);
 93:     }
 94: 
 95:      96:  97:  98:  99: 100: 
101:     public function getFileName()
102:     {
103:         return preg_replace('/,v$/', '', $this->_name);
104:     }
105: 
106:     107: 108: 109: 110: 111: 112: 
113:     public function getPreviousRevision($rev)
114:     {
115:         
116:         $rev--;
117:         return $rev ? $rev : null;
118:     }
119: 
120:     121: 122: 123: 124: 125: 
126:     public function getLastLog()
127:     {
128:         $cmd = $this->_rep->getCommand() . ' log -l 1 ' . escapeshellarg($this->getPath()) . ' 2>&1';
129:         $this->_logpipe = popen($cmd, 'r');
130:         if (!$this->_logpipe) {
131:             throw new Horde_Vcs_Exception('Failed to execute svn log: ' . $cmd);
132:         }
133: 
134:         $header = fgets($this->_logpipe);
135:         if (!strspn($header, '-')) {
136:             throw new Horde_Vcs_Exception('Error executing svn log: ' . $header);
137:         }
138: 
139:         list($rev, $author, $log, $date) = $this->parseLog(false);
140:         pclose($this->_logpipe);
141: 
142:         return new Horde_Vcs_QuickLog_Svn($this->_rep, $rev, $date, $author, $log);
143:     }
144: }
145: