| [ 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 * @since 2.5.0 253 * 254 * @param string $file Path to the file. 255 * @return string Mode of the file (the last 3 digits), or the string "0" on failure. 256 */ 257 public function getchmod( $file ) { 258 $perms = @fileperms( $file ); 259 if ( false === $perms ) { 260 return '0'; 261 } 262 263 return substr( decoct( $perms ), -3 ); 264 } 265 266 /** 267 * Gets the file's group. 268 * 269 * @since 2.5.0 270 * 271 * @param string $file Path to the file. 272 * @return string|false The group on success, false on failure. 273 */ 274 public function group( $file ) { 275 $gid = @filegroup( $file ); 276 277 if ( ! $gid ) { 278 return false; 279 } 280 281 if ( ! function_exists( 'posix_getgrgid' ) ) { 282 return $gid; 283 } 284 285 $grouparray = posix_getgrgid( $gid ); 286 287 if ( ! $grouparray ) { 288 return false; 289 } 290 291 return $grouparray['name']; 292 } 293 294 /** 295 * Copies a file. 296 * 297 * @since 2.5.0 298 * 299 * @param string $source Path to the source file. 300 * @param string $destination Path to the destination file. 301 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. 302 * Default false. 303 * @param int|false $mode Optional. The permissions as octal number, usually 0644 for files, 304 * 0755 for dirs. Default false. 305 * @return bool True on success, false on failure. 306 */ 307 public function copy( $source, $destination, $overwrite = false, $mode = false ) { 308 if ( ! $overwrite && $this->exists( $destination ) ) { 309 return false; 310 } 311 312 $rtval = copy( $source, $destination ); 313 314 if ( $mode ) { 315 $this->chmod( $destination, $mode ); 316 } 317 318 return $rtval; 319 } 320 321 /** 322 * Moves a file or directory. 323 * 324 * After moving files or directories, OPcache will need to be invalidated. 325 * 326 * If moving a directory fails, `copy_dir()` can be used for a recursive copy. 327 * 328 * Use `move_dir()` for moving directories with OPcache invalidation and a 329 * fallback to `copy_dir()`. 330 * 331 * @since 2.5.0 332 * 333 * @param string $source Path to the source file. 334 * @param string $destination Path to the destination file. 335 * @param bool $overwrite Optional. Whether to overwrite the destination file if it exists. 336 * Default false. 337 * @return bool True on success, false on failure. 338 */ 339 public function move( $source, $destination, $overwrite = false ) { 340 if ( ! $overwrite && $this->exists( $destination ) ) { 341 return false; 342 } 343 344 if ( $overwrite && $this->exists( $destination ) && ! $this->delete( $destination, true ) ) { 345 // Can't overwrite if the destination couldn't be deleted. 346 return false; 347 } 348 349 // Try using rename first. if that fails (for example, source is read only) try copy. 350 if ( @rename( $source, $destination ) ) { 351 return true; 352 } 353 354 // Backward compatibility: Only fall back to `::copy()` for single files. 355 if ( $this->is_file( $source ) && $this->copy( $source, $destination, $overwrite ) && $this->exists( $destination ) ) { 356 $this->delete( $source ); 357 358 return true; 359 } else { 360 return false; 361 } 362 } 363 364 /** 365 * Deletes a file or directory. 366 * 367 * @since 2.5.0 368 * 369 * @param string $file Path to the file or directory. 370 * @param bool $recursive Optional. If set to true, deletes files and folders recursively. 371 * Default false. 372 * @param string|false $type Type of resource. 'f' for file, 'd' for directory. 373 * Default false. 374 * @return bool True on success, false on failure. 375 */ 376 public function delete( $file, $recursive = false, $type = false ) { 377 if ( empty( $file ) ) { 378 // Some filesystems report this as /, which can cause non-expected recursive deletion of all files in the filesystem. 379 return false; 380 } 381 382 $file = str_replace( '\\', '/', $file ); // For Win32, occasional problems deleting files otherwise. 383 384 if ( 'f' === $type || $this->is_file( $file ) ) { 385 return @unlink( $file ); 386 } 387 388 if ( ! $recursive && $this->is_dir( $file ) ) { 389 return @rmdir( $file ); 390 } 391 392 // At this point it's a folder, and we're in recursive mode. 393 $file = trailingslashit( $file ); 394 $filelist = $this->dirlist( $file, true ); 395 396 $retval = true; 397 398 if ( is_array( $filelist ) ) { 399 foreach ( $filelist as $filename => $fileinfo ) { 400 if ( ! $this->delete( $file . $filename, $recursive, $fileinfo['type'] ) ) { 401 $retval = false; 402 } 403 } 404 } 405 406 if ( file_exists( $file ) && ! @rmdir( $file ) ) { 407 $retval = false; 408 } 409 410 return $retval; 411 } 412 413 /** 414 * Checks if a file or directory exists. 415 * 416 * @since 2.5.0 417 * 418 * @param string $path Path to file or directory. 419 * @return bool Whether $path exists or not. 420 */ 421 public function exists( $path ) { 422 return @file_exists( $path ); 423 } 424 425 /** 426 * Checks if resource is a file. 427 * 428 * @since 2.5.0 429 * 430 * @param string $file File path. 431 * @return bool Whether $file is a file. 432 */ 433 public function is_file( $file ) { 434 return @is_file( $file ); 435 } 436 437 /** 438 * Checks if resource is a directory. 439 * 440 * @since 2.5.0 441 * 442 * @param string $path Directory path. 443 * @return bool Whether $path is a directory. 444 */ 445 public function is_dir( $path ) { 446 return @is_dir( $path ); 447 } 448 449 /** 450 * Checks if a file is readable. 451 * 452 * @since 2.5.0 453 * 454 * @param string $file Path to file. 455 * @return bool Whether $file is readable. 456 */ 457 public function is_readable( $file ) { 458 return @is_readable( $file ); 459 } 460 461 /** 462 * Checks if a file or directory is writable. 463 * 464 * @since 2.5.0 465 * 466 * @param string $path Path to file or directory. 467 * @return bool Whether $path is writable. 468 */ 469 public function is_writable( $path ) { 470 return @is_writable( $path ); 471 } 472 473 /** 474 * Gets the file's last access time. 475 * 476 * @since 2.5.0 477 * 478 * @param string $file Path to file. 479 * @return int|false Unix timestamp representing last access time, false on failure. 480 */ 481 public function atime( $file ) { 482 return @fileatime( $file ); 483 } 484 485 /** 486 * Gets the file modification time. 487 * 488 * @since 2.5.0 489 * 490 * @param string $file Path to file. 491 * @return int|false Unix timestamp representing modification time, false on failure. 492 */ 493 public function mtime( $file ) { 494 return @filemtime( $file ); 495 } 496 497 /** 498 * Gets the file size (in bytes). 499 * 500 * @since 2.5.0 501 * 502 * @param string $file Path to file. 503 * @return int|false Size of the file in bytes on success, false on failure. 504 */ 505 public function size( $file ) { 506 return @filesize( $file ); 507 } 508 509 /** 510 * Sets the access and modification times of a file. 511 * 512 * Note: If $file doesn't exist, it will be created. 513 * 514 * @since 2.5.0 515 * 516 * @param string $file Path to file. 517 * @param int $time Optional. Modified time to set for file. 518 * Default 0. 519 * @param int $atime Optional. Access time to set for file. 520 * Default 0. 521 * @return bool True on success, false on failure. 522 */ 523 public function touch( $file, $time = 0, $atime = 0 ) { 524 if ( 0 === $time ) { 525 $time = time(); 526 } 527 528 if ( 0 === $atime ) { 529 $atime = time(); 530 } 531 532 return touch( $file, $time, $atime ); 533 } 534 535 /** 536 * Creates a directory. 537 * 538 * @since 2.5.0 539 * 540 * @param string $path Path for new directory. 541 * @param int|false $chmod Optional. The permissions as octal number (or false to skip chmod). 542 * Default false. 543 * @param string|int|false $chown Optional. A user name or number (or false to skip chown). 544 * Default false. 545 * @param string|int|false $chgrp Optional. A group name or number (or false to skip chgrp). 546 * Default false. 547 * @return bool True on success, false on failure. 548 */ 549 public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) { 550 // Safe mode fails with a trailing slash under certain PHP versions. 551 $path = untrailingslashit( $path ); 552 553 if ( empty( $path ) ) { 554 return false; 555 } 556 557 if ( ! $chmod ) { 558 $chmod = FS_CHMOD_DIR; 559 } 560 561 if ( ! @mkdir( $path ) ) { 562 return false; 563 } 564 565 $this->chmod( $path, $chmod ); 566 567 if ( $chown ) { 568 $this->chown( $path, $chown ); 569 } 570 571 if ( $chgrp ) { 572 $this->chgrp( $path, $chgrp ); 573 } 574 575 return true; 576 } 577 578 /** 579 * Deletes a directory. 580 * 581 * @since 2.5.0 582 * 583 * @param string $path Path to directory. 584 * @param bool $recursive Optional. Whether to recursively remove files/directories. 585 * Default false. 586 * @return bool True on success, false on failure. 587 */ 588 public function rmdir( $path, $recursive = false ) { 589 return $this->delete( $path, $recursive ); 590 } 591 592 /** 593 * Gets details for files in a directory or a specific file. 594 * 595 * @since 2.5.0 596 * 597 * @param string $path Path to directory or file. 598 * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. 599 * Default true. 600 * @param bool $recursive Optional. Whether to recursively include file details in nested directories. 601 * Default false. 602 * @return array|false { 603 * Array of arrays containing file information. False if unable to list directory contents. 604 * 605 * @type array ...$0 { 606 * Array of file information. Note that some elements may not be available on all filesystems. 607 * 608 * @type string $name Name of the file or directory. 609 * @type string $perms *nix representation of permissions. 610 * @type string $permsn Octal representation of permissions. 611 * @type false $number File number. Always false in this context. 612 * @type string|false $owner Owner name or ID, or false if not available. 613 * @type string|false $group File permissions group, or false if not available. 614 * @type int|string|false $size Size of file in bytes. May be a numeric string. 615 * False if not available. 616 * @type int|string|false $lastmodunix Last modified unix timestamp. May be a numeric string. 617 * False if not available. 618 * @type string|false $lastmod Last modified month (3 letters) and day (without leading 0), or 619 * false if not available. 620 * @type string|false $time Last modified time, or false if not available. 621 * @type string $type Type of resource. 'f' for file, 'd' for directory, 'l' for link. 622 * @type array|false $files If a directory and `$recursive` is true, contains another array of 623 * files. False if unable to list directory contents. 624 * } 625 * } 626 */ 627 public function dirlist( $path, $include_hidden = true, $recursive = false ) { 628 if ( $this->is_file( $path ) ) { 629 $limit_file = basename( $path ); 630 $path = dirname( $path ); 631 } else { 632 $limit_file = false; 633 } 634 635 if ( ! $this->is_dir( $path ) || ! $this->is_readable( $path ) ) { 636 return false; 637 } 638 639 $dir = dir( $path ); 640 641 if ( ! $dir ) { 642 return false; 643 } 644 645 $path = trailingslashit( $path ); 646 $ret = array(); 647 648 while ( false !== ( $entry = $dir->read() ) ) { 649 $struc = array(); 650 $struc['name'] = $entry; 651 652 if ( '.' === $struc['name'] || '..' === $struc['name'] ) { 653 continue; 654 } 655 656 if ( ! $include_hidden && '.' === $struc['name'][0] ) { 657 continue; 658 } 659 660 if ( $limit_file && $struc['name'] !== $limit_file ) { 661 continue; 662 } 663 664 $struc['perms'] = $this->gethchmod( $path . $entry ); 665 $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] ); 666 $struc['number'] = false; 667 $struc['owner'] = $this->owner( $path . $entry ); 668 $struc['group'] = $this->group( $path . $entry ); 669 $struc['size'] = $this->size( $path . $entry ); 670 $struc['lastmodunix'] = $this->mtime( $path . $entry ); 671 $struc['lastmod'] = gmdate( 'M j', $struc['lastmodunix'] ); 672 $struc['time'] = gmdate( 'h:i:s', $struc['lastmodunix'] ); 673 $struc['type'] = $this->is_dir( $path . $entry ) ? 'd' : 'f'; 674 675 if ( 'd' === $struc['type'] ) { 676 if ( $recursive ) { 677 $struc['files'] = $this->dirlist( $path . $struc['name'], $include_hidden, $recursive ); 678 } else { 679 $struc['files'] = array(); 680 } 681 } 682 683 $ret[ $struc['name'] ] = $struc; 684 } 685 686 $dir->close(); 687 unset( $dir ); 688 689 return $ret; 690 } 691 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sun Jan 18 08:20:04 2026 | Cross-referenced by PHPXref |