[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

title

Body

[close]

/wp-admin/includes/ -> class-wp-filesystem-ftpsockets.php (source)

   1  <?php
   2  /**
   3   * WordPress FTP Sockets Filesystem.
   4   *
   5   * @package WordPress
   6   * @subpackage Filesystem
   7   */
   8  
   9  /**
  10   * WordPress Filesystem Class for implementing FTP Sockets.
  11   *
  12   * @since 2.5.0
  13   *
  14   * @see WP_Filesystem_Base
  15   */
  16  class WP_Filesystem_ftpsockets extends WP_Filesystem_Base {
  17  
  18      /**
  19       * @since 2.5.0
  20       * @var ftp
  21       */
  22      public $ftp;
  23  
  24      /**
  25       * Constructor.
  26       *
  27       * @since 2.5.0
  28       *
  29       * @param array $opt
  30       */
  31  	public function __construct( $opt = '' ) {
  32          $this->method = 'ftpsockets';
  33          $this->errors = new WP_Error();
  34  
  35          // Check if possible to use ftp functions.
  36          if ( ! include_once ( ABSPATH . 'wp-admin/includes/class-ftp.php' ) ) {
  37              return;
  38          }
  39          $this->ftp = new ftp();
  40  
  41          if ( empty( $opt['port'] ) ) {
  42              $this->options['port'] = 21;
  43          } else {
  44              $this->options['port'] = (int) $opt['port'];
  45          }
  46  
  47          if ( empty( $opt['hostname'] ) ) {
  48              $this->errors->add( 'empty_hostname', __( 'FTP hostname is required' ) );
  49          } else {
  50              $this->options['hostname'] = $opt['hostname'];
  51          }
  52  
  53          // Check if the options provided are OK.
  54          if ( empty( $opt['username'] ) ) {
  55              $this->errors->add( 'empty_username', __( 'FTP username is required' ) );
  56          } else {
  57              $this->options['username'] = $opt['username'];
  58          }
  59  
  60          if ( empty( $opt['password'] ) ) {
  61              $this->errors->add( 'empty_password', __( 'FTP password is required' ) );
  62          } else {
  63              $this->options['password'] = $opt['password'];
  64          }
  65      }
  66  
  67      /**
  68       * Connects filesystem.
  69       *
  70       * @since 2.5.0
  71       *
  72       * @return bool True on success, false on failure.
  73       */
  74  	public function connect() {
  75          if ( ! $this->ftp ) {
  76              return false;
  77          }
  78  
  79          $this->ftp->setTimeout( FS_CONNECT_TIMEOUT );
  80  
  81          if ( ! $this->ftp->SetServer( $this->options['hostname'], $this->options['port'] ) ) {
  82              $this->errors->add(
  83                  'connect',
  84                  sprintf(
  85                      /* translators: %s: hostname:port */
  86                      __( 'Failed to connect to FTP Server %s' ),
  87                      $this->options['hostname'] . ':' . $this->options['port']
  88                  )
  89              );
  90              return false;
  91          }
  92  
  93          if ( ! $this->ftp->connect() ) {
  94              $this->errors->add(
  95                  'connect',
  96                  sprintf(
  97                      /* translators: %s: hostname:port */
  98                      __( 'Failed to connect to FTP Server %s' ),
  99                      $this->options['hostname'] . ':' . $this->options['port']
 100                  )
 101              );
 102              return false;
 103          }
 104  
 105          if ( ! $this->ftp->login( $this->options['username'], $this->options['password'] ) ) {
 106              $this->errors->add(
 107                  'auth',
 108                  sprintf(
 109                      /* translators: %s: Username. */
 110                      __( 'Username/Password incorrect for %s' ),
 111                      $this->options['username']
 112                  )
 113              );
 114              return false;
 115          }
 116  
 117          $this->ftp->SetType( FTP_BINARY );
 118          $this->ftp->Passive( true );
 119          $this->ftp->setTimeout( FS_TIMEOUT );
 120          return true;
 121      }
 122  
 123      /**
 124       * Reads entire file into a string.
 125       *
 126       * @since 2.5.0
 127       *
 128       * @param string $file Name of the file to read.
 129       * @return string|false Read data on success, false if no temporary file could be opened,
 130       *                      or if the file couldn't be retrieved.
 131       */
 132  	public function get_contents( $file ) {
 133          if ( ! $this->exists( $file ) ) {
 134              return false;
 135          }
 136  
 137          $temp = wp_tempnam( $file );
 138  
 139          $temphandle = fopen( $temp, 'w+' );
 140          if ( ! $temphandle ) {
 141              unlink( $temp );
 142              return false;
 143          }
 144  
 145          mbstring_binary_safe_encoding();
 146  
 147          if ( ! $this->ftp->fget( $temphandle, $file ) ) {
 148              fclose( $temphandle );
 149              unlink( $temp );
 150  
 151              reset_mbstring_encoding();
 152  
 153              return ''; // Blank document, File does exist, It's just blank.
 154          }
 155  
 156          reset_mbstring_encoding();
 157  
 158          fseek( $temphandle, 0 ); // Skip back to the start of the file being written to
 159          $contents = '';
 160  
 161          while ( ! feof( $temphandle ) ) {
 162              $contents .= fread( $temphandle, 8 * KB_IN_BYTES );
 163          }
 164  
 165          fclose( $temphandle );
 166          unlink( $temp );
 167          return $contents;
 168      }
 169  
 170      /**
 171       * Reads entire file into an array.
 172       *
 173       * @since 2.5.0
 174       *
 175       * @param string $file Path to the file.
 176       * @return array|false File contents in an array on success, false on failure.
 177       */
 178  	public function get_contents_array( $file ) {
 179          return explode( "\n", $this->get_contents( $file ) );
 180      }
 181  
 182      /**
 183       * Writes a string to a file.
 184       *
 185       * @since 2.5.0
 186       *
 187       * @param string    $file     Remote path to the file where to write the data.
 188       * @param string    $contents The data to write.
 189       * @param int|false $mode     Optional. The file permissions as octal number, usually 0644.
 190       *                            Default false.
 191       * @return bool True on success, false on failure.
 192       */
 193  	public function put_contents( $file, $contents, $mode = false ) {
 194          $temp       = wp_tempnam( $file );
 195          $temphandle = @fopen( $temp, 'w+' );
 196          if ( ! $temphandle ) {
 197              unlink( $temp );
 198              return false;
 199          }
 200  
 201          // The FTP class uses string functions internally during file download/upload
 202          mbstring_binary_safe_encoding();
 203  
 204          $bytes_written = fwrite( $temphandle, $contents );
 205          if ( false === $bytes_written || $bytes_written != strlen( $contents ) ) {
 206              fclose( $temphandle );
 207              unlink( $temp );
 208  
 209              reset_mbstring_encoding();
 210  
 211              return false;
 212          }
 213  
 214          fseek( $temphandle, 0 ); // Skip back to the start of the file being written to
 215  
 216          $ret = $this->ftp->fput( $file, $temphandle );
 217  
 218          reset_mbstring_encoding();
 219  
 220          fclose( $temphandle );
 221          unlink( $temp );
 222  
 223          $this->chmod( $file, $mode );
 224  
 225          return $ret;
 226      }
 227  
 228      /**
 229       * Gets the current working directory.
 230       *
 231       * @since 2.5.0
 232       *
 233       * @return string|false The current working directory on success, false on failure.
 234       */
 235  	public function cwd() {
 236          $cwd = $this->ftp->pwd();
 237          if ( $cwd ) {
 238              $cwd = trailingslashit( $cwd );
 239          }
 240          return $cwd;
 241      }
 242  
 243      /**
 244       * Changes current directory.
 245       *
 246       * @since 2.5.0
 247       *
 248       * @param string $dir The new current directory.
 249       * @return bool True on success, false on failure.
 250       */
 251  	public function chdir( $dir ) {
 252          return $this->ftp->chdir( $dir );
 253      }
 254  
 255      /**
 256       * Changes filesystem permissions.
 257       *
 258       * @since 2.5.0
 259       *
 260       * @param string    $file      Path to the file.
 261       * @param int|false $mode      Optional. The permissions as octal number, usually 0644 for files,
 262       *                             0755 for directories. Default false.
 263       * @param bool      $recursive Optional. If set to true, changes file group recursively.
 264       *                             Default false.
 265       * @return bool True on success, false on failure.
 266       */
 267  	public function chmod( $file, $mode = false, $recursive = false ) {
 268          if ( ! $mode ) {
 269              if ( $this->is_file( $file ) ) {
 270                  $mode = FS_CHMOD_FILE;
 271              } elseif ( $this->is_dir( $file ) ) {
 272                  $mode = FS_CHMOD_DIR;
 273              } else {
 274                  return false;
 275              }
 276          }
 277  
 278          // chmod any sub-objects if recursive.
 279          if ( $recursive && $this->is_dir( $file ) ) {
 280              $filelist = $this->dirlist( $file );
 281              foreach ( (array) $filelist as $filename => $filemeta ) {
 282                  $this->chmod( $file . '/' . $filename, $mode, $recursive );
 283              }
 284          }
 285  
 286          // chmod the file or directory
 287          return $this->ftp->chmod( $file, $mode );
 288      }
 289  
 290      /**
 291       * Gets the file owner.
 292       *
 293       * @since 2.5.0
 294       *
 295       * @param string $file Path to the file.
 296       * @return string|false Username of the owner on success, false on failure.
 297       */
 298  	public function owner( $file ) {
 299          $dir = $this->dirlist( $file );
 300          return $dir[ $file ]['owner'];
 301      }
 302  
 303      /**
 304       * Gets the permissions of the specified file or filepath in their octal format.
 305       *
 306       * @since 2.5.0
 307       *
 308       * @param string $file Path to the file.
 309       * @return string Mode of the file (the last 3 digits).
 310       */
 311  	public function getchmod( $file ) {
 312          $dir = $this->dirlist( $file );
 313          return $dir[ $file ]['permsn'];
 314      }
 315  
 316      /**
 317       * Gets the file's group.
 318       *
 319       * @since 2.5.0
 320       *
 321       * @param string $file Path to the file.
 322       * @return string|false The group on success, false on failure.
 323       */
 324  	public function group( $file ) {
 325          $dir = $this->dirlist( $file );
 326          return $dir[ $file ]['group'];
 327      }
 328  
 329      /**
 330       * Copies a file.
 331       *
 332       * @since 2.5.0
 333       *
 334       * @param string    $source      Path to the source file.
 335       * @param string    $destination Path to the destination file.
 336       * @param bool      $overwrite   Optional. Whether to overwrite the destination file if it exists.
 337       *                               Default false.
 338       * @param int|false $mode        Optional. The permissions as octal number, usually 0644 for files,
 339       *                               0755 for dirs. Default false.
 340       * @return bool True on success, false on failure.
 341       */
 342  	public function copy( $source, $destination, $overwrite = false, $mode = false ) {
 343          if ( ! $overwrite && $this->exists( $destination ) ) {
 344              return false;
 345          }
 346  
 347          $content = $this->get_contents( $source );
 348          if ( false === $content ) {
 349              return false;
 350          }
 351  
 352          return $this->put_contents( $destination, $content, $mode );
 353      }
 354  
 355      /**
 356       * Moves a file.
 357       *
 358       * @since 2.5.0
 359       *
 360       * @param string $source      Path to the source file.
 361       * @param string $destination Path to the destination file.
 362       * @param bool   $overwrite   Optional. Whether to overwrite the destination file if it exists.
 363       *                            Default false.
 364       * @return bool True on success, false on failure.
 365       */
 366  	public function move( $source, $destination, $overwrite = false ) {
 367          return $this->ftp->rename( $source, $destination );
 368      }
 369  
 370      /**
 371       * Deletes a file or directory.
 372       *
 373       * @since 2.5.0
 374       *
 375       * @param string       $file      Path to the file or directory.
 376       * @param bool         $recursive Optional. If set to true, changes file group recursively.
 377       *                                Default false.
 378       * @param string|false $type      Type of resource. 'f' for file, 'd' for directory.
 379       *                                Default false.
 380       * @return bool True on success, false on failure.
 381       */
 382  	public function delete( $file, $recursive = false, $type = false ) {
 383          if ( empty( $file ) ) {
 384              return false;
 385          }
 386          if ( 'f' == $type || $this->is_file( $file ) ) {
 387              return $this->ftp->delete( $file );
 388          }
 389          if ( ! $recursive ) {
 390              return $this->ftp->rmdir( $file );
 391          }
 392  
 393          return $this->ftp->mdel( $file );
 394      }
 395  
 396      /**
 397       * Checks if a file or directory exists.
 398       *
 399       * @since 2.5.0
 400       *
 401       * @param string $file Path to file or directory.
 402       * @return bool Whether $file exists or not.
 403       */
 404  	public function exists( $file ) {
 405          $list = $this->ftp->nlist( $file );
 406  
 407          if ( empty( $list ) && $this->is_dir( $file ) ) {
 408              return true; // File is an empty directory.
 409          }
 410  
 411          return ! empty( $list ); //empty list = no file, so invert.
 412          // Return $this->ftp->is_exists($file); has issues with ABOR+426 responses on the ncFTPd server.
 413      }
 414  
 415      /**
 416       * Checks if resource is a file.
 417       *
 418       * @since 2.5.0
 419       *
 420       * @param string $file File path.
 421       * @return bool Whether $file is a file.
 422       */
 423  	public function is_file( $file ) {
 424          if ( $this->is_dir( $file ) ) {
 425              return false;
 426          }
 427          if ( $this->exists( $file ) ) {
 428              return true;
 429          }
 430          return false;
 431      }
 432  
 433      /**
 434       * Checks if resource is a directory.
 435       *
 436       * @since 2.5.0
 437       *
 438       * @param string $path Directory path.
 439       * @return bool Whether $path is a directory.
 440       */
 441  	public function is_dir( $path ) {
 442          $cwd = $this->cwd();
 443          if ( $this->chdir( $path ) ) {
 444              $this->chdir( $cwd );
 445              return true;
 446          }
 447          return false;
 448      }
 449  
 450      /**
 451       * Checks if a file is readable.
 452       *
 453       * @since 2.5.0
 454       *
 455       * @param string $file Path to file.
 456       * @return bool Whether $file is readable.
 457       */
 458  	public function is_readable( $file ) {
 459          return true;
 460      }
 461  
 462      /**
 463       * Checks if a file or directory is writable.
 464       *
 465       * @since 2.5.0
 466       *
 467       * @param string $file Path to file or directory.
 468       * @return bool Whether $file is writable.
 469       */
 470  	public function is_writable( $file ) {
 471          return true;
 472      }
 473  
 474      /**
 475       * Gets the file's last access time.
 476       *
 477       * @since 2.5.0
 478       *
 479       * @param string $file Path to file.
 480       * @return int|false Unix timestamp representing last access time, false on failure.
 481       */
 482  	public function atime( $file ) {
 483          return false;
 484      }
 485  
 486      /**
 487       * Gets the file modification time.
 488       *
 489       * @since 2.5.0
 490       *
 491       * @param string $file Path to file.
 492       * @return int|false Unix timestamp representing modification time, false on failure.
 493       */
 494  	public function mtime( $file ) {
 495          return $this->ftp->mdtm( $file );
 496      }
 497  
 498      /**
 499       * Gets the file size (in bytes).
 500       *
 501       * @since 2.5.0
 502       *
 503       * @param string $file Path to file.
 504       * @return int|false Size of the file in bytes on success, false on failure.
 505       */
 506  	public function size( $file ) {
 507          return $this->ftp->filesize( $file );
 508      }
 509  
 510      /**
 511       * Sets the access and modification times of a file.
 512       *
 513       * Note: If $file doesn't exist, it will be created.
 514       *
 515       * @since 2.5.0
 516       *
 517       * @param string $file  Path to file.
 518       * @param int    $time  Optional. Modified time to set for file.
 519       *                      Default 0.
 520       * @param int    $atime Optional. Access time to set for file.
 521       *                      Default 0.
 522       * @return bool True on success, false on failure.
 523       */
 524  	public function touch( $file, $time = 0, $atime = 0 ) {
 525          return false;
 526      }
 527  
 528      /**
 529       * Creates a directory.
 530       *
 531       * @since 2.5.0
 532       *
 533       * @param string     $path  Path for new directory.
 534       * @param int|false  $chmod Optional. The permissions as octal number (or false to skip chmod).
 535       *                          Default false.
 536       * @param string|int $chown Optional. A user name or number (or false to skip chown).
 537       *                          Default false.
 538       * @param string|int $chgrp Optional. A group name or number (or false to skip chgrp).
 539       *                          Default false.
 540       * @return bool True on success, false on failure.
 541       */
 542  	public function mkdir( $path, $chmod = false, $chown = false, $chgrp = false ) {
 543          $path = untrailingslashit( $path );
 544          if ( empty( $path ) ) {
 545              return false;
 546          }
 547  
 548          if ( ! $this->ftp->mkdir( $path ) ) {
 549              return false;
 550          }
 551          if ( ! $chmod ) {
 552              $chmod = FS_CHMOD_DIR;
 553          }
 554          $this->chmod( $path, $chmod );
 555          return true;
 556      }
 557  
 558      /**
 559       * Deletes a directory.
 560       *
 561       * @since 2.5.0
 562       *
 563       * @param string $path      Path to directory.
 564       * @param bool   $recursive Optional. Whether to recursively remove files/directories.
 565       *                          Default false.
 566       * @return bool True on success, false on failure.
 567       */
 568  	public function rmdir( $path, $recursive = false ) {
 569          return $this->delete( $path, $recursive );
 570      }
 571  
 572      /**
 573       * Gets details for files in a directory or a specific file.
 574       *
 575       * @since 2.5.0
 576       *
 577       * @param string $path           Path to directory or file.
 578       * @param bool   $include_hidden Optional. Whether to include details of hidden ("." prefixed) files.
 579       *                               Default true.
 580       * @param bool   $recursive      Optional. Whether to recursively include file details in nested directories.
 581       *                               Default false.
 582       * @return array|false {
 583       *     Array of files. False if unable to list directory contents.
 584       *
 585       *     @type string $name        Name of the file or directory.
 586       *     @type string $perms       *nix representation of permissions.
 587       *     @type int    $permsn      Octal representation of permissions.
 588       *     @type string $owner       Owner name or ID.
 589       *     @type int    $size        Size of file in bytes.
 590       *     @type int    $lastmodunix Last modified unix timestamp.
 591       *     @type mixed  $lastmod     Last modified month (3 letter) and day (without leading 0).
 592       *     @type int    $time        Last modified time.
 593       *     @type string $type        Type of resource. 'f' for file, 'd' for directory.
 594       *     @type mixed  $files       If a directory and $recursive is true, contains another array of files.
 595       * }
 596       */
 597  	public function dirlist( $path = '.', $include_hidden = true, $recursive = false ) {
 598          if ( $this->is_file( $path ) ) {
 599              $limit_file = basename( $path );
 600              $path       = dirname( $path ) . '/';
 601          } else {
 602              $limit_file = false;
 603          }
 604  
 605          mbstring_binary_safe_encoding();
 606  
 607          $list = $this->ftp->dirlist( $path );
 608          if ( empty( $list ) && ! $this->exists( $path ) ) {
 609  
 610              reset_mbstring_encoding();
 611  
 612              return false;
 613          }
 614  
 615          $ret = array();
 616          foreach ( $list as $struc ) {
 617  
 618              if ( '.' == $struc['name'] || '..' == $struc['name'] ) {
 619                  continue;
 620              }
 621  
 622              if ( ! $include_hidden && '.' == $struc['name'][0] ) {
 623                  continue;
 624              }
 625  
 626              if ( $limit_file && $struc['name'] != $limit_file ) {
 627                  continue;
 628              }
 629  
 630              if ( 'd' == $struc['type'] ) {
 631                  if ( $recursive ) {
 632                      $struc['files'] = $this->dirlist( $path . '/' . $struc['name'], $include_hidden, $recursive );
 633                  } else {
 634                      $struc['files'] = array();
 635                  }
 636              }
 637  
 638              // Replace symlinks formatted as "source -> target" with just the source name
 639              if ( $struc['islink'] ) {
 640                  $struc['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $struc['name'] );
 641              }
 642  
 643              // Add the Octal representation of the file permissions
 644              $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] );
 645  
 646              $ret[ $struc['name'] ] = $struc;
 647          }
 648  
 649          reset_mbstring_encoding();
 650  
 651          return $ret;
 652      }
 653  
 654      /**
 655       * Destructor.
 656       *
 657       * @since 2.5.0
 658       */
 659  	public function __destruct() {
 660          $this->ftp->quit();
 661      }
 662  }


Generated: Fri Oct 25 08:20:01 2019 Cross-referenced by PHPXref 0.7