summary refs log tree commit diff stats
path: root/includes/phpsvnclient.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/phpsvnclient.php')
-rw-r--r--includes/phpsvnclient.php420
1 files changed, 420 insertions, 0 deletions
diff --git a/includes/phpsvnclient.php b/includes/phpsvnclient.php new file mode 100644 index 0000000..811c86d --- /dev/null +++ b/includes/phpsvnclient.php
@@ -0,0 +1,420 @@
1<?php
2/*
3***************************************************************************
4* Copyright (C) 2007-2008 by Sixdegrees *
5* cesar@sixdegrees.com.br *
6* "Working with freedom" *
7* http://www.sixdegrees.com.br *
8* *
9* Permission is hereby granted, free of charge, to any person obtaining *
10* a copy of this software and associated documentation files (the *
11* "Software"), to deal in the Software without restriction, including *
12* without limitation the rights to use, copy, modify, merge, publish, *
13* distribute, sublicense, and/or sell copies of the Software, and to *
14* permit persons to whom the Software is furnished to do so, subject to *
15* the following conditions: *
16* *
17* The above copyright notice and this permission notice shall be *
18* included in all copies or substantial portions of the Software. *
19* *
20* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
21* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
22* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
23* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
24* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
25* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
26* OTHER DEALINGS IN THE SOFTWARE. *
27***************************************************************************
28*/
29define("PHPSVN_DIR",dirname(__FILE__) );
30
31require(PHPSVN_DIR."/http.php");
32require(PHPSVN_DIR."/xml_parser.php");
33require(PHPSVN_DIR."/definitions.php");
34
35
36/**
37 * PHP SVN CLIENT
38 *
39 * This class is a SVN client. It can perform read operations
40 * to a SVN server (over Web-DAV).
41 * It can get directory files, file contents, logs. All the operaration
42 * could be done for a specific version or for the last version.
43 *
44 * @author Cesar D. Rodas <cesar@sixdegrees.com.br>
45 * @license BSD License
46 */
47class phpSVNclient
48{
49 /**
50 * SVN Repository URL
51 *
52 * @var string
53 * @access private
54 */
55 var $_url;
56 /**
57 * Cache, for don't request the same thing in a
58 * short period of time.
59 *
60 * @var string
61 * @access private
62 */
63 var $_cache;
64 /**
65 * HTTP Client object
66 *
67 * @var object
68 * @access private
69 */
70 var $_http;
71 /**
72 * Respository Version.
73 *
74 * @access private
75 * @var interger
76 */
77 var $_repVersion;
78 /**
79 * Password
80 *
81 * @access private
82 * @var string
83 */
84 var $pass;
85 /**
86 * Password
87 *
88 * @access private
89 * @var string
90 */
91 var $user;
92 /**
93 * Last error number
94 *
95 * Possible values are NOT_ERROR, NOT_FOUND, AUTH_REQUIRED, UNKOWN_ERROR
96 *
97 * @access public
98 * @var integer
99 */
100 var $errNro;
101
102 function phpSVNclient()
103 {
104 $http = & $this->_http;
105 $http = new http_class;
106 $http->user_agent = "phpSVNclient (http://cesars.users.phpclasses.org/svnclient)";
107 }
108
109 /**
110 * Set URL
111 *
112 * Set the project repository URL.
113 *
114 * @param string $url URL of the project.
115 * @access public
116 */
117 function setRespository($url)
118 {
119 $this->_url = $url;
120 }
121
122 /**
123 * Add Authentication settings
124 *
125 * @param string $user Username
126 * @param string $pass Password
127 */
128 function setAuth($user,$pass) {
129 $this->user = $user;
130 $this->pass = $pass;
131 }
132
133 /**
134 * Get Files
135 *
136 * This method returns all the files in $folder
137 * in the version $version of the repository.
138 *
139 * @param string $folder Folder to get files
140 * @param integer $version Repository version, -1 means actual
141 * @return array List of files.
142 */
143 function getDirectoryFiles($folder='/',$version=-1) {
144 $actVersion = $this->getVersion();
145 if ( $version == -1 || $version > $actVersion) {
146 $version = $actVersion;
147 }
148 $url = $this->cleanURL($this->_url."/!svn/bc/".$version."/".$folder."/");
149 $this->initQuery($args,"PROPFIND",$url);
150 $args['Body'] = PHPSVN_NORMAL_REQUEST;
151 $args['Headers']['Content-Length'] = strlen(PHPSVN_NORMAL_REQUEST);
152
153 if ( ! $this->Request($args, $headers, $body) ) {
154 return false;
155 }
156 $parser=new xml_parser_class;
157 $parser->Parse( $body,true);
158
159
160 $fileinfo = array(
161
162 SVN_LAST_MODIFIED => "last-mod",
163 SVN_RELATIVE_URL => "path",
164 SVN_STATUS => "status"
165 );
166
167 $start = false;
168 $last = "";
169 $tmp = array();
170 $files = array();
171 $tmp1 = 0;
172
173
174 foreach($parser->structure as $key=>$value) {
175 if ( is_array($value) and $value["Tag"] == SVN_FILE) {
176 if ( count($tmp) > 0 && $tmp1++ > 0) {
177 $files[] = $tmp;
178 }
179 $start=true;
180 $last = "";
181 $tmp = array();
182 continue;
183 }
184 if (!$start) continue;
185 if ( $last != "") {
186 $tmp[ $fileinfo[$last] ] = $value;
187 $last = "";
188 continue;
189 }
190 if ( is_array($value) && isset($value["Tag"]) && isset( $fileinfo[$value["Tag"]] ) ) {
191 $last = $value["Tag"];
192 }
193 }
194
195 return $files;
196 }
197
198 /**
199 * Returns file contents
200 *
201 * @param string $file File pathname
202 * @param integer $version File Version
203 * @return Array File content and information
204 */
205 function getFile($file,$version=-1) {
206 $actVersion = $this->getVersion();
207 if ( $version == -1 || $version > $actVersion) {
208 $version = $actVersion;
209 }
210 $url = $this->cleanURL($this->_url."/!svn/bc/".$version."/".$file."/");
211 $this->initQuery($args,"GET",$url);
212 if ( ! $this->Request($args, $headers, $body) )
213 return false;
214 return $body;
215 }
216
217 /**
218 * Get changes logs of a file.
219 *
220 * Get repository change logs between version
221 * $vini and $vend.
222 *
223 * @param integer $vini Initial Version
224 * @param integer $vend End Version
225 * @return Array Respository Logs
226 */
227 function getRepositoryLogs($vini=0,$vend=-1) {
228 return $this->getFileLogs("/",$vini,$vend);
229 }
230
231 /**
232 * Get changes logs of a file.
233 *
234 * Get repository change of a file between version
235 * $vini and $vend.
236 *
237 * @param
238 * @param integer $vini Initial Version
239 * @param integer $vend End Version
240 * @return Array Respository Logs
241 */
242 function getFileLogs($file, $vini=0,$vend=-1) {
243 $actVersion = $this->getVersion();
244 if ( $vend == -1 || $vend > $actVersion)
245 $vend = $actVersion;
246 else
247 $vend++;
248
249 if ( $vini < 0) $vini=0;
250 if ( $vini > $vend) $vini = $vend;
251
252 $url = $this->cleanURL($this->_url."/!svn/bc/".$actVersion."/".$file."/");
253 $this->initQuery($args,"REPORT",$url);
254 $args['Body'] = sprintf(PHPSVN_LOGS_REQUEST,$vini,$vend);
255 $args['Headers']['Content-Length'] = strlen($args['Body']);
256 $args['Headers']['Depth']=1;
257
258 if ( ! $this->Request($args, $headers, $body) )
259 return false;
260
261
262 $parser=new xml_parser_class;
263 $parser->Parse( $body,true);
264
265
266 $fileinfo = array(
267 SVN_LOGS_VERSION=>"version",
268 SVN_LOGS_AUTHOR => "author",
269 SVN_LOGS_DATE => "date",
270 SVN_LOGS_COMMENT => "comment"
271
272 );
273
274 $start = false;
275 $last = "";
276 $tmp = array();
277 $files = array();
278 $tmp1 = 0;
279
280
281 foreach($parser->structure as $key=>$value) {
282 if ( is_array($value) and $value["Tag"] == SVN_LOGS_BEGINGS) {
283 if ( count($tmp) > 0 && $tmp1++ > 0) {
284 $logs[] = $tmp;
285 }
286 $start=true;
287 $last = "";
288 $tmp = array();
289 continue;
290 }
291 if (!$start) continue;
292 if ( $last != "") {
293 $tmp[ $fileinfo[$last] ] = $value;
294 $last = "";
295 continue;
296 }
297 if ( is_array($value) && isset($value["Tag"]) && isset( $fileinfo[$value["Tag"]] ) ) {
298 $last = $value["Tag"];
299 }
300 }
301
302 return $logs;
303 }
304
305 /**
306 * Get the repository version
307 *
308 * @return integer Repository version
309 * @access public
310 */
311 function getVersion() {
312 if ( $this->_repVersion < 0) return $this->_repVersion;
313
314 $this->_repVersion = -1;
315
316 $this->initQuery($args,"PROPFIND",$this->cleanURL($this->_url."/!svn/vcc/default") );
317 $args['Body'] = PHPSVN_VERSION_REQUEST;
318 $args['Headers']['Content-Length'] = strlen(PHPSVN_NORMAL_REQUEST);
319 $args['Headers']['Depth']=0;
320
321 if ( !$this->Request($args, $tmp, $body) ) {
322 return $this->_repVersion;
323 }
324
325 $parser=new xml_parser_class;
326 $parser->Parse( $body,true);
327 $enable=false;
328 foreach($parser->structure as $value) {
329 if ( $enable ) {
330 $t = explode("/",$value);
331 if ( is_numeric($t[ count($t) -1 ]) ) {
332 $this->_repVersion = $t[ count($t) -1 ];
333 break;
334 }
335 }
336 if ( is_array($value) && $value['Tag'] == 'D:href') $enable = true;
337 }
338
339 return $this->_repVersion;
340 }
341
342 /**
343 * Prepare HTTP CLIENT object
344 *
345 * @param array &$arguments Byreferences variable.
346 * @param string $method Method for the request (GET,POST,PROPFIND, REPORT,ETC).
347 * @param string $url URL for the action.
348 * @access private
349 */
350 function initQuery(&$arguments,$method, $url) {
351 $http = & $this->_http;
352 $http->GetRequestArguments($url,$arguments);
353 if ( isset($this->user) && isset($this->pass)) {
354 $arguments["Headers"]["Authorization"] = " Basic ".base64_encode($this->user.":".$this->pass);
355 }
356 $arguments["RequestMethod"]=$method;
357 $arguments["Headers"]["Content-Type"] = "text/xml";
358 $arguments["Headers"]["Depth"] = 1;
359 }
360
361 /**
362 * Open a connection, send request, read header
363 * and body.
364 *
365 * @param Array $args Connetion's argument
366 * @param Array &$headers Array with the header response.
367 * @param string &$body Body response.
368 * @return boolean True is query success
369 * @access private
370 */
371 function Request($args, &$headers, &$body) {
372 $http = & $this->_http;
373 $http->Open($args);
374 $http->SendRequest($args);
375 $http->ReadReplyHeaders($headers);
376 if ($http->response_status[0] != 2) {
377 switch( $http->response_status ) {
378 case 404:
379 $this->errNro=NOT_FOUND;
380 break;
381 case 401:
382 $this->errNro=AUTH_REQUIRED;
383 break;
384 default:
385 $this->errNro=UNKNOWN_ERROR;
386
387 }
388 $http->close();
389 return false;
390 }
391 $this->errNro = NO_ERROR;
392 $body='';
393 $tbody='';
394 for(;;)
395 {
396 $error=$http->ReadReplyBody($tbody,1000);
397 if($error!="" || strlen($tbody)==0) break;
398 $body.=($tbody);
399 }
400 $http->close();
401 return true;
402 }
403
404 /**
405 * Clean URL
406 *
407 * Delete "//" on URL requests.
408 *
409 * @param string $url URL
410 * @return string New cleaned URL.
411 * @access private
412 */
413 function cleanURL($url) {
414 $t = parse_url($url);
415 if ( isset($t['path']) )
416 $t['path'] = str_replace("//","/",$t['path']);
417 return $t['scheme']."://".$t['host'].(isset($t['path']) ? $t['path'] : "/");
418 }
419}
420?>