| [ Index ] |
|
Code source de Symfony 1.0.0 |
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 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |