[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Direct Filesystem. 4 * 5 * @package WordPress 6 * @subpackage Filesystem 7 */ 8 9 /** 10 * WordPress Filesystem Class for direct PHP file and folder manipulation. 11 * 12 * @since 2.5.0 13 * 14 * @see WP_Filesystem_Base 15 */ 16 class WP_Filesystem_Direct extends WP_Filesystem_Base { 17 18 /** 19 * Constructor. 20 * 21 * @since 2.5.0 22 * 23 * @param mixed $arg Not used. 24 */ 25 public function __construct( $arg ) { 26 $this->method = 'direct'; 27 $this->errors = new WP_Error(); 28 } 29 30 /** 31 * Reads entire file into a string. 32 * 33 * @since 2.5.0 34 * 35 * @param string $file Name of the file to read. 36 * @return string|false Read data on success, false on failure. 37 */ 38 public function get_contents( $file ) { 39 return @file_get_contents( $file ); 40 } 41 42 /** 43 * Reads entire file into an array. 44 * 45 * @since 2.5.0 46 * 47 * @param string $file Path to the file. 48 * @return array|false File contents in an array on success, false on failure. 49 */ 50 public function get_contents_array( $file ) { 51 return @file( $file ); 52 } 53 54 /** 55 * Writes a string to a file. 56 * 57 * @since 2.5.0 58 * 59 * @param string $file Remote path to the file where to write the data. 60 * @param string $contents The data to write. 61 * @param int|false $mode Optional. The file permissions as octal number, usually 0644. 62 * Default false. 63 * @return bool True on success, false on failure. 64 */ 65 public function put_contents( $file, $contents, $mode = false ) { 66 $fp = @fopen( $file, 'wb' ); 67 68 if ( ! $fp ) { 69 return false; 70 } 71 72 mbstring_binary_safe_encoding(); 73 74 $data_length = strlen( $contents ); 75 76 $bytes_written = fwrite( $fp, $contents ); 77 78 reset_mbstring_encoding(); 79 80 fclose( $fp ); 81 82 if ( $data_length !== $bytes_written ) { 83 return false; 84 } 85 86 $this->chmod( $file, $mode ); 87 88 return true; 89 } 90 91 /** 92 * Gets the current working directory. 93 * 94 * @since 2.5.0 95 * 96 * @return string|false The current working directory on success, false on failure. 97 */ 98 public function cwd() { 99 return getcwd(); 100 } 101 102 /** 103 * Changes current directory. 104 * 105 * @since 2.5.0 106 * 107 * @param string $dir The new current directory. 108 * @return bool True on success, false on failure. 109 */ 110 public function chdir( $dir ) { 111 return @chdir( $dir ); 112 } 113 114 /** 115 * Changes the file group. 116 * 117 * @since 2.5.0 118 * 119 * @param string $file Path to the file. 120 * @param string|int $group A group name or number. 121 * @param bool $recursive Optional. If set to true, changes file group recursively. 122 * Default false. 123 * @return bool True on success, false on failure. 124 */ 125 public function chgrp( $file, $group, $recursive = false ) { 126 if ( ! $this->exists( $file ) ) { 127 return false; 128 } 129 130 if ( ! $recursive ) { 131 return chgrp( $file, $group ); 132 } 133 134 if ( ! $this->is_dir( $file ) ) { 135 return chgrp( $file, $group ); 136 } 137 138 // Is a directory, and we want recursive. 139 $file = trailingslashit( $file ); 140 $filelist = $this->dirlist( $file ); 141 142 foreach ( $filelist as $filename ) { 143 $this->chgrp( $file . $filename, $group, $recursive ); 144 } 145 146 return true; 147 } 148 149 /** 150 * Changes filesystem permissions. 151 * 152 * @since 2.5.0 153 * 154 * @param string $file Path to the file. 155 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, 156 * 0755 for directories. Default false. 157 * @param bool $recursive Optional. If set to true, changes file permissions recursively. 158 * Default false. 159 * @return bool True on success, false on failure. 160 */ 161 public function chmod( $file, $mode = false, $recursive = false ) { 162 if ( ! $mode ) { 163 if ( $this->is_file( $file ) ) { 164 $mode = FS_CHMOD_FILE; 165 } elseif ( $this->is_dir( $file ) ) { 166 $mode = FS_CHMOD_DIR; 167 } else { 168 return false; 169 } 170 } 171 172 if ( ! $recursive || ! $this->is_dir( $file ) ) { 173 return chmod( $file, $mode ); 174 } 175 176 // Is a directory, and we want recursive. 177 $file = trailingslashit( $file ); 178 $filelist = $this->dirlist( $file ); 179 180 foreach ( (array) $filelist as $filename => $filemeta ) { 181 $this->chmod( $file . $filename, $mode, $recursive ); 182 } 183 184 return true; 185 } 186 187 /** 188 * Changes the owner of a file or directory. 189 * 190 * @since 2.5.0 191 * 192 * @param string $file Path to the file or directory. 193 * @param string|int $owner A user name or number. 194 * @param bool $recursive Optional. If set to true, changes file owner recursively. 195 * Default false. 196 * @return bool True on success, false on failure. 197 */ 198 public function chown( $file, $owner, $recursive = false ) { 199 if ( ! $this->exists( $file ) ) { 200 return false; 201 } 202 203 if ( ! $recursive ) { 204 return chown( $file, $owner ); 205 } 206 207 if ( ! $this->is_dir( $file ) ) { 208 return chown( $file, $owner ); 209 } 210 211 // Is a directory, and we want recursive. 212 $filelist = $this->dirlist( $file ); 213 214 foreach ( $filelist as $filename ) { 215 $this->chown( $file . '/' . $filename, $owner, $recursive ); 216 } 217 218 return true; 219 } 220 221 /** 222 * Gets the file owner. 223 * 224 * @since 2.5.0 225 * 226 * @param string $file Path to the file. 227 * @return string|false Username of the owner on success, false on failure. 228 */ 229 public function owner( $file ) { 230 $owneruid = @fileowner( $file ); 231 232 if ( ! $owneruid ) { 233 return false; 234 } 235 236 if ( ! function_exists( 'posix_getpwuid' ) ) { 237 return $owneruid; 238 } 239 240 $ownerarray = posix_getpwuid( $owneruid ); 241 242 if ( ! $ownerarray ) { 243 return false; 244 } 245 246 return $ownerarray['name']; 247 } 248 249 /** 250 * Gets the permissions of the specified file or filepath in their octal format. 251 * 252 * FIXME does not handle errors in fileperms() 253 * 254 * @since 2.5.0 255 * 256 * @param string $file Path to the file. 257 * @return string Mode of the file (the last 3 digits). 258 */ 259 public function getchmod( $file ) { 260 return substr( decoct( @fileperms( $file ) ), -3 ); 261 } 262 263 /** 264 * Gets the file's group. 265 * 266 * @since 2.5.0 267 * 268 * @param string $file Path to the file. 269 * @return string|false The group on success, false on failure. 270 */ 271 public function group( $file ) { 272 $gid = @filegroup( $file ); 273 274 if ( ! $gid ) { 275 return false; 276 } 277 278 if ( ! function_exists( 'posix_getgrgid' ) ) { 279 return $gid; 280 } 281 282 $grouparray = posix_getgrgid( $gid ); 283 284 if ( ! $grouparray ) { 285 return false; 286 } 287 288 return $grouparray['name']; 289 } 290 291 /** 292 * Copies a file. 293 * 294 * @since 2.5.0 295 * 296 * @param string $source Path to the source file. 297 * @param string $destination Path to the destination file. 298 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. 299 * Default false. 300 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, 301 * 0755 for dirs. Default false. 302 * @return bool True on success, false on failure. 303 */ 304 public function copy( $source, $destination, $overwrite = false, $mode = false ) { 305 if ( ! $overwrite && $this->exists( $destination ) ) { 306 return false; 307 } 308 309 $rtval = copy( $source, $destination ); 310 311 if ( $mode ) { 312 $this->chmod( $destination, $mode ); 313 } 314 315 return $rtval; 316 } 317 318 /** 319 * Moves a file or directory. 320 * 321 * After moving files or directories, OPcache will need to be invalidated. 322 * 323 * If moving a directory fails, `copy_dir()` can be used for a recursive copy. 324 * 325 * Use `move_dir()` for moving directories with OPcache invalidation and a 326 * fallback to `copy_dir()`. 327 * 328 * @since 2.5.0 329 * 330 * @param string $source Path to the source file. 331 * @param string $destination Path to the destination file. 332 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. 333 * Default false. 334 * @return bool True on success, false on failure. 335 */ 336 public function move( $source, $destination, $overwrite = false ) { 337 if ( ! $overwrite && $this->exists( $destination ) ) { 338 return false; 339 } 340 341 if ( $overwrite && $this->exists( $destination ) && ! $this->delete( $destination, true ) ) { 342 // Can't overwrite if the destination couldn't be deleted. 343 return false; 344 } 345 346 // Try using rename first. if that fails (for example, source is read only) try copy. 347 if ( @rename( $source, $destination ) ) { 348 return true; 349 } 350 351 // Backward compatibility: Only fall back to `::copy()` for single files. 352 if ( $this->is_file( $source ) && $this->copy( $source, $destination, $overwrite ) && $this->exists( $destination ) ) { 353 $this->delete( $source ); 354 355 return true; 356 } else { 357 return false; 358 } 359 } 360 361 /** 362 * Deletes a file or directory. 363 * 364 * @since 2.5.0 365 * 366 * @param string $file Path to the file or directory. 367 * @param bool $recursive Optional. If set to true, deletes files and folders recursively. 368 * Default false. 369 * @param string|false $type Type of resource. 'f' for file, 'd' for directory. 370 * Default false. 371 * @return bool True on success, false on failure. 372 */ 373 public function delete( $file, $recursive = false, $type = false ) { 374 if ( empty( $file ) ) { 375 // Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem. 376 return false; 377 } 378 379 $file = str_replace( '\\', '/', $file ); // For Win32, occasional problems deleting files otherwise. 380 381 if ( 'f' === $type || $this->is_file( $file ) ) { 382 return @unlink( $file ); 383 } 384 385 if ( ! $recursive && $this->is_dir( $file ) ) { 386 return @rmdir( $file ); 387 } 388 389 // At this point it's a folder, and we're in recursive mode. 390 $file = trailingslashit( $file ); 391 $filelist = $this->dirlist( $file, true ); 392 393 $retval = true; 394 395 if ( is_array( $filelist ) ) { 396 foreach ( $filelist as $filename => $fileinfo ) { 397 if ( ! $this->delete( $file . $filename, $recursive, $fileinfo['type'] ) ) { 398 $retval = false; 399 } 400 } 401 } 402 403 if ( file_exists( $file ) && ! @rmdir( $file ) ) { 404 $retval = false; 405 } 406 407 return $retval; 408 } 409 410 /** 411 * Checks if a file or directory exists. 412 * 413 * @since 2.5.0 414 * 415 * @param string $path Path to file or directory. 416 * @return bool Whether $path exists or not. 417 */ 418 public function exists( $path ) { 419 return @file_exists( $path ); 420 } 421 422 /** 423 * Checks if resource is a file. 424 * 425 * @since 2.5.0 426 * 427 * @param string $file File path. 428 * @return bool Whether $file is a file. 429 */ 430 public function is_file( $file ) { 431 return @is_file( $file ); 432 } 433 434 /** 435 * Checks if resource is a directory. 436 * 437 * @since 2.5.0 438 * 439 * @param string $path Directory path. 440 * @return bool Whether $path is a directory. 441 */ 442 public function is_dir( $path ) { 443 return @is_dir( $path ); 444 } 445 446 /** 447 * Checks if a file is readable. 448 * 449 * @since 2.5.0 450 * 451 * @param string $file Path to file. 452 * @return bool Whether $file is readable. 453 */ 454 public function is_readable( $file ) { 455 return @is_readable( $file ); 456 } 457 458 /** 459 * Checks if a file or directory is writable. 460 * 461 * @since 2.5.0 462 * 463 * @param string $path Path to file or directory. 464 * @return bool Whether $path is writable. 465 */ 466 public function is_writable( $path ) { 467 return @is_writable( $path ); 468 } 469 470 /** 471 * Gets the file's last access time. 472 * 473 * @since 2.5.0 474 * 475 * @param string $file Path to file. 476 * @return int|false Unix timestamp representing last access time, false on failure. 477 */ 478 public function atime( $file ) { 479 return @fileatime( $file ); 480 } 481 482 /** 483 * Gets the file modification time. 484 * 485 * @since 2.5.0 486 * 487 * @param string $file Path to file. 488 * @return int|false Unix timestamp representing modification time, false on failure. 489 */ 490 public function mtime( $file ) { 491 return @filemtime( $file ); 492 } 493 494 /** 495 * Gets the file size (in bytes). 496 * 497 * @since 2.5.0 498 * 499 * @param string $file Path to file. 500 * @return int|false Size of the file in bytes on success, false on failure. 501 */ 502 public function size( $file ) { 503 return @filesize( $file ); 504 } 505 506 /** 507 * Sets the access and modification times of a file. 508 * 509 * Note: If $file doesn't exist, it will be created. 510 * 511 * @since 2.5.0 512 * 513 * @param string $file Path to file. 514 * @param int $time Optional. Modified time to set for file. 515 * Default 0. 516 * @param int $atime Optional. Access time to set for file. 517 * Default 0. 518 * @return bool True on success, false on failure. 519 */ 520 public function touch( $file, $time = 0, $atime = 0 ) { 521 if ( 0 === $time ) { 522 $time = time(); 523 } 524 525 if ( 0 === $atime ) { 526 $atime = time(); 527 } 528 529 return touch( $file, $time, $atime ); 530 } 531 532 /** 533 * Creates a directory. 534 * 535 * @since 2.5.0 536 * 537 * @param string $path Path for new directory. 538 * @param int|false $chmod Optional. The permissions as octal number (or false to skip chmod). 539 * Default false. 540 * @param string|int|false $chown Optional. A user name or number (or false to skip chown). 541 * Default false. 542 * @param string|int|false $chgrp Optional. A group name or number (or false to skip chgrp). 543 * Default false. 544 * @return bool True on success, false on failure. 545 */ 546 public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) { 547 // Safe mode fails with a trailing slash under certain PHP versions. 548 $path = untrailingslashit( $path ); 549 550 if ( empty( $path ) ) { 551 return false; 552 } 553 554 if ( ! $chmod ) { 555 $chmod = FS_CHMOD_DIR; 556 } 557 558 if ( ! @mkdir( $path ) ) { 559 return false; 560 } 561 562 $this->chmod( $path, $chmod ); 563 564 if ( $chown ) { 565 $this->chown( $path, $chown ); 566 } 567 568 if ( $chgrp ) { 569 $this->chgrp( $path, $chgrp ); 570 } 571 572 return true; 573 } 574 575 /** 576 * Deletes a directory. 577 * 578 * @since 2.5.0 579 * 580 * @param string $path Path to directory. 581 * @param bool $recursive Optional. Whether to recursively remove files/directories. 582 * Default false. 583 * @return bool True on success, false on failure. 584 */ 585 public function rmdir( $path, $recursive = false ) { 586 return $this->delete( $path, $recursive ); 587 } 588 589 /** 590 * Gets details for files in a directory or a specific file. 591 * 592 * @since 2.5.0 593 * 594 * @param string $path Path to directory or file. 595 * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. 596 * Default true. 597 * @param bool $recursive Optional. Whether to recursively include file details in nested directories. 598 * Default false. 599 * @return array|false { 600 * Array of arrays containing file information. False if unable to list directory contents. 601 * 602 * @type array ...$0 { 603 * Array of file information. Note that some elements may not be available on all filesystems. 604 * 605 * @type string $name Name of the file or directory. 606 * @type string $perms *nix representation of permissions. 607 * @type string $permsn Octal representation of permissions. 608 * @type false $number File number. Always false in this context. 609 * @type string|false $owner Owner name or ID, or false if not available. 610 * @type string|false $group File permissions group, or false if not available. 611 * @type int|string|false $size Size of file in bytes. May be a numeric string. 612 * False if not available. 613 * @type int|string|false $lastmodunix Last modified unix timestamp. May be a numeric string. 614 * False if not available. 615 * @type string|false $lastmod Last modified month (3 letters) and day (without leading 0), or 616 * false if not available. 617 * @type string|false $time Last modified time, or false if not available. 618 * @type string $type Type of resource. 'f' for file, 'd' for directory, 'l' for link. 619 * @type array|false $files If a directory and `$recursive` is true, contains another array of 620 * files. False if unable to list directory contents. 621 * } 622 * } 623 */ 624 public function dirlist( $path, $include_hidden = true, $recursive = false ) { 625 if ( $this->is_file( $path ) ) { 626 $limit_file = basename( $path ); 627 $path = dirname( $path ); 628 } else { 629 $limit_file = false; 630 } 631 632 if ( ! $this->is_dir( $path ) || ! $this->is_readable( $path ) ) { 633 return false; 634 } 635 636 $dir = dir( $path ); 637 638 if ( ! $dir ) { 639 return false; 640 } 641 642 $path = trailingslashit( $path ); 643 $ret = array(); 644 645 while ( false !== ( $entry = $dir->read() ) ) { 646 $struc = array(); 647 $struc['name'] = $entry; 648 649 if ( '.' === $struc['name'] || '..' === $struc['name'] ) { 650 continue; 651 } 652 653 if ( ! $include_hidden && '.' === $struc['name'][0] ) { 654 continue; 655 } 656 657 if ( $limit_file && $struc['name'] !== $limit_file ) { 658 continue; 659 } 660 661 $struc['perms'] = $this->gethchmod( $path . $entry ); 662 $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] ); 663 $struc['number'] = false; 664 $struc['owner'] = $this->owner( $path . $entry ); 665 $struc['group'] = $this->group( $path . $entry ); 666 $struc['size'] = $this->size( $path . $entry ); 667 $struc['lastmodunix'] = $this->mtime( $path . $entry ); 668 $struc['lastmod'] = gmdate( 'M j', $struc['lastmodunix'] ); 669 $struc['time'] = gmdate( 'h:i:s', $struc['lastmodunix'] ); 670 $struc['type'] = $this->is_dir( $path . $entry ) ? 'd' : 'f'; 671 672 if ( 'd' === $struc['type'] ) { 673 if ( $recursive ) { 674 $struc['files'] = $this->dirlist( $path . $struc['name'], $include_hidden, $recursive ); 675 } else { 676 $struc['files'] = array(); 677 } 678 } 679 680 $ret[ $struc['name'] ] = $struc; 681 } 682 683 $dir->close(); 684 unset( $dir ); 685 686 return $ret; 687 } 688 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |