| Server IP : 162.253.224.18 / Your IP : 216.73.217.81 Web Server : Apache System : Linux s18.infinitysrv.com 3.10.0-962.3.2.lve1.5.89.el7.x86_64 #1 SMP Thu Jul 9 15:55:31 UTC 2026 x86_64 User : dejavumk ( 1184) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/dejavumk/perbec.com/wp-content/plugins/duplicator-pro/classes/net/ |
Upload File : |
<?php
defined("ABSPATH") or die("");
class DUP_PRO_FTPcURL
{
/** @var string FTP host */
private $server;
/** @var string FTP port */
private $port = 21;
/** @var string FTP username */
private $username;
/** @var string FTP password */
private $password;
/** @var string remote FTP directory */
private $directory = '/';
/** @var integer timeout in seconds */
private $timeout_in_sec = 90;
/** @var boolean whether FTP is ssl ftp or not */
private $ssl = false;
/** @var boolean whether FTP is passive mode or not */
private $passive_mode = false;
/**
* class constructor
*
* @param string $server FTP host
* @param integer $port FTP port
* @param string $username FTP username
* @param string $password FTP password
* @param string $directory remote FTP directory
* @param integer $timeout_in_sec timeout in seconds
* @param boolean $ssl whether it is ssl ftp or not
* @param boolean $passive_mode whether it is passive mode or not
*
* @return void
*/
public function __construct($server, $port = 21, $username = 'anonymous', $password = 'anonymous@gmail.com', $directory = '/', $timeout_in_sec = 15, $ssl = false, $passive_mode = false)
{
if (empty($server)) {
throw new InvalidArgumentException(DUP_PRO_U::esc_html__('Invalid $server argument with the empty in DUP_PRO_FTPcURL class constructor.'));
}
if (!is_string($server)) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $server argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $server);
}
if (empty($port)) {
throw new InvalidArgumentException(DUP_PRO_U::esc_html__('Invalid $port argument with the empty in DUP_PRO_FTPcURL class constructor.'));
}
$port = (int) $port;
if ($port <= 0) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $port argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $port);
}
if (empty($username)) {
throw new InvalidArgumentException(DUP_PRO_U::esc_html__('Invalid $username argument with the empty in DUP_PRO_FTPcURL class constructor.'));
}
if (!is_string($username)) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $username argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $username);
}
if (empty($password)) {
throw new InvalidArgumentException(DUP_PRO_U::esc_html__('Invalid $password argument with the empty in DUP_PRO_FTPcURL class constructor.'));
}
if (!is_string($password)) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $password argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $password);
}
if (empty($directory)) {
throw new InvalidArgumentException(DUP_PRO_U::esc_html__('Invalid $directory argument with the empty in DUP_PRO_FTPcURL class constructor.'));
}
if (!is_string($directory)) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $directory argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $directory);
}
if (empty($timeout_in_sec)) {
throw new InvalidArgumentException(DUP_PRO_U::esc_html__('Invalid $timeout_in_sec argument with the empty in DUP_PRO_FTPcURL class constructor.'));
}
$timeout_in_sec = (int) $timeout_in_sec;
if ($timeout_in_sec <= 0) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $timeout_in_sec argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $timeout_in_sec);
}
if (!is_bool($ssl)) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $ssl argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $ssl);
}
if (!is_bool($passive_mode)) {
throw new InvalidArgumentException(sprintf(DUP_PRO_U::esc_html__('Invalid $passive_mode argument with the value %s in DUP_PRO_FTPcURL class constructor.')), $passive_mode);
}
$this->server = $server;
$this->port = $port;
$this->username = $username;
$this->password = $password;
$this->directory = $directory;
$this->timeout_in_sec = $timeout_in_sec;
$this->ssl = $ssl;
$this->passive_mode = $passive_mode;
}
/**
* curl call
*
* @param string $path where the curl call occur
* @param array $options configuration options
*
* @throws Exception upon error
* @return void
*/
private function curl_call($path, $options = array())
{
$ch = curl_init();
$url = sprintf('ftp://%s:%d/%s', $this->server, $this->port, $this->untrailing_left_slash_path($path));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_USERPWD, sprintf('%s:%s', $this->username, $this->password));
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout_in_sec);
curl_setopt($ch, CURLOPT_TIMEOUT, 0);
if ($this->ssl) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
curl_setopt($ch, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_TLS);
} else {
// To do based on settings verify peer
$global = DUP_PRO_Global_Entity::get_instance();
$setopts[CURLOPT_SSL_VERIFYPEER] = $global->ssl_disableverify ? false : true;
$setopts[CURLOPT_SSL_VERIFYHOST] = $global->ssl_disableverify ? 0 : 2;
if (!$global->ssl_useservercerts) {
$setopts[CURLOPT_CAINFO] = DUPLICATOR_PRO_CERT_PATH;
$setopts[CURLOPT_CAPATH] = DUPLICATOR_PRO_CERT_PATH;
}
}
if ($this->passive_mode) {
curl_setopt($ch, CURLOPT_FTP_USE_EPSV, true);
} else {
curl_setopt($ch, CURLOPT_FTP_USE_EPRT, true);
curl_setopt($ch, CURLOPT_FTPPORT, 0);
}
foreach ($options as $name => $value) {
curl_setopt($ch, $name, $value);
}
if (($response = curl_exec($ch)) === false) {
if (($errno = curl_errno($ch))) {
switch ($errno) {
case 6:
case 7:
throw new Exception(DUP_PRO_U::esc_html__('Unable to connect to FTP server. Please check your FTP hostname, port, and active mode settings.'));
case 9:
throw new Exception(DUP_PRO_U::esc_html__('Unable to change FTP directory. Please ensure that you have permission on the server.'));
case 23:
throw new Exception(DUP_PRO_U::esc_html__('Unable to download file from FTP server. Please ensure that you have enough disk space.'));
case 28:
throw new Exception(DUP_PRO_U::esc_html__('Connecting to FTP server timed out. Please check FTP hostname, port, username, password, and active mode settings.'));
case 67:
throw new Exception(DUP_PRO_U::esc_html__('Unable to login to FTP server. Please check your username and password.'));
default:
throw new Exception(sprintf(DUP_PRO_U::esc_html__('Unable to connect to FTP. Error code: %s.'), $errno));
}
}
}
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code >= 400) {
if (isset($this->messages[$http_code])) {
throw new Exception(sprintf(DUP_PRO_U::esc_html__('Error code: %s.'), $this->messages[ $http_code ]));
} else {
throw new Exception(sprintf(DUP_PRO_U::esc_html__('Error code: %s.'), $http_code));
}
}
return $response;
}
/**
* test ftp connection
*
* @throws Exception upon error
* @return boolean
*/
public function test_conn() {
try {
$this->curl_call(
'/',
array(
CURLOPT_TIMEOUT => $this->timeout_in_sec,
)
);
} catch (Exception $e) {
$message = sprintf(DUP_PRO_U::esc_html__('Error connecting to FTP server %1$s:%2$d. Exception Error: %3$s.'), $this->server, $this->port, $e->getMessage());
DUP_PRO_LOG::trace($message);
throw $e;
}
return true;
}
/**
* create a dir
*
* @param string $folder_path a dir path which need to create
*
* @throws Exception upon error
* @return boolean
*/
public function create_directory($folder_path)
{
try {
$this->curl_call(
$folder_path,
array(
CURLOPT_FTP_CREATE_MISSING_DIRS => true,
)
);
} catch(Exception $e) {
DUP_PRO_LOG::trace("Error creating folder when using FTP cURL. FTP Info: " . $this->get_info().' Exception Error: ' . $e->getMessage());
return false;
}
DUP_PRO_LOG::trace("Successfully created folder by FTP cURL.");
return true;
}
/**
* upload file
*
* @param string $local_file_path local file path
* @param string $remote_file_path remote file path
* @param string $dest_filename destination file name
*
* @throws Exception upon error
* @return void
*/
public function upload_file($local_file_path, $remote_file_path, $dest_filename = '')
{
$remote_file_path = $this->untrailing_left_slash_path($remote_file_path);
$file_size = filesize($local_file_path);
// Upload file from file stream
if (($file_stream = fopen($local_file_path, 'rb'))) {
$options = array(
CURLOPT_UPLOAD => true,
// by chance If FTP curl storage set and In btw a user has deleted storage dir from a FTP program
CURLOPT_FTP_CREATE_MISSING_DIRS => true,
CURLOPT_INFILE => $file_stream,
CURLOPT_INFILESIZE => $file_size,
CURLOPT_NOPROGRESS => true,
);
$this->curl_call(sprintf('/%s/%s', $this->directory, $remote_file_path), $options);
fclose( $file_stream );
}
return true;
}
/**
* download file
*
* @param string $remote_file_path
* @param string $local either local file path or local dir, depends on the $is_local_directory
* @param boolean $is_local_directory whether $local is local directory or full path to download
*
* @throws Exception upon error
* @return boolean
*/
public function download_file($remote_file_path, $local, $is_local_directory = true)
{
$remote_file_path = $this->untrailing_left_slash_path($remote_file_path);
if ($is_local_directory) {
$filename = basename($remote_file_path);
$local_file_path = "$local/$filename";
} else {
$local_file_path = $local;
}
if (($file_stream = fopen($local_file_path, 'wb'))) {
try {
$options = array(
CURLOPT_FILE => $file_stream,
CURLOPT_NOPROGRESS => true,
);
$this->curl_call(sprintf('/%s/%s', $this->directory, $remote_file_path), $options);
} catch (Exception $e) {
DUP_PRO_LOG::trace("Error downloading " . $remote_source_filepath . " into " . $local_dest_filepath . ". FTP Info: " . $this->get_info().' Exception Error: ' . $e->getMessage());
throw $e;
}
fclose($file_stream);
}
return true;
}
/**
* delete remote file
*
* @param string $file_path remote file path
*
* @throws Exception upon error
* @return boolean
*/
public function delete($file_path)
{
$file_path = $this->untrailing_left_slash_path($file_path);
try {
$this->curl_call(
sprintf('/%s/', $this->directory),
array(
CURLOPT_QUOTE => array(sprintf('DELE /%s', $this->untrailing_left_slash_path(sprintf('/%s/%s', $this->directory, $file_path)))),
)
);
} catch (Exception $e) {
DUP_PRO_LOG::trace("Failed to delete ".$file_path." from " . $this->server . ". Error code: " . $e->getCode() . ". Error Message:" . $e->getMessage());
return false;
}
DUP_PRO_LOG::trace("Successfully deleted ".$file_path." from " . $this->server);
return true;
}
/**
* upload file by chunking mode
*
* @param string $source_filepath local file path
* @param string $storage_folder remote folder
* @param integer $max_upload_time_in_sec max upload time in sec in a chunk
* @param integer $offset file offset
* @param integer $server_load_delay
* @param string $dest_filename remote file name
* @return object
*/
public function upload_chunk($source_filepath, $storage_folder, $max_upload_time_in_sec = 15, $offset = 0, $server_load_delay = 0, $dest_filename = '')
{
DUP_PRO_LOG::trace("----------------------------");
DUP_PRO_LOG::trace("FTP CURL CHUNK UPLOAD START");
DUP_PRO_LOG::trace("FTP CHUNK OFFSET IN=$offset");
/* @var $ftp_upload_info DUP_PRO_FTP_UploadInfo */
$ftp_upload_info = new DUP_PRO_FTP_UploadInfo();
$start_time = time();
$remote_file_path = !empty($dest_filename) ? $dest_filename : basename($source_filepath);
try {
DUP_PRO_LOG::trace("call upload chunk for FTP cURL");
$fp = fopen($source_filepath, 'rb');
if ($fp) {
// Read file chunk data
while (fseek($fp, $offset) !== -1
&& $file_chunk_data = fread($fp, DUPLICATOR_PRO_FTP_CURL_CHUNK_SIZE)) {
$ret = $this->upload_file_chunk($file_chunk_data, $remote_file_path, $offset);
if ($ret) {
$offset = ftell($fp);
}
$time_passed = time() - $start_time;
if ($time_passed < $max_upload_time_in_sec) {
$offset = ftell($fp);
DUP_PRO_LOG::trace("Timed out $max_upload_time_in_sec so saving off offset $offset");
break;
}
if($server_load_delay !== 0) {
usleep($server_load_delay);
}
}
$ftp_upload_info->next_offset = $offset;
} else {
$message = sprintf(DUP_PRO_U::esc_html__('Error opening %1$ for cURL FTP'), $source_filepath);
DUP_PRO_LOG::trace($message);
$ftp_upload_info->error_details = $message;
$ftp_upload_info->next_offset = $offset;
}
DUP_PRO_LOG::trace("closing local file handle");
fclose($fp);
$source_filesize = filesize($source_filepath);
if ($source_filesize <= $ftp_upload_info->next_offset) {
$ftp_size = $this->get_file_size($remote_file_path);
if (!$ftp_size && $ftp_size != $source_filesize) {
$error_message = sprintf(DUP_PRO_U::esc_html__('cURL FTP size mismatch for %1$s. Local file=%2$d bytes while server\'s file is %3$d bytes.'), $source_filepath, $source_filesize, $ftp_size);
DUP_PRO_LOG::trace($error_message);
$ftp_upload_info->error_details = $error_message;
$ftp_upload_info->fatal_error = true;
$this->delete($remote_file_path);
} else {
DUP_PRO_LOG::trace("FTP cURL upload file finish");
$ftp_upload_info->success = true;
}
} else {
DUP_PRO_LOG::trace("FTP cURL upload file is not finished yet..");
}
} catch (Exception $e) {
$message = "Tried to upload file when connection wasn't opened. Info:" . $this->get_info() .' Exception Error: '. $e->getMessage();
$ftp_upload_info->error_details = $message;
DUP_PRO_LOG::trace($message);
$ftp_upload_info->next_offset = $offset;
}
DUP_PRO_LOG::trace("FTP CURL CHUNK UPLOAD END");
DUP_PRO_LOG::trace("----------------------------");
return $ftp_upload_info;
}
/**
* upload file chunk with given data
*
* @param string $file_chunk_data
* @param string $remote_file_path
* @param integer $file_range_start
*
* @throws Exception upon error
* @return boolean
*/
private function upload_file_chunk($file_chunk_data, $remote_file_path, $file_range_start = 0)
{
$remote_file_path = $this->untrailing_left_slash_path($remote_file_path);
if (($file_chunk_stream = fopen('php://temp', 'wb+')) === false) {
return true;
}
if (($file_chunk_size = fwrite($file_chunk_stream, $file_chunk_data)) === false) {
return true;
}
rewind($file_chunk_stream);
$this->curl_call(
sprintf('/%s/%s', $this->directory, $remote_file_path),
array(
CURLOPT_UPLOAD => true,
CURLOPT_FTPAPPEND => true,
CURLOPT_INFILE => $file_chunk_stream,
CURLOPT_INFILESIZE => $file_chunk_size,
)
);
fclose($file_chunk_stream);
return true;
}
/**
* get remote file size
*
* @param string $remote_file_name
* @return boolean|integer gives size of remote file or false on failure
*/
public function get_file_size($remote_file_name)
{
$items = $this->raw_list_folder($this->directory);
foreach ($items as $item) {
if ($meta = preg_split('/\s+/', $item)) {
if (!empty($meta[8]) && !empty($meta[4]) && $meta[8] == $remote_file_name) {
return $meta[4];
}
}
}
return false;
}
/**
* get information of the FTP
*
* @return string
*/
private function get_info()
{
$ssl_string = DUP_PRO_STR::boolToString($this->ssl);
$passive_string = DUP_PRO_STR::boolToString($this->passive_mode);
return sprintf(DUP_PRO_U::esc_html__('Server:%1$s Port:%2$d User:%3$s Directory:%4$s SSL:%5$s Passive:%6$s.'), $this->server, $this->port, $this->username, $this->directory, $ssl_string, $passive_string);
}
/**
* get all files in remote folder
*
* @param string $folder_path remote folder path
*
* @throws Exception upon error
* @return array
*/
public function get_filelist($folder_path)
{
$items = $this->raw_list_folder($folder_path);
$files = array();
foreach ($items as $item) {
if ($meta = preg_split('/\s+/', $item)) {
if (!empty($meta[8])) {
$files[] = trim($meta[8]);
}
}
}
DUP_PRO_LOG::trace("Get file list from cURL FTP: " . print_r($files, true));
return $files;
}
/**
* get all files meta information
*
* @param string $folder_path remote dir path
*
* @throws Exception upon error
* @return array
*/
private function raw_list_folder($folder_path)
{
$folder_path = $this->untrailing_left_slash_path($folder_path);
$items = $this->curl_call(
sprintf('/%s/', $folder_path),
array(
CURLOPT_CUSTOMREQUEST => 'LIST -tlA',
)
);
return explode("\n", $items);
}
/**
* clean path with removing left slash
*
* @param string $path
* @return string
*/
private function untrailing_left_slash_path($path)
{
return ltrim(preg_replace('/[\\\\\/]+/', '/', $path), '/');
}
}