[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/vendor/phing/system/io/ -> FileSystem.php (source)

   1  <?php
   2  
   3  /* 
   4   *  $Id: FileSystem.php 3076 2006-12-18 08:52:12Z fabien $
   5   *
   6   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   7   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   8   * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   9   * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10   * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  12   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  13   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  14   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  15   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  16   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17   *
  18   * This software consists of voluntary contributions made by many individuals
  19   * and is licensed under the LGPL. For more information please see
  20   * <http://phing.info>. 
  21   */
  22  
  23  /**
  24   * This is an abstract class for platform specific filesystem implementations
  25   * you have to implement each method in the platform specific filesystem implementation
  26   * classes Your local filesytem implementation must extend this class.
  27   * You should also use this class as a template to write your local implementation
  28   * Some native PHP filesystem specific methods are abstracted here as well. Anyway
  29   * you _must_ always use this methods via a PhingFile object (that by nature uses the
  30   * *FileSystem drivers to access the real filesystem via this class using natives.
  31   *
  32   * FIXME:
  33   *  - Error handling reduced to min fallthrough runtime excetions
  34   *    more precise errorhandling is done by the PhingFile class
  35   *    
  36   * @author Charlie Killian <charlie@tizac.com>
  37   * @author Hans Lellelid <hans@xmpl.org>
  38   * @version $Revision: 1.11 $
  39   * @package phing.system.io
  40   */
  41  abstract class FileSystem {    
  42  
  43      /* properties for simple boolean attributes */
  44      const BA_EXISTS    = 0x01;
  45      const BA_REGULAR   = 0x02;
  46      const BA_DIRECTORY = 0x04;
  47      const BA_HIDDEN    = 0x08;
  48      
  49      /** Instance for getFileSystem() method. */
  50      private static $fs;
  51      
  52      /**
  53       * Static method to return the FileSystem singelton representing
  54       * this platform's local filesystem driver.
  55       */
  56      public static function getFileSystem() {
  57          if (self::$fs === null) {
  58              switch(Phing::getProperty('host.fstype')) {
  59                  case 'UNIX':
  60                      include_once 'phing/system/io/UnixFileSystem.php';
  61                      self::$fs = new UnixFileSystem();
  62                  break;
  63                  case 'WIN32':
  64                      include_once 'phing/system/io/Win32FileSystem.php';
  65                      self::$fs = new Win32FileSystem();
  66                  break;
  67                  case 'WINNT':
  68                      include_once 'phing/system/io/WinNTFileSystem.php';
  69                      self::$fs = new WinNTFileSystem();
  70                  break;
  71                  default:
  72                      throw new Exception("Host uses unsupported filesystem, unable to proceed");
  73              }
  74          }
  75          return self::$fs;
  76      }
  77  
  78      /* -- Normalization and construction -- */
  79  
  80      /**
  81       * Return the local filesystem's name-separator character.
  82       */
  83      abstract function getSeparator();
  84  
  85      /**
  86       * Return the local filesystem's path-separator character.
  87       */
  88      abstract function getPathSeparator();
  89  
  90      /**
  91       * Convert the given pathname string to normal form.  If the string is
  92       * already in normal form then it is simply returned.
  93       */
  94      abstract function normalize($strPath);
  95  
  96      /**
  97       * Compute the length of this pathname string's prefix.  The pathname
  98       * string must be in normal form.
  99       */
 100      abstract function prefixLength($pathname);
 101  
 102      /**
 103       * Resolve the child pathname string against the parent.
 104       * Both strings must be in normal form, and the result
 105       * will be a string in normal form.
 106       */
 107      abstract function resolve($parent, $child);
 108      
 109      /**
 110       * Resolve the given abstract pathname into absolute form.  Invoked by the
 111       * getAbsolutePath and getCanonicalPath methods in the PhingFile class.
 112       */
 113      abstract function resolveFile(PhingFile $f);
 114  
 115      /**
 116       * Return the parent pathname string to be used when the parent-directory
 117       * argument in one of the two-argument PhingFile constructors is the empty
 118       * pathname.
 119       */
 120      abstract function getDefaultParent();
 121  
 122      /**
 123       * Post-process the given URI path string if necessary.  This is used on
 124       * win32, e.g., to transform "/c:/foo" into "c:/foo".  The path string
 125       * still has slash separators; code in the PhingFile class will translate them
 126       * after this method returns.
 127       */
 128      abstract function fromURIPath($path);
 129  
 130      /* -- Path operations -- */
 131  
 132      /**
 133       * Tell whether or not the given abstract pathname is absolute.
 134       */
 135      abstract function isAbsolute(PhingFile $f);
 136  
 137      /** 
 138       * canonicalize filename by checking on disk 
 139       * @return mixed Canonical path or false if the file doesn't exist.
 140       */
 141      function canonicalize($strPath) {
 142          return @realpath($strPath);        
 143      }
 144  
 145      /* -- Attribute accessors -- */
 146  
 147      /**
 148       * Return the simple boolean attributes for the file or directory denoted
 149       * by the given abstract pathname, or zero if it does not exist or some
 150       * other I/O error occurs.
 151       */
 152      function getBooleanAttributes($f) {
 153          throw new Exception("SYSTEM ERROR method getBooleanAttributes() not implemented by fs driver");
 154      }
 155  
 156      /**
 157       * Check whether the file or directory denoted by the given abstract
 158       * pathname may be accessed by this process.  If the second argument is
 159       * false, then a check for read access is made; if the second
 160       * argument is true, then a check for write (not read-write)
 161       * access is made.  Return false if access is denied or an I/O error
 162       * occurs.
 163       */
 164      function checkAccess(PhingFile $f, $write = false) {
 165          // we clear stat cache, its expensive to look up from scratch,
 166          // but we need to be sure
 167          @clearstatcache();
 168  
 169  
 170          // Shouldn't this be $f->GetAbsolutePath() ?
 171          // And why doesn't GetAbsolutePath() work?
 172  
 173          $strPath = (string) $f->getPath();
 174  
 175          // FIXME
 176          // if file object does denote a file that yet not existst
 177          // path rights are checked
 178          if (!@file_exists($strPath) && !is_dir($strPath)) {
 179              $strPath = $f->getParent();
 180              if ($strPath === null || !is_dir($strPath)) {
 181                  $strPath = Phing::getProperty("user.dir");
 182              }
 183              //$strPath = dirname($strPath);
 184          }
 185  
 186          if (!$write) {
 187              return (boolean) @is_readable($strPath);
 188          } else {
 189              return (boolean) @is_writable($strPath);
 190          }
 191      }
 192  
 193      /**
 194       * Return the time at which the file or directory denoted by the given
 195       * abstract pathname was last modified, or zero if it does not exist or
 196       * some other I/O error occurs.
 197       */
 198      function getLastModifiedTime(PhingFile $f) {
 199          
 200          if (!$f->exists()) {
 201              return 0;
 202          }
 203  
 204          @clearstatcache();
 205          $strPath = (string) $f->getPath();
 206          $mtime = @filemtime($strPath);
 207          if (false === $mtime) {
 208              // FAILED. Log and return err.
 209              $msg = "FileSystem::Filemtime() FAILED. Cannot can not get modified time of $strPath. $php_errormsg";
 210              throw new Exception($msg);
 211          } else {
 212              return (int) $mtime;
 213          }
 214      }
 215  
 216      /**
 217       * Return the length in bytes of the file denoted by the given abstract
 218       * pathname, or zero if it does not exist, is a directory, or some other
 219       * I/O error occurs.
 220       */
 221      function getLength(PhingFile $f) {
 222          $strPath = (string) $f->getAbsolutePath();
 223          $fs = filesize((string) $strPath);
 224          if ($fs !== false) {
 225              return $fs;
 226          } else {
 227              $msg = "FileSystem::Read() FAILED. Cannot get filesize of $strPath. $php_errormsg";
 228              throw new Exception($msg);
 229          }
 230      }
 231  
 232      /* -- File operations -- */
 233  
 234      /**
 235       * Create a new empty file with the given pathname.  Return
 236       * true if the file was created and false if a
 237       * file or directory with the given pathname already exists.  Throw an
 238       * IOException if an I/O error occurs.
 239       *
 240       * @param       string      Path of the file to be created.
 241       *     
 242       * @throws      IOException
 243       */
 244      function createNewFile($strPathname) {
 245          if (@file_exists($strPathname))
 246              return false;
 247              
 248          // Create new file
 249          $fp = @fopen($strPathname, "w");
 250          if ($fp === false) {
 251              throw new IOException("The file \"$strPathname\" could not be created");            
 252          }
 253          @fclose($fp);        
 254          return true;
 255      }
 256  
 257      /**
 258       * Delete the file or directory denoted by the given abstract pathname,
 259       * returning true if and only if the operation succeeds.
 260       */
 261      function delete(PhingFile $f) {
 262          if ($f->isDirectory()) {
 263              return $this->rmdir($f->getPath());
 264          } else {
 265              return $this->unlink($f->getPath());
 266          }
 267      }
 268  
 269      /**
 270       * Arrange for the file or directory denoted by the given abstract
 271       * pathname to be deleted when Phing::shutdown is called, returning
 272      * true if and only if the operation succeeds.
 273       */
 274      function deleteOnExit($f) {
 275          throw new Exception("deleteOnExit() not implemented by local fs driver");
 276      }
 277  
 278      /**
 279       * List the elements of the directory denoted by the given abstract
 280       * pathname.  Return an array of strings naming the elements of the
 281       * directory if successful; otherwise, return <code>null</code>.
 282       */
 283      function listDir(PhingFile $f) {
 284          $strPath = (string) $f->getAbsolutePath();
 285          $d = @dir($strPath);
 286          if (!$d) {
 287              return null;
 288          }
 289          $list = array();
 290          while($entry = $d->read()) {
 291              if ($entry != "." && $entry != "..") {
 292                  array_push($list, $entry);
 293              }
 294          }
 295          $d->close();
 296          unset($d);
 297          return $list;
 298      }
 299  
 300      /**
 301       * Create a new directory denoted by the given abstract pathname,
 302       * returning true if and only if the operation succeeds.
 303       */
 304      function createDirectory(&$f) {
 305          return @mkdir($f->getAbsolutePath(),0755);
 306      }
 307  
 308      /**
 309       * Rename the file or directory denoted by the first abstract pathname to
 310       * the second abstract pathname, returning true if and only if
 311       * the operation succeeds.
 312       *
 313       * @param PhingFile $f1 abstract source file
 314       * @param PhingFile $f2 abstract destination file
 315       * @return void    
 316       * @throws Exception if rename cannot be performed
 317       */
 318      function rename(PhingFile $f1, PhingFile $f2) {        
 319          // get the canonical paths of the file to rename
 320          $src = $f1->getAbsolutePath();
 321          $dest = $f2->getAbsolutePath();
 322          if (false === @rename($src, $dest)) {
 323              $msg = "Rename FAILED. Cannot rename $src to $dest. $php_errormsg";
 324              throw new Exception($msg);
 325          }
 326      }
 327  
 328      /**
 329       * Set the last-modified time of the file or directory denoted by the
 330       * given abstract pathname returning true if and only if the
 331       * operation succeeds.
 332       * @return void
 333       * @throws Exception
 334       */
 335      function setLastModifiedTime(PhingFile $f, $time) {        
 336          $path = $f->getPath();
 337          $success = @touch($path, $time);
 338          if (!$success) {
 339              throw new Exception("Could not create directory due to: $php_errormsg");
 340          }
 341      }
 342  
 343      /**
 344       * Mark the file or directory denoted by the given abstract pathname as
 345       * read-only, returning <code>true</code> if and only if the operation
 346       * succeeds.
 347       */
 348      function setReadOnly($f) {
 349          throw new Exception("setReadonle() not implemented by local fs driver");
 350      }
 351  
 352      /* -- Filesystem interface -- */
 353  
 354      /**
 355       * List the available filesystem roots, return array of PhingFile objects
 356       */
 357      function listRoots() {
 358          throw new Exception("SYSTEM ERROR [listRoots() not implemented by local fs driver]");
 359      }
 360  
 361      /* -- Basic infrastructure -- */
 362  
 363      /**
 364       * Compare two abstract pathnames lexicographically.
 365       */
 366      function compare($f1, $f2) {
 367          throw new Exception("SYSTEM ERROR [compare() not implemented by local fs driver]");
 368      }
 369  
 370      /**
 371       * Copy a file.
 372       *
 373       * @param PhingFile $src Source path and name file to copy.
 374       * @param PhingFile $dest Destination path and name of new file.
 375       *
 376       * @return void     
 377       * @throws Exception if file cannot be copied.
 378       */
 379      function copy(PhingFile $src, PhingFile $dest) {
 380          global $php_errormsg;
 381          $srcPath  = $src->getAbsolutePath();
 382          $destPath = $dest->getAbsolutePath();
 383  
 384          if (false === @copy($srcPath, $destPath)) { // Copy FAILED. Log and return err.
 385              // Add error from php to end of log message. $php_errormsg.
 386              $msg = "FileSystem::copy() FAILED. Cannot copy $srcPath to $destPath. $php_errormsg";
 387              throw new Exception($msg);
 388          }
 389          
 390          try {
 391              $dest->setMode($src->getMode());
 392          } catch(Exception $exc) {
 393              // [MA] does chmod returns an error on systems that do not support it ?
 394              // eat it up for now.
 395          }
 396      }
 397  
 398      /**
 399       * Change the permissions on a file or directory.
 400       *
 401       * @param    pathname    String. Path and name of file or directory.
 402       * @param    mode        Int. The mode (permissions) of the file or
 403       *                        directory. If using octal add leading 0. eg. 0777.
 404       *                        Mode is affected by the umask system setting.
 405       *
 406       * @return void     
 407       * @throws Exception if operation failed.
 408       */
 409      function chmod($pathname, $mode) {    
 410          $str_mode = decoct($mode); // Show octal in messages.    
 411          if (false === @chmod($pathname, $mode)) {// FAILED.
 412              $msg = "FileSystem::chmod() FAILED. Cannot chmod $pathname. Mode $str_mode. $php_errormsg";
 413              throw new Exception($msg);
 414          }
 415      }
 416  
 417      /**
 418       * Locks a file and throws an Exception if this is not possible.
 419       * @return void
 420       * @throws Exception
 421       */
 422      function lock(PhingFile $f) {
 423          $filename = $f->getPath();
 424          $fp = @fopen($filename, "w");
 425          $result = @flock($fp, LOCK_EX);
 426          @fclose($fp);
 427          if (!$result) {
 428              throw new Exception("Could not lock file '$filename'");
 429          }
 430      }
 431  
 432      /**
 433       * Unlocks a file and throws an IO Error if this is not possible.
 434       *
 435       * @throws Exception
 436       * @return void
 437       */
 438      function unlock(PhingFile $f) {
 439          $filename = $f->getPath();
 440          $fp = @fopen($filename, "w");
 441          $result = @flock($fp, LOCK_UN);
 442          fclose($fp);
 443          if (!$result) {
 444              throw new Exception("Could not unlock file '$filename'");
 445          }
 446      }
 447  
 448      /**
 449       * Delete a file.
 450       *
 451       * @param    file    String. Path and/or name of file to delete.
 452       *
 453       * @return void
 454       * @throws Exception - if an error is encountered.
 455       */
 456      function unlink($file) {
 457          global $php_errormsg;
 458          if (false === @unlink($file)) {
 459              $msg = "FileSystem::unlink() FAILED. Cannot unlink '$file'. $php_errormsg";
 460              throw new Exception($msg);
 461          }
 462      }
 463  
 464      /**
 465       * Symbolically link a file to another name.
 466       * 
 467       * Currently symlink is not implemented on Windows. Don't use if the application is to be portable.
 468       *
 469       * @param string $target Path and/or name of file to link.
 470       * @param string $link Path and/or name of link to be created.
 471       * @return void
 472       */
 473      function symlink($target, $link) {
 474      
 475          // If Windows OS then symlink() will report it is not supported in
 476          // the build. Use this error instead of checking for Windows as the OS.
 477  
 478          if (false === @symlink($target, $link)) {
 479              // Add error from php to end of log message. $php_errormsg.
 480              $msg = "FileSystem::Symlink() FAILED. Cannot symlink '$target' to '$link'. $php_errormsg";
 481              throw new Exception($msg);
 482          }
 483  
 484      }
 485  
 486      /**
 487       * Set the modification and access time on a file to the present time.
 488       *
 489       * @param string $file Path and/or name of file to touch.
 490       * @param int $time 
 491       * @return void
 492       */
 493      function touch($file, $time = null) {
 494          global $php_errormsg;
 495          
 496          if (null === $time) {
 497              $error = @touch($file);
 498          } else {
 499              $error = @touch($file, $time);
 500          }
 501  
 502          if (false === $error) { // FAILED.
 503              // Add error from php to end of log message. $php_errormsg.
 504              $msg = "FileSystem::touch() FAILED. Cannot touch '$file'. $php_errormsg";            
 505              throw new Exception($msg);            
 506          }
 507      }
 508  
 509      /**
 510       * Delete an empty directory OR a directory and all of its contents.
 511       *
 512       * @param    dir    String. Path and/or name of directory to delete.
 513       * @param    children    Boolean.    False: don't delete directory contents.
 514       *                                    True: delete directory contents.
 515       *
 516       * @return void
 517       */
 518      function rmdir($dir, $children = false) {
 519          global $php_errormsg;
 520          
 521          // If children=FALSE only delete dir if empty.
 522          if (false === $children) {
 523          
 524              if (false === @rmdir($dir)) { // FAILED.
 525                  // Add error from php to end of log message. $php_errormsg.
 526                  $msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg";
 527                  throw new Exception($msg);
 528              }
 529              
 530          } else { // delete contents and dir.
 531  
 532              $handle = @opendir($dir);
 533  
 534              if (false === $handle) { // Error.
 535  
 536                  $msg = "FileSystem::rmdir() FAILED. Cannot opendir() $dir. $php_errormsg";                
 537                  throw new Exception($msg);
 538  
 539              } else { // Read from handle.
 540  
 541                  // Don't error on readdir().
 542                  while (false !== ($entry = @readdir($handle))) {
 543  
 544                      if ($entry != '.' && $entry != '..') {
 545  
 546                          // Only add / if it isn't already the last char.
 547                          // This ONLY serves the purpose of making the Logger
 548                          // output look nice:)
 549  
 550                          if (strpos(strrev($dir), DIRECTORY_SEPARATOR) === 0) {// there is a /
 551                              $next_entry = $dir . $entry;
 552                          } else { // no /
 553                              $next_entry = $dir . DIRECTORY_SEPARATOR . $entry;
 554                          }
 555  
 556                          // NOTE: As of php 4.1.1 is_dir doesn't return FALSE it
 557                          // returns 0. So use == not ===.
 558  
 559                          // Don't error on is_dir()
 560                          if (false == @is_dir($next_entry)) { // Is file.
 561                              
 562                              try {
 563                                  self::unlink($next_entry); // Delete.
 564                              } catch (Exception $e) {                            
 565                                  $msg = "FileSystem::Rmdir() FAILED. Cannot FileSystem::Unlink() $next_entry. ". $e->getMessage();
 566                                  throw new Exception($msg);
 567                              }
 568  
 569                          } else { // Is directory.
 570                              
 571                              try {
 572                                  self::rmdir($next_entry, true); // Delete
 573                              } catch (Exception $e) {
 574                                  $msg = "FileSystem::rmdir() FAILED. Cannot FileSystem::rmdir() $next_entry. ". $e->getMessage();
 575                                  throw new Exception($msg);
 576                              }
 577  
 578                          } // end is_dir else
 579                      } // end .. if
 580                  } // end while
 581              } // end handle if
 582  
 583              // Don't error on closedir()
 584              @closedir($handle);
 585              
 586              if (false === @rmdir($dir)) { // FAILED.
 587                  // Add error from php to end of log message. $php_errormsg.
 588                  $msg = "FileSystem::rmdir() FAILED. Cannot rmdir $dir. $php_errormsg";
 589                  throw new Exception($msg);
 590              }
 591              
 592          }
 593                  
 594      }
 595  
 596      /**
 597       * Set the umask for file and directory creation.
 598       *
 599       * @param    mode    Int. Permissions ususally in ocatal. Use leading 0 for
 600       *                    octal. Number between 0 and 0777.
 601       *
 602       * @return void
 603       * @throws Exception if there is an error performing operation.     
 604       */
 605      function umask($mode) {
 606          global $php_errormsg;
 607          
 608          // CONSIDERME:
 609          // Throw a warning if mode is 0. PHP converts illegal octal numbers to
 610          // 0 so 0 might not be what the user intended.
 611                          
 612          $str_mode = decoct($mode); // Show octal in messages.
 613  
 614          if (false === @umask($mode)) { // FAILED.
 615              // Add error from php to end of log message. $php_errormsg.
 616              $msg = "FileSystem::Umask() FAILED. Value $mode. $php_errormsg";
 617              throw new Exception($msg);
 618          }
 619      }
 620  
 621      /**
 622       * Compare the modified time of two files.
 623       *
 624       * @param    file1    String. Path and name of file1.
 625       * @param    file2    String. Path and name of file2.
 626       *
 627       * @return    Int.     1 if file1 is newer.
 628       *                 -1 if file2 is newer.
 629       *                  0 if files have the same time.
 630       *                  Err object on failure.
 631       *     
 632       * @throws Exception - if cannot get modified time of either file.
 633       */
 634      function compareMTimes($file1, $file2) {
 635  
 636          $mtime1 = filemtime($file1);
 637          $mtime2 = filemtime($file2);
 638  
 639          if ($mtime1 === false) { // FAILED. Log and return err.        
 640              // Add error from php to end of log message. $php_errormsg.
 641              $msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file1.";
 642              throw new Exception($msg);            
 643          } elseif ($mtime2 === false) { // FAILED. Log and return err.
 644              // Add error from php to end of log message. $php_errormsg.
 645              $msg = "FileSystem::compareMTimes() FAILED. Cannot can not get modified time of $file2.";
 646              throw new Exception($msg);
 647          } else { // Worked. Log and return compare.                
 648              // Compare mtimes.
 649              if ($mtime1 == $mtime2) {
 650                  return 0;
 651              } else {
 652                  return ($mtime1 < $mtime2) ? -1 : 1;
 653              } // end compare
 654          }
 655      }
 656          
 657  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7