b2evolution PHP Cross Reference Blogging Systems

Source: /inc/_ext/phpsvnclient/phpsvnclient.php - 1146 lines - 42170 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /*
   4   * **************************************************************************
   5   *   Copyright (C) 2007-2008 by Sixdegrees                                 *
   6   *   cesar@sixdegrees.com.br                                               *
   7   *   "Working with freedom"                                                *
   8   *   http://www.sixdegrees.com.br                                          *
   9   *                                                                         *  
  10   *   Permission is hereby granted, free of charge, to any person obtaining *
  11   *   a copy of this software and associated documentation files (the       *
  12   *   "Software"), to deal in the Software without restriction, including   *
  13   *   without limitation the rights to use, copy, modify, merge, publish,   *
  14   *   distribute, sublicense, and/or sell copies of the Software, and to    *
  15   *   permit persons to whom the Software is furnished to do so, subject to *
  16   *   the following conditions:                                             *
  17   *                                                                         *
  18   *   The above copyright notice and this permission notice shall be        *
  19   *   included in all copies or substantial portions of the Software.       *
  20   *                                                                         *
  21   *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       *
  22   *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    *
  23   *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
  24   *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR     *
  25   *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
  26   *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
  27   *   OTHER DEALINGS IN THE SOFTWARE.                                       *
  28   * **************************************************************************
  29   */
  30  if( ! defined( 'EVO_MAIN_INIT' ) ) die( 'Please, do not access this page directly.' );
  31  
  32  define("PHPSVN_DIR", dirname(__FILE__));
  33  define("LOG_ENABLED", false);
  34  define("LOG_FILE", PHPSVN_DIR . time() . ".log.html");
  35  
  36  require_once  PHPSVN_DIR . "/http.php";
  37  require_once  PHPSVN_DIR . "/xml_parser.php"; // to be dropped?
  38  require_once  PHPSVN_DIR . "/definitions.php";
  39  require_once  PHPSVN_DIR .  "/xml2Array.php";
  40  
  41  /**
  42   *  PHP SVN CLIENT
  43   *
  44   *  This class is a SVN client. It can perform read operations
  45   *  to a SVN server (over Web-DAV). 
  46   *  It can get directory files, file contents, logs. All the operaration
  47   *  could be done for a specific version or for the last version.
  48   *
  49   *  @author Cesar D. Rodas <cesar@sixdegrees.com.br>
  50   *  @license BSD License
  51   */
  52  class phpsvnclient {
  53  
  54      /**
  55       *  SVN Repository URL
  56       *
  57       *  @var string
  58       *  @access private
  59       */
  60      private $_url;
  61  
  62      /**
  63       *  Cache, for don't request the same thing in a
  64       *  short period of time.
  65       *
  66       *  @var string
  67       *  @access private
  68       */
  69      private $_cache;
  70  
  71      /**
  72       *  HTTP Client object
  73       *
  74       *  @var object
  75       *  @access private
  76       */
  77      private $_http;
  78  
  79      /**
  80       *  Respository Version.
  81       *
  82       *  @access private
  83       *  @var interger
  84       */
  85      private $_repVersion;
  86  
  87      /**
  88       *  Password
  89       *
  90       *  @access private
  91       *  @var string
  92       */
  93      private $pass;
  94  
  95      /**
  96       *  Password
  97       *
  98       *  @access private
  99       *  @var string
 100       */
 101      private $user;
 102  
 103      /**
 104       *  Last error number
 105       *
 106       *  Possible values are NOT_ERROR, NOT_FOUND, AUTH_REQUIRED, UNKOWN_ERROR
 107       *
 108       *  @access public
 109       *  @var integer
 110       */
 111      public $errNro;
 112  
 113      /**
 114       * Number of actual revision local repository.
 115       * @var Integer, Long
 116       */
 117      private $actVersion;
 118      private $storeDirectoryFiles = array();
 119      private $lastDirectoryFiles;
 120      private $file_size;
 121      private $file_size_founded = false;
 122  
 123      /**
 124       * The path to the file to perform after update procedure 
 125       * or checkout of a local repository.
 126       * @var String
 127       */
 128      private $path_exec_after_completition = '';
 129  
 130      /**
 131       * Array with MIME types.
 132       * @var Array
 133       */
 134      private $mime_array;
 135  
 136      public function phpsvnclient($url = 'http://phpsvnclient.googlecode.com/svn/', $user = false, $pass = false) {
 137          $this->__construct($url, $user, $pass);
 138          register_shutdown_function(array(&$this, '__destruct'));
 139      }
 140  
 141      public function __construct($url = 'http://phpsvnclient.googlecode.com/svn/', $user = false, $pass = false) {
 142          $http = & $this->_http;
 143          $http = new http_class;
 144          $http->user_agent = "phpsvnclient (http://phpsvnclient.googlecode.com/)";
 145  
 146          $this->_url = $url;
 147          $this->user = $user;
 148          $this->pass = $pass;
 149  
 150          $this->actVersion = $this->getVersion();
 151      }
 152  
 153      /**
 154       * Function for creating directories.
 155       * @param type $path The path to the directory that will be created.
 156       */
 157      function createDirs($path) {
 158          $dirs = explode("/", $path);
 159  
 160          foreach ($dirs as $dir) {
 161              if ($dir != "") {
 162                  $createDir = substr($path, 0, strpos($path, $dir) + strlen($dir));
 163                  evo_mkdir($createDir);
 164              }
 165          }
 166      }
 167  
 168      /**
 169       * Function for the recursive removal of directories.
 170       * @param type $path The path to the directory to be deleted.
 171       * @return type Returns the status of a function or function rmdir unlink.
 172       */
 173      function removeDirs($path) {
 174          if (is_dir($path)) {
 175              $entries = scandir($path);
 176              if ($entries === false) {
 177                  $entries = array();
 178              }
 179              foreach ($entries as $entry) {
 180                  if ($entry != '.' && $entry != '..') {
 181                      $this->removeDirs($path . '/' . $entry);
 182                  }
 183              }
 184              return rmdir($path);
 185          } else {
 186              return unlink($path);
 187          }
 188      }
 189  
 190      /**
 191       * Function for logging.
 192       * @param type $contents The line for entry in the log file.
 193       */
 194      function logging($contents) {
 195          if( LOG_ENABLED )
 196          {
 197              $hOut = fopen(LOG_FILE, 'a+');
 198              fwrite($hOut, $contents);
 199              fclose($hOut);
 200          }
 201      }
 202  
 203      /**
 204       *  Public Functions
 205       */
 206  
 207      /**
 208       * Performs a checkout and creates files and folders.
 209       * 
 210       * @param string $folder Defaults to disk root
 211       * @param string $outPath Defaults to current folder (.)
 212       * @param boolean $checkFiles Whether it is necessary to check the received 
 213       * files in the sizes. Can be useful in case often files are accepted 
 214       * with an error.
 215       * @param boolean Display the progress dots
 216       * @return boolean TRUE on success
 217       */
 218      public function checkOut($folder = '/', $outPath = '.', $checkFiles = false, $display_progress = false) {
 219          while ($outPath[strlen($outPath) - 1] == '/' && strlen($outPath) > 1) {
 220              $outPath = substr($outPath, 0, -1);
 221          }
 222  
 223          $tree = $this->getDirectoryTree($folder, $this->getVersion(), true, $display_progress);
 224          if( $tree === false )
 225          {
 226              return false;
 227          }
 228          if (!file_exists($outPath)) {
 229              evo_mkdir( $outPath, NULL, TRUE );
 230          }
 231          if( $display_progress )
 232          {
 233              echo '<br />';
 234          }
 235          foreach ($tree as $file) {
 236              $path = $file['path'];
 237              $tmp = strstr(trim($path, '/'), trim($folder, '/'));
 238              $createPath = $outPath . ($tmp ? substr($tmp, strlen(trim($folder, '/'))) : "");
 239              if (trim($path, '/') == trim($folder, '/'))
 240                  continue;
 241              if ($file['type'] == 'directory' && !is_dir($createPath)) {
 242                  echo "Current status: <font color='blue'>Directory: " . $createPath . "</font><br /> \r\n";
 243                  $this->logging("Current status: <font color='blue'>Directory: " . $createPath . "</font><br /> \r\n");
 244                  evo_flush();
 245                  evo_mkdir( $createPath );
 246              } elseif ($file['type'] == 'file') {
 247  
 248                  $outText = '';
 249                  for ($x = 0; $x < 2; $x++) {
 250                      $contents = $this->getFile($path, $this->getVersion());
 251                      $outText .= "<font color='blue'>Getting file: </font> " . $path;
 252                      $outText .= " <br />\r\n";
 253                      if ($checkFiles) {
 254                          $fileSize = $this->getFileSize($path, $this->getVersion());
 255                          $outText.= " The size of the received file: " . strlen($contents) .
 256                                  " File size in a repository: " . $fileSize;
 257                          $outText.= " <br />\r\n";
 258  
 259                          if (strlen($contents) != $fileSize) {
 260                              $outText.= "<font color='red'> Error receiving file: " . $createPath . "</font> --- " . $x;
 261                          } else {
 262                              break;
 263                          }
 264                          $outText.= " <br />\r\n";
 265                      } else {
 266                          break;
 267                      }
 268                  }
 269                  echo $outText;
 270                  $this->logging($outText);
 271                  evo_flush();
 272  
 273                  $hOut = fopen($createPath, 'w');
 274                  fwrite($hOut, $contents);
 275                  fclose($hOut);
 276              }
 277          }
 278          if ($this->path_exec_after_completition != '') {
 279              $this->exec_after_completition();
 280          }
 281          return true;
 282      }
 283  
 284      /**
 285       * Function to easily create and update a working copy of the repository.
 286       * @param type $folder Folder in remote repository
 287       * @param type $outPath Folder for storing files
 288       * @param boolean $checkFiles Whether it is necessary to check the received 
 289       * files in the sizes. Can be useful in case often files are accepted 
 290       * with an error.
 291       */
 292      public function createOrUpdateWorkingCopy($folder = '/', $outPath = '.', $checkFiles = false) {
 293  
 294          if (!file_exists($outPath . '/.svn/entries')) {
 295              //Create a directory for storing system information for further updates.
 296              $this->createDirs($outPath . '/.svn');
 297              //Keeping the current version of the copy.
 298              $hOut = fopen($outPath . '/.svn/entries', 'w');
 299              fwrite($hOut, $this->actVersion);
 300              fclose($hOut);
 301              echo "Current status: <font color='blue'>Starting checkout...</font><br /> \r\n";
 302              $this->logging("Current status: <font color='blue'>Starting checkout...</font><br /> \r\n");
 303              evo_flush();
 304              $this->checkOut($folder, $outPath, $checkFiles);
 305          } else {
 306              //Obtain the number of current version number of the local copy.
 307              $hOut = fopen($outPath . '/.svn/entries', 'r');
 308              while (!feof($hOut)) {
 309                  $copy_version = fgets($hOut);
 310              }
 311              fclose($hOut);
 312  
 313              echo "Repository exist with version: " . $copy_version . "<br /> \r\n";
 314              $this->logging("Repository exist with version: " . $copy_version . "<br /> \r\n");
 315              evo_flush();
 316  
 317              //Get a list of objects to be updated.
 318              $objects_list = $this->getLogsForUpdate($folder, $copy_version + 1);
 319              if (!is_null($objects_list)) {
 320                  ////Lets update dirs
 321                  // Add dirs
 322                  foreach ($objects_list['dirs'] as $file) {
 323                      if ($file != '') {
 324                          $file = str_replace($folder, "", $file);
 325                          $file = $outPath . '/' . $file;
 326                          $file = str_replace("///", "/", $file);
 327                          echo "<font color='blue'>Added or modified directory: </font>" . $file . "<br />\r\n";
 328                          $this->logging("<font color='blue'>Added or modified directory: </font>" . $file . "<br />\r\n");
 329                          $this->createDirs($file);
 330                      }
 331                  }
 332                  // Remove dirs
 333                  // TEST IT!
 334                  foreach ($objects_list['dirsDelete'] as $file) {
 335                      if ($file != '') {
 336                          $file = str_replace($folder, "", $file);
 337                          $file = $outPath . '/' . $file;
 338                          $file = str_replace("///", "/", $file);
 339                          $this->removeDirs($file);
 340                          echo "<font color='red'>Removed directory: </font>" . $file . "<br />\r\n";
 341                      }
 342                  }
 343  
 344                  echo "<font color='green'>************************</font><br />\r\n";
 345  
 346                  ////Lets update files
 347                  // Add files
 348                  foreach ($objects_list['files'] as $file) {
 349                      if ($file != '') {
 350                          $createPath = str_replace($folder, "", $file);
 351                          $createPath = $outPath . '/' . $createPath;
 352                          $createPath = str_replace("///", "/", $createPath);
 353  
 354                          $contents = $this->getFile($file);
 355                          $hOut = fopen($createPath, 'w');
 356                          fwrite($hOut, $contents);
 357                          fclose($hOut);
 358                          $out = "<font color='blue'>Added or modified file: </font> ";
 359                          if (strlen($contents) < 1) {
 360                              $out.= "<font color='red'> " . $file . " with 0 size </font> ";
 361                          } else {
 362                              $out.= $file;
 363                          }
 364                          $out.= " <br />\r\n";
 365                          echo $out;
 366                      }
 367                  }
 368                  //Remove files
 369                  foreach ($objects_list['filesDelete'] as $file) {
 370                      if ($file != '') {
 371                          $file = str_replace($folder, "", $file);
 372                          $file = $outPath . '/' . $file;
 373                          $file = str_replace("///", "/", $file);
 374                          unlink($file);
 375                          echo "<font color='red'>Removed file: </font>" . $file . "<br />\r\n";
 376                      }
 377                  }
 378                  $hOut = fopen($outPath . '/.svn/entries', 'w');
 379                  fwrite($hOut, $this->actVersion);
 380                  fclose($hOut);
 381              }
 382          }
 383  
 384          if ($this->path_exec_after_completition != '') {
 385              $this->exec_after_completition();
 386          }
 387      }
 388  
 389      /**
 390       * Function to view the changes between revisions of the specified object.
 391       * @param type $path The path to the object (file or directory).
 392       * @param type $revFrom Initial revision.
 393       * @param type $revTo The final revision.
 394       */
 395      public function diffVersions($path = '', $revFrom = 0, $revTo = 0) {
 396  
 397          require_once  'ext/Diff/Diff.php';
 398          require_once 'ext/Diff/Renderer.php';
 399          require_once 'ext/Diff/Renderer/unified.php';
 400  
 401          $this->mime_array = $this->get_mime_array();
 402  
 403          //Get a list of objects to be updated.
 404          $objects_list = $this->getLogsForUpdate($path, $revFrom, $revTo, false);
 405          if (!is_null($objects_list)) {
 406  //            print_r($objects_list);
 407              foreach ($objects_list['files'] as $file) {
 408                  if ($file != '') {
 409  
 410                      $path_info = pathinfo($file);
 411                      $mime_type = $this->mime_array[$path_info['extension']];
 412  
 413                      if (strpos($mime_type, "text") !== false) {
 414  
 415                          $file_revFrom = $this->getFile($file, $revFrom);
 416                          $file_revFrom =
 417                                  $this->explodeX(array("\r\n", "\r", "\n"), $file_revFrom);
 418  
 419                          $file_revTo = $this->getFile($file, $revTo);
 420                          $file_revTo = $this->explodeX(array("\r\n", "\r", "\n"), $file_revTo);
 421  
 422  
 423                          /* Create the Diff object. */
 424                          $diff = new Text_Diff('auto', array($file_revFrom, $file_revTo));
 425  
 426                          /* Output the diff in unified format. */
 427                          $renderer = new Text_Diff_Renderer_unified();
 428                          $result = $renderer->render($diff);
 429                          if (strlen($result) > 1) {
 430                              echo "Index: " . $file . " \r\n";
 431                              echo "===================================================================" . " \r\n";
 432                              echo "--- " . $file . "    (revision " . $revFrom . ")" . " \r\n";
 433                              echo "+++ " . $file . "    (revision " . $revTo . ")" . " \r\n";
 434                              echo $renderer->render($diff) . " \r\n";
 435                          }
 436                      }
 437                  }
 438              }
 439              foreach ($objects_list['filesDelete'] as $file) {
 440                  if ($file != '') {
 441  
 442                      $path_info = pathinfo($file);
 443                      $mime_type = $this->mime_array[$path_info['extension']];
 444  
 445                      if (strpos($mime_type, "text") !== false) {
 446  
 447                          $file_revFrom = $this->getFile($file, $revFrom);
 448                          $file_revFrom =
 449                                  $this->explodeX(array("\r\n", "\r", "\n"), $file_revFrom);
 450  
 451                          $file_revTo = $this->getFile($file, $revTo);
 452                          $file_revTo = $this->explodeX(array("\r\n", "\r", "\n"), $file_revTo);
 453  
 454  
 455                          /* Create the Diff object. */
 456                          $diff = new Text_Diff('auto', array($file_revFrom, $file_revTo));
 457  
 458                          /* Output the diff in unified format. */
 459                          $renderer = new Text_Diff_Renderer_unified();
 460                          $result = $renderer->render($diff);
 461                          if (strlen($result) > 1) {
 462                              echo "Index: " . $file . " \r\n";
 463                              echo "===================================================================" . " \r\n";
 464                              echo "--- " . $file . "    (revision " . $revFrom . ")" . " \r\n";
 465                              echo "+++ " . $file . "    (revision " . $revTo . ")" . " \r\n";
 466                              echo $renderer->render($diff) . " \r\n";
 467                          }
 468                      }
 469                  }
 470              }
 471          }
 472      }
 473  
 474      /**
 475       *  rawDirectoryDump
 476       *
 477       * Dumps SVN data for $folder in the version $version of the repository.
 478       *
 479       *  @param string  $folder Folder to get data
 480       *  @param integer $version Repository version, -1 means actual
 481       *  @return array SVN data dump.
 482       */
 483      public function rawDirectoryDump($folder = '/', $version = -1) {
 484  
 485          if ($version == -1 || $version > $this->actVersion) {
 486              $version = $this->actVersion;
 487          }
 488          $url = $this->cleanURL($this->_url . "/!svn/bc/" . $version . "/" . $folder . "/");
 489          $this->initQuery($args, "PROPFIND", $url);
 490          $args['Body'] = PHPSVN_NORMAL_REQUEST;
 491          $args['Headers']['Content-Length'] = strlen(PHPSVN_NORMAL_REQUEST);
 492  
 493          if (!$this->Request($args, $headers, $body)) {
 494              return false;
 495          }
 496          $xml2Array = new xml2Array();
 497          return $xml2Array->xmlParse($body);
 498      }
 499  
 500      /**
 501       *  getDirectoryFiles
 502       *
 503       *  Returns all the files in $folder in the version $version of 
 504       *  the repository.
 505       *
 506       *  @param string  $folder Folder to get files
 507       *  @param integer $version Repository version, -1 means actual
 508       *  @return array List of files.     
 509       */
 510      public function getDirectoryFiles($folder = '/', $version = -1) {
 511          if ($arrOutput = $this->rawDirectoryDump($folder, $version)) {
 512              $files = array();
 513              foreach ($arrOutput['children'] as $key => $value) {
 514                  array_walk_recursive($value, array($this, 'storeDirectoryFiles'));
 515                  array_push($files, $this->storeDirectoryFiles);
 516                  unset($this->storeDirectoryFiles);
 517              }
 518              return $files;
 519          }
 520          return false;
 521      }
 522  
 523      /**
 524       *  getDirectoryTree
 525       *
 526       *   Returns the complete tree of files and directories in $folder from the
 527       *  version $version of the repository. Can also be used to get the info 
 528       *  for a single file or directory.
 529       *
 530       *  @param string  $folder Folder to get tree
 531       *  @param integer $version Repository version, -1 means current
 532       *  @param boolean $recursive Whether to get the tree recursively, or just
 533       *  the specified directory/file.
 534       *  @param boolean Display the progress dots
 535       *
 536       *  @return array List of files and directories.
 537       */
 538      public function getDirectoryTree($folder = '/', $version = -1, $recursive = true, $display_progress = false) {
 539          $directoryTree = array();
 540  
 541          if (!($arrOutput = $this->getDirectoryFiles($folder, $version)))
 542              return false;
 543  
 544          if (!$recursive)
 545              return $arrOutput[0];
 546  
 547          $i = 0;
 548          while (count($arrOutput) && is_array($arrOutput)) {
 549              $array = array_shift($arrOutput);
 550  
 551              array_push($directoryTree, $array);
 552  
 553              if (trim($array['path'], '/') == trim($folder, '/'))
 554                  continue;
 555  
 556              if ($array['type'] == 'directory') {
 557                  if( ! ( $walk = $this->getDirectoryFiles($array['path'], $version) ) )
 558                  {
 559                      return false;
 560                  }
 561                  array_shift($walk);
 562  
 563                  foreach ($walk as $step) {
 564                      array_unshift($arrOutput, $step);
 565                  }
 566              }
 567  
 568              if( $display_progress && $i == 10 )
 569              {
 570                  echo ' .';
 571                  evo_flush();
 572                  $i = 0;
 573              }
 574              $i++;
 575          }
 576          return $directoryTree;
 577      }
 578  
 579      /**
 580       *  Returns file contents
 581       *
 582       *  @param    string     $file File pathname
 583       *  @param    integer    $version File Version
 584       *  @return    string    File content and information, false on error, or if a
 585       *                  directory is requested
 586       */
 587      public function getFile($file, $version = -1) {
 588          if ($version == -1 || $version > $this->actVersion) {
 589              $version = $this->actVersion;
 590          }
 591  
 592          // check if this is a directory... if so, return false, otherwise we
 593          // get the HTML output of the directory listing from the SVN server. 
 594          // This is maybe a bit heavy since it makes another connection to the
 595          // SVN server. Maybe add this as an option/parameter? ES 23/06/08
 596          $fileInfo = $this->getDirectoryTree($file, $version, false);
 597          if ($fileInfo["type"] == "directory")
 598              return false;
 599  
 600          $url = $this->cleanURL($this->_url . "/!svn/bc/" . $version . "/" . $file . "/");
 601          $this->initQuery($args, "GET", $url);
 602          if (!$this->Request($args, $headers, $body))
 603              return false;
 604  
 605          return $body;
 606      }
 607  
 608      /**
 609       *  Get changes logs of a file.
 610       *
 611       *  Get repository change logs between version
 612       *  $vini and $vend.
 613       *
 614       *  @param integer $vini Initial Version
 615       *  @param integer $vend End Version
 616       *  @return Array Respository Logs
 617       */
 618      public function getRepositoryLogs($path = "/", $vini = 0, $vend = -1) {
 619          return $this->getFileLogs($path, $vini, $vend);
 620      }
 621  
 622      /**
 623       *  Get changes logs of a file.
 624       *
 625       *  Get repository change of a file between version
 626       *  $vini and $vend.
 627       *
 628       *  @param string $file File for which to get log data
 629       *  @param integer $vini Initial Version
 630       *  @param integer $vend End Version
 631       *  @return array Respository Logs
 632       */
 633      public function getFileLogs($file, $vini = 0, $vend = -1) {
 634          $fileLogs = array();
 635  
 636          if ($vend == -1 || $vend > $this->actVersion)
 637              $vend = $this->actVersion;
 638  
 639          if ($vini < 0)
 640              $vini = 0;
 641          if ($vini > $vend)
 642              $vini = $vend;
 643  
 644          $url = $this->cleanURL($this->_url . "/!svn/bc/" . $this->actVersion . "/" . $file . "/");
 645          $this->initQuery($args, "REPORT", $url);
 646          $args['Body'] = sprintf(PHPSVN_LOGS_REQUEST, $vini, $vend);
 647          $args['Headers']['Content-Length'] = strlen($args['Body']);
 648          $args['Headers']['Depth'] = 1;
 649  
 650          if (!$this->Request($args, $headers, $body))
 651              return false;
 652  
 653          $xml2Array = new xml2Array();
 654          $arrOutput = $xml2Array->xmlParse($body);
 655  
 656          foreach ($arrOutput['children'] as $value) {
 657              $array = array();
 658              foreach ($value['children'] as $entry) {
 659                  if ($entry['name'] == 'D:VERSION-NAME')
 660                      $array['version'] = $entry['tagData'];
 661                  if ($entry['name'] == 'D:CREATOR-DISPLAYNAME')
 662                      $array['author'] = $entry['tagData'];
 663                  if ($entry['name'] == 'S:DATE')
 664                      $array['date'] = $entry['tagData'];
 665                  if ($entry['name'] == 'D:COMMENT')
 666                      $array['comment'] = $entry['tagData'];
 667  
 668                  if (($entry['name'] == 'S:ADDED-PATH') ||
 669                          ($entry['name'] == 'S:MODIFIED-PATH') ||
 670                          ($entry['name'] == 'S:DELETED-PATH')) {
 671                      // For backward compatability
 672                      $array['files'][] = $entry['tagData'];
 673  
 674                      if ($entry['name'] == 'S:ADDED-PATH')
 675                          $array['add_files'][] = $entry['tagData'];
 676                      if ($entry['name'] == 'S:MODIFIED-PATH')
 677                          $array['mod_files'][] = $entry['tagData'];
 678                      if ($entry['name'] == 'S:DELETED-PATH')
 679                          $array['del_files'][] = $entry['tagData'];
 680                  }
 681              }
 682              array_push($fileLogs, $array);
 683          }
 684  
 685          return $fileLogs;
 686      }
 687  
 688      public function getLogsForUpdate($file, $vini = 0, $vend = -1, $checkvend = true) {
 689          $fileLogs = array();
 690  
 691          if (($vend == -1 || $vend > $this->actVersion) && $checkvend) {
 692              $vend = $this->actVersion;
 693          }
 694  
 695          if ($vini < 0)
 696              $vini = 0;
 697  
 698          if ($vini > $vend) {
 699              $vini = $vend;
 700              echo "Nothing updated";
 701              $this->logging("Nothing updated");
 702              return null;
 703          }
 704  
 705          $url = $this->cleanURL($this->_url . "/!svn/bc/" . $this->actVersion . "/" . $file . "/");
 706          $this->initQuery($args, "REPORT", $url);
 707          $args['Body'] = sprintf(PHPSVN_LOGS_REQUEST, $vini, $vend);
 708          $args['Headers']['Content-Length'] = strlen($args['Body']);
 709          $args['Headers']['Depth'] = 1;
 710  
 711          if (!$this->Request($args, $headers, $body)) {
 712              echo "ERROR in request";
 713              return false;
 714          }
 715  
 716          $xml2Array = new xml2Array();
 717          $arrOutput = $xml2Array->xmlParse($body);
 718  
 719          $array = array();
 720          foreach ($arrOutput['children'] as $value) {
 721              foreach ($value['children'] as $entry) {
 722  
 723                  if (($entry['name'] == 'S:ADDED-PATH') ||
 724                          ($entry['name'] == 'S:MODIFIED-PATH') ||
 725                          ($entry['name'] == 'S:DELETED-PATH')) {
 726                      if ($entry['attrs']['NODE-KIND'] == "file") {
 727                          $array['objects'][] = array('object_name' => $entry['tagData'], 'action' => $entry['name'], 'type' => 'file');
 728                      } else if ($entry['attrs']['NODE-KIND'] == "dir") {
 729                          $array['objects'][] = array('object_name' => $entry['tagData'], 'action' => $entry['name'], 'type' => 'dir');
 730                      }
 731                  }
 732              }
 733          }
 734          $files = "";
 735          $filesDelete = "";
 736          $dirs = "";
 737          $dirsDelete = "";
 738  
 739          foreach ($array['objects'] as $objects) {
 740              if ($objects['type'] == "file") {
 741                  if ($objects['action'] == "S:ADDED-PATH" || $objects['action'] == "S:MODIFIED-PATH") {
 742                      $file = $objects['object_name'] . "/*+++*/";
 743                      $files.=$file;
 744                      $filesDelete = str_replace($file, "", $filesDelete, $count);
 745                  }
 746                  if ($objects['action'] == "S:DELETED-PATH") {
 747                      if (strpos($files, $objects['object_name']) !== false) {
 748                          $file = $objects['object_name'] . "/*+++*/";
 749                          $count = 1;
 750                          $files = str_replace($file, "", $files, $count);
 751                      } else {
 752                          $filesDelete.=$objects['object_name'] . "/*+++*/";
 753                      }
 754                  }
 755              }
 756              if ($objects['type'] == "dir") {
 757                  if ($objects['action'] == "S:ADDED-PATH" || $objects['action'] == "S:MODIFIED-PATH") {
 758                      $dir = $objects['object_name'] . "/*+++*/";
 759                      $dirs.=$dir;
 760                      $dirsDelete = str_replace($dir, "", $dirsDelete, $count);
 761                  }
 762                  if ($objects['action'] == "S:DELETED-PATH") {
 763                      // Delete files from filelist
 764                      $dir = $objects['object_name'] . "/";
 765                      $files1 = explode("/*+++*/", $files);
 766                      for ($x = 0; $x < count($files1); $x++) {
 767                          if (strpos($files1[$x], $dir) !== false) {
 768                              unset($files1[$x]);
 769                          }
 770                      }
 771                      $files = implode("/*+++*/", $files1);
 772                      // END OF Delete files from filelist
 773                      // Delete dirs from dirslist
 774                      if (strpos($dirs, $objects['object_name']) !== false) {
 775                          $dir = $objects['object_name'] . "/*+++*/";
 776                          $count = 1;
 777                          $dirs = str_replace($dir, "", $dirs, $count);
 778                      } else {
 779                          $dirsDelete.=$objects['object_name'] . "/*+++*/";
 780                      }
 781                      // END OF Delete dirs from dirslist
 782                  }
 783              }
 784          }
 785          $files = explode("/*+++*/", $files);
 786          $filesDelete = explode("/*+++*/", $filesDelete);
 787          $dirs = explode("/*+++*/", $dirs);
 788          $dirsDelete = explode("/*+++*/", $dirsDelete);
 789          $out = array();
 790          $out['files'] = $files;
 791          $out['filesDelete'] = $filesDelete;
 792          $out['dirs'] = $dirs;
 793          $out['dirsDelete'] = $dirsDelete;
 794          return $out;
 795      }
 796  
 797      /**
 798       *  Returns the repository version
 799       *
 800       *  @return integer Repository version
 801       *  @access public
 802       */
 803      public function getVersion() {
 804          if ($this->_repVersion > 0)
 805              return $this->_repVersion;
 806  
 807          $this->_repVersion = -1;
 808          $this->initQuery($args, "PROPFIND", $this->cleanURL($this->_url . "/!svn/vcc/default"));
 809          $args['Body'] = PHPSVN_VERSION_REQUEST;
 810          $args['Headers']['Content-Length'] = strlen(PHPSVN_NORMAL_REQUEST);
 811          $args['Headers']['Depth'] = 0;
 812  
 813          if (!$this->Request($args, $tmp, $body)) {
 814              return $this->_repVersion;
 815          }
 816  
 817          $parser = new xml_parser_class;
 818          $parser->Parse($body, true);
 819          $enable = false;
 820          foreach ($parser->structure as $value) {
 821              if ($enable) {
 822                  $t = explode("/", $value);
 823  
 824                  // start from the end and move backwards until we find a non-blank entry
 825                  $index = count($t) - 1;
 826                  while ($t[$index] == "") {
 827                      $index--;
 828                  }
 829  
 830                  // check the last non-empty element to see if it's numeric. If so, it's the revision number
 831                  if (is_numeric($t[$index])) {
 832                      $this->_repVersion = $t[$index];
 833                      break;
 834                  } else {
 835                      $enable = false;
 836                      continue;
 837                  }
 838              }
 839              if (is_array($value) && $value['Tag'] == 'D:href')
 840                  $enable = true;
 841          }
 842          return $this->_repVersion;
 843      }
 844  
 845      /**
 846       *  Set the repository version
 847       *
 848       *  @param integer Repository version
 849       *  @access public
 850       */
 851      public function setVersion( $version ) {
 852          $this->_repVersion = intval( $version );
 853      }
 854  
 855      /**
 856       *  Deprecated functions for backward comatability
 857       */
 858  
 859      /**
 860       *  Set URL
 861       *
 862       *  Set the project repository URL.
 863       *
 864       *  @param string $url URL of the project.
 865       *  @access public
 866       */
 867      public function setRepository($url) {
 868          $this->_url = $url;
 869          $this->_repVersion = 0;
 870          $this->actVersion = $this->getVersion();
 871      }
 872  
 873      /**
 874       *  Old method; there's a typo in the name. This is now a wrapper for setRepository
 875       */
 876      public function setRespository($url) {
 877          return $this->setRepository($url);
 878      }
 879  
 880      /**
 881       *  Add Authentication  settings
 882       *
 883       *  @param string $user Username
 884       *  @param string $pass Password
 885       */
 886      public function setAuth($user, $pass) {
 887          $this->user = $user;
 888          $this->pass = $pass;
 889      }
 890  
 891      /**
 892       *  Private Functions
 893       */
 894  
 895      /**
 896       *  Callback for array_walk_recursive in public function getDirectoryFiles
 897       *
 898       *  @access private
 899       */
 900      private function storeDirectoryFiles($item, $key) {
 901          if ($key == 'name') {
 902              if (($item == 'D:HREF') ||
 903                      ($item == 'LP1:GETLASTMODIFIED') ||
 904                      ($item == 'LP1:VERSION-NAME') ||
 905                      ($item == 'LP2:BASELINE-RELATIVE-PATH') ||
 906                      ($item == 'LP3:BASELINE-RELATIVE-PATH') ||
 907                      ($item == 'D:STATUS')) {
 908                  $this->lastDirectoryFiles = $item;
 909              }
 910          } elseif (($key == 'tagData') && ($this->lastDirectoryFiles != '')) {
 911  
 912              // Unsure if the 1st of two D:HREF's always returns the result we want, but for now...
 913              if (($this->lastDirectoryFiles == 'D:HREF') && (isset($this->storeDirectoryFiles['type'])))
 914                  return;
 915  
 916              // Dump into the array 
 917              switch ($this->lastDirectoryFiles) {
 918                  case 'D:HREF':
 919                      $var = 'type';
 920                      break;
 921                  case 'LP1:VERSION-NAME':
 922                      $var = 'version';
 923                      break;
 924                  case 'LP1:GETLASTMODIFIED':
 925                      $var = 'last-mod';
 926                      break;
 927                  case 'LP2:BASELINE-RELATIVE-PATH':
 928                  case 'LP3:BASELINE-RELATIVE-PATH':
 929                      $var = 'path';
 930                      break;
 931                  case 'D:STATUS':
 932                      $var = 'status';
 933                      break;
 934              }
 935              $this->storeDirectoryFiles[$var] = $item;
 936              $this->lastDirectoryFiles = '';
 937  
 938              // Detect 'type' as either a 'directory' or 'file'
 939              if ((isset($this->storeDirectoryFiles['type'])) &&
 940                      (isset($this->storeDirectoryFiles['last-mod'])) &&
 941                      (isset($this->storeDirectoryFiles['path'])) &&
 942                      (isset($this->storeDirectoryFiles['status']))) {
 943                  $this->storeDirectoryFiles['path'] = str_replace(' ', '%20', $this->storeDirectoryFiles['path']); //Hack to make filenames with spaces work.
 944                  $len = strlen($this->storeDirectoryFiles['path']);
 945                  if (substr($this->storeDirectoryFiles['type'], strlen($this->storeDirectoryFiles['type']) - $len) == $this->storeDirectoryFiles['path']) {
 946                      $this->storeDirectoryFiles['type'] = 'file';
 947                  } else {
 948                      $this->storeDirectoryFiles['type'] = 'directory';
 949                  }
 950              }
 951          } else {
 952              $this->lastDirectoryFiles = '';
 953          }
 954      }
 955  
 956      /**
 957       *  Prepare HTTP CLIENT object
 958       *
 959       *  @param array &$arguments Byreferences variable.
 960       *  @param string $method Method for the request (GET,POST,PROPFIND, REPORT,ETC).
 961       *  @param string $url URL for the action.
 962       *  @access private
 963       */
 964      private function initQuery(&$arguments, $method, $url) {
 965          $http = & $this->_http;
 966          $http->GetRequestArguments($url, $arguments);
 967          if (isset($this->user) && isset($this->pass)) {
 968              $arguments["Headers"]["Authorization"] = " Basic " . base64_encode($this->user . ":" . $this->pass);
 969          }
 970          $arguments["RequestMethod"] = $method;
 971          $arguments["Headers"]["Content-Type"] = "text/xml";
 972          $arguments["Headers"]["Depth"] = 1;
 973      }
 974  
 975      /**
 976       *  Open a connection, send request, read header
 977       *  and body.
 978       *
 979       *  @param Array $args Connetion's argument
 980       *  @param Array &$headers Array with the header response.
 981       *  @param string &$body Body response.
 982       *  @return boolean True is query success
 983       *  @access private
 984       */
 985      private function Request($args, &$headers, &$body) {
 986          if( !isset( $args['RequestURI'] ) )
 987          {
 988              $args['RequestURI'] = '';
 989          }
 990          $args['RequestURI'] = str_replace(' ', '%20', $args['RequestURI']); //Hack to make filenames with spaces work.
 991          $http = & $this->_http;
 992          $error_open = $http->Open($args);
 993          if( !empty( $error_open ) )
 994          {
 995              echo '<b>Error opening of SVN server:</b> '.$error_open;
 996              return false;
 997          }
 998          $http->SendRequest($args);
 999          $http->ReadReplyHeaders($headers);
1000          if ($http->response_status[0] != 2) {
1001              switch ($http->response_status) {
1002                  case 404:
1003                      $this->errNro = NOT_FOUND;
1004                      break;
1005                  case 401:
1006                      $this->errNro = AUTH_REQUIRED;
1007                      break;
1008                  default:
1009                      $this->errNro = UNKNOWN_ERROR;
1010                      break;
1011              }
1012  //            trigger_error("request to $args[RequestURI] failed: $http->response_status
1013  //Error: $http->error");
1014              $http->close();
1015              return false;
1016          }
1017          $this->errNro = NO_ERROR;
1018          $body = '';
1019          $tbody = '';
1020          for (;;) {
1021              $error = $http->ReadReplyBody($tbody, 1000);
1022              if ($error != "" || strlen($tbody) == 0) {
1023                  break;
1024              }
1025              $body.= ( $tbody);
1026          }
1027          //print_r($tbody);
1028          $http->close();
1029          return true;
1030      }
1031  
1032      /**
1033       *  Returns $url stripped of '//'
1034       *
1035       *  Delete "//" on URL requests.
1036       *
1037       *  @param string $url URL
1038       *  @return string New cleaned URL.
1039       *  @access private
1040       */
1041      private function cleanURL($url) {
1042          return preg_replace("/((^:)\/\/)/", "//", $url);
1043      }
1044  
1045      /**
1046       * Private function for executing external script.
1047       */
1048      private function exec_after_completition() {
1049          require_once $this->path_exec_after_completition;
1050      }
1051  
1052      /**
1053       * Function to specify a script that should be executed 
1054       * after the checkout or update a local repository.
1055       * @param type $path_to_file - Path to file (script) for execution
1056       */
1057      function set_job_for_exec_after_completition($path_to_file) {
1058          $this->path_exec_after_completition = $path_to_file;
1059      }
1060  
1061      private function get_mime_array() {
1062          $regex = "/([\w\+\-\.\/]+)\t+([\w\s]+)/i";
1063          $lines = file("ext/mime/mime.types", FILE_IGNORE_NEW_LINES);
1064          foreach ($lines as $line) {
1065              if (substr($line, 0, 1) == '#')
1066                  continue; // skip comments 
1067              if (!preg_match($regex, $line, $matches))
1068                  continue; // skip mime types w/o any extensions 
1069              $mime = $matches[1];
1070              $extensions = explode(" ", $matches[2]);
1071              foreach ($extensions as $ext)
1072                  $mimeArray[trim($ext)] = $mime;
1073          }
1074          return ($mimeArray);
1075      }
1076  
1077      private function explodeX($delimiters, $string) {
1078          $return_array = Array($string); // The array to return
1079          $d_count = 0;
1080          while (isset($delimiters[$d_count])) { // Loop to loop through all delimiters
1081              $new_return_array = Array();
1082              foreach ($return_array as $el_to_split) { // Explode all returned elements by the next delimiter
1083                  $put_in_new_return_array = explode($delimiters[$d_count], $el_to_split);
1084                  foreach ($put_in_new_return_array as $substr) { // Put all the exploded elements in array to return
1085                      $new_return_array[] = $substr;
1086                  }
1087              }
1088              $return_array = $new_return_array; // Replace the previous return array by the next version
1089              $d_count++;
1090          }
1091          return $return_array; // Return the exploded elements
1092      }
1093  
1094      public function getFileSize($file = '/', $version = -1) {
1095  
1096          if ($version == -1 || $version > $this->actVersion) {
1097              $version = $this->actVersion;
1098          }
1099          $url = $this->cleanURL($this->_url . "/!svn/bc/" . $version . "/" . $file . "/");
1100          $this->initQuery($args, "PROPFIND", $url);
1101          $args['Body'] = PHPSVN_GET_FILE_SIZE;
1102          $args['Headers']['Content-Length'] = strlen(PHPSVN_GET_FILE_SIZE);
1103  
1104          if (!$this->Request($args, $headers, $body)) {
1105              return false;
1106          }
1107          $xml2Array = new xml2Array();
1108          $arrOutput = $xml2Array->xmlParse($body);
1109  
1110          if ($arrOutput) {
1111              $files = array();
1112              foreach ($arrOutput['children'] as $key => $value) {
1113                  array_walk_recursive($value, array($this, 'get_file_size_resursively'));
1114              }
1115              return $this->file_size;
1116          }
1117      }
1118  
1119      private function get_file_size_resursively($item, $key) {
1120          if ($key == 'name') {
1121              if ($item == 'LP1:GETCONTENTLENGTH') {
1122                  $this->file_size_founded = true;
1123              }
1124          } elseif (($key == 'tagData') && $this->file_size_founded) {
1125              $this->file_size = $item;
1126              $this->file_size_founded = false;
1127          }
1128      }
1129  
1130      /**
1131       * Get an error of HTTP request
1132       *
1133       * @return string Error text
1134       */
1135  	public function getError()
1136      {
1137          if( ! empty( $this->_http ) && ! empty( $this->_http->error ) )
1138          {
1139              return $this->_http->error;
1140          }
1141  
1142          return '';
1143      }
1144  }
1145  
1146  ?>

title

Description

title

Description

title

Description

title

title

Body