File manager - Edit - /home/proidvn/me.proid.vn/wp-content/plugins/wp-all-import-pro/classes/filesystem/RemoteFilesystem.php
Back
<?php defined( 'ABSPATH' ) || exit; use Wpai\Http\Request; use Wpai\Http\JsonResponse; use League\Flysystem\Filesystem; use League\Flysystem\Sftp\SftpAdapter; use League\Flysystem\Adapter\Ftp as FtpAdapter; class RemoteFilesystem { private $options; private $filesystem; private $error = false; private $rel_type; private $default_port = false; private $error_stack = []; private $type = ''; private $contents; private $orig_type = ''; private $allow_hidden_files_folders; // Should match list in classes/upload.php#56 - xml|gzip|zip|csv|tsv|gz|json|txt|dat|psv|sql|xls|xlsx private $allowed_file_extensions = ['xml','gzip','zip','csv','tsv','gz','json','txt','dat','psv','sql','xls','xlsx']; private $debug; private $attempted_roots = []; public function __construct( $options ) { // Enable debug filter $this->debug = apply_filters('wpai_ftp_enable_debug', false); // Show hidden files filter. $this->allow_hidden_files_folders = apply_filters('wpai_ftp_allow_hidden_files_folders', false); // Allowed file extensions filter. $this->allowed_file_extensions = apply_filters('wpai_ftp_allowed_file_extensions', $this->allowed_file_extensions); /* * INI default_socket_timeout should be higher than the 'timeout' parameter below. */ // Default options $default_options = [ 'root' => '/', 'timeout' => apply_filters('wpai_ftp_timeout', 10), // FTP only options 'passive' => apply_filters('wpai_ftp_passive_mode', true), 'ignorePassiveAddress' => apply_filters('wpai_ftp_ignore_passive_address', false), 'enableTimestampsOnUnixListings' => true, 'ssl' => false, ]; $this->options = $this->option_merge( $default_options, $options ); // Root override $this->options['root'] = apply_filters('wpai_ftp_root', $this->options['root'], PMXI_Plugin::getCurrentImportId()); $this->attempted_roots[] = $this->options['root']; // Ensure no trailing slash or text after the URL exists. $this->options['host'] = preg_replace( '@(?<![/:])/.*@', '', $this->options['host'] ); // Connect to FTP server. $this->connect(); // Process any relative file references. $this->get_relative(); } /** * Determine protocol and attempt to connect. */ private function connect() { if ( preg_match( '%^sftp://%i', trim( $this->options['host'] ) ) || !empty($this->options['privateKey']) ) { $this->default_port = [ 22, 2222 ]; $this->options['host'] = preg_replace( '%^sftp://%i', '', trim($this->options['host'] )); $this->buildFilesystem( 'sftp' ); } elseif ( preg_match( '%^ftp://%i', trim( $this->options['host'] ) ) ) { $this->default_port = [ 21 ]; $this->options['host'] = preg_replace( '%^ftp://%i', '', trim( $this->options['host'] )); $this->buildFilesystem( 'ftp' ); } elseif ( preg_match( '%^ftps://%i', trim( $this->options['host'] ) ) ) { $this->default_port = [ 21 ]; $this->options['host'] = preg_replace( '%^ftps://%i', '', trim( $this->options['host'] ) ); $this->options['ssl'] = true; $this->buildFilesystem( 'ftp' ); } elseif ( trim( $this->options['port'] ) == 21 ) { $this->default_port = [ 21 ]; $this->buildFilesystem( 'ftp' ); } elseif ( trim( $this->options['port'] ) == 22 || trim( $this->options['port'] ) == 2222 ) { $this->default_port = [ 22, 2222 ]; $this->buildFilesystem( 'sftp' ); } else { // Try SFTP by default. $this->default_port = [ 22, 2222 ]; $this->buildFilesystem( 'sftp' ); } } private function buildFilesystem( $type ) { $this->type = $type; if( $this->orig_type === '' ) $this->orig_type = $type; try { switch ( $type ) { case 'ftp': $this->filesystem = new Filesystem( new FtpAdapter( $this->options ) ); break; case 'sftp': $this->filesystem = new Filesystem( new SftpAdapter( $this->options ) ); break; } } catch ( \Exception $e ) { $this->error = $e->getMessage(); } } public function listContents( $recursive = false ) { try { // Store the contents in a parameter since we are using a recursive method on error. $this->contents = $this->filesystem->listContents( $this->options['dir'], $recursive ); // Filter the contents. $this->filter_contents(); } catch ( \Exception $e ) { $this->error = $e->getMessage(); // Log all of the error messages if debug mode is enabled. if( $this->debug ){ error_log("WPAI_FTP_DEBUG"); error_log("Error Message:"); error_log($e->getMessage()); error_log("Options Array:"); error_log(print_r($this->options, true)); error_log("END WPAI_FTP_DEBUG"); } if ( str_replace( [ 'Root is invalid or does not exist:', ], '', $e->getMessage() ) !== $e->getMessage() ) { $new_root = '/'; if ( ! in_array( '/home/', $this->attempted_roots ) ) { $new_root = '/home/'; } elseif ( preg_match( '@\..{0,4}@', $this->options['root'] ) === 1 && ! in_array( dirname( $this->options['root'] ), $this->attempted_roots ) ) { $new_root = dirname( $this->options['root'] ); } elseif ( ! in_array( $this->options['dir'], $this->attempted_roots ) ) { $new_root = $this->options['dir']; } if ( ! in_array( $new_root, $this->attempted_roots ) ) { // Remove the root from the directory path to ensure it's not doubled. $this->options['dir'] = str_replace( $new_root, '', $this->options['dir']); $this->options['root'] = $new_root; $this->attempted_roots[] = $this->options['root']; $this->error_stack[] = $this->error; $this->error = false; $this->buildFilesystem( $this->type ); $this->listContents( $recursive ); } else { return $this->contents; } } // Check if it was a login failure or connection failure. // Don't retry if login failure or if host couldn't be found. elseif ( str_replace( [ 'Could not login', 'php_network_getaddresses: getaddrinfo failed:', ], '',$e->getMessage() ) !== $e->getMessage() ) { return $this->contents; } else { errorProcessing: // Retry with default port(s) if ( is_array( $this->default_port ) && count( $this->default_port ) > 0) { $port = array_pop( $this->default_port ); while ( $port === $this->options['port'] && count( $this->default_port ) > 0 ) { $port = array_pop( $this->default_port ); } if ( $port != $this->options['port'] ) { $this->options['port'] = $port; $this->error_stack[] = $this->error; $this->error = false; $this->buildFilesystem( $this->type ); $this->listContents( $recursive ); }else{ goto errorProcessing; } } elseif ( $this->orig_type === $this->type && empty( $this->options['privateKey'] ) ) { $this->type = $this->type === 'sftp' ? 'ftp' : 'sftp'; $this->default_port = $this->type === 'sftp' ? [ 22, 2222 ] : [ 21 ]; $this->error_stack[] = $this->error; $this->error = false; $this->buildFilesystem( $this->type ); $this->listContents( $recursive ); } elseif ( count( $this->error_stack ) > 0 ) { // Sort the errors so they are in order $this->error = '<br/><br/><b>Connection Attempt:</b><br/>' . implode( '<br/><br/><b>Connection Attempt:</b><br/>', $this->error_stack ) . '<br/><br/><b>Connection Attempt:</b><br/>' . $this->error; } // Return if there was an error. return $this->contents; } } // If an additional error wasn't caught then clear the error stack and move on. $this->error = false; $this->error_stack = []; return $this->contents; } public function copy() { try { $uploads = wp_upload_dir(); $destination = wp_all_import_secure_file( $uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::UPLOADS_DIRECTORY, PMXI_Plugin::getCurrentImportId(), true ); // Write the file. $result = file_put_contents( $destination . '/' . basename( $this->options['dir'] ), $this->filesystem->readStream( $this->options['dir'] ) ); if ( $result ) { return [ $destination . '/' . basename( $this->options['dir'] ) ]; } } catch ( \Exception $e ) { $this->error = $e->getMessage(); // If FTP try via cURL as a last resort if ( $this->type == 'ftp' ) { try { $curl = curl_init(); $filename = $destination . '/' . basename( $this->options['dir'] ); $file = fopen( $destination . '/' . basename( $this->options['dir'] ), 'w' ); curl_setopt( $curl, CURLOPT_URL, 'ftp://' . str_replace(array('ftps://', 'ftp://'), '', $this->options['ftp_host']) . '/' . $this->options['dir'] ); #input curl_setopt( $curl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $curl, CURLOPT_FILE, $file ); #output curl_setopt( $curl, CURLOPT_USERPWD, $this->options['ftp_username'] . ':' . $this->options['ftp_password'] ); curl_setopt($curl, CURLOPT_FTP_SSL, CURLFTPSSL_TRY); curl_setopt($curl, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_DEFAULT); curl_setopt($curl, CURLOPT_PORT, $this->options['port']); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); curl_exec( $curl ); curl_close( $curl ); fclose( $file ); if ( ( is_file( $filename ) ) && ( 0 !== filesize( $filename ) ) ) { return [ $filename ]; } } catch ( \Exception $e ) { $this->error = $e->getMessage(); return false; } } else { return false; } } } public function getError() { return $this->error; } private function option_merge( $default, $opts ) { $options = array_merge( $default, $opts ); if ( isset( $opts['ftp_host'] ) ) { $options['host'] = $opts['ftp_host']; } if ( isset( $opts['ftp_port'] ) ) { $options['port'] = $opts['ftp_port']; } if ( isset( $opts['ftp_path'] ) ) { $options['dir'] = $opts['ftp_path']; } if ( isset( $opts['ftp_root'] ) ) { $options['root'] = $opts['ftp_root']; } if ( isset( $opts['ftp_username'] ) ) { $options['username'] = $opts['ftp_username']; } if ( isset( $opts['ftp_password'] ) ) { $options['password'] = $opts['ftp_password']; } if ( isset( $opts['ftp_private_key'] ) ) { $options['privateKey'] = $opts['ftp_private_key']; } return $options; } private function get_relative() { try { $matches = []; // Check if a relative file reference was provided. preg_match( '#{(.*)\.(.{0,4})}#', $this->options['dir'], $matches ); // Ensure all the expected pieces were found or do nothing. if ( isset( $matches[0] ) && isset( $matches[1] ) && isset( $matches[2] ) ) { $relative = $matches[1]; // Relative reference such as oldest. $this->rel_type = $matches[2]; // The file extension to find. // Remove relative file reference from dir before LIST. $this->options['dir'] = trim( str_replace( $matches[0], '', $this->options['dir'] ), '/' ); $contents = $this->listContents(); if ( $this->error !== false ) { throw new Exception( 'Failed to retrieve remote file listing.' ); } switch ( $relative ) { case ( 'any' ): // Filter out any non files and filter by file type. $contents = array_filter( $contents, function ( $var ) { return ( isset( $var['type'] ) && $var['type'] == 'file' && isset( $var['extension'] ) && ( $var['extension'] == $this->rel_type || empty( $this->rel_type ) ) ); } ); $file = array_pop( $contents ); isset( $file['path'] ) && $this->options['dir'] = $file['path']; break; case ( 'oldest' ): // Sort by timestamp newest to oldest. uasort( $contents, function ( $a, $b ) { return $b['timestamp'] - $a['timestamp']; } ); // Filter out any non files and filter by file type. $contents = array_filter( $contents, function ( $var ) { return ( isset( $var['type'] ) && $var['type'] == 'file' && isset( $var['extension'] ) && ( $var['extension'] == $this->rel_type || empty( $this->rel_type ) ) ); } ); $file = array_pop( $contents ); isset( $file['path'] ) && $this->options['dir'] = $file['path']; break; case ( 'newest' ): // Sort by timestamp oldest to newest. uasort( $contents, function ( $a, $b ) { return $a['timestamp'] - $b['timestamp']; } ); // Filter out any non files and filter by file type. $contents = array_filter( $contents, function ( $var ) { return ( isset( $var['type'] ) && $var['type'] == 'file' && isset( $var['extension'] ) && ( $var['extension'] == $this->rel_type || empty( $this->rel_type ) ) ); } ); $file = array_pop( $contents ); isset( $file['path'] ) && $this->options['dir'] = $file['path']; break; case ( 'custom' ): // Pass the current dir, found files, and target extension back to the user via filter. // The full directory pointing to a single file must be returned. $this->options['dir'] = apply_filters('wpai_ftp_custom_target_file_filter', $this->options['dir'], $contents, $this->rel_type); break; } } } catch ( \Exception $e ) { $this->error = $e->getMessage(); } } public function get_port() { return $this->options['port']; } public function get_protocol() { if( $this->type == 'ftp' && $this->options['ssl'] == true ) $this->type = 'ftps'; return $this->type; } public function get_root() { return $this->options['root']; } private function filter_contents(){ // Build filter string. $filters = []; if( !$this->allow_hidden_files_folders ) { $filters[] = '^\.'; // Match leading period. } if( count($filters) > 0) { $filter = '@' . implode( '|', $filters ) . '@'; $this->contents = array_filter( $this->contents, function ( $var ) use ( $filter ) { // Ensure that $var has an extension element in all cases. if( !isset($var['extension'])) $var['extension'] = ''; return ( preg_match( $filter, $var['basename'] ) !== 1 && ( $var['type'] === 'dir' || in_array( strtolower($var['extension']), $this->allowed_file_extensions ) ) ); } ); } } }
| ver. 1.4 |
Github
|
.
| PHP 8.0.30 | Generation time: 0.17 |
proxy
|
phpinfo
|
Settings