| 4988 | 
        kaklik | 
        1 | 
        <?php | 
      
      
         | 
         | 
        2 | 
        // WebSVN - Subversion repository viewing via the web using PHP | 
      
      
         | 
         | 
        3 | 
        // Copyright (C) 2004-2006 Tim Armes | 
      
      
         | 
         | 
        4 | 
        // | 
      
      
         | 
         | 
        5 | 
        // This program is free software; you can redistribute it and/or modify | 
      
      
         | 
         | 
        6 | 
        // it under the terms of the GNU General Public License as published by | 
      
      
         | 
         | 
        7 | 
        // the Free Software Foundation; either version 2 of the License, or | 
      
      
         | 
         | 
        8 | 
        // (at your option) any later version. | 
      
      
         | 
         | 
        9 | 
        // | 
      
      
         | 
         | 
        10 | 
        // This program is distributed in the hope that it will be useful, | 
      
      
         | 
         | 
        11 | 
        // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
      
      
         | 
         | 
        12 | 
        // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the | 
      
      
         | 
         | 
        13 | 
        // GNU General Public License for more details. | 
      
      
         | 
         | 
        14 | 
        // | 
      
      
         | 
         | 
        15 | 
        // You should have received a copy of the GNU General Public License | 
      
      
         | 
         | 
        16 | 
        // along with this program; if not, write to the Free Software | 
      
      
         | 
         | 
        17 | 
        // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA	02111-1307	USA | 
      
      
         | 
         | 
        18 | 
        // | 
      
      
         | 
         | 
        19 | 
        // -- | 
      
      
         | 
         | 
        20 | 
        // | 
      
      
         | 
         | 
        21 | 
        // svn-look.php | 
      
      
         | 
         | 
        22 | 
        // | 
      
      
         | 
         | 
        23 | 
        // Svn bindings | 
      
      
         | 
         | 
        24 | 
        // | 
      
      
         | 
         | 
        25 | 
        // These binding currently use the svn command line to achieve their goal.	Once a proper | 
      
      
         | 
         | 
        26 | 
        // SWIG binding has been produced for PHP, there'll be an option to use that instead. | 
      
      
         | 
         | 
        27 | 
          | 
      
      
         | 
         | 
        28 | 
        require_once 'include/utils.php'; | 
      
      
         | 
         | 
        29 | 
          | 
      
      
         | 
         | 
        30 | 
        // {{{ Classes for retaining log information --- | 
      
      
         | 
         | 
        31 | 
          | 
      
      
         | 
         | 
        32 | 
        $debugxml = false; | 
      
      
         | 
         | 
        33 | 
          | 
      
      
         | 
         | 
        34 | 
        class SVNInfoEntry { | 
      
      
         | 
         | 
        35 | 
        	var $rev = 1; | 
      
      
         | 
         | 
        36 | 
        	var $path = ''; | 
      
      
         | 
         | 
        37 | 
        	var $isdir = null; | 
      
      
         | 
         | 
        38 | 
        } | 
      
      
         | 
         | 
        39 | 
          | 
      
      
         | 
         | 
        40 | 
        class SVNMod { | 
      
      
         | 
         | 
        41 | 
        	var $action = ''; | 
      
      
         | 
         | 
        42 | 
        	var $copyfrom = ''; | 
      
      
         | 
         | 
        43 | 
        	var $copyrev = ''; | 
      
      
         | 
         | 
        44 | 
        	var $path = ''; | 
      
      
         | 
         | 
        45 | 
        	var $isdir = null; | 
      
      
         | 
         | 
        46 | 
        } | 
      
      
         | 
         | 
        47 | 
          | 
      
      
         | 
         | 
        48 | 
        class SVNListEntry { | 
      
      
         | 
         | 
        49 | 
        	var $rev = 1; | 
      
      
         | 
         | 
        50 | 
        	var $author = ''; | 
      
      
         | 
         | 
        51 | 
        	var $date = ''; | 
      
      
         | 
         | 
        52 | 
        	var $committime; | 
      
      
         | 
         | 
        53 | 
        	var $age = ''; | 
      
      
         | 
         | 
        54 | 
        	var $file = ''; | 
      
      
         | 
         | 
        55 | 
        	var $isdir = null; | 
      
      
         | 
         | 
        56 | 
        } | 
      
      
         | 
         | 
        57 | 
          | 
      
      
         | 
         | 
        58 | 
        class SVNList { | 
      
      
         | 
         | 
        59 | 
        	var $entries; // Array of entries | 
      
      
         | 
         | 
        60 | 
        	var $curEntry; // Current entry | 
      
      
         | 
         | 
        61 | 
          | 
      
      
         | 
         | 
        62 | 
        	var $path = ''; // The path of the list | 
      
      
         | 
         | 
        63 | 
        } | 
      
      
         | 
         | 
        64 | 
          | 
      
      
         | 
         | 
        65 | 
        class SVNLogEntry { | 
      
      
         | 
         | 
        66 | 
        	var $rev = 1; | 
      
      
         | 
         | 
        67 | 
        	var $author = ''; | 
      
      
         | 
         | 
        68 | 
        	var $date = ''; | 
      
      
         | 
         | 
        69 | 
        	var $committime; | 
      
      
         | 
         | 
        70 | 
        	var $age = ''; | 
      
      
         | 
         | 
        71 | 
        	var $msg = ''; | 
      
      
         | 
         | 
        72 | 
        	var $path = ''; | 
      
      
         | 
         | 
        73 | 
        	var $precisePath = ''; | 
      
      
         | 
         | 
        74 | 
          | 
      
      
         | 
         | 
        75 | 
        	var $mods; | 
      
      
         | 
         | 
        76 | 
        	var $curMod; | 
      
      
         | 
         | 
        77 | 
        } | 
      
      
         | 
         | 
        78 | 
          | 
      
      
         | 
         | 
        79 | 
        function SVNLogEntry_compare($a, $b) { | 
      
      
         | 
         | 
        80 | 
        	return strnatcasecmp($a->path, $b->path); | 
      
      
         | 
         | 
        81 | 
        } | 
      
      
         | 
         | 
        82 | 
          | 
      
      
         | 
         | 
        83 | 
        class SVNLog { | 
      
      
         | 
         | 
        84 | 
        	var $entries; // Array of entries | 
      
      
         | 
         | 
        85 | 
        	var $curEntry; // Current entry | 
      
      
         | 
         | 
        86 | 
          | 
      
      
         | 
         | 
        87 | 
        	var $path = ''; // Temporary variable used to trace path history | 
      
      
         | 
         | 
        88 | 
          | 
      
      
         | 
         | 
        89 | 
        	// findEntry | 
      
      
         | 
         | 
        90 | 
        	// | 
      
      
         | 
         | 
        91 | 
        	// Return the entry for a given revision | 
      
      
         | 
         | 
        92 | 
          | 
      
      
         | 
         | 
        93 | 
        	function findEntry($rev) { | 
      
      
         | 
         | 
        94 | 
        		foreach ($this->entries as $index => $entry) { | 
      
      
         | 
         | 
        95 | 
        			if ($entry->rev == $rev) { | 
      
      
         | 
         | 
        96 | 
        				return $index; | 
      
      
         | 
         | 
        97 | 
        			} | 
      
      
         | 
         | 
        98 | 
        		} | 
      
      
         | 
         | 
        99 | 
        	} | 
      
      
         | 
         | 
        100 | 
        } | 
      
      
         | 
         | 
        101 | 
          | 
      
      
         | 
         | 
        102 | 
        // }}} | 
      
      
         | 
         | 
        103 | 
          | 
      
      
         | 
         | 
        104 | 
        // {{{ XML parsing functions--- | 
      
      
         | 
         | 
        105 | 
          | 
      
      
         | 
         | 
        106 | 
        $curTag = ''; | 
      
      
         | 
         | 
        107 | 
          | 
      
      
         | 
         | 
        108 | 
        $curInfo = 0; | 
      
      
         | 
         | 
        109 | 
          | 
      
      
         | 
         | 
        110 | 
        // {{{ infoStartElement | 
      
      
         | 
         | 
        111 | 
          | 
      
      
         | 
         | 
        112 | 
        function infoStartElement($parser, $name, $attrs) { | 
      
      
         | 
         | 
        113 | 
        	global $curInfo, $curTag, $debugxml; | 
      
      
         | 
         | 
        114 | 
          | 
      
      
         | 
         | 
        115 | 
        	switch ($name) { | 
      
      
         | 
         | 
        116 | 
        		case 'INFO': | 
      
      
         | 
         | 
        117 | 
        			if ($debugxml) print 'Starting info'."\n"; | 
      
      
         | 
         | 
        118 | 
        			break; | 
      
      
         | 
         | 
        119 | 
          | 
      
      
         | 
         | 
        120 | 
        		case 'ENTRY': | 
      
      
         | 
         | 
        121 | 
        			if ($debugxml) print 'Creating info entry'."\n"; | 
      
      
         | 
         | 
        122 | 
          | 
      
      
         | 
         | 
        123 | 
        			if (count($attrs)) { | 
      
      
         | 
         | 
        124 | 
        				foreach ($attrs as $k => $v) { | 
      
      
         | 
         | 
        125 | 
        					switch ($k) { | 
      
      
         | 
         | 
        126 | 
        						case 'KIND': | 
      
      
         | 
         | 
        127 | 
        							if ($debugxml) print 'Kind '.$v."\n"; | 
      
      
         | 
         | 
        128 | 
        							$curInfo->isdir = ($v == 'dir'); | 
      
      
         | 
         | 
        129 | 
        							break; | 
      
      
         | 
         | 
        130 | 
        						case 'REVISION': | 
      
      
         | 
         | 
        131 | 
        							if ($debugxml) print 'Revision '.$v."\n"; | 
      
      
         | 
         | 
        132 | 
        							$curInfo->rev = $v; | 
      
      
         | 
         | 
        133 | 
        							break; | 
      
      
         | 
         | 
        134 | 
        					} | 
      
      
         | 
         | 
        135 | 
        				} | 
      
      
         | 
         | 
        136 | 
        			} | 
      
      
         | 
         | 
        137 | 
        			break; | 
      
      
         | 
         | 
        138 | 
          | 
      
      
         | 
         | 
        139 | 
        		default: | 
      
      
         | 
         | 
        140 | 
        			$curTag = $name; | 
      
      
         | 
         | 
        141 | 
        			break; | 
      
      
         | 
         | 
        142 | 
        	} | 
      
      
         | 
         | 
        143 | 
        } | 
      
      
         | 
         | 
        144 | 
          | 
      
      
         | 
         | 
        145 | 
        // }}} | 
      
      
         | 
         | 
        146 | 
          | 
      
      
         | 
         | 
        147 | 
        // {{{ infoEndElement | 
      
      
         | 
         | 
        148 | 
          | 
      
      
         | 
         | 
        149 | 
        function infoEndElement($parser, $name) { | 
      
      
         | 
         | 
        150 | 
        	global $curInfo, $debugxml, $curTag; | 
      
      
         | 
         | 
        151 | 
          | 
      
      
         | 
         | 
        152 | 
        	switch ($name) { | 
      
      
         | 
         | 
        153 | 
        		case 'ENTRY': | 
      
      
         | 
         | 
        154 | 
        			if ($debugxml) print 'Ending info entry'."\n"; | 
      
      
         | 
         | 
        155 | 
        			if ($curInfo->isdir) { | 
      
      
         | 
         | 
        156 | 
        				$curInfo->path .= '/'; | 
      
      
         | 
         | 
        157 | 
        			} | 
      
      
         | 
         | 
        158 | 
        			break; | 
      
      
         | 
         | 
        159 | 
        	} | 
      
      
         | 
         | 
        160 | 
          | 
      
      
         | 
         | 
        161 | 
        	$curTag = ''; | 
      
      
         | 
         | 
        162 | 
        } | 
      
      
         | 
         | 
        163 | 
          | 
      
      
         | 
         | 
        164 | 
        // }}} | 
      
      
         | 
         | 
        165 | 
          | 
      
      
         | 
         | 
        166 | 
        // {{{ infoCharacterData | 
      
      
         | 
         | 
        167 | 
          | 
      
      
         | 
         | 
        168 | 
        function infoCharacterData($parser, $data) { | 
      
      
         | 
         | 
        169 | 
        	global $curInfo, $curTag, $debugxml; | 
      
      
         | 
         | 
        170 | 
          | 
      
      
         | 
         | 
        171 | 
        	switch ($curTag) { | 
      
      
         | 
         | 
        172 | 
        		case 'URL': | 
      
      
         | 
         | 
        173 | 
        			if ($debugxml) print 'URL: '.$data."\n"; | 
      
      
         | 
         | 
        174 | 
        			$curInfo->path = $data; | 
      
      
         | 
         | 
        175 | 
        			break; | 
      
      
         | 
         | 
        176 | 
          | 
      
      
         | 
         | 
        177 | 
        		case 'ROOT': | 
      
      
         | 
         | 
        178 | 
        			if ($debugxml) print 'Root: '.$data."\n"; | 
      
      
         | 
         | 
        179 | 
        			$curInfo->path = urldecode(substr($curInfo->path, strlen($data))); | 
      
      
         | 
         | 
        180 | 
        			break; | 
      
      
         | 
         | 
        181 | 
        	} | 
      
      
         | 
         | 
        182 | 
        } | 
      
      
         | 
         | 
        183 | 
          | 
      
      
         | 
         | 
        184 | 
        // }}} | 
      
      
         | 
         | 
        185 | 
          | 
      
      
         | 
         | 
        186 | 
        $curList = 0; | 
      
      
         | 
         | 
        187 | 
          | 
      
      
         | 
         | 
        188 | 
        // {{{ listStartElement | 
      
      
         | 
         | 
        189 | 
          | 
      
      
         | 
         | 
        190 | 
        function listStartElement($parser, $name, $attrs) { | 
      
      
         | 
         | 
        191 | 
        	global $curList, $curTag, $debugxml; | 
      
      
         | 
         | 
        192 | 
          | 
      
      
         | 
         | 
        193 | 
        	switch ($name) { | 
      
      
         | 
         | 
        194 | 
        		case 'LIST': | 
      
      
         | 
         | 
        195 | 
        			if ($debugxml) print 'Starting list'."\n"; | 
      
      
         | 
         | 
        196 | 
          | 
      
      
         | 
         | 
        197 | 
        			if (count($attrs)) { | 
      
      
         | 
         | 
        198 | 
        				foreach ($attrs as $k => $v) { | 
      
      
         | 
         | 
        199 | 
        					switch ($k) { | 
      
      
         | 
         | 
        200 | 
        						case 'PATH': | 
      
      
         | 
         | 
        201 | 
        							if ($debugxml) print 'Path '.$v."\n"; | 
      
      
         | 
         | 
        202 | 
        							$curList->path = $v; | 
      
      
         | 
         | 
        203 | 
        							break; | 
      
      
         | 
         | 
        204 | 
        					} | 
      
      
         | 
         | 
        205 | 
        				} | 
      
      
         | 
         | 
        206 | 
        			} | 
      
      
         | 
         | 
        207 | 
        			break; | 
      
      
         | 
         | 
        208 | 
          | 
      
      
         | 
         | 
        209 | 
        		case 'ENTRY': | 
      
      
         | 
         | 
        210 | 
        			if ($debugxml) print 'Creating new entry'."\n"; | 
      
      
         | 
         | 
        211 | 
        			$curList->curEntry = new SVNListEntry; | 
      
      
         | 
         | 
        212 | 
          | 
      
      
         | 
         | 
        213 | 
        			if (count($attrs)) { | 
      
      
         | 
         | 
        214 | 
        				foreach ($attrs as $k => $v) { | 
      
      
         | 
         | 
        215 | 
        					switch ($k) { | 
      
      
         | 
         | 
        216 | 
        						case 'KIND': | 
      
      
         | 
         | 
        217 | 
        							if ($debugxml) print 'Kind '.$v."\n"; | 
      
      
         | 
         | 
        218 | 
        							$curList->curEntry->isdir = ($v == 'dir'); | 
      
      
         | 
         | 
        219 | 
        							break; | 
      
      
         | 
         | 
        220 | 
        					} | 
      
      
         | 
         | 
        221 | 
        				} | 
      
      
         | 
         | 
        222 | 
        			} | 
      
      
         | 
         | 
        223 | 
        			break; | 
      
      
         | 
         | 
        224 | 
          | 
      
      
         | 
         | 
        225 | 
        		case 'COMMIT': | 
      
      
         | 
         | 
        226 | 
        			if ($debugxml) print 'Commit'."\n"; | 
      
      
         | 
         | 
        227 | 
          | 
      
      
         | 
         | 
        228 | 
        			if (count($attrs)) { | 
      
      
         | 
         | 
        229 | 
        				foreach ($attrs as $k => $v) { | 
      
      
         | 
         | 
        230 | 
        					switch ($k) { | 
      
      
         | 
         | 
        231 | 
        						case 'REVISION': | 
      
      
         | 
         | 
        232 | 
        							if ($debugxml) print 'Revision '.$v."\n"; | 
      
      
         | 
         | 
        233 | 
        							$curList->curEntry->rev = $v; | 
      
      
         | 
         | 
        234 | 
        							break; | 
      
      
         | 
         | 
        235 | 
        					} | 
      
      
         | 
         | 
        236 | 
        				} | 
      
      
         | 
         | 
        237 | 
        			} | 
      
      
         | 
         | 
        238 | 
        			break; | 
      
      
         | 
         | 
        239 | 
          | 
      
      
         | 
         | 
        240 | 
        		default: | 
      
      
         | 
         | 
        241 | 
        			$curTag = $name; | 
      
      
         | 
         | 
        242 | 
        			break; | 
      
      
         | 
         | 
        243 | 
        	} | 
      
      
         | 
         | 
        244 | 
        } | 
      
      
         | 
         | 
        245 | 
          | 
      
      
         | 
         | 
        246 | 
        // }}} | 
      
      
         | 
         | 
        247 | 
          | 
      
      
         | 
         | 
        248 | 
        // {{{ listEndElement | 
      
      
         | 
         | 
        249 | 
          | 
      
      
         | 
         | 
        250 | 
        function listEndElement($parser, $name) { | 
      
      
         | 
         | 
        251 | 
        	global $curList, $debugxml, $curTag; | 
      
      
         | 
         | 
        252 | 
          | 
      
      
         | 
         | 
        253 | 
        	switch ($name) { | 
      
      
         | 
         | 
        254 | 
        		case 'ENTRY': | 
      
      
         | 
         | 
        255 | 
        			if ($debugxml) print 'Ending new list entry'."\n"; | 
      
      
         | 
         | 
        256 | 
        			if ($curList->curEntry->isdir) { | 
      
      
         | 
         | 
        257 | 
        				$curList->curEntry->file .= '/'; | 
      
      
         | 
         | 
        258 | 
        			} | 
      
      
         | 
         | 
        259 | 
        			$curList->entries[] = $curList->curEntry; | 
      
      
         | 
         | 
        260 | 
        			$curList->curEntry = null; | 
      
      
         | 
         | 
        261 | 
        			break; | 
      
      
         | 
         | 
        262 | 
        	} | 
      
      
         | 
         | 
        263 | 
          | 
      
      
         | 
         | 
        264 | 
        	$curTag = ''; | 
      
      
         | 
         | 
        265 | 
        } | 
      
      
         | 
         | 
        266 | 
          | 
      
      
         | 
         | 
        267 | 
        // }}} | 
      
      
         | 
         | 
        268 | 
          | 
      
      
         | 
         | 
        269 | 
        // {{{ listCharacterData | 
      
      
         | 
         | 
        270 | 
          | 
      
      
         | 
         | 
        271 | 
        function listCharacterData($parser, $data) { | 
      
      
         | 
         | 
        272 | 
        	global $curList, $curTag, $debugxml; | 
      
      
         | 
         | 
        273 | 
          | 
      
      
         | 
         | 
        274 | 
        	switch ($curTag) { | 
      
      
         | 
         | 
        275 | 
        		case 'NAME': | 
      
      
         | 
         | 
        276 | 
        			if ($debugxml) print 'Name: '.$data."\n"; | 
      
      
         | 
         | 
        277 | 
        			if ($data === false || $data === '') return; | 
      
      
         | 
         | 
        278 | 
        			$curList->curEntry->file .= $data; | 
      
      
         | 
         | 
        279 | 
        			break; | 
      
      
         | 
         | 
        280 | 
          | 
      
      
         | 
         | 
        281 | 
        		case 'AUTHOR': | 
      
      
         | 
         | 
        282 | 
        			if ($debugxml) print 'Author: '.$data."\n"; | 
      
      
         | 
         | 
        283 | 
        			if ($data === false || $data === '') return; | 
      
      
         | 
         | 
        284 | 
        			if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) | 
      
      
         | 
         | 
        285 | 
        				$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)); | 
      
      
         | 
         | 
        286 | 
        			$curList->curEntry->author .= $data; | 
      
      
         | 
         | 
        287 | 
        			break; | 
      
      
         | 
         | 
        288 | 
          | 
      
      
         | 
         | 
        289 | 
        		case 'DATE': | 
      
      
         | 
         | 
        290 | 
        			if ($debugxml) print 'Date: '.$data."\n"; | 
      
      
         | 
         | 
        291 | 
        			if ($data === false || $data === '') return; | 
      
      
         | 
         | 
        292 | 
        			$committime = parseSvnTimestamp($data); | 
      
      
         | 
         | 
        293 | 
        			$curList->curEntry->committime = $committime; | 
      
      
         | 
         | 
        294 | 
        			$curList->curEntry->date = date('Y-m-d H:i:s', $committime); | 
      
      
         | 
         | 
        295 | 
        			$curList->curEntry->age = datetimeFormatDuration(max(time() - $committime, 0), true, true); | 
      
      
         | 
         | 
        296 | 
        			break; | 
      
      
         | 
         | 
        297 | 
        	} | 
      
      
         | 
         | 
        298 | 
        } | 
      
      
         | 
         | 
        299 | 
          | 
      
      
         | 
         | 
        300 | 
        // }}} | 
      
      
         | 
         | 
        301 | 
          | 
      
      
         | 
         | 
        302 | 
        $curLog = 0; | 
      
      
         | 
         | 
        303 | 
          | 
      
      
         | 
         | 
        304 | 
        // {{{ logStartElement | 
      
      
         | 
         | 
        305 | 
          | 
      
      
         | 
         | 
        306 | 
        function logStartElement($parser, $name, $attrs) { | 
      
      
         | 
         | 
        307 | 
        	global $curLog, $curTag, $debugxml; | 
      
      
         | 
         | 
        308 | 
          | 
      
      
         | 
         | 
        309 | 
        	switch ($name) { | 
      
      
         | 
         | 
        310 | 
        		case 'LOGENTRY': | 
      
      
         | 
         | 
        311 | 
        			if ($debugxml) print 'Creating new log entry'."\n"; | 
      
      
         | 
         | 
        312 | 
        			$curLog->curEntry = new SVNLogEntry; | 
      
      
         | 
         | 
        313 | 
        			$curLog->curEntry->mods = array(); | 
      
      
         | 
         | 
        314 | 
          | 
      
      
         | 
         | 
        315 | 
        			$curLog->curEntry->path = $curLog->path; | 
      
      
         | 
         | 
        316 | 
          | 
      
      
         | 
         | 
        317 | 
        			if (count($attrs)) { | 
      
      
         | 
         | 
        318 | 
        				foreach ($attrs as $k => $v) { | 
      
      
         | 
         | 
        319 | 
        					switch ($k) { | 
      
      
         | 
         | 
        320 | 
        						case 'REVISION': | 
      
      
         | 
         | 
        321 | 
        							if ($debugxml) print 'Revision '.$v."\n"; | 
      
      
         | 
         | 
        322 | 
        							$curLog->curEntry->rev = $v; | 
      
      
         | 
         | 
        323 | 
        							break; | 
      
      
         | 
         | 
        324 | 
        					} | 
      
      
         | 
         | 
        325 | 
        				} | 
      
      
         | 
         | 
        326 | 
        			} | 
      
      
         | 
         | 
        327 | 
        			break; | 
      
      
         | 
         | 
        328 | 
          | 
      
      
         | 
         | 
        329 | 
        		case 'PATH': | 
      
      
         | 
         | 
        330 | 
        			if ($debugxml) print 'Creating new path'."\n"; | 
      
      
         | 
         | 
        331 | 
        			$curLog->curEntry->curMod = new SVNMod; | 
      
      
         | 
         | 
        332 | 
          | 
      
      
         | 
         | 
        333 | 
        			if (count($attrs)) { | 
      
      
         | 
         | 
        334 | 
        				foreach ($attrs as $k => $v) { | 
      
      
         | 
         | 
        335 | 
        					switch ($k) { | 
      
      
         | 
         | 
        336 | 
        						case 'ACTION': | 
      
      
         | 
         | 
        337 | 
        							if ($debugxml) print 'Action '.$v."\n"; | 
      
      
         | 
         | 
        338 | 
        							$curLog->curEntry->curMod->action = $v; | 
      
      
         | 
         | 
        339 | 
        							break; | 
      
      
         | 
         | 
        340 | 
          | 
      
      
         | 
         | 
        341 | 
        						case 'COPYFROM-PATH': | 
      
      
         | 
         | 
        342 | 
        							if ($debugxml) print 'Copy from: '.$v."\n"; | 
      
      
         | 
         | 
        343 | 
        							$curLog->curEntry->curMod->copyfrom = $v; | 
      
      
         | 
         | 
        344 | 
        							break; | 
      
      
         | 
         | 
        345 | 
          | 
      
      
         | 
         | 
        346 | 
        						case 'COPYFROM-REV': | 
      
      
         | 
         | 
        347 | 
        							$curLog->curEntry->curMod->copyrev = $v; | 
      
      
         | 
         | 
        348 | 
        							break; | 
      
      
         | 
         | 
        349 | 
          | 
      
      
         | 
         | 
        350 | 
        						case 'KIND': | 
      
      
         | 
         | 
        351 | 
        							if ($debugxml) print 'Kind '.$v."\n"; | 
      
      
         | 
         | 
        352 | 
        							$curLog->curEntry->curMod->isdir = ($v == 'dir'); | 
      
      
         | 
         | 
        353 | 
        							break; | 
      
      
         | 
         | 
        354 | 
        					} | 
      
      
         | 
         | 
        355 | 
        				} | 
      
      
         | 
         | 
        356 | 
        			} | 
      
      
         | 
         | 
        357 | 
          | 
      
      
         | 
         | 
        358 | 
        			$curTag = $name; | 
      
      
         | 
         | 
        359 | 
        			break; | 
      
      
         | 
         | 
        360 | 
          | 
      
      
         | 
         | 
        361 | 
        		default: | 
      
      
         | 
         | 
        362 | 
        			$curTag = $name; | 
      
      
         | 
         | 
        363 | 
        			break; | 
      
      
         | 
         | 
        364 | 
        	} | 
      
      
         | 
         | 
        365 | 
        } | 
      
      
         | 
         | 
        366 | 
          | 
      
      
         | 
         | 
        367 | 
        // }}} | 
      
      
         | 
         | 
        368 | 
          | 
      
      
         | 
         | 
        369 | 
        // {{{ logEndElement | 
      
      
         | 
         | 
        370 | 
          | 
      
      
         | 
         | 
        371 | 
        function logEndElement($parser, $name) { | 
      
      
         | 
         | 
        372 | 
        	global $curLog, $debugxml, $curTag; | 
      
      
         | 
         | 
        373 | 
          | 
      
      
         | 
         | 
        374 | 
        	switch ($name) { | 
      
      
         | 
         | 
        375 | 
        		case 'LOGENTRY': | 
      
      
         | 
         | 
        376 | 
        			if ($debugxml) print 'Ending new log entry'."\n"; | 
      
      
         | 
         | 
        377 | 
        			$curLog->entries[] = $curLog->curEntry; | 
      
      
         | 
         | 
        378 | 
        			break; | 
      
      
         | 
         | 
        379 | 
          | 
      
      
         | 
         | 
        380 | 
        		case 'PATH': | 
      
      
         | 
         | 
        381 | 
        			// The XML returned when a file is renamed/branched in inconsistent. | 
      
      
         | 
         | 
        382 | 
        			// In the case of a branch, the path doesn't include the leafname. | 
      
      
         | 
         | 
        383 | 
        			// In the case of a rename, it does.	Ludicrous. | 
      
      
         | 
         | 
        384 | 
          | 
      
      
         | 
         | 
        385 | 
        			if (!empty($curLog->path)) { | 
      
      
         | 
         | 
        386 | 
        				$pos = strrpos($curLog->path, '/'); | 
      
      
         | 
         | 
        387 | 
        				$curpath = substr($curLog->path, 0, $pos); | 
      
      
         | 
         | 
        388 | 
        				$leafname = substr($curLog->path, $pos + 1); | 
      
      
         | 
         | 
        389 | 
        			} else { | 
      
      
         | 
         | 
        390 | 
        				$curpath = ''; | 
      
      
         | 
         | 
        391 | 
        				$leafname = ''; | 
      
      
         | 
         | 
        392 | 
        			} | 
      
      
         | 
         | 
        393 | 
          | 
      
      
         | 
         | 
        394 | 
        			$curMod = $curLog->curEntry->curMod; | 
      
      
         | 
         | 
        395 | 
        			if ($curMod->action == 'A') { | 
      
      
         | 
         | 
        396 | 
        				if ($debugxml) print 'Examining added path "'.$curMod->copyfrom.'" - Current path = "'.$curpath.'", leafname = "'.$leafname.'"'."\n"; | 
      
      
         | 
         | 
        397 | 
        				if ($curMod->path == $curLog->path) { | 
      
      
         | 
         | 
        398 | 
        					// For directories and renames | 
      
      
         | 
         | 
        399 | 
        					$curLog->path = $curMod->copyfrom; | 
      
      
         | 
         | 
        400 | 
        				} else if ($curMod->path == $curpath || $curMod->path == $curpath.'/') { | 
      
      
         | 
         | 
        401 | 
        					// Logs of files that have moved due to branching | 
      
      
         | 
         | 
        402 | 
        					$curLog->path = $curMod->copyfrom.'/'.$leafname; | 
      
      
         | 
         | 
        403 | 
        				} else { | 
      
      
         | 
         | 
        404 | 
        					$curLog->path = str_replace($curMod->path, $curMod->copyfrom, $curLog->path); | 
      
      
         | 
         | 
        405 | 
        				} | 
      
      
         | 
         | 
        406 | 
        				if ($debugxml) print 'New path for comparison: "'.$curLog->path.'"'."\n"; | 
      
      
         | 
         | 
        407 | 
        			} | 
      
      
         | 
         | 
        408 | 
          | 
      
      
         | 
         | 
        409 | 
        			if ($debugxml) print 'Ending path'."\n"; | 
      
      
         | 
         | 
        410 | 
        			$curLog->curEntry->mods[] = $curLog->curEntry->curMod; | 
      
      
         | 
         | 
        411 | 
        			break; | 
      
      
         | 
         | 
        412 | 
          | 
      
      
         | 
         | 
        413 | 
        		case 'MSG': | 
      
      
         | 
         | 
        414 | 
        			$curLog->curEntry->msg = trim($curLog->curEntry->msg); | 
      
      
         | 
         | 
        415 | 
        			if ($debugxml) print 'Completed msg = "'.$curLog->curEntry->msg.'"'."\n"; | 
      
      
         | 
         | 
        416 | 
        			break; | 
      
      
         | 
         | 
        417 | 
        	} | 
      
      
         | 
         | 
        418 | 
          | 
      
      
         | 
         | 
        419 | 
        	$curTag = ''; | 
      
      
         | 
         | 
        420 | 
        } | 
      
      
         | 
         | 
        421 | 
          | 
      
      
         | 
         | 
        422 | 
        // }}} | 
      
      
         | 
         | 
        423 | 
          | 
      
      
         | 
         | 
        424 | 
        // {{{ logCharacterData | 
      
      
         | 
         | 
        425 | 
          | 
      
      
         | 
         | 
        426 | 
        function logCharacterData($parser, $data) { | 
      
      
         | 
         | 
        427 | 
        	global $curLog, $curTag, $debugxml; | 
      
      
         | 
         | 
        428 | 
          | 
      
      
         | 
         | 
        429 | 
        	switch ($curTag) { | 
      
      
         | 
         | 
        430 | 
        		case 'AUTHOR': | 
      
      
         | 
         | 
        431 | 
        			if ($debugxml) print 'Author: '.$data."\n"; | 
      
      
         | 
         | 
        432 | 
        			if ($data === false || $data === '') return; | 
      
      
         | 
         | 
        433 | 
        			if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) | 
      
      
         | 
         | 
        434 | 
        				$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)); | 
      
      
         | 
         | 
        435 | 
        			$curLog->curEntry->author .= $data; | 
      
      
         | 
         | 
        436 | 
        			break; | 
      
      
         | 
         | 
        437 | 
          | 
      
      
         | 
         | 
        438 | 
        		case 'DATE': | 
      
      
         | 
         | 
        439 | 
        			if ($debugxml) print 'Date: '.$data."\n"; | 
      
      
         | 
         | 
        440 | 
        			if ($data === false || $data === '') return; | 
      
      
         | 
         | 
        441 | 
        			$committime = parseSvnTimestamp($data); | 
      
      
         | 
         | 
        442 | 
        			$curLog->curEntry->committime = $committime; | 
      
      
         | 
         | 
        443 | 
        			$curLog->curEntry->date = date('Y-m-d H:i:s', $committime); | 
      
      
         | 
         | 
        444 | 
        			$curLog->curEntry->age = datetimeFormatDuration(max(time() - $committime, 0), true, true); | 
      
      
         | 
         | 
        445 | 
        			break; | 
      
      
         | 
         | 
        446 | 
          | 
      
      
         | 
         | 
        447 | 
        		case 'MSG': | 
      
      
         | 
         | 
        448 | 
        			if ($debugxml) print 'Msg: '.$data."\n"; | 
      
      
         | 
         | 
        449 | 
        			if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) | 
      
      
         | 
         | 
        450 | 
        				$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)); | 
      
      
         | 
         | 
        451 | 
        			$curLog->curEntry->msg .= $data; | 
      
      
         | 
         | 
        452 | 
        			break; | 
      
      
         | 
         | 
        453 | 
          | 
      
      
         | 
         | 
        454 | 
        		case 'PATH': | 
      
      
         | 
         | 
        455 | 
        			if ($debugxml) print 'Path name: '.$data."\n"; | 
      
      
         | 
         | 
        456 | 
        			if ($data === false || $data === '') return; | 
      
      
         | 
         | 
        457 | 
        			$curLog->curEntry->curMod->path .= $data; | 
      
      
         | 
         | 
        458 | 
        			break; | 
      
      
         | 
         | 
        459 | 
        	} | 
      
      
         | 
         | 
        460 | 
        } | 
      
      
         | 
         | 
        461 | 
          | 
      
      
         | 
         | 
        462 | 
        // }}} | 
      
      
         | 
         | 
        463 | 
          | 
      
      
         | 
         | 
        464 | 
        // }}} | 
      
      
         | 
         | 
        465 | 
          | 
      
      
         | 
         | 
        466 | 
        // {{{ internal functions (_topLevel and _listSort) | 
      
      
         | 
         | 
        467 | 
          | 
      
      
         | 
         | 
        468 | 
        // Function returns true if the give entry in a directory tree is at the top level | 
      
      
         | 
         | 
        469 | 
          | 
      
      
         | 
         | 
        470 | 
        function _topLevel($entry) { | 
      
      
         | 
         | 
        471 | 
        	// To be at top level, there must be one space before the entry | 
      
      
         | 
         | 
        472 | 
        	return (strlen($entry) > 1 && $entry[0] == ' ' && $entry[ 1 ] != ' '); | 
      
      
         | 
         | 
        473 | 
        } | 
      
      
         | 
         | 
        474 | 
          | 
      
      
         | 
         | 
        475 | 
        // Function to sort two given directory entries. | 
      
      
         | 
         | 
        476 | 
        // Directories go at the top if config option alphabetic is not set | 
      
      
         | 
         | 
        477 | 
          | 
      
      
         | 
         | 
        478 | 
        function _listSort($e1, $e2) { | 
      
      
         | 
         | 
        479 | 
        	global $config; | 
      
      
         | 
         | 
        480 | 
          | 
      
      
         | 
         | 
        481 | 
        	$file1 = $e1->file; | 
      
      
         | 
         | 
        482 | 
        	$file2 = $e2->file; | 
      
      
         | 
         | 
        483 | 
        	$isDir1 = ($file1[strlen($file1) - 1] == '/'); | 
      
      
         | 
         | 
        484 | 
        	$isDir2 = ($file2[strlen($file2) - 1] == '/'); | 
      
      
         | 
         | 
        485 | 
          | 
      
      
         | 
         | 
        486 | 
        	if (!$config->isAlphabeticOrder()) { | 
      
      
         | 
         | 
        487 | 
        		if ($isDir1 && !$isDir2) return -1; | 
      
      
         | 
         | 
        488 | 
        		if ($isDir2 && !$isDir1) return 1; | 
      
      
         | 
         | 
        489 | 
        	} | 
      
      
         | 
         | 
        490 | 
          | 
      
      
         | 
         | 
        491 | 
        	if ($isDir1) $file1 = substr($file1, 0, -1); | 
      
      
         | 
         | 
        492 | 
        	if ($isDir2) $file2 = substr($file2, 0, -1); | 
      
      
         | 
         | 
        493 | 
          | 
      
      
         | 
         | 
        494 | 
        	return strnatcasecmp($file1, $file2); | 
      
      
         | 
         | 
        495 | 
        } | 
      
      
         | 
         | 
        496 | 
          | 
      
      
         | 
         | 
        497 | 
        // }}} | 
      
      
         | 
         | 
        498 | 
          | 
      
      
         | 
         | 
        499 | 
        // {{{ encodePath | 
      
      
         | 
         | 
        500 | 
          | 
      
      
         | 
         | 
        501 | 
        // Function to encode a URL without encoding the /'s | 
      
      
         | 
         | 
        502 | 
          | 
      
      
         | 
         | 
        503 | 
        function encodePath($uri) { | 
      
      
         | 
         | 
        504 | 
        	global $config; | 
      
      
         | 
         | 
        505 | 
          | 
      
      
         | 
         | 
        506 | 
        	$uri = str_replace(DIRECTORY_SEPARATOR, '/', $uri); | 
      
      
         | 
         | 
        507 | 
        	if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) { | 
      
      
         | 
         | 
        508 | 
        		$uri = mb_convert_encoding($uri, 'UTF-8', mb_detect_encoding($uri)); | 
      
      
         | 
         | 
        509 | 
        	} | 
      
      
         | 
         | 
        510 | 
          | 
      
      
         | 
         | 
        511 | 
        	$parts = explode('/', $uri); | 
      
      
         | 
         | 
        512 | 
        	$partscount = count($parts); | 
      
      
         | 
         | 
        513 | 
        	for ($i = 0; $i < $partscount; $i++) { | 
      
      
         | 
         | 
        514 | 
        		// do not rawurlencode the 'svn+ssh://' part! | 
      
      
         | 
         | 
        515 | 
        		if ($i != 0 || $parts[$i] != 'svn+ssh:') { | 
      
      
         | 
         | 
        516 | 
        			$parts[$i] = rawurlencode($parts[$i]); | 
      
      
         | 
         | 
        517 | 
        		} | 
      
      
         | 
         | 
        518 | 
        	} | 
      
      
         | 
         | 
        519 | 
          | 
      
      
         | 
         | 
        520 | 
        	$uri = implode('/', $parts); | 
      
      
         | 
         | 
        521 | 
          | 
      
      
         | 
         | 
        522 | 
        	// Quick hack. Subversion seems to have a bug surrounding the use of %3A instead of : | 
      
      
         | 
         | 
        523 | 
          | 
      
      
         | 
         | 
        524 | 
        	$uri = str_replace('%3A', ':', $uri); | 
      
      
         | 
         | 
        525 | 
          | 
      
      
         | 
         | 
        526 | 
        	// Correct for Window share names | 
      
      
         | 
         | 
        527 | 
        	if ($config->serverIsWindows) { | 
      
      
         | 
         | 
        528 | 
        		if (substr($uri, 0, 2) == '//') { | 
      
      
         | 
         | 
        529 | 
        			$uri = '\\'.substr($uri, 2, strlen($uri)); | 
      
      
         | 
         | 
        530 | 
        		} | 
      
      
         | 
         | 
        531 | 
          | 
      
      
         | 
         | 
        532 | 
        		if (substr($uri, 0, 10) == 'file://///' ) { | 
      
      
         | 
         | 
        533 | 
        			$uri = 'file:///\\'.substr($uri, 10, strlen($uri)); | 
      
      
         | 
         | 
        534 | 
        		} | 
      
      
         | 
         | 
        535 | 
        	} | 
      
      
         | 
         | 
        536 | 
          | 
      
      
         | 
         | 
        537 | 
        	return $uri; | 
      
      
         | 
         | 
        538 | 
        } | 
      
      
         | 
         | 
        539 | 
          | 
      
      
         | 
         | 
        540 | 
        // }}} | 
      
      
         | 
         | 
        541 | 
          | 
      
      
         | 
         | 
        542 | 
        function _equalPart($str1, $str2) { | 
      
      
         | 
         | 
        543 | 
        	$len1 = strlen($str1); | 
      
      
         | 
         | 
        544 | 
        	$len2 = strlen($str2); | 
      
      
         | 
         | 
        545 | 
        	$i = 0; | 
      
      
         | 
         | 
        546 | 
        	while ($i < $len1 && $i < $len2) { | 
      
      
         | 
         | 
        547 | 
        		if (strcmp($str1[$i], $str2[$i]) != 0) { | 
      
      
         | 
         | 
        548 | 
        			break; | 
      
      
         | 
         | 
        549 | 
        		} | 
      
      
         | 
         | 
        550 | 
        		$i++; | 
      
      
         | 
         | 
        551 | 
        	} | 
      
      
         | 
         | 
        552 | 
        	if ($i == 0) { | 
      
      
         | 
         | 
        553 | 
        		return ''; | 
      
      
         | 
         | 
        554 | 
        	} | 
      
      
         | 
         | 
        555 | 
        	return substr($str1, 0, $i); | 
      
      
         | 
         | 
        556 | 
        } | 
      
      
         | 
         | 
        557 | 
          | 
      
      
         | 
         | 
        558 | 
        function _logError($string) { | 
      
      
         | 
         | 
        559 | 
        	$string = preg_replace("/--password '.*'/", "--password '[...]'", $string); | 
      
      
         | 
         | 
        560 | 
        	error_log($string); | 
      
      
         | 
         | 
        561 | 
        } | 
      
      
         | 
         | 
        562 | 
          | 
      
      
         | 
         | 
        563 | 
        // The SVNRepository class | 
      
      
         | 
         | 
        564 | 
          | 
      
      
         | 
         | 
        565 | 
        class SVNRepository { | 
      
      
         | 
         | 
        566 | 
        	var $repConfig; | 
      
      
         | 
         | 
        567 | 
        	var $geshi = null; | 
      
      
         | 
         | 
        568 | 
          | 
      
      
         | 
         | 
        569 | 
        	function __construct($repConfig) { | 
      
      
         | 
         | 
        570 | 
        		$this->repConfig = $repConfig; | 
      
      
         | 
         | 
        571 | 
        	} | 
      
      
         | 
         | 
        572 | 
          | 
      
      
         | 
         | 
        573 | 
        	// {{{ highlightLine | 
      
      
         | 
         | 
        574 | 
        	// | 
      
      
         | 
         | 
        575 | 
        	// Distill line-spanning syntax highlighting so that each line can stand alone | 
      
      
         | 
         | 
        576 | 
        	// (when invoking on the first line, $attributes should be an empty array) | 
      
      
         | 
         | 
        577 | 
        	// Invoked to make sure all open syntax highlighting tags (<font>, <i>, <b>, etc.) | 
      
      
         | 
         | 
        578 | 
        	// are closed at the end of each line and re-opened on the next line | 
      
      
         | 
         | 
        579 | 
          | 
      
      
         | 
         | 
        580 | 
        	function highlightLine($line, &$attributes) { | 
      
      
         | 
         | 
        581 | 
        		$hline = ''; | 
      
      
         | 
         | 
        582 | 
          | 
      
      
         | 
         | 
        583 | 
        		// Apply any highlighting in effect from the previous line | 
      
      
         | 
         | 
        584 | 
        		foreach ($attributes as $attr) { | 
      
      
         | 
         | 
        585 | 
        			$hline .= $attr['text']; | 
      
      
         | 
         | 
        586 | 
        		} | 
      
      
         | 
         | 
        587 | 
          | 
      
      
         | 
         | 
        588 | 
        		// append the new line | 
      
      
         | 
         | 
        589 | 
        		$hline .= $line; | 
      
      
         | 
         | 
        590 | 
          | 
      
      
         | 
         | 
        591 | 
        		// update attributes | 
      
      
         | 
         | 
        592 | 
        		for ($line = strstr($line, '<'); $line; $line = strstr(substr($line, 1), '<')) { | 
      
      
         | 
         | 
        593 | 
        			if (substr($line, 1, 1) == '/') { | 
      
      
         | 
         | 
        594 | 
        				// if this closes a tag, remove most recent corresponding opener | 
      
      
         | 
         | 
        595 | 
        				$tagNamLen = strcspn($line, '> '."\t", 2); | 
      
      
         | 
         | 
        596 | 
        				$tagNam = substr($line, 2, $tagNamLen); | 
      
      
         | 
         | 
        597 | 
        				foreach (array_reverse(array_keys($attributes)) as $k) { | 
      
      
         | 
         | 
        598 | 
        					if ($attributes[$k]['tag'] == $tagNam) { | 
      
      
         | 
         | 
        599 | 
        						unset($attributes[$k]); | 
      
      
         | 
         | 
        600 | 
        						break; | 
      
      
         | 
         | 
        601 | 
        					} | 
      
      
         | 
         | 
        602 | 
        				} | 
      
      
         | 
         | 
        603 | 
        			} else { | 
      
      
         | 
         | 
        604 | 
        				// if this opens a tag, add it to the list | 
      
      
         | 
         | 
        605 | 
        				$tagNamLen = strcspn($line, '> '."\t", 1); | 
      
      
         | 
         | 
        606 | 
        				$tagNam = substr($line, 1, $tagNamLen); | 
      
      
         | 
         | 
        607 | 
        				$tagLen = strcspn($line, '>') + 1; | 
      
      
         | 
         | 
        608 | 
        				$attributes[] = array('tag' => $tagNam, 'text' => substr($line, 0, $tagLen)); | 
      
      
         | 
         | 
        609 | 
        			} | 
      
      
         | 
         | 
        610 | 
        		} | 
      
      
         | 
         | 
        611 | 
          | 
      
      
         | 
         | 
        612 | 
        		// close any still-open tags | 
      
      
         | 
         | 
        613 | 
        		foreach (array_reverse($attributes) as $attr) { | 
      
      
         | 
         | 
        614 | 
        			$hline .= '</'.$attr['tag'].'>'; | 
      
      
         | 
         | 
        615 | 
        		} | 
      
      
         | 
         | 
        616 | 
          | 
      
      
         | 
         | 
        617 | 
        		// XXX: this just simply replaces [ and ] with their entities to prevent | 
      
      
         | 
         | 
        618 | 
        		//		it from being parsed by the template parser; maybe something more | 
      
      
         | 
         | 
        619 | 
        		//		elegant is in order? | 
      
      
         | 
         | 
        620 | 
        		$hline = str_replace('[', '[', str_replace(']', ']', $hline) ); | 
      
      
         | 
         | 
        621 | 
        		return $hline; | 
      
      
         | 
         | 
        622 | 
        	} | 
      
      
         | 
         | 
        623 | 
          | 
      
      
         | 
         | 
        624 | 
        	// }}} | 
      
      
         | 
         | 
        625 | 
          | 
      
      
         | 
         | 
        626 | 
        	// Private function to simplify creation of common SVN command string text. | 
      
      
         | 
         | 
        627 | 
        	function svnCommandString($command, $path, $rev, $peg) { | 
      
      
         | 
         | 
        628 | 
        		global $config; | 
      
      
         | 
         | 
        629 | 
        		return $config->getSvnCommand().$this->repConfig->svnCredentials().' '.$command.' '.($rev ? '-r '.$rev.' ' : '').quote(encodePath($this->getSvnPath($path)).'@'.($peg ? $peg : '')); | 
      
      
         | 
         | 
        630 | 
        	} | 
      
      
         | 
         | 
        631 | 
          | 
      
      
         | 
         | 
        632 | 
        	// Private function to simplify creation of enscript command string text. | 
      
      
         | 
         | 
        633 | 
        	function enscriptCommandString($path) { | 
      
      
         | 
         | 
        634 | 
        		global $config, $extEnscript; | 
      
      
         | 
         | 
        635 | 
          | 
      
      
         | 
         | 
        636 | 
        		$filename = basename($path); | 
      
      
         | 
         | 
        637 | 
        		$ext = strrchr($path, '.'); | 
      
      
         | 
         | 
        638 | 
          | 
      
      
         | 
         | 
        639 | 
        		$lang = false; | 
      
      
         | 
         | 
        640 | 
        		if (array_key_exists($filename, $extEnscript)) { | 
      
      
         | 
         | 
        641 | 
        			$lang = $extEnscript[$filename]; | 
      
      
         | 
         | 
        642 | 
        		} else if ($ext && array_key_exists(strtolower($ext), $extEnscript)) { | 
      
      
         | 
         | 
        643 | 
        			$lang = $extEnscript[strtolower($ext)]; | 
      
      
         | 
         | 
        644 | 
        		} | 
      
      
         | 
         | 
        645 | 
          | 
      
      
         | 
         | 
        646 | 
        		$cmd = $config->enscript.' --language=html'; | 
      
      
         | 
         | 
        647 | 
        		if ($lang !== false) { | 
      
      
         | 
         | 
        648 | 
        			$cmd .= ' --color --'.(!$config->getUseEnscriptBefore_1_6_3() ? 'highlight' : 'pretty-print').'='.$lang; | 
      
      
         | 
         | 
        649 | 
        		} | 
      
      
         | 
         | 
        650 | 
        		$cmd .= ' -o -'; | 
      
      
         | 
         | 
        651 | 
        		return $cmd; | 
      
      
         | 
         | 
        652 | 
        	} | 
      
      
         | 
         | 
        653 | 
          | 
      
      
         | 
         | 
        654 | 
        	// {{{ getFileContents | 
      
      
         | 
         | 
        655 | 
        	// | 
      
      
         | 
         | 
        656 | 
        	// Dump the content of a file to the given filename | 
      
      
         | 
         | 
        657 | 
          | 
      
      
         | 
         | 
        658 | 
        	function getFileContents($path, $filename, $rev = 0, $peg = '', $pipe = '', $highlight = 'file') { | 
      
      
         | 
         | 
        659 | 
        		global $config; | 
      
      
         | 
         | 
        660 | 
        		assert ($highlight == 'file' || $highlight == 'no' || $highlight == 'line'); | 
      
      
         | 
         | 
        661 | 
          | 
      
      
         | 
         | 
        662 | 
        		$highlighted = false; | 
      
      
         | 
         | 
        663 | 
          | 
      
      
         | 
         | 
        664 | 
        		// If there's no filename, just deliver the contents as-is to the user | 
      
      
         | 
         | 
        665 | 
        		if ($filename == '') { | 
      
      
         | 
         | 
        666 | 
        			$cmd = $this->svnCommandString('cat', $path, $rev, $peg); | 
      
      
         | 
         | 
        667 | 
        			passthruCommand($cmd.' '.$pipe); | 
      
      
         | 
         | 
        668 | 
        			return $highlighted; | 
      
      
         | 
         | 
        669 | 
        		} | 
      
      
         | 
         | 
        670 | 
          | 
      
      
         | 
         | 
        671 | 
        		// Get the file contents info | 
      
      
         | 
         | 
        672 | 
          | 
      
      
         | 
         | 
        673 | 
        		$tempname = $filename; | 
      
      
         | 
         | 
        674 | 
        		if ($highlight == 'line') { | 
      
      
         | 
         | 
        675 | 
        			$tempname = tempnamWithCheck($config->getTempDir(), ''); | 
      
      
         | 
         | 
        676 | 
        		} | 
      
      
         | 
         | 
        677 | 
        		$highlighted = true; | 
      
      
         | 
         | 
        678 | 
        		$shouldTrimOutput = false; | 
      
      
         | 
         | 
        679 | 
        		$explodeStr = "\n"; | 
      
      
         | 
         | 
        680 | 
        		if ($highlight != 'no' && $config->useGeshi && $geshiLang = $this->highlightLanguageUsingGeshi($path)) { | 
      
      
         | 
         | 
        681 | 
        			$this->applyGeshi($path, $tempname, $geshiLang, $rev, $peg, false, $highlight); | 
      
      
         | 
         | 
        682 | 
        			// Geshi outputs in HTML format, enscript does not | 
      
      
         | 
         | 
        683 | 
        			$shouldTrimOutput = true; | 
      
      
         | 
         | 
        684 | 
        			$explodeStr = "<br />"; | 
      
      
         | 
         | 
        685 | 
        		} else if ($highlight != 'no' && $config->useEnscript) { | 
      
      
         | 
         | 
        686 | 
        			// Get the files, feed it through enscript, then remove the enscript headers using sed | 
      
      
         | 
         | 
        687 | 
        			// Note that the sed command returns only the part of the file between <PRE> and </PRE>. | 
      
      
         | 
         | 
        688 | 
        			// It's complicated because it's designed not to return those lines themselves. | 
      
      
         | 
         | 
        689 | 
        			$cmd = $this->svnCommandString('cat', $path, $rev, $peg); | 
      
      
         | 
         | 
        690 | 
        			$cmd = $cmd.' | '.$this->enscriptCommandString($path).' | '. | 
      
      
         | 
         | 
        691 | 
        				$config->sed.' -n '.$config->quote.'1,/^<PRE.$/!{/^<\\/PRE.$/,/^<PRE.$/!p;}'.$config->quote.' > '.$tempname; | 
      
      
         | 
         | 
        692 | 
        		} else { | 
      
      
         | 
         | 
        693 | 
        			$highlighted = false; | 
      
      
         | 
         | 
        694 | 
        			$cmd = $this->svnCommandString('cat', $path, $rev, $peg); | 
      
      
         | 
         | 
        695 | 
        			$cmd = $cmd.' > '.quote($filename); | 
      
      
         | 
         | 
        696 | 
        		} | 
      
      
         | 
         | 
        697 | 
          | 
      
      
         | 
         | 
        698 | 
        		if (isset($cmd)) { | 
      
      
         | 
         | 
        699 | 
        			$error	= ''; | 
      
      
         | 
         | 
        700 | 
        			$output	= runCommand($cmd, true, $error); | 
      
      
         | 
         | 
        701 | 
          | 
      
      
         | 
         | 
        702 | 
        			if (!empty($error)) { | 
      
      
         | 
         | 
        703 | 
        				global $lang; | 
      
      
         | 
         | 
        704 | 
        				_logError($lang['BADCMD'].': '.$cmd); | 
      
      
         | 
         | 
        705 | 
        				_logError($error); | 
      
      
         | 
         | 
        706 | 
          | 
      
      
         | 
         | 
        707 | 
        				global $vars; | 
      
      
         | 
         | 
        708 | 
        				$vars['warning'] = nl2br(escape(toOutputEncoding($error))); | 
      
      
         | 
         | 
        709 | 
        			} | 
      
      
         | 
         | 
        710 | 
        		} | 
      
      
         | 
         | 
        711 | 
          | 
      
      
         | 
         | 
        712 | 
        		if ($highlighted && $highlight == 'line') { | 
      
      
         | 
         | 
        713 | 
        			// If we need each line independently highlighted (e.g. for diff or blame) | 
      
      
         | 
         | 
        714 | 
        			// then we'll need to filter the output of the highlighter | 
      
      
         | 
         | 
        715 | 
        			// to make sure tags like <font>, <i> or <b> don't span lines | 
      
      
         | 
         | 
        716 | 
          | 
      
      
         | 
         | 
        717 | 
        			$dst = fopen($filename, 'w'); | 
      
      
         | 
         | 
        718 | 
        			if ($dst) { | 
      
      
         | 
         | 
        719 | 
        				$content = file_get_contents($tempname); | 
      
      
         | 
         | 
        720 | 
        				$content = explode($explodeStr, $content); | 
      
      
         | 
         | 
        721 | 
          | 
      
      
         | 
         | 
        722 | 
        				// $attributes is used to remember what highlighting attributes | 
      
      
         | 
         | 
        723 | 
        				// are in effect from one line to the next | 
      
      
         | 
         | 
        724 | 
        				$attributes = array(); // start with no attributes in effect | 
      
      
         | 
         | 
        725 | 
          | 
      
      
         | 
         | 
        726 | 
        				foreach ($content as $line) { | 
      
      
         | 
         | 
        727 | 
        					if ($shouldTrimOutput) { | 
      
      
         | 
         | 
        728 | 
        						$line = trim($line); | 
      
      
         | 
         | 
        729 | 
        					} | 
      
      
         | 
         | 
        730 | 
        					fputs($dst, $this->highlightLine($line, $attributes)."\n"); | 
      
      
         | 
         | 
        731 | 
        				} | 
      
      
         | 
         | 
        732 | 
        				fclose($dst); | 
      
      
         | 
         | 
        733 | 
        			} | 
      
      
         | 
         | 
        734 | 
        		} | 
      
      
         | 
         | 
        735 | 
        		if ($tempname != $filename) { | 
      
      
         | 
         | 
        736 | 
        			@unlink($tempname); | 
      
      
         | 
         | 
        737 | 
        		} | 
      
      
         | 
         | 
        738 | 
        		return $highlighted; | 
      
      
         | 
         | 
        739 | 
        	} | 
      
      
         | 
         | 
        740 | 
          | 
      
      
         | 
         | 
        741 | 
        	// }}} | 
      
      
         | 
         | 
        742 | 
          | 
      
      
         | 
         | 
        743 | 
        	// {{{ highlightLanguageUsingGeshi | 
      
      
         | 
         | 
        744 | 
        	// | 
      
      
         | 
         | 
        745 | 
        	// check if geshi can highlight the given extension and return the language | 
      
      
         | 
         | 
        746 | 
          | 
      
      
         | 
         | 
        747 | 
        	function highlightLanguageUsingGeshi($path) { | 
      
      
         | 
         | 
        748 | 
        		global $config; | 
      
      
         | 
         | 
        749 | 
        		global $extGeshi; | 
      
      
         | 
         | 
        750 | 
          | 
      
      
         | 
         | 
        751 | 
        		$filename = basename($path); | 
      
      
         | 
         | 
        752 | 
        		$ext = strrchr($path, '.'); | 
      
      
         | 
         | 
        753 | 
        		if (substr($ext, 0, 1) == '.') $ext = substr($ext, 1); | 
      
      
         | 
         | 
        754 | 
          | 
      
      
         | 
         | 
        755 | 
        		foreach ($extGeshi as $language => $extensions) { | 
      
      
         | 
         | 
        756 | 
        			if (in_array($filename, $extensions) || in_array(strtolower($ext), $extensions)) { | 
      
      
         | 
         | 
        757 | 
        				if ($this->geshi === null) { | 
      
      
         | 
         | 
        758 | 
        					if (!defined('USE_AUTOLOADER')) { | 
      
      
         | 
         | 
        759 | 
        						require_once $config->getGeshiScript(); | 
      
      
         | 
         | 
        760 | 
        					} | 
      
      
         | 
         | 
        761 | 
        					$this->geshi = new GeSHi(); | 
      
      
         | 
         | 
        762 | 
        				} | 
      
      
         | 
         | 
        763 | 
        				$this->geshi->set_language($language); | 
      
      
         | 
         | 
        764 | 
        				if ($this->geshi->error() === false) { | 
      
      
         | 
         | 
        765 | 
        					return $language; | 
      
      
         | 
         | 
        766 | 
        				} | 
      
      
         | 
         | 
        767 | 
        			} | 
      
      
         | 
         | 
        768 | 
        		} | 
      
      
         | 
         | 
        769 | 
        		return ''; | 
      
      
         | 
         | 
        770 | 
        	} | 
      
      
         | 
         | 
        771 | 
          | 
      
      
         | 
         | 
        772 | 
        	// }}} | 
      
      
         | 
         | 
        773 | 
          | 
      
      
         | 
         | 
        774 | 
        	// {{{ applyGeshi | 
      
      
         | 
         | 
        775 | 
        	// | 
      
      
         | 
         | 
        776 | 
        	// perform syntax highlighting using geshi | 
      
      
         | 
         | 
        777 | 
          | 
      
      
         | 
         | 
        778 | 
        	function applyGeshi($path, $filename, $language, $rev, $peg = '', $return = false, $highlight = 'file') { | 
      
      
         | 
         | 
        779 | 
        		global $config; | 
      
      
         | 
         | 
        780 | 
          | 
      
      
         | 
         | 
        781 | 
        		// Output the file to the filename | 
      
      
         | 
         | 
        782 | 
        		$error	= ''; | 
      
      
         | 
         | 
        783 | 
        		$cmd	= $this->svnCommandString('cat', $path, $rev, $peg).' > '.quote($filename); | 
      
      
         | 
         | 
        784 | 
        		$output	= runCommand($cmd, true, $error); | 
      
      
         | 
         | 
        785 | 
          | 
      
      
         | 
         | 
        786 | 
        		if (!empty($error)) { | 
      
      
         | 
         | 
        787 | 
        			global $lang; | 
      
      
         | 
         | 
        788 | 
        			_logError($lang['BADCMD'].': '.$cmd); | 
      
      
         | 
         | 
        789 | 
        			_logError($error); | 
      
      
         | 
         | 
        790 | 
          | 
      
      
         | 
         | 
        791 | 
        			global $vars; | 
      
      
         | 
         | 
        792 | 
        			$vars['warning'] = 'Unable to cat file: '.nl2br(escape(toOutputEncoding($error))); | 
      
      
         | 
         | 
        793 | 
        			return; | 
      
      
         | 
         | 
        794 | 
        		} | 
      
      
         | 
         | 
        795 | 
          | 
      
      
         | 
         | 
        796 | 
        		$source = file_get_contents($filename); | 
      
      
         | 
         | 
        797 | 
          | 
      
      
         | 
         | 
        798 | 
        		if ($this->geshi === null) { | 
      
      
         | 
         | 
        799 | 
        			if (!defined('USE_AUTOLOADER')) { | 
      
      
         | 
         | 
        800 | 
        				require_once $config->getGeshiScript(); | 
      
      
         | 
         | 
        801 | 
        			} | 
      
      
         | 
         | 
        802 | 
        			$this->geshi = new GeSHi(); | 
      
      
         | 
         | 
        803 | 
        		} | 
      
      
         | 
         | 
        804 | 
          | 
      
      
         | 
         | 
        805 | 
        		$this->geshi->set_source($source); | 
      
      
         | 
         | 
        806 | 
        		$this->geshi->set_language($language); | 
      
      
         | 
         | 
        807 | 
        		$this->geshi->set_header_type(GESHI_HEADER_NONE); | 
      
      
         | 
         | 
        808 | 
        		$this->geshi->set_overall_class('geshi'); | 
      
      
         | 
         | 
        809 | 
        		$this->geshi->set_tab_width($this->repConfig->getExpandTabsBy()); | 
      
      
         | 
         | 
        810 | 
          | 
      
      
         | 
         | 
        811 | 
        		if ($highlight == 'file') { | 
      
      
         | 
         | 
        812 | 
        			$this->geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS); | 
      
      
         | 
         | 
        813 | 
        			$this->geshi->set_overall_id('geshi'); | 
      
      
         | 
         | 
        814 | 
        			$this->geshi->enable_ids(true); | 
      
      
         | 
         | 
        815 | 
        		} | 
      
      
         | 
         | 
        816 | 
          | 
      
      
         | 
         | 
        817 | 
        		if ($return) { | 
      
      
         | 
         | 
        818 | 
        			return $this->geshi->parse_code(); | 
      
      
         | 
         | 
        819 | 
        		} else { | 
      
      
         | 
         | 
        820 | 
        			$f = @fopen($filename, 'w'); | 
      
      
         | 
         | 
        821 | 
        			fwrite($f, $this->geshi->parse_code()); | 
      
      
         | 
         | 
        822 | 
        			fclose($f); | 
      
      
         | 
         | 
        823 | 
        		} | 
      
      
         | 
         | 
        824 | 
        	} | 
      
      
         | 
         | 
        825 | 
          | 
      
      
         | 
         | 
        826 | 
        	// }}} | 
      
      
         | 
         | 
        827 | 
          | 
      
      
         | 
         | 
        828 | 
        	// {{{ listFileContents | 
      
      
         | 
         | 
        829 | 
        	// | 
      
      
         | 
         | 
        830 | 
        	// Print the contents of a file without filling up Apache's memory | 
      
      
         | 
         | 
        831 | 
          | 
      
      
         | 
         | 
        832 | 
        	function listFileContents($path, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        833 | 
        		global $config; | 
      
      
         | 
         | 
        834 | 
          | 
      
      
         | 
         | 
        835 | 
        		if ($config->useGeshi && $geshiLang = $this->highlightLanguageUsingGeshi($path)) { | 
      
      
         | 
         | 
        836 | 
        			$tempname = tempnamWithCheck($config->getTempDir(), 'websvn'); | 
      
      
         | 
         | 
        837 | 
        			if ($tempname !== false) { | 
      
      
         | 
         | 
        838 | 
        				print toOutputEncoding($this->applyGeshi($path, $tempname, $geshiLang, $rev, $peg, true)); | 
      
      
         | 
         | 
        839 | 
        				@unlink($tempname); | 
      
      
         | 
         | 
        840 | 
        			} | 
      
      
         | 
         | 
        841 | 
        		} else { | 
      
      
         | 
         | 
        842 | 
        			$pre = false; | 
      
      
         | 
         | 
        843 | 
        			$cmd = $this->svnCommandString('cat', $path, $rev, $peg); | 
      
      
         | 
         | 
        844 | 
        			if ($config->useEnscript) { | 
      
      
         | 
         | 
        845 | 
        				$cmd .= ' | '.$this->enscriptCommandString($path).' | '. | 
      
      
         | 
         | 
        846 | 
        					$config->sed.' -n '.$config->quote.'/^<PRE.$/,/^<\\/PRE.$/p'.$config->quote; | 
      
      
         | 
         | 
        847 | 
        			} else { | 
      
      
         | 
         | 
        848 | 
        				$pre = true; | 
      
      
         | 
         | 
        849 | 
        			} | 
      
      
         | 
         | 
        850 | 
          | 
      
      
         | 
         | 
        851 | 
        			if ($result = popenCommand($cmd, 'r')) { | 
      
      
         | 
         | 
        852 | 
        				if ($pre) | 
      
      
         | 
         | 
        853 | 
        					echo '<pre>'; | 
      
      
         | 
         | 
        854 | 
        				while (!feof($result)) { | 
      
      
         | 
         | 
        855 | 
        					$line = fgets($result, 1024); | 
      
      
         | 
         | 
        856 | 
        					$line = toOutputEncoding($line); | 
      
      
         | 
         | 
        857 | 
        					if ($pre) { | 
      
      
         | 
         | 
        858 | 
        						$line = escape($line); | 
      
      
         | 
         | 
        859 | 
        					} | 
      
      
         | 
         | 
        860 | 
        					print hardspace($line); | 
      
      
         | 
         | 
        861 | 
        				} | 
      
      
         | 
         | 
        862 | 
        				if ($pre) | 
      
      
         | 
         | 
        863 | 
        					echo '</pre>'; | 
      
      
         | 
         | 
        864 | 
        				pclose($result); | 
      
      
         | 
         | 
        865 | 
        			} | 
      
      
         | 
         | 
        866 | 
        		} | 
      
      
         | 
         | 
        867 | 
        	} | 
      
      
         | 
         | 
        868 | 
          | 
      
      
         | 
         | 
        869 | 
        	// }}} | 
      
      
         | 
         | 
        870 | 
          | 
      
      
         | 
         | 
        871 | 
        	// {{{ listReadmeContents | 
      
      
         | 
         | 
        872 | 
        	// | 
      
      
         | 
         | 
        873 | 
        	// Parse the README.md file | 
      
      
         | 
         | 
        874 | 
        	function listReadmeContents($path, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        875 | 
        		global $config; | 
      
      
         | 
         | 
        876 | 
          | 
      
      
         | 
         | 
        877 | 
        		$file = "README.md"; | 
      
      
         | 
         | 
        878 | 
          | 
      
      
         | 
         | 
        879 | 
        		if ($this->isFile($path.$file) != True) | 
      
      
         | 
         | 
        880 | 
        		{ | 
      
      
         | 
         | 
        881 | 
        			return; | 
      
      
         | 
         | 
        882 | 
        		} | 
      
      
         | 
         | 
        883 | 
          | 
      
      
         | 
         | 
        884 | 
        		if (!$config->getUseParsedown()) | 
      
      
         | 
         | 
        885 | 
        		{ | 
      
      
         | 
         | 
        886 | 
        			return; | 
      
      
         | 
         | 
        887 | 
        		} | 
      
      
         | 
         | 
        888 | 
          | 
      
      
         | 
         | 
        889 | 
        		// Autoloader handles most of the time | 
      
      
         | 
         | 
        890 | 
        		if (!defined('USE_AUTOLOADER')) { | 
      
      
         | 
         | 
        891 | 
        			require_once $config->getParsedownScript(); | 
      
      
         | 
         | 
        892 | 
        		} | 
      
      
         | 
         | 
        893 | 
          | 
      
      
         | 
         | 
        894 | 
        		$mdParser = new Parsedown(); | 
      
      
         | 
         | 
        895 | 
        		$cmd = $this->svnCommandString('cat', $path.$file, $rev, $peg); | 
      
      
         | 
         | 
        896 | 
          | 
      
      
         | 
         | 
        897 | 
        		if (!($result = popenCommand($cmd, 'r'))) | 
      
      
         | 
         | 
        898 | 
        		{ | 
      
      
         | 
         | 
        899 | 
        			return; | 
      
      
         | 
         | 
        900 | 
        		} | 
      
      
         | 
         | 
        901 | 
          | 
      
      
         | 
         | 
        902 | 
        		echo('<div id="wrap">'); | 
      
      
         | 
         | 
        903 | 
        		while (!feof($result)) | 
      
      
         | 
         | 
        904 | 
        		{ | 
      
      
         | 
         | 
        905 | 
        			$line = fgets($result, 1024); | 
      
      
         | 
         | 
        906 | 
        			echo $mdParser->text($line); | 
      
      
         | 
         | 
        907 | 
        		} | 
      
      
         | 
         | 
        908 | 
        		echo('</div>'); | 
      
      
         | 
         | 
        909 | 
        		pclose($result); | 
      
      
         | 
         | 
        910 | 
          | 
      
      
         | 
         | 
        911 | 
        	} | 
      
      
         | 
         | 
        912 | 
          | 
      
      
         | 
         | 
        913 | 
        	// }}} | 
      
      
         | 
         | 
        914 | 
          | 
      
      
         | 
         | 
        915 | 
        	// {{{ getBlameDetails | 
      
      
         | 
         | 
        916 | 
        	// | 
      
      
         | 
         | 
        917 | 
        	// Dump the blame content of a file to the given filename | 
      
      
         | 
         | 
        918 | 
          | 
      
      
         | 
         | 
        919 | 
        	function getBlameDetails($path, $filename, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        920 | 
        		$error	= ''; | 
      
      
         | 
         | 
        921 | 
        		$cmd	= $this->svnCommandString('blame', $path, $rev, $peg).' > '.quote($filename); | 
      
      
         | 
         | 
        922 | 
        		$output	= runCommand($cmd, true, $error); | 
      
      
         | 
         | 
        923 | 
          | 
      
      
         | 
         | 
        924 | 
        		if (!empty($error)) { | 
      
      
         | 
         | 
        925 | 
        			global $lang; | 
      
      
         | 
         | 
        926 | 
        			_logError($lang['BADCMD'].': '.$cmd); | 
      
      
         | 
         | 
        927 | 
        			_logError($error); | 
      
      
         | 
         | 
        928 | 
          | 
      
      
         | 
         | 
        929 | 
        			global $vars; | 
      
      
         | 
         | 
        930 | 
        			$vars['warning'] = 'No blame info: '.nl2br(escape(toOutputEncoding($error))); | 
      
      
         | 
         | 
        931 | 
        		} | 
      
      
         | 
         | 
        932 | 
        	} | 
      
      
         | 
         | 
        933 | 
          | 
      
      
         | 
         | 
        934 | 
        	// }}} | 
      
      
         | 
         | 
        935 | 
          | 
      
      
         | 
         | 
        936 | 
        	function getProperties($path, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        937 | 
        		$cmd = $this->svnCommandString('proplist', $path, $rev, $peg); | 
      
      
         | 
         | 
        938 | 
        		$ret = runCommand($cmd, true); | 
      
      
         | 
         | 
        939 | 
        		$properties = array(); | 
      
      
         | 
         | 
        940 | 
        		if (is_array($ret)) { | 
      
      
         | 
         | 
        941 | 
        			foreach ($ret as $line) { | 
      
      
         | 
         | 
        942 | 
        				if (substr($line, 0, 1) == ' ') { | 
      
      
         | 
         | 
        943 | 
        					$properties[] = ltrim($line); | 
      
      
         | 
         | 
        944 | 
        				} | 
      
      
         | 
         | 
        945 | 
        			} | 
      
      
         | 
         | 
        946 | 
        		} | 
      
      
         | 
         | 
        947 | 
        		return $properties; | 
      
      
         | 
         | 
        948 | 
        	} | 
      
      
         | 
         | 
        949 | 
          | 
      
      
         | 
         | 
        950 | 
        	// {{{ getProperty | 
      
      
         | 
         | 
        951 | 
          | 
      
      
         | 
         | 
        952 | 
        	function getProperty($path, $property, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        953 | 
        		$cmd = $this->svnCommandString('propget '.$property, $path, $rev, $peg); | 
      
      
         | 
         | 
        954 | 
        		$ret = runCommand($cmd, true); | 
      
      
         | 
         | 
        955 | 
        		// Remove the surplus newline | 
      
      
         | 
         | 
        956 | 
        		if (count($ret)) { | 
      
      
         | 
         | 
        957 | 
        			unset($ret[count($ret) - 1]); | 
      
      
         | 
         | 
        958 | 
        		} | 
      
      
         | 
         | 
        959 | 
        		return implode("\n", $ret); | 
      
      
         | 
         | 
        960 | 
        	} | 
      
      
         | 
         | 
        961 | 
          | 
      
      
         | 
         | 
        962 | 
        	// }}} | 
      
      
         | 
         | 
        963 | 
          | 
      
      
         | 
         | 
        964 | 
        	// {{{ exportDirectory | 
      
      
         | 
         | 
        965 | 
        	// | 
      
      
         | 
         | 
        966 | 
        	// Exports the directory to the given location | 
      
      
         | 
         | 
        967 | 
          | 
      
      
         | 
         | 
        968 | 
        	function exportRepositoryPath($path, $filename, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        969 | 
        		$cmd = $this->svnCommandString('export', $path, $rev, $peg).' '.quote($filename.'@'); | 
      
      
         | 
         | 
        970 | 
        		$retcode = 0; | 
      
      
         | 
         | 
        971 | 
        		execCommand($cmd, $retcode); | 
      
      
         | 
         | 
        972 | 
        		if ($retcode != 0) { | 
      
      
         | 
         | 
        973 | 
        			global $lang; | 
      
      
         | 
         | 
        974 | 
        			_logError($lang['BADCMD'].': '.$cmd); | 
      
      
         | 
         | 
        975 | 
        		} | 
      
      
         | 
         | 
        976 | 
        		return $retcode; | 
      
      
         | 
         | 
        977 | 
        	} | 
      
      
         | 
         | 
        978 | 
          | 
      
      
         | 
         | 
        979 | 
        	// }}} | 
      
      
         | 
         | 
        980 | 
          | 
      
      
         | 
         | 
        981 | 
        	// {{{ _xmlParseCmdOutput | 
      
      
         | 
         | 
        982 | 
          | 
      
      
         | 
         | 
        983 | 
        	function _xmlParseCmdOutput($cmd, $startElem, $endElem, $charData) { | 
      
      
         | 
         | 
        984 | 
        		$error		= ''; | 
      
      
         | 
         | 
        985 | 
        		$lines		= runCommand($cmd, false, $error); | 
      
      
         | 
         | 
        986 | 
        		$linesCnt	= count($lines); | 
      
      
         | 
         | 
        987 | 
        		$xml_parser	= xml_parser_create('UTF-8'); | 
      
      
         | 
         | 
        988 | 
          | 
      
      
         | 
         | 
        989 | 
        		xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true); | 
      
      
         | 
         | 
        990 | 
        		xml_set_element_handler($xml_parser, $startElem, $endElem); | 
      
      
         | 
         | 
        991 | 
        		xml_set_character_data_handler($xml_parser, $charData); | 
      
      
         | 
         | 
        992 | 
          | 
      
      
         | 
         | 
        993 | 
        		for ($i = 0; $i < $linesCnt; ++$i) { | 
      
      
         | 
         | 
        994 | 
        			$line	= $lines[$i] . "\n"; | 
      
      
         | 
         | 
        995 | 
        			$isLast	= $i == ($linesCnt - 1); | 
      
      
         | 
         | 
        996 | 
          | 
      
      
         | 
         | 
        997 | 
        			if (xml_parse($xml_parser, $line, $isLast)) { | 
      
      
         | 
         | 
        998 | 
        				continue; | 
      
      
         | 
         | 
        999 | 
        			} | 
      
      
         | 
         | 
        1000 | 
          | 
      
      
         | 
         | 
        1001 | 
        			$errorMsg = sprintf('XML error: %s (%d) at line %d column %d byte %d'."\n".'cmd: %s', | 
      
      
         | 
         | 
        1002 | 
        								xml_error_string(xml_get_error_code($xml_parser)), | 
      
      
         | 
         | 
        1003 | 
        								xml_get_error_code($xml_parser), | 
      
      
         | 
         | 
        1004 | 
        								xml_get_current_line_number($xml_parser), | 
      
      
         | 
         | 
        1005 | 
        								xml_get_current_column_number($xml_parser), | 
      
      
         | 
         | 
        1006 | 
        								xml_get_current_byte_index($xml_parser), | 
      
      
         | 
         | 
        1007 | 
        								$cmd); | 
      
      
         | 
         | 
        1008 | 
          | 
      
      
         | 
         | 
        1009 | 
        			if (xml_get_error_code($xml_parser) == 5) { | 
      
      
         | 
         | 
        1010 | 
        				break; | 
      
      
         | 
         | 
        1011 | 
        			} | 
      
      
         | 
         | 
        1012 | 
          | 
      
      
         | 
         | 
        1013 | 
        			// errors can contain sensitive info! don't echo this ~J | 
      
      
         | 
         | 
        1014 | 
        			_logError($errorMsg); | 
      
      
         | 
         | 
        1015 | 
        			exit; | 
      
      
         | 
         | 
        1016 | 
        		} | 
      
      
         | 
         | 
        1017 | 
          | 
      
      
         | 
         | 
        1018 | 
        		xml_parser_free($xml_parser); | 
      
      
         | 
         | 
        1019 | 
        		if (empty($error)) { | 
      
      
         | 
         | 
        1020 | 
        			return; | 
      
      
         | 
         | 
        1021 | 
        		} | 
      
      
         | 
         | 
        1022 | 
          | 
      
      
         | 
         | 
        1023 | 
        		$error = toOutputEncoding(nl2br(str_replace('svn: ', '', $error))); | 
      
      
         | 
         | 
        1024 | 
        		global $lang; | 
      
      
         | 
         | 
        1025 | 
        		_logError($lang['BADCMD'].': '.$cmd); | 
      
      
         | 
         | 
        1026 | 
        		_logError($error); | 
      
      
         | 
         | 
        1027 | 
          | 
      
      
         | 
         | 
        1028 | 
        		global $vars; | 
      
      
         | 
         | 
        1029 | 
        		if (strstr($error, 'found format')) { | 
      
      
         | 
         | 
        1030 | 
        			$vars['error'] = 'Repository uses a newer format than Subversion '.$config->getSubversionVersion().' can read. ("'.nl2br(escape(toOutputEncoding(substr($error, strrpos($error, 'Expected'))))).'.")'; | 
      
      
         | 
         | 
        1031 | 
        		} else if (strstr($error, 'No such revision')) { | 
      
      
         | 
         | 
        1032 | 
        			$vars['warning'] = 'Revision '.$rev.' of this resource does not exist.'; | 
      
      
         | 
         | 
        1033 | 
        		} else { | 
      
      
         | 
         | 
        1034 | 
        			$vars['error'] = $lang['BADCMD'].': <code>'.escape(stripCredentialsFromCommand($cmd)).'</code><br />'.nl2br(escape(toOutputEncoding($error))); | 
      
      
         | 
         | 
        1035 | 
        		} | 
      
      
         | 
         | 
        1036 | 
        	} | 
      
      
         | 
         | 
        1037 | 
          | 
      
      
         | 
         | 
        1038 | 
        	// }}} | 
      
      
         | 
         | 
        1039 | 
          | 
      
      
         | 
         | 
        1040 | 
        	// {{{ getInfo | 
      
      
         | 
         | 
        1041 | 
          | 
      
      
         | 
         | 
        1042 | 
        	function getInfo($path, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        1043 | 
        		global $config, $curInfo; | 
      
      
         | 
         | 
        1044 | 
          | 
      
      
         | 
         | 
        1045 | 
        		// Since directories returned by svn log don't have trailing slashes (:-(), we need to remove | 
      
      
         | 
         | 
        1046 | 
        		// the trailing slash from the path for comparison purposes | 
      
      
         | 
         | 
        1047 | 
          | 
      
      
         | 
         | 
        1048 | 
        		if ($path[strlen($path) - 1] == '/' && $path != '/') { | 
      
      
         | 
         | 
        1049 | 
        			$path = substr($path, 0, -1); | 
      
      
         | 
         | 
        1050 | 
        		} | 
      
      
         | 
         | 
        1051 | 
          | 
      
      
         | 
         | 
        1052 | 
        		$curInfo = new SVNInfoEntry; | 
      
      
         | 
         | 
        1053 | 
          | 
      
      
         | 
         | 
        1054 | 
        		// Get the svn info | 
      
      
         | 
         | 
        1055 | 
          | 
      
      
         | 
         | 
        1056 | 
        		if ($rev == 0) { | 
      
      
         | 
         | 
        1057 | 
        			$headlog = $this->getLog('/', '', '', true, 1); | 
      
      
         | 
         | 
        1058 | 
        			if ($headlog && isset($headlog->entries[0])) | 
      
      
         | 
         | 
        1059 | 
        				$rev = $headlog->entries[0]->rev; | 
      
      
         | 
         | 
        1060 | 
        		} | 
      
      
         | 
         | 
        1061 | 
          | 
      
      
         | 
         | 
        1062 | 
        		$cmd = $this->svnCommandString('info --xml', $path, $rev, $peg); | 
      
      
         | 
         | 
        1063 | 
        		$this->_xmlParseCmdOutput($cmd, 'infoStartElement', 'infoEndElement', 'infoCharacterData'); | 
      
      
         | 
         | 
        1064 | 
          | 
      
      
         | 
         | 
        1065 | 
        		if ($this->repConfig->subpath !== null) { | 
      
      
         | 
         | 
        1066 | 
        			if (substr($curInfo->path, 0, strlen($this->repConfig->subpath) + 1) === '/'. $this->repConfig->subpath) { | 
      
      
         | 
         | 
        1067 | 
        				$curInfo->path = substr($curInfo->path, strlen($this->repConfig->subpath) + 1); | 
      
      
         | 
         | 
        1068 | 
        			} else { | 
      
      
         | 
         | 
        1069 | 
        				// hide entry when file is outside of subpath | 
      
      
         | 
         | 
        1070 | 
        				return null; | 
      
      
         | 
         | 
        1071 | 
        			} | 
      
      
         | 
         | 
        1072 | 
        		} | 
      
      
         | 
         | 
        1073 | 
          | 
      
      
         | 
         | 
        1074 | 
        		return $curInfo; | 
      
      
         | 
         | 
        1075 | 
        	} | 
      
      
         | 
         | 
        1076 | 
          | 
      
      
         | 
         | 
        1077 | 
        	// }}} | 
      
      
         | 
         | 
        1078 | 
          | 
      
      
         | 
         | 
        1079 | 
        	// {{{ getList | 
      
      
         | 
         | 
        1080 | 
          | 
      
      
         | 
         | 
        1081 | 
        	function getList($path, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        1082 | 
        		global $config, $curList; | 
      
      
         | 
         | 
        1083 | 
          | 
      
      
         | 
         | 
        1084 | 
        		// Since directories returned by svn log don't have trailing slashes (:-(), we need to remove | 
      
      
         | 
         | 
        1085 | 
        		// the trailing slash from the path for comparison purposes | 
      
      
         | 
         | 
        1086 | 
          | 
      
      
         | 
         | 
        1087 | 
        		if ($path[strlen($path) - 1] == '/' && $path != '/') { | 
      
      
         | 
         | 
        1088 | 
        			$path = substr($path, 0, -1); | 
      
      
         | 
         | 
        1089 | 
        		} | 
      
      
         | 
         | 
        1090 | 
          | 
      
      
         | 
         | 
        1091 | 
        		$curList = new SVNList; | 
      
      
         | 
         | 
        1092 | 
        		$curList->entries = array(); | 
      
      
         | 
         | 
        1093 | 
        		$curList->path = $path; | 
      
      
         | 
         | 
        1094 | 
          | 
      
      
         | 
         | 
        1095 | 
        		// Get the list info | 
      
      
         | 
         | 
        1096 | 
          | 
      
      
         | 
         | 
        1097 | 
        		if ($rev == 0) { | 
      
      
         | 
         | 
        1098 | 
        			$headlog = $this->getLog('/', '', '', true, 1); | 
      
      
         | 
         | 
        1099 | 
        			if ($headlog && isset($headlog->entries[0])) | 
      
      
         | 
         | 
        1100 | 
        				$rev = $headlog->entries[0]->rev; | 
      
      
         | 
         | 
        1101 | 
        		} | 
      
      
         | 
         | 
        1102 | 
          | 
      
      
         | 
         | 
        1103 | 
        		if ($config->showLoadAllRepos()) { | 
      
      
         | 
         | 
        1104 | 
        			$cmd = $this->svnCommandString('list -R --xml', $path, $rev, $peg); | 
      
      
         | 
         | 
        1105 | 
        			$this->_xmlParseCmdOutput($cmd, 'listStartElement', 'listEndElement', 'listCharacterData'); | 
      
      
         | 
         | 
        1106 | 
        		} | 
      
      
         | 
         | 
        1107 | 
        		else { | 
      
      
         | 
         | 
        1108 | 
        			$cmd = $this->svnCommandString('list --xml', $path, $rev, $peg); | 
      
      
         | 
         | 
        1109 | 
        			$this->_xmlParseCmdOutput($cmd, 'listStartElement', 'listEndElement', 'listCharacterData'); | 
      
      
         | 
         | 
        1110 | 
        			usort($curList->entries, '_listSort'); | 
      
      
         | 
         | 
        1111 | 
        		} | 
      
      
         | 
         | 
        1112 | 
          | 
      
      
         | 
         | 
        1113 | 
        		return $curList; | 
      
      
         | 
         | 
        1114 | 
        	} | 
      
      
         | 
         | 
        1115 | 
          | 
      
      
         | 
         | 
        1116 | 
        	// }}} | 
      
      
         | 
         | 
        1117 | 
          | 
      
      
         | 
         | 
        1118 | 
        	// {{{ getListSearch | 
      
      
         | 
         | 
        1119 | 
          | 
      
      
         | 
         | 
        1120 | 
        	function getListSearch($path, $term = '', $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        1121 | 
        		global $config, $curList; | 
      
      
         | 
         | 
        1122 | 
          | 
      
      
         | 
         | 
        1123 | 
        		// Since directories returned by "svn log" don't have trailing slashes (:-(), we need to | 
      
      
         | 
         | 
        1124 | 
        		// remove the trailing slash from the path for comparison purposes. | 
      
      
         | 
         | 
        1125 | 
        		if (($path[strlen($path) - 1] == '/') && ($path != '/')) { | 
      
      
         | 
         | 
        1126 | 
        			$path = substr($path, 0, -1); | 
      
      
         | 
         | 
        1127 | 
        		} | 
      
      
         | 
         | 
        1128 | 
          | 
      
      
         | 
         | 
        1129 | 
        		$curList			= new SVNList; | 
      
      
         | 
         | 
        1130 | 
        		$curList->entries	= array(); | 
      
      
         | 
         | 
        1131 | 
        		$curList->path		= $path; | 
      
      
         | 
         | 
        1132 | 
          | 
      
      
         | 
         | 
        1133 | 
        		// Get the list info | 
      
      
         | 
         | 
        1134 | 
          | 
      
      
         | 
         | 
        1135 | 
        		if ($rev == 0) { | 
      
      
         | 
         | 
        1136 | 
        			$headlog = $this->getLog('/', '', '', true, 1); | 
      
      
         | 
         | 
        1137 | 
        			if ($headlog && isset($headlog->entries[0])) | 
      
      
         | 
         | 
        1138 | 
        				$rev = $headlog->entries[0]->rev; | 
      
      
         | 
         | 
        1139 | 
        		} | 
      
      
         | 
         | 
        1140 | 
          | 
      
      
         | 
         | 
        1141 | 
        		$term	= escapeshellarg($term); | 
      
      
         | 
         | 
        1142 | 
        		$cmd	= 'list -R --search ' . $term . ' --xml'; | 
      
      
         | 
         | 
        1143 | 
        		$cmd	= $this->svnCommandString($cmd, $path, $rev, $peg); | 
      
      
         | 
         | 
        1144 | 
        		$this->_xmlParseCmdOutput($cmd, 'listStartElement', 'listEndElement', 'listCharacterData'); | 
      
      
         | 
         | 
        1145 | 
          | 
      
      
         | 
         | 
        1146 | 
        		return $curList; | 
      
      
         | 
         | 
        1147 | 
        	} | 
      
      
         | 
         | 
        1148 | 
          | 
      
      
         | 
         | 
        1149 | 
        	// }}} | 
      
      
         | 
         | 
        1150 | 
          | 
      
      
         | 
         | 
        1151 | 
          | 
      
      
         | 
         | 
        1152 | 
        	// {{{ getLog | 
      
      
         | 
         | 
        1153 | 
          | 
      
      
         | 
         | 
        1154 | 
        	function getLog($path, $brev = '', $erev = 1, $quiet = false, $limit = 2, $peg = '', $verbose = false) { | 
      
      
         | 
         | 
        1155 | 
        		global $config, $curLog; | 
      
      
         | 
         | 
        1156 | 
          | 
      
      
         | 
         | 
        1157 | 
        		// Since directories returned by svn log don't have trailing slashes (:-(), | 
      
      
         | 
         | 
        1158 | 
        		// we must remove the trailing slash from the path for comparison purposes. | 
      
      
         | 
         | 
        1159 | 
        		if (!empty($path) && $path != '/' && $path[strlen($path) - 1] == '/') { | 
      
      
         | 
         | 
        1160 | 
        			$path = substr($path, 0, -1); | 
      
      
         | 
         | 
        1161 | 
        		} | 
      
      
         | 
         | 
        1162 | 
          | 
      
      
         | 
         | 
        1163 | 
        		$curLog = new SVNLog; | 
      
      
         | 
         | 
        1164 | 
        		$curLog->entries = array(); | 
      
      
         | 
         | 
        1165 | 
        		$curLog->path = $path; | 
      
      
         | 
         | 
        1166 | 
          | 
      
      
         | 
         | 
        1167 | 
        		// Get the log info | 
      
      
         | 
         | 
        1168 | 
        		$effectiveRev	= ($brev && $erev ? $brev.':'.$erev : ($brev ? $brev.':1' : '')); | 
      
      
         | 
         | 
        1169 | 
        		$effectivePeg	= ($peg ? $peg : ($brev ? $brev : '')); | 
      
      
         | 
         | 
        1170 | 
        		$cmd			= $this->svnCommandString('log --xml '.($verbose ? '--verbose' : ($quiet ? '--quiet' : '')).($limit != 0 ? ' --limit '.$limit : ''), $path, $effectiveRev, $effectivePeg); | 
      
      
         | 
         | 
        1171 | 
          | 
      
      
         | 
         | 
        1172 | 
        		$this->_xmlParseCmdOutput($cmd, 'logStartElement', 'logEndElement', 'logCharacterData'); | 
      
      
         | 
         | 
        1173 | 
          | 
      
      
         | 
         | 
        1174 | 
        		foreach ($curLog->entries as $entryKey => $entry) { | 
      
      
         | 
         | 
        1175 | 
        			$fullModAccess = true; | 
      
      
         | 
         | 
        1176 | 
        			$anyModAccess = (count($entry->mods) == 0); | 
      
      
         | 
         | 
        1177 | 
        			$precisePath = null; | 
      
      
         | 
         | 
        1178 | 
        			foreach ($entry->mods as $modKey => $mod) { | 
      
      
         | 
         | 
        1179 | 
        				$access = $this->repConfig->hasLogReadAccess($mod->path); | 
      
      
         | 
         | 
        1180 | 
        				if ($access) { | 
      
      
         | 
         | 
        1181 | 
        					$anyModAccess = true; | 
      
      
         | 
         | 
        1182 | 
          | 
      
      
         | 
         | 
        1183 | 
        					// find path which is parent of all modification but more precise than $curLogEntry->path | 
      
      
         | 
         | 
        1184 | 
        					$modpath = $mod->path; | 
      
      
         | 
         | 
        1185 | 
        					if (!$mod->isdir || $mod->action == 'D') { | 
      
      
         | 
         | 
        1186 | 
        						$pos = strrpos($modpath, '/'); | 
      
      
         | 
         | 
        1187 | 
        						$modpath = substr($modpath, 0, $pos + 1); | 
      
      
         | 
         | 
        1188 | 
        					} | 
      
      
         | 
         | 
        1189 | 
        					if (strlen($modpath) == 0 || substr($modpath, -1) !== '/') { | 
      
      
         | 
         | 
        1190 | 
        						$modpath .= '/'; | 
      
      
         | 
         | 
        1191 | 
        					} | 
      
      
         | 
         | 
        1192 | 
        					//compare with current precise path | 
      
      
         | 
         | 
        1193 | 
        					if ($precisePath === null) { | 
      
      
         | 
         | 
        1194 | 
        						$precisePath = $modpath; | 
      
      
         | 
         | 
        1195 | 
        					} else { | 
      
      
         | 
         | 
        1196 | 
        						$equalPart = _equalPart($precisePath, $modpath); | 
      
      
         | 
         | 
        1197 | 
        						if (substr($equalPart, -1) !== '/') { | 
      
      
         | 
         | 
        1198 | 
        							$pos = strrpos($equalPart, '/'); | 
      
      
         | 
         | 
        1199 | 
        							$equalPart = substr($equalPart, 0, $pos + 1); | 
      
      
         | 
         | 
        1200 | 
        						} | 
      
      
         | 
         | 
        1201 | 
        						$precisePath = $equalPart; | 
      
      
         | 
         | 
        1202 | 
        					} | 
      
      
         | 
         | 
        1203 | 
          | 
      
      
         | 
         | 
        1204 | 
        					// fix paths if command was for a subpath repository | 
      
      
         | 
         | 
        1205 | 
        					if ($this->repConfig->subpath !== null) { | 
      
      
         | 
         | 
        1206 | 
        						if (substr($mod->path, 0, strlen($this->repConfig->subpath) + 1) === '/'. $this->repConfig->subpath) { | 
      
      
         | 
         | 
        1207 | 
        							$curLog->entries[$entryKey]->mods[$modKey]->path = substr($mod->path, strlen($this->repConfig->subpath) + 1); | 
      
      
         | 
         | 
        1208 | 
        						} else { | 
      
      
         | 
         | 
        1209 | 
        							// hide modified entry when file is outside of subpath | 
      
      
         | 
         | 
        1210 | 
        							unset($curLog->entries[$entryKey]->mods[$modKey]); | 
      
      
         | 
         | 
        1211 | 
        						} | 
      
      
         | 
         | 
        1212 | 
        					} | 
      
      
         | 
         | 
        1213 | 
        				} else { | 
      
      
         | 
         | 
        1214 | 
        					// hide modified entry when access is prohibited | 
      
      
         | 
         | 
        1215 | 
        					unset($curLog->entries[$entryKey]->mods[$modKey]); | 
      
      
         | 
         | 
        1216 | 
        					$fullModAccess = false; | 
      
      
         | 
         | 
        1217 | 
        				} | 
      
      
         | 
         | 
        1218 | 
        			} | 
      
      
         | 
         | 
        1219 | 
        			if (!$fullModAccess) { | 
      
      
         | 
         | 
        1220 | 
        				// hide commit message when access to any of the entries is prohibited | 
      
      
         | 
         | 
        1221 | 
        				$curLog->entries[$entryKey]->msg = ''; | 
      
      
         | 
         | 
        1222 | 
        			} | 
      
      
         | 
         | 
        1223 | 
        			if (!$anyModAccess) { | 
      
      
         | 
         | 
        1224 | 
        				// hide author and date when access to all of the entries is prohibited | 
      
      
         | 
         | 
        1225 | 
        				$curLog->entries[$entryKey]->author = ''; | 
      
      
         | 
         | 
        1226 | 
        				$curLog->entries[$entryKey]->date = ''; | 
      
      
         | 
         | 
        1227 | 
        				$curLog->entries[$entryKey]->committime = ''; | 
      
      
         | 
         | 
        1228 | 
        				$curLog->entries[$entryKey]->age = ''; | 
      
      
         | 
         | 
        1229 | 
        			} | 
      
      
         | 
         | 
        1230 | 
          | 
      
      
         | 
         | 
        1231 | 
        			if ($precisePath !== null) { | 
      
      
         | 
         | 
        1232 | 
        				$curLog->entries[$entryKey]->precisePath = $precisePath; | 
      
      
         | 
         | 
        1233 | 
        			} else { | 
      
      
         | 
         | 
        1234 | 
        				$curLog->entries[$entryKey]->precisePath = $curLog->entries[$entryKey]->path; | 
      
      
         | 
         | 
        1235 | 
        			} | 
      
      
         | 
         | 
        1236 | 
        		} | 
      
      
         | 
         | 
        1237 | 
        		return $curLog; | 
      
      
         | 
         | 
        1238 | 
        	} | 
      
      
         | 
         | 
        1239 | 
          | 
      
      
         | 
         | 
        1240 | 
        	// }}} | 
      
      
         | 
         | 
        1241 | 
          | 
      
      
         | 
         | 
        1242 | 
        	function isFile($path, $rev = 0, $peg = '') { | 
      
      
         | 
         | 
        1243 | 
        		$cmd = $this->svnCommandString('info --xml', $path, $rev, $peg); | 
      
      
         | 
         | 
        1244 | 
        		return strpos(implode(' ', runCommand($cmd, true)), 'kind="file"') !== false; | 
      
      
         | 
         | 
        1245 | 
        	} | 
      
      
         | 
         | 
        1246 | 
          | 
      
      
         | 
         | 
        1247 | 
        	// {{{ getSvnPath | 
      
      
         | 
         | 
        1248 | 
          | 
      
      
         | 
         | 
        1249 | 
        	function getSvnPath($path) { | 
      
      
         | 
         | 
        1250 | 
        		if ($this->repConfig->subpath === null) { | 
      
      
         | 
         | 
        1251 | 
        			return $this->repConfig->path.$path; | 
      
      
         | 
         | 
        1252 | 
        		} else { | 
      
      
         | 
         | 
        1253 | 
        			return $this->repConfig->path.'/'.$this->repConfig->subpath.$path; | 
      
      
         | 
         | 
        1254 | 
        		} | 
      
      
         | 
         | 
        1255 | 
        	} | 
      
      
         | 
         | 
        1256 | 
          | 
      
      
         | 
         | 
        1257 | 
        	// }}} | 
      
      
         | 
         | 
        1258 | 
          | 
      
      
         | 
         | 
        1259 | 
        } | 
      
      
         | 
         | 
        1260 | 
          | 
      
      
         | 
         | 
        1261 | 
        // Initialize SVN version information by parsing from command-line output. | 
      
      
         | 
         | 
        1262 | 
        $cmd = $config->getSvnCommand(); | 
      
      
         | 
         | 
        1263 | 
        $cmd = str_replace(array('--non-interactive', '--trust-server-cert'), array('', ''), $cmd); | 
      
      
         | 
         | 
        1264 | 
        $cmd .= ' --version -q'; | 
      
      
         | 
         | 
        1265 | 
        $ret = runCommand($cmd, false); | 
      
      
         | 
         | 
        1266 | 
        if (preg_match('~([0-9]+)\.([0-9]+)\.([0-9]+)~', $ret[0], $matches)) { | 
      
      
         | 
         | 
        1267 | 
        	$config->setSubversionVersion($matches[0]); | 
      
      
         | 
         | 
        1268 | 
        	$config->setSubversionMajorVersion($matches[1]); | 
      
      
         | 
         | 
        1269 | 
        	$config->setSubversionMinorVersion($matches[2]); | 
      
      
         | 
         | 
        1270 | 
        } |