home *** CD-ROM | disk | FTP | other *** search
/ HTML Examples / WP.iso / wordpress / wp-admin / includes / class-wp-filesystem-ftpsockets.php < prev    next >
Encoding:
PHP Script  |  2017-07-26  |  10.3 KB  |  518 lines

  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.      * @var ftp
  19.      */
  20.     public $ftp;
  21.  
  22.     /**
  23.      *
  24.      * @param array $opt
  25.      */
  26.     public function __construct( $opt  = '' ) {
  27.         $this->method = 'ftpsockets';
  28.         $this->errors = new WP_Error();
  29.  
  30.         // Check if possible to use ftp functions.
  31.         if ( ! @include_once( ABSPATH . 'wp-admin/includes/class-ftp.php' ) ) {
  32.             return;
  33.         }
  34.         $this->ftp = new ftp();
  35.  
  36.         if ( empty($opt['port']) )
  37.             $this->options['port'] = 21;
  38.         else
  39.             $this->options['port'] = (int) $opt['port'];
  40.  
  41.         if ( empty($opt['hostname']) )
  42.             $this->errors->add('empty_hostname', __('FTP hostname is required'));
  43.         else
  44.             $this->options['hostname'] = $opt['hostname'];
  45.  
  46.         // Check if the options provided are OK.
  47.         if ( empty ($opt['username']) )
  48.             $this->errors->add('empty_username', __('FTP username is required'));
  49.         else
  50.             $this->options['username'] = $opt['username'];
  51.  
  52.         if ( empty ($opt['password']) )
  53.             $this->errors->add('empty_password', __('FTP password is required'));
  54.         else
  55.             $this->options['password'] = $opt['password'];
  56.     }
  57.  
  58.     /**
  59.      *
  60.      * @return bool
  61.      */
  62.     public function connect() {
  63.         if ( ! $this->ftp )
  64.             return false;
  65.  
  66.         $this->ftp->setTimeout(FS_CONNECT_TIMEOUT);
  67.  
  68.         if ( ! $this->ftp->SetServer( $this->options['hostname'], $this->options['port'] ) ) {
  69.             $this->errors->add( 'connect',
  70.                 /* translators: %s: hostname:port */
  71.                 sprintf( __( 'Failed to connect to FTP Server %s' ),
  72.                     $this->options['hostname'] . ':' . $this->options['port']
  73.                 )
  74.             );
  75.             return false;
  76.         }
  77.  
  78.         if ( ! $this->ftp->connect() ) {
  79.             $this->errors->add( 'connect',
  80.                 /* translators: %s: hostname:port */
  81.                 sprintf( __( 'Failed to connect to FTP Server %s' ),
  82.                     $this->options['hostname'] . ':' . $this->options['port']
  83.                 )
  84.             );
  85.             return false;
  86.         }
  87.  
  88.         if ( ! $this->ftp->login( $this->options['username'], $this->options['password'] ) ) {
  89.             $this->errors->add( 'auth',
  90.                 /* translators: %s: username */
  91.                 sprintf( __( 'Username/Password incorrect for %s' ),
  92.                     $this->options['username']
  93.                 )
  94.             );
  95.             return false;
  96.         }
  97.  
  98.         $this->ftp->SetType( FTP_BINARY );
  99.         $this->ftp->Passive( true );
  100.         $this->ftp->setTimeout( FS_TIMEOUT );
  101.         return true;
  102.     }
  103.  
  104.     /**
  105.      * Retrieves the file contents.
  106.      *
  107.      * @since 2.5.0
  108.      *
  109.      * @param string $file Filename.
  110.      * @return string|false File contents on success, false if no temp file could be opened,
  111.      *                      or if the file doesn't exist.
  112.      */
  113.     public function get_contents( $file ) {
  114.         if ( ! $this->exists($file) )
  115.             return false;
  116.  
  117.         $temp = wp_tempnam( $file );
  118.  
  119.         if ( ! $temphandle = fopen( $temp, 'w+' ) ) {
  120.             unlink( $temp );
  121.             return false;
  122.         }
  123.  
  124.         mbstring_binary_safe_encoding();
  125.  
  126.         if ( ! $this->ftp->fget($temphandle, $file) ) {
  127.             fclose($temphandle);
  128.             unlink($temp);
  129.  
  130.             reset_mbstring_encoding();
  131.  
  132.             return ''; // Blank document, File does exist, It's just blank.
  133.         }
  134.  
  135.         reset_mbstring_encoding();
  136.  
  137.         fseek( $temphandle, 0 ); // Skip back to the start of the file being written to
  138.         $contents = '';
  139.  
  140.         while ( ! feof($temphandle) )
  141.             $contents .= fread($temphandle, 8192);
  142.  
  143.         fclose($temphandle);
  144.         unlink($temp);
  145.         return $contents;
  146.     }
  147.  
  148.     /**
  149.      *
  150.      * @param string $file
  151.      * @return array
  152.      */
  153.     public function get_contents_array($file) {
  154.         return explode("\n", $this->get_contents($file) );
  155.     }
  156.  
  157.     /**
  158.      *
  159.      * @param string $file
  160.      * @param string $contents
  161.      * @param int|bool $mode
  162.      * @return bool
  163.      */
  164.     public function put_contents($file, $contents, $mode = false ) {
  165.         $temp = wp_tempnam( $file );
  166.         if ( ! $temphandle = @fopen($temp, 'w+') ) {
  167.             unlink($temp);
  168.             return false;
  169.         }
  170.  
  171.         // The FTP class uses string functions internally during file download/upload
  172.         mbstring_binary_safe_encoding();
  173.  
  174.         $bytes_written = fwrite( $temphandle, $contents );
  175.         if ( false === $bytes_written || $bytes_written != strlen( $contents ) ) {
  176.             fclose( $temphandle );
  177.             unlink( $temp );
  178.  
  179.             reset_mbstring_encoding();
  180.  
  181.             return false;
  182.         }
  183.  
  184.         fseek( $temphandle, 0 ); // Skip back to the start of the file being written to
  185.  
  186.         $ret = $this->ftp->fput($file, $temphandle);
  187.  
  188.         reset_mbstring_encoding();
  189.  
  190.         fclose($temphandle);
  191.         unlink($temp);
  192.  
  193.         $this->chmod($file, $mode);
  194.  
  195.         return $ret;
  196.     }
  197.  
  198.     /**
  199.      *
  200.      * @return string
  201.      */
  202.     public function cwd() {
  203.         $cwd = $this->ftp->pwd();
  204.         if ( $cwd )
  205.             $cwd = trailingslashit($cwd);
  206.         return $cwd;
  207.     }
  208.  
  209.     /**
  210.      *
  211.      * @param string $file
  212.      * @return bool
  213.      */
  214.     public function chdir($file) {
  215.         return $this->ftp->chdir($file);
  216.     }
  217.  
  218.     /**
  219.      *
  220.      * @param string $file
  221.      * @param int|bool $mode
  222.      * @param bool $recursive
  223.      * @return bool
  224.      */
  225.     public function chmod($file, $mode = false, $recursive = false ) {
  226.         if ( ! $mode ) {
  227.             if ( $this->is_file($file) )
  228.                 $mode = FS_CHMOD_FILE;
  229.             elseif ( $this->is_dir($file) )
  230.                 $mode = FS_CHMOD_DIR;
  231.             else
  232.                 return false;
  233.         }
  234.  
  235.         // chmod any sub-objects if recursive.
  236.         if ( $recursive && $this->is_dir($file) ) {
  237.             $filelist = $this->dirlist($file);
  238.             foreach ( (array)$filelist as $filename => $filemeta )
  239.                 $this->chmod($file . '/' . $filename, $mode, $recursive);
  240.         }
  241.  
  242.         // chmod the file or directory
  243.         return $this->ftp->chmod($file, $mode);
  244.     }
  245.  
  246.     /**
  247.      *
  248.      * @param string $file
  249.      * @return string
  250.      */
  251.     public function owner($file) {
  252.         $dir = $this->dirlist($file);
  253.         return $dir[$file]['owner'];
  254.     }
  255.  
  256.     /**
  257.      *
  258.      * @param string $file
  259.      * @return string
  260.      */
  261.     public function getchmod($file) {
  262.         $dir = $this->dirlist($file);
  263.         return $dir[$file]['permsn'];
  264.     }
  265.  
  266.     /**
  267.      *
  268.      * @param string $file
  269.      * @return string
  270.      */
  271.     public function group($file) {
  272.         $dir = $this->dirlist($file);
  273.         return $dir[$file]['group'];
  274.     }
  275.  
  276.     /**
  277.      *
  278.      * @param string   $source
  279.      * @param string   $destination
  280.      * @param bool     $overwrite
  281.      * @param int|bool $mode
  282.      * @return bool
  283.      */
  284.     public function copy($source, $destination, $overwrite = false, $mode = false) {
  285.         if ( ! $overwrite && $this->exists($destination) )
  286.             return false;
  287.  
  288.         $content = $this->get_contents($source);
  289.         if ( false === $content )
  290.             return false;
  291.  
  292.         return $this->put_contents($destination, $content, $mode);
  293.     }
  294.  
  295.     /**
  296.      *
  297.      * @param string $source
  298.      * @param string $destination
  299.      * @param bool   $overwrite
  300.      * @return bool
  301.      */
  302.     public function move($source, $destination, $overwrite = false ) {
  303.         return $this->ftp->rename($source, $destination);
  304.     }
  305.  
  306.     /**
  307.      *
  308.      * @param string $file
  309.      * @param bool   $recursive
  310.      * @param string $type
  311.      * @return bool
  312.      */
  313.     public function delete($file, $recursive = false, $type = false) {
  314.         if ( empty($file) )
  315.             return false;
  316.         if ( 'f' == $type || $this->is_file($file) )
  317.             return $this->ftp->delete($file);
  318.         if ( !$recursive )
  319.             return $this->ftp->rmdir($file);
  320.  
  321.         return $this->ftp->mdel($file);
  322.     }
  323.  
  324.     /**
  325.      *
  326.      * @param string $file
  327.      * @return bool
  328.      */
  329.     public function exists( $file ) {
  330.         $list = $this->ftp->nlist( $file );
  331.  
  332.         if ( empty( $list ) && $this->is_dir( $file ) ) {
  333.             return true; // File is an empty directory.
  334.         }
  335.  
  336.         return !empty( $list ); //empty list = no file, so invert.
  337.         // Return $this->ftp->is_exists($file); has issues with ABOR+426 responses on the ncFTPd server.
  338.     }
  339.  
  340.     /**
  341.      *
  342.      * @param string $file
  343.      * @return bool
  344.      */
  345.     public function is_file($file) {
  346.         if ( $this->is_dir($file) )
  347.             return false;
  348.         if ( $this->exists($file) )
  349.             return true;
  350.         return false;
  351.     }
  352.  
  353.     /**
  354.      *
  355.      * @param string $path
  356.      * @return bool
  357.      */
  358.     public function is_dir($path) {
  359.         $cwd = $this->cwd();
  360.         if ( $this->chdir($path) ) {
  361.             $this->chdir($cwd);
  362.             return true;
  363.         }
  364.         return false;
  365.     }
  366.  
  367.     /**
  368.      *
  369.      * @param string $file
  370.      * @return bool
  371.      */
  372.     public function is_readable($file) {
  373.         return true;
  374.     }
  375.  
  376.     /**
  377.      *
  378.      * @param string $file
  379.      * @return bool
  380.      */
  381.     public function is_writable($file) {
  382.         return true;
  383.     }
  384.  
  385.     /**
  386.      *
  387.      * @param string $file
  388.      * @return bool
  389.      */
  390.     public function atime($file) {
  391.         return false;
  392.     }
  393.  
  394.     /**
  395.      *
  396.      * @param string $file
  397.      * @return int
  398.      */
  399.     public function mtime($file) {
  400.         return $this->ftp->mdtm($file);
  401.     }
  402.  
  403.     /**
  404.      * @param string $file
  405.      * @return int
  406.      */
  407.     public function size($file) {
  408.         return $this->ftp->filesize($file);
  409.     }
  410.  
  411.     /**
  412.      *
  413.      * @param string $file
  414.      * @param int $time
  415.      * @param int $atime
  416.      * @return bool
  417.      */
  418.     public function touch($file, $time = 0, $atime = 0 ) {
  419.         return false;
  420.     }
  421.  
  422.     /**
  423.      *
  424.      * @param string $path
  425.      * @param mixed  $chmod
  426.      * @param mixed  $chown
  427.      * @param mixed  $chgrp
  428.      * @return bool
  429.      */
  430.     public function mkdir($path, $chmod = false, $chown = false, $chgrp = false ) {
  431.         $path = untrailingslashit($path);
  432.         if ( empty($path) )
  433.             return false;
  434.  
  435.         if ( ! $this->ftp->mkdir($path) )
  436.             return false;
  437.         if ( ! $chmod )
  438.             $chmod = FS_CHMOD_DIR;
  439.         $this->chmod($path, $chmod);
  440.         return true;
  441.     }
  442.  
  443.     /**
  444.      *
  445.      * @param string $path
  446.      * @param bool $recursive
  447.      * @return bool
  448.      */
  449.     public function rmdir($path, $recursive = false ) {
  450.         return $this->delete($path, $recursive);
  451.     }
  452.  
  453.     /**
  454.      *
  455.      * @param string $path
  456.      * @param bool   $include_hidden
  457.      * @param bool   $recursive
  458.      * @return bool|array
  459.      */
  460.     public function dirlist($path = '.', $include_hidden = true, $recursive = false ) {
  461.         if ( $this->is_file($path) ) {
  462.             $limit_file = basename($path);
  463.             $path = dirname($path) . '/';
  464.         } else {
  465.             $limit_file = false;
  466.         }
  467.  
  468.         mbstring_binary_safe_encoding();
  469.  
  470.         $list = $this->ftp->dirlist($path);
  471.         if ( empty( $list ) && ! $this->exists( $path ) ) {
  472.  
  473.             reset_mbstring_encoding();
  474.  
  475.             return false;
  476.         }
  477.  
  478.         $ret = array();
  479.         foreach ( $list as $struc ) {
  480.  
  481.             if ( '.' == $struc['name'] || '..' == $struc['name'] )
  482.                 continue;
  483.  
  484.             if ( ! $include_hidden && '.' == $struc['name'][0] )
  485.                 continue;
  486.  
  487.             if ( $limit_file && $struc['name'] != $limit_file )
  488.                 continue;
  489.  
  490.             if ( 'd' == $struc['type'] ) {
  491.                 if ( $recursive )
  492.                     $struc['files'] = $this->dirlist($path . '/' . $struc['name'], $include_hidden, $recursive);
  493.                 else
  494.                     $struc['files'] = array();
  495.             }
  496.  
  497.             // Replace symlinks formatted as "source -> target" with just the source name
  498.             if ( $struc['islink'] )
  499.                 $struc['name'] = preg_replace( '/(\s*->\s*.*)$/', '', $struc['name'] );
  500.  
  501.             // Add the Octal representation of the file permissions
  502.             $struc['permsn'] = $this->getnumchmodfromh( $struc['perms'] );
  503.  
  504.             $ret[ $struc['name'] ] = $struc;
  505.         }
  506.  
  507.         reset_mbstring_encoding();
  508.  
  509.         return $ret;
  510.     }
  511.  
  512.     /**
  513.      */
  514.     public function __destruct() {
  515.         $this->ftp->quit();
  516.     }
  517. }
  518.