update
This commit is contained in:
@@ -0,0 +1,822 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
if(!defined('WPVIVID_REMOTE_AMAZONS3'))
|
||||
define('WPVIVID_REMOTE_AMAZONS3','amazons3');
|
||||
if(!defined('WPVIVID_AMAZONS3_DEFAULT_FOLDER'))
|
||||
define('WPVIVID_AMAZONS3_DEFAULT_FOLDER','/wpvivid_backup');
|
||||
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-remote.php';
|
||||
require_once 'class-wpvivid-base-s3.php';
|
||||
class WPvivid_AMAZONS3Class extends WPvivid_Remote{
|
||||
|
||||
public $options;
|
||||
public $bucket='';
|
||||
|
||||
private $upload_chunk_size = 5242880;
|
||||
private $download_chunk_size = 5242880;
|
||||
|
||||
public $current_file_size;
|
||||
public $current_file_name;
|
||||
|
||||
public function __construct($options=array())
|
||||
{
|
||||
if(empty($options))
|
||||
{
|
||||
add_action('wpvivid_add_storage_tab',array($this,'wpvivid_add_storage_tab_amazons3'), 13);
|
||||
add_action('wpvivid_add_storage_page',array($this,'wpvivid_add_storage_page_amazons3'), 13);
|
||||
add_action('wpvivid_edit_remote_page',array($this,'wpvivid_edit_storage_page_amazons3'), 13);
|
||||
add_filter('wpvivid_remote_pic',array($this,'wpvivid_remote_pic_amazons3'),11);
|
||||
add_filter('wpvivid_get_out_of_date_remote',array($this,'wpvivid_get_out_of_date_amazons3'),10,2);
|
||||
add_filter('wpvivid_storage_provider_tran',array($this,'wpvivid_storage_provider_amazons3'),10);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->options=$options;
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_tab_amazons3()
|
||||
{
|
||||
?>
|
||||
<div class="storage-providers" remote_type="amazons3" onclick="select_remote_storage(event, 'storage_account_amazons3');">
|
||||
<img src="<?php echo esc_url(WPVIVID_PLUGIN_URL.'/admin/partials/images/storage-amazon-s3.png'); ?>" style="vertical-align:middle;"/><?php esc_html_e('Amazon S3', 'wpvivid-backuprestore'); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_page_amazons3()
|
||||
{
|
||||
if(!function_exists('simplexml_load_string')){
|
||||
$need_extension = true;
|
||||
$add_btn_style = 'pointer-events: none; opacity: 0.4;';
|
||||
}
|
||||
else{
|
||||
$need_extension = false;
|
||||
$add_btn_style = 'pointer-events: auto; opacity: 1;';
|
||||
}
|
||||
?>
|
||||
<div id="storage_account_amazons3" class="storage-account-page" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your Amazon S3 Account', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="amazons3" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. Amazon S3-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="amazons3" name="access" placeholder="<?php esc_attr_e('Amazon S3 access key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your Amazon S3 access key.', 'wpvivid-backuprestore'); ?></i><a href="https://wpvivid.com/get-amazon-access-secret-key.html" target="_blank"> <?php esc_html_e('How to get an AmazonS3 access key.', 'wpvivid-backuprestore'); ?></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="amazons3" name="secret" placeholder="<?php esc_attr_e('Amazon S3 secret key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your Amazon S3 secret key.', 'wpvivid-backuprestore'); ?></i><a href="https://wpvivid.com/get-amazon-access-secret-key.html" target="_blank"> <?php esc_html_e('How to get an Amazon S3 secret key.', 'wpvivid-backuprestore'); ?></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="amazons3" name="bucket" placeholder="<?php esc_attr_e('Amazon S3 Bucket Name(e.g. test)', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Enter an existed Bucket to create a custom backup storage directory.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="amazons3" name="path" placeholder="<?php esc_attr_e('Custom Path', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Customize the directory where you want to store backups within the Bucket.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="amazons3" name="default" checked /><?php esc_html_e('Set as the default remote storage.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Once checked, all this sites backups sent to a remote storage destination will be uploaded to this storage by default.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="amazons3" name="classMode" checked /><?php esc_html_e('Storage class: Standard (infrequent access).', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Check the option to use Amazon S3 Standard-Infrequent Access (S3 Standard-IA) storage class for data transfer.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="amazons3" name="sse" checked /><?php esc_html_e('Server-side encryption.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Check the option to use Amazon S3 server-side encryption to protect data.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" option="add-remote" type="submit" value="<?php esc_attr_e('Test and Add', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to connect to Amazon S3 storage and add it to the storage list below.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php
|
||||
if($need_extension){
|
||||
?>
|
||||
<p style="padding-left: 10px;"><?php esc_html_e('The simplexml extension is not detected. Please install the extension first.', 'wpvivid-backuprestore'); ?></p>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_edit_storage_page_amazons3()
|
||||
{
|
||||
?>
|
||||
<div id="remote_storage_edit_amazons3" class="postbox storage-account-block remote-storage-edit" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your Amazon S3 Account', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-amazons3" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. Amazon S3-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-amazons3" name="access" placeholder="<?php esc_attr_e('Amazon S3 access key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your Amazon S3 access key.', 'wpvivid-backuprestore'); ?></i><a href="https://wpvivid.com/get-amazon-access-secret-key.html" target="_blank"> <?php esc_html_e('How to get an AmazonS3 access key.', 'wpvivid-backuprestore'); ?></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="edit-amazons3" name="secret" placeholder="<?php esc_attr_e('Amazon S3 secret key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your Amazon S3 secret key.', 'wpvivid-backuprestore'); ?></i><a href="https://wpvivid.com/get-amazon-access-secret-key.html" target="_blank"> <?php esc_html_e('How to get an Amazon S3 secret key.', 'wpvivid-backuprestore'); ?></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-amazons3" name="bucket" placeholder="<?php esc_attr_e('Amazon S3 Bucket Name(e.g. test)', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Enter an existed Bucket to create a custom backup storage directory.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-amazons3" name="path" placeholder="<?php esc_attr_e('Custom Path', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Customize the directory where you want to store backups within the Bucket.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="edit-amazons3" name="classMode" /><?php esc_html_e('Storage class: Standard (infrequent access).', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Check the option to use Amazon S3 Standard-Infrequent Access (S3 Standard-IA) storage class for data transfer.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="edit-amazons3" name="sse" /><?php esc_html_e('Server-side encryption.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Check the option to use Amazon S3 server-side encryption to protect data.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" option="edit-remote" type="submit" value="<?php esc_attr_e('Save Changes', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to save the changes.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_remote_pic_amazons3($remote){
|
||||
$remote['amazons3']['default_pic'] = '/admin/partials/images/storage-amazon-s3(gray).png';
|
||||
$remote['amazons3']['selected_pic'] = '/admin/partials/images/storage-amazon-s3.png';
|
||||
$remote['amazons3']['title'] = 'Amazon S3';
|
||||
return $remote;
|
||||
}
|
||||
|
||||
public function test_connect()
|
||||
{
|
||||
$amazons3 = $this -> getS3();
|
||||
if(is_array($amazons3) && $amazons3['result'] === WPVIVID_FAILED)
|
||||
return $amazons3;
|
||||
$temp_file = md5(wp_rand());
|
||||
try
|
||||
{
|
||||
if(isset($this->options['s3Path']))
|
||||
{
|
||||
$url=$this->options['s3Path'].$temp_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url=$this->options['path'].'/'.$temp_file;
|
||||
}
|
||||
|
||||
if(!$amazons3 -> putObjectString($temp_file,$this -> bucket,$url))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'We successfully accessed the bucket, but create test file failed.');
|
||||
}
|
||||
if(!$amazons3 -> deleteObject($this -> bucket,$url))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'We successfully accessed the bucket, and create test file succeed, but delete test file failed.');
|
||||
}
|
||||
}catch(Exception $e){
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$e -> getMessage());
|
||||
}
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function sanitize_options($skip_name='')
|
||||
{
|
||||
$ret['result']=WPVIVID_FAILED;
|
||||
if(!isset($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['name']=sanitize_text_field($this->options['name']);
|
||||
|
||||
if(empty($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$remoteslist=WPvivid_Setting::get_all_remote_options();
|
||||
foreach ($remoteslist as $key=>$value)
|
||||
{
|
||||
if(isset($value['name'])&&$value['name'] == $this->options['name']&&$skip_name!=$value['name'])
|
||||
{
|
||||
$ret['error']="Warning: The alias already exists in storage list.";
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($this->options['access']))
|
||||
{
|
||||
$ret['error']="Warning: The access key for Amazon S3 is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['access']=sanitize_text_field($this->options['access']);
|
||||
|
||||
if(empty($this->options['access']))
|
||||
{
|
||||
$ret['error']="Warning: The access key for Amazon S3 is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['secret']))
|
||||
{
|
||||
$ret['error']="Warning: The storage secret key is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['secret']=sanitize_text_field($this->options['secret']);
|
||||
|
||||
if(empty($this->options['secret']))
|
||||
{
|
||||
$ret['error']="Warning: The storage secret key is required.";
|
||||
return $ret;
|
||||
}
|
||||
$this->options['secret'] = base64_encode($this->options['secret']);
|
||||
$this->options['is_encrypt'] = 1;
|
||||
|
||||
if(!isset($this->options['bucket']))
|
||||
{
|
||||
$ret['error']="Warning: A Bucket name is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['bucket']=sanitize_text_field($this->options['bucket']);
|
||||
|
||||
if(empty($this->options['bucket']))
|
||||
{
|
||||
$ret['error']="Warning: A Bucket name is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['path']))
|
||||
{
|
||||
$ret['error']="Warning: A directory name is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['path']=sanitize_text_field($this->options['path']);
|
||||
|
||||
if(empty($this->options['path'])){
|
||||
$ret['error']="Warning: A directory name is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
$ret['options']=$this->options;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function upload($task_id,$files,$callback='')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$amazons3 = $this -> getS3();
|
||||
|
||||
if(is_array($amazons3) && $amazons3['result'] == WPVIVID_FAILED)
|
||||
return $amazons3;
|
||||
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3);
|
||||
if(empty($upload_job))
|
||||
{
|
||||
$job_data=array();
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$file_data['size']=filesize($file);
|
||||
$file_data['uploaded']=0;
|
||||
$job_data[basename($file)]=$file_data;
|
||||
}
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_UNDO,'Start uploading',$job_data);
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3);
|
||||
}
|
||||
|
||||
foreach ($files as $file){
|
||||
if(is_array($upload_job['job_data']) &&array_key_exists(basename($file),$upload_job['job_data']))
|
||||
{
|
||||
if($upload_job['job_data'][basename($file)]['uploaded']==1)
|
||||
continue;
|
||||
}
|
||||
|
||||
$this -> last_time = time();
|
||||
$this -> last_size = 0;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Start uploading '.basename($file),'notice');
|
||||
$wpvivid_plugin->set_time_limit($task_id);
|
||||
if(!file_exists($file))
|
||||
return array('result' =>WPVIVID_FAILED,'error' =>$file.' not found. The file might has been moved, renamed or deleted. Please reload the list and verify the file exists.');
|
||||
$result = $this -> _put($task_id,$amazons3,$file,$callback);
|
||||
if($result['result'] !==WPVIVID_SUCCESS){
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploading '.basename($file).' failed.','notice');
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
WPvivid_taskmanager::wpvivid_reset_backup_retry_times($task_id);
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Finished uploading '.basename($file),'notice');
|
||||
$upload_job['job_data'][basename($file)]['uploaded']=1;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
|
||||
}
|
||||
return array('result' =>WPVIVID_SUCCESS);
|
||||
}
|
||||
private function _put($task_id,$amazons3,$file,$callback)
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3);
|
||||
$this -> current_file_size = filesize($file);
|
||||
$this -> current_file_name = basename($file);
|
||||
|
||||
if(isset($this->options['s3Path']))
|
||||
{
|
||||
$url=$this->options['s3Path'].$this -> current_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url=$this->options['path'].'/'.$this -> current_file_name;
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog($url,'notice');
|
||||
|
||||
$chunk_num = floor($this -> current_file_size / $this -> upload_chunk_size);
|
||||
if($this -> current_file_size % $this -> upload_chunk_size > 0) $chunk_num ++;
|
||||
|
||||
for($i =0;$i <WPVIVID_REMOTE_CONNECT_RETRY_TIMES;$i ++)
|
||||
{
|
||||
try
|
||||
{
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_UNDO,'Start uploading '.basename($file).'.',$upload_job['job_data']);
|
||||
|
||||
if(true)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Creating Multipart Upload.','notice');
|
||||
if(!empty($upload_job['job_data'][basename($file)]['upload_id']))
|
||||
{
|
||||
$build_id = $upload_job['job_data'][basename($file)]['upload_id'];
|
||||
}else{
|
||||
$build_id = $amazons3 -> initiateMultipartUpload($this -> bucket,$url);
|
||||
$upload_job['job_data'][basename($file)]['upload_id'] = $build_id;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_UNDO,'InitiateMultipartUpload, created build id of '.basename($file).'.',$upload_job['job_data']);
|
||||
}
|
||||
if(!empty($upload_job['job_data'][basename($file)]['upload_chunks']))
|
||||
{
|
||||
$chunks = $upload_job['job_data'][basename($file)]['upload_chunks'];
|
||||
}else{
|
||||
$chunks = array();
|
||||
$upload_job['job_data'][basename($file)]['upload_chunks'] = $chunks;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_UNDO,'Start multipartupload of '.basename($file).'.',$upload_job['job_data']);
|
||||
}
|
||||
|
||||
for($i =sizeof($chunks);$i <$chunk_num;$i ++)
|
||||
{
|
||||
$chunk_id = $amazons3 -> uploadPart($this -> bucket,$url,$build_id,$file,$i+1,$this ->upload_chunk_size);
|
||||
if(!$chunk_id){
|
||||
$chunks = array();
|
||||
$upload_job['job_data'][basename($file)]['upload_chunks'] = $chunks;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_UNDO,'Start multipartupload of '.basename($file).'.',$upload_job['job_data']);
|
||||
return array('result' => WPVIVID_FAILED,'error' => 'upload '.$file.' failed.');
|
||||
}
|
||||
$chunks[] = $chunk_id;
|
||||
$upload_job['job_data'][basename($file)]['upload_chunks'] = $chunks;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_UNDO,'Uploading '.basename($file).'.',$upload_job['job_data']);
|
||||
|
||||
$offset = (($i + 1) * $this -> upload_chunk_size) > $this -> current_file_size ? $this -> current_file_size : (($i + 1) * $this -> upload_chunk_size);
|
||||
if((time() - $this -> last_time) >3)
|
||||
{
|
||||
if(is_callable($callback))
|
||||
{
|
||||
call_user_func_array($callback,array($offset,$this -> current_file_name,
|
||||
$this->current_file_size,$this -> last_time,$this -> last_size));
|
||||
}
|
||||
$this -> last_size = $offset;
|
||||
$this -> last_time = time();
|
||||
}
|
||||
}
|
||||
$result = $amazons3 -> completeMultipartUpload($this -> bucket,$url,$build_id,$chunks);
|
||||
}else{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploaded files are less than 5M.','notice');
|
||||
$input = $amazons3 -> inputFile($file);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('putObject input:'.wp_json_encode($input).' bucket:'.$this->bucket.' url:'.$url,'notice');
|
||||
$result = $amazons3 -> putObject($input,$this ->bucket,$url);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('putObject end:'.$result,'notice');
|
||||
}
|
||||
}catch(Exception $e)
|
||||
{
|
||||
if(strstr($e -> getMessage(), 'upload ID may be invalid'))
|
||||
{
|
||||
$upload_job['job_data'][basename($file)]['upload_id'] = '';
|
||||
$upload_job['job_data'][basename($file)]['upload_chunks'] = '';
|
||||
continue;
|
||||
}
|
||||
return array('result' => WPVIVID_FAILED,'error'=>$e -> getMessage());
|
||||
}
|
||||
if($result){
|
||||
$upload_job['job_data'][basename($file)]['uploaded']=1;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_AMAZONS3,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
|
||||
break;
|
||||
}
|
||||
if(!$result && $i == (WPVIVID_REMOTE_CONNECT_RETRY_TIMES - 1))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Uploading '.$file.' to Amazon S3 server failed. '.$file.' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
sleep(WPVIVID_REMOTE_CONNECT_RETRY_INTERVAL);
|
||||
}
|
||||
return array('result' =>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function download($file,$local_path,$callback = '')
|
||||
{
|
||||
try {
|
||||
global $wpvivid_plugin;
|
||||
$this->current_file_name = $file['file_name'];
|
||||
$this->current_file_size = $file['size'];
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Get amazons3 client.','notice');
|
||||
$amazons3 = $this->getS3();
|
||||
if (is_array($amazons3) && $amazons3['result'] === WPVIVID_FAILED) {
|
||||
return $amazons3;
|
||||
}
|
||||
if(isset($this->options['s3Path']))
|
||||
{
|
||||
$url=$this->options['s3Path']. $this -> current_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url=$this->options['path'].'/'. $this -> current_file_name;
|
||||
}
|
||||
$file_path = trailingslashit($local_path) . $this->current_file_name;
|
||||
$start_offset = file_exists($file_path) ? filesize($file_path) : 0;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Create local file.','notice');
|
||||
$fh = fopen($file_path, 'a');
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Downloading file ' . $file['file_name'] . ', Size: ' . $file['size'] ,'notice');
|
||||
while ($start_offset < $this->current_file_size) {
|
||||
$last_byte = min($start_offset + $this->download_chunk_size - 1, $this->current_file_size - 1);
|
||||
$headers['Range'] = "bytes=$start_offset-$last_byte";
|
||||
$response = $amazons3->getObject($this->bucket,$url, $fh, $headers['Range']);
|
||||
if (!$response)
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'download ' . $url. ' failed.');
|
||||
clearstatcache();
|
||||
$state = stat($file_path);
|
||||
$start_offset = $state['size'];
|
||||
|
||||
if ((time() - $this->last_time) > 3) {
|
||||
if (is_callable($callback)) {
|
||||
call_user_func_array($callback, array($start_offset, $this->current_file_name,
|
||||
$this->current_file_size, $this->last_time, $this->last_size));
|
||||
}
|
||||
$this->last_size = $start_offset;
|
||||
$this->last_time = time();
|
||||
}
|
||||
}
|
||||
@fclose($fh);
|
||||
|
||||
if(filesize($file_path) == $file['size']){
|
||||
if($wpvivid_plugin->wpvivid_check_zip_valid()) {
|
||||
$res = TRUE;
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
|
||||
if ($res !== TRUE) {
|
||||
@wp_delete_file($file_path);
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . $file['file_name'] . ' failed. ' . $file['file_name'] . ' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
catch (Exception $error){
|
||||
$message = 'An exception has occurred. class: '.get_class($error).';msg: '.$error->getMessage().';code: '.$error->getCode().';line: '.$error->getLine().';in_file: '.$error->getFile().';';
|
||||
error_log($message);
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>$message);
|
||||
}
|
||||
}
|
||||
|
||||
public function cleanup($files)
|
||||
{
|
||||
$amazons3 = $this -> getS3();
|
||||
|
||||
if(is_array($amazons3) && $amazons3['result'] === WPVIVID_FAILED)
|
||||
return $amazons3;
|
||||
foreach ($files as $file){
|
||||
|
||||
if(isset($this->options['s3Path']))
|
||||
{
|
||||
$url=$this->options['s3Path'].$file;
|
||||
}
|
||||
else
|
||||
{
|
||||
$url=$this->options['path'].'/'.$file;
|
||||
}
|
||||
|
||||
$amazons3 -> deleteObject($this -> bucket , $url);
|
||||
}
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
private function getS3()
|
||||
{
|
||||
if(isset($this->options['s3Path']))
|
||||
{
|
||||
$path_temp = str_replace('s3://','',$this->options['s3Path']);
|
||||
if (preg_match("#^/*([^/]+)/(.*)$#", $path_temp, $bmatches))
|
||||
{
|
||||
$this->bucket = $bmatches[1];
|
||||
if(empty($bmatches[2])){
|
||||
$this->options['s3Path'] = '';
|
||||
}else{
|
||||
$this->options['s3Path'] = trailingslashit($bmatches[2]);
|
||||
}
|
||||
} else {
|
||||
$this->bucket = $path_temp;
|
||||
$this->options['s3Path'] = '';
|
||||
}
|
||||
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$secret = base64_decode($this->options['secret']);
|
||||
}
|
||||
else {
|
||||
$secret = $this->options['secret'];
|
||||
}
|
||||
$amazons3 = new WPvivid_Base_S3($this->options['access'],$secret);
|
||||
|
||||
$amazons3 -> setExceptions();
|
||||
if($this->options['classMode'])
|
||||
$amazons3 -> setStorageClass();
|
||||
if($this->options['sse'])
|
||||
$amazons3 -> setServerSideEncryption();
|
||||
|
||||
try{
|
||||
$region = $amazons3 -> getBucketLocation($this->bucket);
|
||||
}catch(Exception $e){
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getMessage());
|
||||
}
|
||||
$endpoint = $this -> getEndpoint($region);
|
||||
if(!empty($endpoint))
|
||||
$amazons3 -> setEndpoint($endpoint);
|
||||
return $amazons3;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->bucket= $this->options['bucket'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$secret = base64_decode($this->options['secret']);
|
||||
}
|
||||
else {
|
||||
$secret = $this->options['secret'];
|
||||
}
|
||||
$amazons3 = new WPvivid_Base_S3($this->options['access'],$secret);
|
||||
$amazons3 -> setExceptions();
|
||||
if($this->options['classMode'])
|
||||
$amazons3 -> setStorageClass();
|
||||
if($this->options['sse'])
|
||||
$amazons3 -> setServerSideEncryption();
|
||||
|
||||
try{
|
||||
$region = $amazons3 -> getBucketLocation($this->bucket);
|
||||
}catch(Exception $e){
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getMessage());
|
||||
}
|
||||
|
||||
$amazons3->setSignatureVersion('v4');
|
||||
$amazons3->setRegion($region);
|
||||
|
||||
$endpoint = $this -> getEndpoint($region);
|
||||
if(!empty($endpoint))
|
||||
$amazons3 -> setEndpoint($endpoint);
|
||||
return $amazons3;
|
||||
}
|
||||
|
||||
}
|
||||
private function getEndpoint($region){
|
||||
switch ($region) {
|
||||
case 'EU':
|
||||
case 'eu-west-1':
|
||||
$endpoint = 's3-eu-west-1.amazonaws.com';
|
||||
break;
|
||||
case 'US':
|
||||
case 'us-east-1':
|
||||
$endpoint = 's3.amazonaws.com';
|
||||
break;
|
||||
case 'us-west-1':
|
||||
case 'us-east-2':
|
||||
case 'us-west-2':
|
||||
case 'eu-west-2':
|
||||
case 'eu-west-3':
|
||||
case 'ap-southeast-1':
|
||||
case 'ap-southeast-2':
|
||||
case 'ap-northeast-2':
|
||||
case 'sa-east-1':
|
||||
case 'ca-central-1':
|
||||
case 'us-gov-west-1':
|
||||
case 'eu-north-1':
|
||||
case 'eu-central-1':
|
||||
$endpoint = 's3-'.$region.'.amazonaws.com';
|
||||
break;
|
||||
case 'ap-northeast-1':
|
||||
$endpoint = 's3.'.$region.'.amazonaws.com';
|
||||
break;
|
||||
case 'ap-south-1':
|
||||
$endpoint = 's3.'.$region.'.amazonaws.com';
|
||||
break;
|
||||
case 'cn-north-1':
|
||||
$endpoint = 's3.'.$region.'.amazonaws.com.cn';
|
||||
break;
|
||||
case 'af-south-1':
|
||||
$endpoint = 's3.'.$region.'.amazonaws.com';
|
||||
break;
|
||||
default:
|
||||
$endpoint = 's3.amazonaws.com';
|
||||
break;
|
||||
}
|
||||
return $endpoint;
|
||||
}
|
||||
|
||||
public function wpvivid_get_out_of_date_amazons3($out_of_date_remote, $remote)
|
||||
{
|
||||
if($remote['type'] == WPVIVID_REMOTE_AMAZONS3)
|
||||
{
|
||||
if(isset($remote['s3Path']))
|
||||
$out_of_date_remote = $remote['s3Path'];
|
||||
else
|
||||
$out_of_date_remote = $remote['path'];
|
||||
}
|
||||
return $out_of_date_remote;
|
||||
}
|
||||
|
||||
public function wpvivid_storage_provider_amazons3($storage_type)
|
||||
{
|
||||
if($storage_type == WPVIVID_REMOTE_AMAZONS3){
|
||||
$storage_type = 'Amazon S3';
|
||||
}
|
||||
return $storage_type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
class Dropbox_Base{
|
||||
|
||||
const API_URL_V2 = 'https://api.dropboxapi.com/';
|
||||
const CONTENT_URL_V2 = 'https://content.dropboxapi.com/2/';
|
||||
const API_ID = 'cwn4z5jg8wy7b4u';
|
||||
|
||||
private $access_token;
|
||||
private $created;
|
||||
private $expires_in;
|
||||
private $refresh_token;
|
||||
private $option;
|
||||
|
||||
public function __construct($option)
|
||||
{
|
||||
$this -> option = $option;
|
||||
$this -> access_token = $option['access_token'];
|
||||
|
||||
$this -> created = $option['created'];
|
||||
$this -> expires_in = $option['expires_in'];
|
||||
$this -> refresh_token = $option['refresh_token'];
|
||||
}
|
||||
|
||||
public function check_token()
|
||||
{
|
||||
if(!isset($this->option['refresh_token']))
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error' => 'Invalid or expired token. Please remove '.$this -> option['name'].' from the storage list and re-authenticate it.');
|
||||
}
|
||||
$now=time()-10;
|
||||
if ($now>$this->option['created']+$this->option['expires_in'])
|
||||
{
|
||||
$result=$this->getRefreshToken();
|
||||
if($result['result']=='failed')
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error' => $result['error']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote_options=WPvivid_Setting::get_remote_option($this->option['id']);
|
||||
if($remote_options!==false)
|
||||
{
|
||||
$remote_options['access_token']= base64_encode($result['data']['access_token']);
|
||||
if(!isset($remote_options['is_encrypt']))
|
||||
{
|
||||
$remote_options['refresh_token']=base64_encode($remote_options['refresh_token']);
|
||||
$this -> refresh_token = base64_encode($this->option['refresh_token']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this -> refresh_token = $this->option['refresh_token'];
|
||||
}
|
||||
$remote_options['expires_in'] = $result['data']['expires_in'];
|
||||
$remote_options['created'] = time();
|
||||
$remote_options['is_encrypt']=1;
|
||||
WPvivid_Setting::update_remote_option($this->option['id'],$remote_options);
|
||||
$this -> access_token = $remote_options['access_token'];
|
||||
$this -> created = $remote_options['created'];
|
||||
$this -> expires_in = $remote_options['expires_in'];
|
||||
$this -> option['is_encrypt']=1;
|
||||
|
||||
$ret['result']='success';
|
||||
return $ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error'=>'get refresh token failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret['result']='success';
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
public function upload($target_path, $file_data, $mode = "add")
|
||||
{
|
||||
$endpoint = self::CONTENT_URL_V2."files/upload";
|
||||
$headers = array(
|
||||
"Content-Type: application/octet-stream",
|
||||
"Dropbox-API-Arg: {\"path\": \"$target_path\", \"mode\": \"$mode\"}"
|
||||
);
|
||||
|
||||
if (file_exists($file_data))
|
||||
$postdata = file_get_contents($file_data);
|
||||
else
|
||||
$postdata = $file_data;
|
||||
|
||||
$returnData = $this ->postRequest($endpoint, $headers, $postdata);
|
||||
if(isset($returnData['error_summary']) && preg_match( "/Invalid or expired token. Please remove .* from the storage list and re-authenticate it/", $returnData['error_summary'], $matches ))
|
||||
{
|
||||
$ret=$this->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $returnData;
|
||||
}
|
||||
else
|
||||
{
|
||||
$returnData = $this ->postRequest($endpoint, $headers, $postdata);
|
||||
}
|
||||
}
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public function upload_session_start()
|
||||
{
|
||||
$endpoint = self::CONTENT_URL_V2."files/upload_session/start";
|
||||
$headers = array(
|
||||
"Content-Type: application/octet-stream",
|
||||
"Dropbox-API-Arg: {\"close\": false}"
|
||||
);
|
||||
|
||||
$returnData = $this ->postRequest($endpoint, $headers,null);
|
||||
if(isset($returnData['error_summary']) && preg_match( "/Invalid or expired token. Please remove .* from the storage list and re-authenticate it/", $returnData['error_summary'], $matches ))
|
||||
{
|
||||
$ret=$this->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $returnData;
|
||||
}
|
||||
else
|
||||
{
|
||||
$returnData = $this ->postRequest($endpoint, $headers,null);
|
||||
}
|
||||
}
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public function upload_session_append_v2($session_id, $offset, $postdata)
|
||||
{
|
||||
$endpoint = self::CONTENT_URL_V2."files/upload_session/append_v2";
|
||||
$headers = array(
|
||||
"Content-Type: application/octet-stream",
|
||||
"Dropbox-API-Arg: {\"cursor\": {\"session_id\": \"$session_id\",\"offset\": $offset},\"close\": false}"
|
||||
);
|
||||
|
||||
$returnData = $this ->postRequest($endpoint, $headers, $postdata);
|
||||
if(isset($returnData['error_summary']) && preg_match( "/Invalid or expired token. Please remove .* from the storage list and re-authenticate it/", $returnData['error_summary'], $matches ))
|
||||
{
|
||||
$ret=$this->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $returnData;
|
||||
}
|
||||
else
|
||||
{
|
||||
$returnData = $this ->postRequest($endpoint, $headers,null);
|
||||
}
|
||||
}
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public function upload_session_finish($session_id, $filesize, $path, $mode = 'add') {
|
||||
$endpoint = self::CONTENT_URL_V2."files/upload_session/finish";
|
||||
$entry = array(
|
||||
'cursor' => array(
|
||||
'session_id' => $session_id,
|
||||
'offset' => $filesize,
|
||||
),
|
||||
'commit' => array(
|
||||
'path' => $path,
|
||||
'mode' => $mode,
|
||||
|
||||
),
|
||||
);
|
||||
$headers = array(
|
||||
"Content-Type: application/octet-stream",
|
||||
"Dropbox-API-Arg: " . wp_json_encode($entry),
|
||||
);
|
||||
|
||||
$returnData = $this ->postRequest($endpoint, $headers,null);
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public function download($path,$header = array()) {
|
||||
$endpoint = "https://content.dropboxapi.com/2/files/download";
|
||||
$headers = array(
|
||||
"Content-Type: text/plain; charset=utf-8",
|
||||
"Dropbox-API-Arg: {\"path\": \"$path\"}"
|
||||
);
|
||||
$headers = array_merge ($headers,$header);
|
||||
$data = $this ->postRequest($endpoint, $headers,null,false);
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function delete($path) {
|
||||
$endpoint = self::API_URL_V2."2/files/delete";
|
||||
$headers = array(
|
||||
"Content-Type: application/json"
|
||||
);
|
||||
$postdata = wp_json_encode(array( "path" => $path ));
|
||||
$returnData = $this -> postRequest($endpoint, $headers, $postdata);
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public function revoke() {
|
||||
$endpoint = self::API_URL_V2."2/auth/token/revoke";
|
||||
$headers = array();
|
||||
$this -> postRequest($endpoint, $headers);
|
||||
}
|
||||
|
||||
public function getUsage(){
|
||||
$endpoint = self::API_URL_V2."2/users/get_space_usage";
|
||||
$headers = array(
|
||||
"Content-Type: application/json"
|
||||
);
|
||||
$postdata = "null";
|
||||
$returnData = $this -> postRequest($endpoint, $headers,$postdata);
|
||||
return $returnData;
|
||||
}
|
||||
|
||||
public static function getUrl($url,$state = '')
|
||||
{
|
||||
$params = array(
|
||||
'client_id' => self::API_ID,
|
||||
'response_type' => 'code',
|
||||
'redirect_uri' => $url,
|
||||
'token_access_type'=>'offline',
|
||||
'state' => $state,
|
||||
);
|
||||
$url = 'https://www.dropbox.com/oauth2/authorize?';
|
||||
$url .= http_build_query($params,'','&');
|
||||
return $url;
|
||||
}
|
||||
|
||||
public function postRequest($endpoint, $headers, $data = null,$returnjson = true) {
|
||||
if(isset($this->option['is_encrypt']) && $this->option['is_encrypt'] == 1) {
|
||||
$access_token=base64_decode($this -> access_token);
|
||||
}
|
||||
else{
|
||||
$access_token=$this -> access_token;
|
||||
}
|
||||
|
||||
$ch = curl_init($endpoint);
|
||||
array_push($headers, "Authorization: Bearer " . $access_token);
|
||||
|
||||
curl_setopt($ch, CURLOPT_POST, TRUE);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
|
||||
//todo delete this code
|
||||
// curl_setopt($ch,CURLOPT_PROXY, '127.0.0.1:1080');
|
||||
$r = curl_exec($ch);
|
||||
$chinfo = curl_getinfo($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if($r === false){
|
||||
$r['error_summary'] = $error;
|
||||
}else{
|
||||
if($chinfo['http_code'] === 401)
|
||||
{
|
||||
$ret=$this->check_token();
|
||||
if($ret['result']=='success')
|
||||
{
|
||||
$ch = curl_init($endpoint);
|
||||
array_push($headers, "Authorization: Bearer " . $access_token);
|
||||
|
||||
curl_setopt($ch, CURLOPT_POST, TRUE);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$r = curl_exec($ch);
|
||||
$chinfo = curl_getinfo($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
if($r === false)
|
||||
{
|
||||
$r['error_summary'] = $error;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($chinfo['http_code'] === 401)
|
||||
{
|
||||
$r = array();
|
||||
$r['error_summary'] = 'Invalid or expired token. Please remove '.$this -> option['name'].' from the storage list and re-authenticate it.';
|
||||
}
|
||||
elseif($chinfo['http_code'] !== 200 && $chinfo['http_code'] !== 206)
|
||||
{
|
||||
$r = json_decode($r,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$r = array();
|
||||
$r['error_summary'] = 'Invalid or expired token. Please remove '.$this -> option['name'].' from the storage list and re-authenticate it.';
|
||||
}
|
||||
|
||||
}elseif($chinfo['http_code'] !== 200 && $chinfo['http_code'] !== 206){
|
||||
$r = json_decode($r,true);
|
||||
}
|
||||
}
|
||||
if($returnjson && !is_array($r))
|
||||
$r = json_decode($r,true);
|
||||
|
||||
return $r;
|
||||
}
|
||||
public function setAccessToken($access_token){
|
||||
$this -> access_token = $access_token;
|
||||
}
|
||||
|
||||
public function getRefreshToken()
|
||||
{
|
||||
if(isset($this->option['is_encrypt']) && $this->option['is_encrypt'] == 1) {
|
||||
$refresh_token=base64_decode($this -> refresh_token);
|
||||
}
|
||||
else{
|
||||
$refresh_token=$this -> refresh_token;
|
||||
}
|
||||
|
||||
$options=array();
|
||||
$options['timeout']=30;
|
||||
$options['sslverify']=FALSE;
|
||||
$params = array(
|
||||
'client_id' => self::API_ID,
|
||||
'refresh_token' => $refresh_token,
|
||||
'version'=>1
|
||||
);
|
||||
$url = 'https://auth.wpvivid.com/dropbox_v3/?';
|
||||
$url .= http_build_query($params,'','&');
|
||||
|
||||
$request = wp_remote_request( $url,$options);
|
||||
|
||||
if(!is_wp_error($request) && ($request['response']['code'] == 200))
|
||||
{
|
||||
$json= wp_remote_retrieve_body($request);
|
||||
$body=json_decode($json,true);
|
||||
if(is_null($body))
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']='Get refresh token failed';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if($body['result']=='success')
|
||||
{
|
||||
return $body;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $body;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']='Get refresh token failed';
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
include_once 'class-wpvivid-s3.php';
|
||||
|
||||
class WPvivid_Base_S3 extends Wpvivid_S3{
|
||||
var $signVer = 'v2';
|
||||
|
||||
/**
|
||||
* Set Signature Version
|
||||
*
|
||||
* @param string $version
|
||||
* @return void
|
||||
*/
|
||||
public function setSignatureVersion($version = 'v2') {
|
||||
$this->signVer = $version;
|
||||
}
|
||||
|
||||
public function setServerSideEncryption($value = self::SSE_AES256) {
|
||||
$this->_serverSideEncryption = $value;
|
||||
}
|
||||
public function setStorageClass($value = self::STORAGE_CLASS_STANDARD_IA){
|
||||
$this -> _storageClass = $value;
|
||||
}
|
||||
|
||||
public function initiateMultipartUpload ($bucket, $uri, $acl = self::ACL_PRIVATE, $metaHeaders = array(), $requestHeaders = array(), $storageClass = self::STORAGE_CLASS_STANDARD) {
|
||||
|
||||
$rest = new WPvivid_S3Request('POST', $bucket, $uri, $this->endpoint, $this);
|
||||
$rest->setParameter('uploads','');
|
||||
|
||||
if (is_array($requestHeaders) && !empty($requestHeaders))
|
||||
foreach ($requestHeaders as $h => $v) $rest->setHeader($h, $v);
|
||||
if(is_array($metaHeaders) && !empty($metaHeaders))
|
||||
foreach ($metaHeaders as $h => $v) $rest->setAmzHeader('x-amz-meta-'.$h, $v);
|
||||
|
||||
if ($this -> _storageClass !== self::STORAGE_CLASS_STANDARD) // Storage class
|
||||
$rest->setAmzHeader('x-amz-storage-class', $this -> _storageClass);
|
||||
if ($this -> _serverSideEncryption !== self::SSE_NONE) // Server-side encryption
|
||||
$rest->setAmzHeader('x-amz-server-side-encryption', $this -> _serverSideEncryption);
|
||||
|
||||
$rest->setAmzHeader('x-amz-acl', $acl);
|
||||
|
||||
$rest->getResponse();
|
||||
if (false === $rest->response->error && 200 !== $rest->response->code) {
|
||||
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
|
||||
if (false !== $rest->response->error) {
|
||||
$this->__triggerError(sprintf("WPvivid_S3::initiateMultipartUpload(): [%s] %s",
|
||||
$rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
|
||||
return false;
|
||||
} elseif (isset($rest->response->body)) {
|
||||
if (is_a($rest->response->body, 'SimpleXMLElement')) {
|
||||
$body = $rest->response->body;
|
||||
} else {
|
||||
$body = new SimpleXMLElement($rest->response->body);
|
||||
}
|
||||
return (string) $body->UploadId;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function uploadPart ($bucket, $uri, $uploadId, $filePath, $partNumber, $partSize = 5242880) {
|
||||
$rest = new WPvivid_S3Request('PUT', $bucket, $uri, $this->endpoint, $this);
|
||||
$rest->setParameter('partNumber', $partNumber);
|
||||
$rest->setParameter('uploadId', $uploadId);
|
||||
|
||||
$fileOffset = ($partNumber - 1 ) * $partSize;
|
||||
$fileBytes = min(filesize($filePath) - $fileOffset, $partSize);
|
||||
if ($fileBytes < 0) $fileBytes = 0;
|
||||
|
||||
$rest->setHeader('Content-Type', 'application/octet-stream');
|
||||
$rest->data = "";
|
||||
|
||||
if ($handle = fopen($filePath, "rb")) {
|
||||
if ($fileOffset >0) fseek($handle, $fileOffset);
|
||||
$bytes_read = 0;
|
||||
while ($fileBytes>0 && $read = fread($handle, max($fileBytes, 131072))) { //128kb
|
||||
$fileBytes = $fileBytes - strlen($read);
|
||||
$bytes_read += strlen($read);
|
||||
$rest->data = $rest->data . $read;
|
||||
}
|
||||
fclose($handle);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$rest->setHeader('Content-MD5', base64_encode(md5($rest->data, true)));
|
||||
$rest->size = $bytes_read;
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if (false === $rest->error && 200 !== $rest->code) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
|
||||
if (false !== $rest->error) {
|
||||
$this->__triggerError(sprintf("S3::uploadPart(): [%s] %s",
|
||||
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
return $rest->headers['hash'];
|
||||
}
|
||||
|
||||
public function completeMultipartUpload ($bucket, $uri, $uploadId, $parts) {
|
||||
$rest = new WPvivid_S3Request('POST', $bucket, $uri, $this->endpoint, $this);
|
||||
$rest->setParameter('uploadId', $uploadId);
|
||||
|
||||
$xml = "<CompleteMultipartUpload>\n";
|
||||
$partno = 1;
|
||||
foreach ($parts as $etag) {
|
||||
$xml .= "<Part><PartNumber>$partno</PartNumber><ETag>$etag</ETag></Part>\n";
|
||||
$partno++;
|
||||
}
|
||||
$xml .= "</CompleteMultipartUpload>";
|
||||
|
||||
$rest->data = $xml;
|
||||
$rest->size = strlen($rest->data);
|
||||
$rest->setHeader('Content-Type', 'application/xml');
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if (false === $rest->error && 200 !== $rest->code) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
|
||||
if (false !== $rest->error) {
|
||||
if ('InternalError' == $rest->error['code'] && 'This multipart completion is already in progress' == $rest->error['message']) {
|
||||
return true;
|
||||
}
|
||||
$this->__triggerError(sprintf("S3::completeMultipartUpload(): [%s] %s",
|
||||
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function abortMultipartUpload ($bucket, $uri, $uploadId) {
|
||||
$rest = new WPvivid_S3Request('DELETE', $bucket, $uri, $this->endpoint, $this);
|
||||
$rest->setParameter('uploadId', $uploadId);
|
||||
|
||||
$rest = $rest->getResponse();
|
||||
if (false === $rest->error && 204 !== $rest->code) {
|
||||
$rest->error = array('code' => $rest->code, 'message' => 'Unexpected HTTP status');
|
||||
}
|
||||
|
||||
if (false !== $rest->error) {
|
||||
$this->__triggerError(sprintf("S3::abortMultipartUpload(): [%s] %s",
|
||||
$rest->error['code'], $rest->error['message']), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getObject($bucket, $uri, $saveTo = false, $resume = false) {
|
||||
$rest = new WPvivid_S3Request('GET', $bucket, $uri, $this->endpoint, $this);
|
||||
if (false !== $saveTo) {
|
||||
if (is_resource($saveTo)) {
|
||||
$rest->fp = $saveTo;
|
||||
if (!is_bool($resume)) $rest->setHeader('Range', $resume);
|
||||
} else {
|
||||
if ($resume && file_exists($saveTo)) {
|
||||
if (false !== ($rest->fp = @fopen($saveTo, 'ab'))) {
|
||||
$rest->setHeader('Range', "bytes=".filesize($saveTo).'-');
|
||||
$rest->file = realpath($saveTo);
|
||||
} else {
|
||||
$rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
|
||||
}
|
||||
} else {
|
||||
if (false !== ($rest->fp = @fopen($saveTo, 'wb')))
|
||||
$rest->file = realpath($saveTo);
|
||||
else
|
||||
$rest->response->error = array('code' => 0, 'message' => 'Unable to open save file for writing: '.$saveTo);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (false === $rest->response->error) $rest->getResponse();
|
||||
|
||||
if (false === $rest->response->error && ( !$resume && 200 != $rest->response->code) || ( $resume && 206 != $rest->response->code && 200 != $rest->response->code))
|
||||
$rest->response->error = array('code' => $rest->response->code, 'message' => 'Unexpected HTTP status');
|
||||
if (false !== $rest->response->error) {
|
||||
$this->__triggerError(sprintf("WPvivid_S3::getObject({$bucket}, {$uri}): [%s] %s",
|
||||
$rest->response->error['code'], $rest->response->error['message']), __FILE__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
return $rest->response;
|
||||
}
|
||||
|
||||
/*public function listObject($bucket, $path)
|
||||
{
|
||||
$rest = new WPvivid_S3Request('GET', $bucket, '', $this->endpoint, $this);
|
||||
$rest->setParameter('list-type', 2);
|
||||
//$rest->setParameter('max-keys', 2000);
|
||||
$rest->setParameter('prefix', $path);
|
||||
$rest->setParameter('start-after', 'wpvividbackuppro/pestcontrolcanberraarea_com_au\/2020_08_03_to_2020_08_10/pestcontrolcanberraarea.com.au_wpvivid-5f28895122706_2020-08-04-08-00_incremental_backup_all.zip');
|
||||
//$rest->setParameter('delimiter', $path);
|
||||
$response = $rest->getResponse();
|
||||
if ($response->error === false && $response->code !== 200)
|
||||
{
|
||||
//$response->error = array('code' => $response->code, 'message' => 'Unexpected HTTP status');
|
||||
$ret['result']='failed';
|
||||
$ret['error']=$response['message'].' '.$response->code;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($response->error !== false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$results = array();
|
||||
|
||||
if (isset($response->body, $response->body->Contents))
|
||||
{
|
||||
foreach ($response->body->Contents as $c)
|
||||
{
|
||||
$results[] = array(
|
||||
'name' => (string)$c->Key,
|
||||
'size' => (int)$c->Size,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$ret['result']='success';
|
||||
$ret['data']=$results;
|
||||
return $ret;
|
||||
}*/
|
||||
|
||||
public function listObject($bucket, $path)
|
||||
{
|
||||
$ret['result']='success';
|
||||
$results = array();
|
||||
$bcheck = true;
|
||||
$bcontinue = false;
|
||||
$continue_token = '';
|
||||
$start_after = '';
|
||||
$rest = new WPvivid_S3Request('GET', $bucket, '', $this->endpoint, $this);
|
||||
while($bcheck){
|
||||
$rest->unsetParameter($bucket);
|
||||
$rest->setParameter('list-type', 2);
|
||||
if($bcontinue) {
|
||||
$rest->setParameter('start-after', $start_after);
|
||||
}
|
||||
else{
|
||||
$rest->setParameter('prefix', $path);
|
||||
}
|
||||
$response = $rest->getResponse();
|
||||
if ($response->error === false && $response->code !== 200)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=$response['message'].' '.$response->code;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($response->error !== false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=sprintf("S3::getBucket(): [%s] %s", $response->error['code'], $response->error['message']);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if (isset($response->body, $response->body->Contents))
|
||||
{
|
||||
foreach ($response->body->Contents as $c)
|
||||
{
|
||||
$results[] = array(
|
||||
'name' => (string)$c->Key,
|
||||
'size' => (int)$c->Size,
|
||||
);
|
||||
$start_after = (string)$c->Key;
|
||||
}
|
||||
}
|
||||
|
||||
if(isset($response->body->NextContinuationToken)){
|
||||
$bcontinue = true;
|
||||
$continue_token = $response->body->NextContinuationToken;
|
||||
$start_after = $start_after;
|
||||
$bcheck = true;
|
||||
}
|
||||
else{
|
||||
$bcontinue = false;
|
||||
$continue_token = '';
|
||||
$bcheck = false;
|
||||
}
|
||||
$ret['result']='success';
|
||||
$ret['data']=$results;
|
||||
if(!$bcheck){
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,900 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
if(!defined('WPVIVID_REMOTE_DROPBOX')){
|
||||
define('WPVIVID_REMOTE_DROPBOX','dropbox');
|
||||
}
|
||||
if(!defined('WPVIVID_DROPBOX_DEFAULT_FOLDER'))
|
||||
define('WPVIVID_DROPBOX_DEFAULT_FOLDER','/');
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-base-dropbox.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-remote.php';
|
||||
class WPvivid_Dropbox extends WPvivid_Remote
|
||||
{
|
||||
|
||||
private $options;
|
||||
private $upload_chunk_size = 2097152;
|
||||
private $download_chunk_size = 2097152;
|
||||
private $redirect_url = 'https://auth.wpvivid.com/dropbox_v3/';
|
||||
public $add_remote;
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if(empty($options))
|
||||
{
|
||||
if(!defined('WPVIVID_INIT_STORAGE_TAB_DROPBOX'))
|
||||
{
|
||||
add_action('init', array($this, 'handle_auth_actions'));
|
||||
//wpvivid_dropbox_add_remote
|
||||
add_action('wp_ajax_wpvivid_dropbox_add_remote',array( $this,'finish_add_remote'));
|
||||
|
||||
add_action('wpvivid_delete_remote_token',array($this,'revoke'));
|
||||
|
||||
add_filter('wpvivid_remote_register', array($this, 'init_remotes'),10);
|
||||
add_action('wpvivid_add_storage_tab',array($this,'wpvivid_add_storage_tab_dropbox'), 11);
|
||||
add_action('wpvivid_add_storage_page',array($this,'wpvivid_add_storage_page_dropbox'), 11);
|
||||
add_action('wpvivid_edit_remote_page',array($this,'wpvivid_edit_storage_page_dropbox'), 11);
|
||||
add_filter('wpvivid_remote_pic',array($this,'wpvivid_remote_pic_dropbox'),10);
|
||||
add_filter('wpvivid_get_out_of_date_remote',array($this,'wpvivid_get_out_of_date_dropbox'),10,2);
|
||||
add_filter('wpvivid_storage_provider_tran',array($this,'wpvivid_storage_provider_dropbox'),10);
|
||||
add_filter('wpvivid_get_root_path',array($this,'wpvivid_get_root_path_dropbox'),10);
|
||||
add_filter('wpvivid_pre_add_remote',array($this, 'pre_add_remote'),10,2);
|
||||
define('WPVIVID_INIT_STORAGE_TAB_DROPBOX',1);
|
||||
}
|
||||
}else{
|
||||
$this -> options = $options;
|
||||
}
|
||||
$this->add_remote=false;
|
||||
}
|
||||
|
||||
public function pre_add_remote($remote,$id)
|
||||
{
|
||||
if($remote['type']==WPVIVID_REMOTE_DROPBOX)
|
||||
{
|
||||
$remote['id']=$id;
|
||||
}
|
||||
|
||||
return $remote;
|
||||
}
|
||||
|
||||
public function test_connect()
|
||||
{
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function sanitize_options($skip_name='')
|
||||
{
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
|
||||
if(!isset($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['name']=sanitize_text_field($this->options['name']);
|
||||
|
||||
if(empty($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$remoteslist=WPvivid_Setting::get_all_remote_options();
|
||||
foreach ($remoteslist as $key=>$value)
|
||||
{
|
||||
if(isset($value['name'])&&$value['name'] == $this->options['name']&&$skip_name!=$value['name'])
|
||||
{
|
||||
$ret['error']="Warning: The alias already exists in storage list.";
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
$ret['options']=$this->options;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function upload($task_id, $files, $callback = '')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
|
||||
$options = $this -> options;
|
||||
$dropbox = new Dropbox_Base($options);
|
||||
$ret=$dropbox->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX);
|
||||
if(empty($upload_job))
|
||||
{
|
||||
$job_data=array();
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$file_data['size']=filesize($file);
|
||||
$file_data['uploaded']=0;
|
||||
$file_data['session_id']='';
|
||||
$file_data['offset']=0;
|
||||
$job_data[basename($file)]=$file_data;
|
||||
}
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX,WPVIVID_UPLOAD_UNDO,'Start uploading',$job_data);
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX);
|
||||
}
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if(is_array($upload_job['job_data']) &&array_key_exists(basename($file),$upload_job['job_data']))
|
||||
{
|
||||
if($upload_job['job_data'][basename($file)]['uploaded']==1)
|
||||
continue;
|
||||
}
|
||||
$ret=$dropbox->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this -> last_time = time();
|
||||
$this -> last_size = 0;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Start uploading '.basename($file),'notice');
|
||||
$wpvivid_plugin->set_time_limit($task_id);
|
||||
if(!file_exists($file))
|
||||
return array('result' =>WPVIVID_FAILED,'error' =>$file.' not found. The file might has been moved, renamed or deleted. Please reload the list and verify the file exists.');
|
||||
$result = $this -> _put($task_id,$dropbox,$file,$callback);
|
||||
if($result['result'] !==WPVIVID_SUCCESS){
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploading '.basename($file).' failed.','notice');
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
WPvivid_taskmanager::wpvivid_reset_backup_retry_times($task_id);
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Finished uploading '.basename($file),'notice');
|
||||
$upload_job['job_data'][basename($file)]['uploaded'] = 1;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id, 'upload', WPVIVID_REMOTE_DROPBOX, WPVIVID_UPLOAD_SUCCESS, 'Uploading ' . basename($file) . ' completed.', $upload_job['job_data']);
|
||||
}
|
||||
return array('result' =>WPVIVID_SUCCESS);
|
||||
}
|
||||
private function _put($task_id,$dropbox,$file,$callback){
|
||||
global $wpvivid_plugin;
|
||||
$options = $this -> options;
|
||||
$path = trailingslashit($options['path']).basename($file);
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX);
|
||||
$this -> current_file_size = filesize($file);
|
||||
$this -> current_file_name = basename($file);
|
||||
|
||||
if($this -> current_file_size > $this -> upload_chunk_size)
|
||||
{
|
||||
|
||||
if(empty($upload_job['job_data'][basename($file)]['session_id']))
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Creating upload session.','notice');
|
||||
//WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX,WPVIVID_UPLOAD_UNDO,'Start uploading '.basename($file).'.',$upload_job['job_data']);
|
||||
$result = $dropbox -> upload_session_start();
|
||||
if(isset($result['error_summary']))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$result['error_summary']);
|
||||
}
|
||||
|
||||
$upload_job['job_data'][basename($file)]['session_id']= $result['session_id'];
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX,WPVIVID_UPLOAD_UNDO,'Start uploading '.basename($file).'.',$upload_job['job_data']);
|
||||
|
||||
$build_id = $result['session_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$build_id = $upload_job['job_data'][basename($file)]['session_id'];
|
||||
}
|
||||
|
||||
$result = $this -> large_file_upload($task_id,$build_id,$file,$dropbox,$callback);
|
||||
}else{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploaded files are less than 2M.','notice');
|
||||
$result = $dropbox -> upload($path,$file);
|
||||
if(isset($result['error_summary'])){
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX,WPVIVID_UPLOAD_FAILED,'Uploading '.basename($file).' failed.',$upload_job['job_data']);
|
||||
$result = array('result' => WPVIVID_FAILED,'error' => $result['error_summary']);
|
||||
}else{
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
|
||||
$result = array('result'=> WPVIVID_SUCCESS);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function large_file_upload($task_id,$session_id,$file,$dropbox,$callback)
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$fh = fopen($file,'rb');
|
||||
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX);
|
||||
|
||||
$offset = $upload_job['job_data'][basename($file)]['offset'];
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('offset:'.size_format($offset,2),'notice');
|
||||
if ($offset > 0)
|
||||
{
|
||||
fseek($fh, $offset);
|
||||
}
|
||||
|
||||
while($data =fread($fh,$this -> upload_chunk_size))
|
||||
{
|
||||
$ret = $this -> _upload_loop($session_id,$offset,$data,$dropbox);
|
||||
if($ret['result'] !== WPVIVID_SUCCESS)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if((time() - $this -> last_time) >3)
|
||||
{
|
||||
if(is_callable($callback))
|
||||
{
|
||||
call_user_func_array($callback,array(min($offset + $this -> upload_chunk_size,$this -> current_file_size),$this -> current_file_name,
|
||||
$this->current_file_size,$this -> last_time,$this -> last_size));
|
||||
}
|
||||
$this -> last_size = $offset;
|
||||
$this -> last_time = time();
|
||||
}
|
||||
|
||||
if(isset($ret['correct_offset']))
|
||||
{
|
||||
$offset = $ret['correct_offset'];
|
||||
fseek($fh, $offset);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('correct_offset:'.size_format($offset,2),'notice');
|
||||
}
|
||||
else
|
||||
{
|
||||
$offset = ftell($fh);
|
||||
}
|
||||
|
||||
$upload_job['job_data'][basename($file)]['offset']=$offset;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('offset:'.size_format($offset,2),'notice');
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_DROPBOX,WPVIVID_UPLOAD_UNDO,'Uploading '.basename($file),$upload_job['job_data']);
|
||||
}
|
||||
|
||||
$options = $this -> options;
|
||||
$path = trailingslashit($options['path']).basename($file);
|
||||
$result = $dropbox -> upload_session_finish($session_id,$offset,$path);
|
||||
if(isset($result['error_summary']))
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('offset:'.$offset,'notice');
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('result:'.wp_json_encode($result),'notice');
|
||||
$ret = array('result' => WPVIVID_FAILED,'error' => $result['error_summary']);
|
||||
}else{
|
||||
$ret = array('result'=> WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
fclose($fh);
|
||||
return $ret;
|
||||
}
|
||||
public function _upload_loop($session_id,$offset,$data,$dropbox)
|
||||
{
|
||||
$result['result']=WPVIVID_SUCCESS;
|
||||
for($i =0;$i <WPVIVID_REMOTE_CONNECT_RETRY_TIMES; $i ++)
|
||||
{
|
||||
$result = $dropbox -> upload_session_append_v2($session_id,$offset,$data);
|
||||
if(isset($result['error_summary']))
|
||||
{
|
||||
if(strstr($result['error_summary'],'incorrect_offset'))
|
||||
{
|
||||
$result['result']=WPVIVID_SUCCESS;
|
||||
$result['correct_offset']=$result['error']['correct_offset'];
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = array('result' => WPVIVID_FAILED,'error' => 'Uploading '.$this -> current_file_name.' to Dropbox server failed. '.$result['error_summary']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function download($file, $local_path, $callback = '')
|
||||
{
|
||||
try {
|
||||
global $wpvivid_plugin;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Remote type: Dropbox.','notice');
|
||||
$this->current_file_name = $file['file_name'];
|
||||
$this->current_file_size = $file['size'];
|
||||
$options = $this->options;
|
||||
$dropbox = new Dropbox_Base($options);
|
||||
$ret=$dropbox->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
$file_path = trailingslashit($local_path) . $this->current_file_name;
|
||||
$start_offset = file_exists($file_path) ? filesize($file_path) : 0;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Create local file.','notice');
|
||||
$fh = fopen($file_path, 'a');
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Downloading file ' . $file['file_name'] . ', Size: ' . $file['size'] ,'notice');
|
||||
while ($start_offset < $this->current_file_size) {
|
||||
$last_byte = min($start_offset + $this->download_chunk_size - 1, $this->current_file_size - 1);
|
||||
$headers = array("Range: bytes=$start_offset-$last_byte");
|
||||
$response = $dropbox->download(trailingslashit($options['path']) . $this->current_file_name, $headers);
|
||||
if (isset($response['error_summary'])) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . trailingslashit($options['path']) . $this->current_file_name . ' failed.' . $response['error_summary']);
|
||||
}
|
||||
if (!fwrite($fh, $response)) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . trailingslashit($options['path']) . $this->current_file_name . ' failed.');
|
||||
}
|
||||
clearstatcache();
|
||||
$state = stat($file_path);
|
||||
$start_offset = $state['size'];
|
||||
|
||||
if ((time() - $this->last_time) > 3) {
|
||||
if (is_callable($callback)) {
|
||||
call_user_func_array($callback, array($start_offset, $this->current_file_name,
|
||||
$this->current_file_size, $this->last_time, $this->last_size));
|
||||
}
|
||||
$this->last_size = $start_offset;
|
||||
$this->last_time = time();
|
||||
}
|
||||
}
|
||||
@fclose($fh);
|
||||
|
||||
if(filesize($file_path) == $file['size']){
|
||||
if($wpvivid_plugin->wpvivid_check_zip_valid()) {
|
||||
$res = TRUE;
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
|
||||
if ($res !== TRUE) {
|
||||
@wp_delete_file($file_path);
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . $file['file_name'] . ' failed. ' . $file['file_name'] . ' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
catch (Exception $error){
|
||||
$message = 'An exception has occurred. class: '.get_class($error).';msg: '.$error->getMessage().';code: '.$error->getCode().';line: '.$error->getLine().';in_file: '.$error->getFile().';';
|
||||
error_log($message);
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>$message);
|
||||
}
|
||||
}
|
||||
|
||||
public function cleanup($files)
|
||||
{
|
||||
$options = $this -> options;
|
||||
$dropbox = new Dropbox_Base($options);
|
||||
$ret=$dropbox->check_token();
|
||||
if($ret['result']=='failed')
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
foreach ($files as $file){
|
||||
$dropbox -> delete(trailingslashit($options['path']).$file);
|
||||
}
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function init_remotes($remote_collection){
|
||||
$remote_collection[WPVIVID_REMOTE_DROPBOX] = 'WPvivid_Dropbox';
|
||||
return $remote_collection;
|
||||
}
|
||||
|
||||
public function handle_auth_actions()
|
||||
{
|
||||
if(isset($_GET['action']) && isset($_GET['page']))
|
||||
{
|
||||
if($_GET['page'] === 'WPvivid')
|
||||
{
|
||||
if($_GET['action'] === 'wpvivid_dropbox_auth')
|
||||
{
|
||||
$check=current_user_can('manage_options');
|
||||
if(!$check)
|
||||
{
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$rand_id = substr(md5(time().rand()), 0,13);
|
||||
$auth_id = 'wpvivid-auth-'.$rand_id;
|
||||
$state = admin_url() . 'admin.php?page=WPvivid' . '&action=wpvivid_dropbox_finish_auth&main_tab=storage&sub_tab=dropbox&sub_page=storage_account_dropbox&auth_id='.$auth_id;
|
||||
$remote_options['auth_id']=$auth_id;
|
||||
set_transient('dropbox_auth_id', $remote_options, 900);
|
||||
$url = Dropbox_Base::getUrl($this->redirect_url, $state);
|
||||
header('Location: ' . filter_var($url, FILTER_SANITIZE_URL));
|
||||
}
|
||||
catch (Exception $e){
|
||||
echo '<div class="notice notice-error"><p>'.esc_html($e->getMessage()).'</p></div>';
|
||||
}
|
||||
}
|
||||
else if($_GET['action'] === 'wpvivid_dropbox_finish_auth')
|
||||
{
|
||||
$tmp_options = get_transient('dropbox_auth_id');
|
||||
if($tmp_options === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if($tmp_options['auth_id'] !== $_GET['auth_id'])
|
||||
{
|
||||
delete_transient('dropbox_auth_id');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$remoteslist = WPvivid_Setting::get_all_remote_options();
|
||||
foreach ($remoteslist as $key => $value)
|
||||
{
|
||||
if (isset($value['auth_id']) && isset($_GET['auth_id']) && $value['auth_id'] == sanitize_text_field($_GET['auth_id']))
|
||||
{
|
||||
echo '<div class="notice notice-success is-dismissible"><p>';
|
||||
esc_html_e('You have authenticated the Dropbox account as your remote storage.', 'wpvivid-backuprestore');
|
||||
echo '</p></div>';
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(empty($_POST['code']))
|
||||
{
|
||||
if(empty($tmp_options['access_token']))
|
||||
{
|
||||
header('Location: ' . admin_url() . 'admin.php?page=' . WPVIVID_PLUGIN_SLUG . '&action=wpvivid_dropbox_drive&result=error&resp_msg=' . 'Get Dropbox token failed.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp_options['type'] = WPVIVID_REMOTE_DROPBOX;
|
||||
$tmp_options['access_token']= base64_encode(sanitize_text_field($_POST['code']));
|
||||
$tmp_options['expires_in'] = sanitize_text_field($_POST['expires_in']);
|
||||
$tmp_options['refresh_token'] = base64_encode(sanitize_text_field($_POST['refresh_token']));
|
||||
$tmp_options['is_encrypt'] = 1;
|
||||
set_transient('dropbox_auth_id', $tmp_options, 900);
|
||||
}
|
||||
$this->add_remote=true;
|
||||
}
|
||||
catch (Exception $e){
|
||||
echo '<div class="notice notice-error"><p>'.esc_html($e->getMessage()).'</p></div>';
|
||||
}
|
||||
}
|
||||
else if($_GET['action']=='wpvivid_dropbox_drive')
|
||||
{
|
||||
try {
|
||||
if (isset($_GET['result'])) {
|
||||
if ($_GET['result'] == 'success') {
|
||||
add_action('show_notice', array($this, 'wpvivid_show_notice_add_dropbox_success'));
|
||||
} else if ($_GET['result'] == 'error') {
|
||||
add_action('show_notice', array($this, 'wpvivid_show_notice_add_dropbox_error'));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception $e){
|
||||
echo '<div class="notice notice-error"><p>'.esc_html($e->getMessage()).'</p></div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public function wpvivid_show_notice_add_dropbox_success(){
|
||||
echo '<div class="notice notice-success is-dismissible"><p>';
|
||||
esc_html_e('You have authenticated the Dropbox account as your remote storage.', 'wpvivid-backuprestore');
|
||||
echo '</p></div>';
|
||||
}
|
||||
public function wpvivid_show_notice_add_dropbox_error(){
|
||||
global $wpvivid_plugin;
|
||||
$wpvivid_plugin->wpvivid_handle_remote_storage_error($_GET['resp_msg'], 'Add Dropbox Remote');
|
||||
echo '<div class="notice notice-error"><p>'.esc_html($_GET['resp_msg']).'</p></div>';
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_tab_dropbox(){
|
||||
?>
|
||||
<div class="storage-providers" remote_type="dropbox" onclick="select_remote_storage(event, 'storage_account_dropbox');">
|
||||
<img src="<?php echo esc_url(WPVIVID_PLUGIN_URL.'/admin/partials/images/storage-dropbox.png'); ?>" style="vertical-align:middle;"/><?php esc_html_e('Dropbox', 'wpvivid-backuprestore'); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
public function wpvivid_add_storage_page_dropbox(){
|
||||
global $wpvivid_plugin;
|
||||
$root_path=apply_filters('wpvivid_get_root_path', WPVIVID_REMOTE_DROPBOX);
|
||||
|
||||
$remote = get_option('wpvivid_upload_setting');
|
||||
if($this->add_remote)
|
||||
{
|
||||
?>
|
||||
<div id="storage_account_dropbox" class="storage-account-page" style="display:none;">
|
||||
<div style="background-color:#f1f1f1; padding: 10px;">
|
||||
Please read<a target="_blank" href="https://wpvivid.com/privacy-policy" style="text-decoration: none;">this privacy policy</a> for use of our Dropbox authorization app (none of your backup data is sent to us).
|
||||
</div>
|
||||
<div style="color:#8bc34a; padding: 10px 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Authentication is done, please continue to enter the storage information, then click \'Add Now\' button to save it.', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<div style="padding: 10px 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your Dropbox Information', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="dropbox" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. Dropbox-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="dropbox" name="path" value="<?php echo esc_attr($root_path.WPVIVID_DROPBOX_DEFAULT_FOLDER); ?>" readonly="readonly" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('All backups will be uploaded to this directory.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" value="mywebsite01" readonly="readonly" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<a href="https://docs.wpvivid.com/wpvivid-backup-pro-dropbox-custom-folder-name.html"><?php esc_html_e('Pro feature: Create a directory for storing the backups of the site', 'wpvivid-backuprestore'); ?></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="dropbox" name="default" checked /><?php esc_html_e('Set as the default remote storage.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Once checked, all this sites backups sent to a remote storage destination will be uploaded to this storage by default.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input id="wpvivid_dropbox_auth" class="button-primary" type="submit" value="<?php esc_attr_e('Add Now', 'wpvivid-backuprestore'); ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to add the storage.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
function wpvivid_check_dropbox_storage_alias(storage_alias)
|
||||
{
|
||||
var find = 1;
|
||||
jQuery('#wpvivid_remote_storage_list tr').each(function (i) {
|
||||
jQuery(this).children('td').each(function (j) {
|
||||
if (j == 3) {
|
||||
if (jQuery(this).text() == storage_alias) {
|
||||
find = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return find;
|
||||
}
|
||||
|
||||
jQuery('#wpvivid_dropbox_auth').click(function()
|
||||
{
|
||||
wpvivid_dropbox_auth();
|
||||
});
|
||||
|
||||
function wpvivid_dropbox_auth()
|
||||
{
|
||||
wpvivid_settings_changed = false;
|
||||
var name='';
|
||||
var path = '';
|
||||
var bdefault = '0';
|
||||
jQuery("input:checkbox[option=dropbox]").each(function(){
|
||||
var key = jQuery(this).prop('name');
|
||||
if(jQuery(this).prop('checked')) {
|
||||
bdefault = '1';
|
||||
}
|
||||
else {
|
||||
bdefault = '0';
|
||||
}
|
||||
});
|
||||
jQuery('input:text[option=dropbox]').each(function()
|
||||
{
|
||||
var type = jQuery(this).prop('name');
|
||||
if(type == 'name'){
|
||||
name = jQuery(this).val();
|
||||
}
|
||||
});
|
||||
if(name == ''){
|
||||
alert(wpvividlion.remotealias);
|
||||
}
|
||||
else if(wpvivid_check_dropbox_storage_alias(name) === -1){
|
||||
alert(wpvividlion.remoteexist);
|
||||
}
|
||||
else{
|
||||
var ajax_data;
|
||||
var remote_from = wpvivid_ajax_data_transfer('dropbox');
|
||||
ajax_data = {
|
||||
'action': 'wpvivid_dropbox_add_remote',
|
||||
'remote': remote_from
|
||||
};
|
||||
jQuery('#wpvivid_dropbox_auth').css({'pointer-events': 'none', 'opacity': '0.4'});
|
||||
jQuery('#wpvivid_remote_notice').html('');
|
||||
wpvivid_post_request(ajax_data, function (data)
|
||||
{
|
||||
try
|
||||
{
|
||||
var jsonarray = jQuery.parseJSON(data);
|
||||
if (jsonarray.result === 'success')
|
||||
{
|
||||
jQuery('#wpvivid_dropbox_auth').css({'pointer-events': 'auto', 'opacity': '1'});
|
||||
jQuery('input:text[option=dropbox]').each(function(){
|
||||
jQuery(this).val('');
|
||||
});
|
||||
jQuery('input:password[option=dropbox]').each(function(){
|
||||
jQuery(this).val('');
|
||||
});
|
||||
wpvivid_handle_remote_storage_data(data);
|
||||
location.href='admin.php?page=WPvivid&action=wpvivid_dropbox_drive&main_tab=storage&sub_tab=dropbox&sub_page=storage_account_dropbox&result=success';
|
||||
}
|
||||
else if (jsonarray.result === 'failed')
|
||||
{
|
||||
jQuery('#wpvivid_remote_notice').html(jsonarray.notice);
|
||||
jQuery('input[option=add-remote]').css({'pointer-events': 'auto', 'opacity': '1'});
|
||||
}
|
||||
}
|
||||
catch (err)
|
||||
{
|
||||
alert(err);
|
||||
jQuery('input[option=add-remote]').css({'pointer-events': 'auto', 'opacity': '1'});
|
||||
}
|
||||
|
||||
}, function (XMLHttpRequest, textStatus, errorThrown)
|
||||
{
|
||||
var error_message = wpvivid_output_ajaxerror('adding the remote storage', textStatus, errorThrown);
|
||||
alert(error_message);
|
||||
jQuery('#wpvivid_dropbox_auth').css({'pointer-events': 'auto', 'opacity': '1'});
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
?>
|
||||
<div id="storage_account_dropbox" class="storage-account-page" style="display:none;">
|
||||
<div style="background-color:#f1f1f1; padding: 10px;">
|
||||
Please read <a target="_blank" href="https://wpvivid.com/privacy-policy" style="text-decoration: none;">this privacy policy</a> for use of our Dropbox authorization app (none of your backup data is sent to us).
|
||||
</div>
|
||||
<div style="padding: 10px 10px 10px 0;">
|
||||
<strong><?php esc_html_e('To add Dropbox, please get Dropbox authentication first. Once authenticated, you will be redirected to this page, then you can add storage information and save it.', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input onclick="wpvivid_dropbox_auth();" class="button-primary" type="submit" value="<?php esc_attr_e('Authenticate with Dropbox', 'wpvivid-backuprestore'); ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click to get Dropbox authentication.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="padding: 10px 0 0 0;">
|
||||
<span>Tip: Get a 404 or 403 error after authorization? Please read this <a href="https://docs.wpvivid.com/http-403-error-authorizing-cloud-storage.html">doc</a>.</span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function wpvivid_dropbox_auth()
|
||||
{
|
||||
location.href ='<?php echo esc_url(admin_url()).'admin.php?page=WPvivid'.'&action=wpvivid_dropbox_auth'?>';
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
public function wpvivid_edit_storage_page_dropbox()
|
||||
{
|
||||
do_action('wpvivid_remote_storage_js');
|
||||
?>
|
||||
<div id="remote_storage_edit_dropbox" class="postbox storage-account-block remote-storage-edit" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('To add Dropbox, please get Dropbox authentication first. Once authenticated, you will be redirected to this page, then you can add storage information and save it', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-dropbox" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. Dropbox-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" type="submit" option="edit-remote" value="<?php esc_attr_e('Save Changes', 'wpvivid-backuprestore'); ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to save the changes.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
function wpvivid_dropbox_update_auth()
|
||||
{
|
||||
var name='';
|
||||
jQuery('input:text[option=edit-dropbox]').each(function()
|
||||
{
|
||||
var key = jQuery(this).prop('name');
|
||||
if(key==='name')
|
||||
{
|
||||
name = jQuery(this).val();
|
||||
}
|
||||
});
|
||||
if(name == ''){
|
||||
alert(wpvividlion.remotealias);
|
||||
}
|
||||
else if(wpvivid_check_onedrive_storage_alias(name) === -1){
|
||||
alert(wpvividlion.remoteexist);
|
||||
}
|
||||
else {
|
||||
location.href = '<?php echo esc_url(admin_url()) . 'admin.php?page=WPvivid' . '&action=wpvivid_dropbox_update_auth&name='?>' + name + '&id=' + wpvivid_editing_storage_id;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
public function wpvivid_remote_pic_dropbox($remote)
|
||||
{
|
||||
$remote['dropbox']['default_pic'] = '/admin/partials/images/storage-dropbox(gray).png';
|
||||
$remote['dropbox']['selected_pic'] = '/admin/partials/images/storage-dropbox.png';
|
||||
$remote['dropbox']['title'] = 'Dropbox';
|
||||
return $remote;
|
||||
}
|
||||
|
||||
public function revoke($id){
|
||||
$upload_options = WPvivid_Setting::get_option('wpvivid_upload_setting');
|
||||
if(array_key_exists($id,$upload_options) && $upload_options[$id] == WPVIVID_REMOTE_DROPBOX){
|
||||
$dropbox = new Dropbox_Base($upload_options);
|
||||
$dropbox -> revoke();
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_get_out_of_date_dropbox($out_of_date_remote, $remote)
|
||||
{
|
||||
if($remote['type'] == WPVIVID_REMOTE_DROPBOX){
|
||||
$root_path=apply_filters('wpvivid_get_root_path', $remote['type']);
|
||||
$out_of_date_remote = $root_path.$remote['path'];
|
||||
}
|
||||
return $out_of_date_remote;
|
||||
}
|
||||
|
||||
public function wpvivid_storage_provider_dropbox($storage_type)
|
||||
{
|
||||
if($storage_type == WPVIVID_REMOTE_DROPBOX){
|
||||
$storage_type = 'Dropbox';
|
||||
}
|
||||
return $storage_type;
|
||||
}
|
||||
|
||||
public function wpvivid_get_root_path_dropbox($storage_type){
|
||||
if($storage_type == WPVIVID_REMOTE_DROPBOX){
|
||||
$storage_type = 'apps/Wpvivid backup restore';
|
||||
}
|
||||
return $storage_type;
|
||||
}
|
||||
|
||||
public function finish_add_remote()
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
check_ajax_referer( 'wpvivid_ajax', 'nonce' );
|
||||
$check=current_user_can('manage_options');
|
||||
$check=apply_filters('wpvivid_ajax_check_security',$check);
|
||||
if(!$check)
|
||||
{
|
||||
die();
|
||||
}
|
||||
try {
|
||||
if (empty($_POST) || !isset($_POST['remote']) || !is_string($_POST['remote'])) {
|
||||
die();
|
||||
}
|
||||
|
||||
$tmp_remote_options = get_transient('dropbox_auth_id');
|
||||
if($tmp_remote_options === false)
|
||||
{
|
||||
die();
|
||||
}
|
||||
delete_transient('dropbox_auth_id');
|
||||
if(empty($tmp_remote_options)||$tmp_remote_options['type']!==WPVIVID_REMOTE_DROPBOX)
|
||||
{
|
||||
die();
|
||||
}
|
||||
|
||||
$json = sanitize_text_field($_POST['remote']);
|
||||
$json = stripslashes($json);
|
||||
$remote_options = json_decode($json, true);
|
||||
if (is_null($remote_options)) {
|
||||
die();
|
||||
}
|
||||
|
||||
$remote_options['created']=time();
|
||||
$remote_options['path'] = WPVIVID_DROPBOX_DEFAULT_FOLDER;
|
||||
$remote_options=array_merge($remote_options,$tmp_remote_options);
|
||||
if(!class_exists('WPvivid_Remote_collection'))
|
||||
{
|
||||
include_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-remote-collection.php';
|
||||
$wpvivid_plugin->remote_collection=new WPvivid_Remote_collection();
|
||||
}
|
||||
$ret = $wpvivid_plugin->remote_collection->add_remote($remote_options);
|
||||
|
||||
if ($ret['result'] == 'success') {
|
||||
$html = '';
|
||||
$html = apply_filters('wpvivid_add_remote_storage_list', $html);
|
||||
$ret['html'] = $html;
|
||||
$pic = '';
|
||||
$pic = apply_filters('wpvivid_schedule_add_remote_pic', $pic);
|
||||
$ret['pic'] = $pic;
|
||||
$dir = '';
|
||||
$dir = apply_filters('wpvivid_get_remote_directory', $dir);
|
||||
$ret['dir'] = $dir;
|
||||
$schedule_local_remote = '';
|
||||
$schedule_local_remote = apply_filters('wpvivid_schedule_local_remote', $schedule_local_remote);
|
||||
$ret['local_remote'] = $schedule_local_remote;
|
||||
$remote_storage = '';
|
||||
$remote_storage = apply_filters('wpvivid_remote_storage', $remote_storage);
|
||||
$ret['remote_storage'] = $remote_storage;
|
||||
$remote_select_part = '';
|
||||
$remote_select_part = apply_filters('wpvivid_remote_storage_select_part', $remote_select_part);
|
||||
$ret['remote_select_part'] = $remote_select_part;
|
||||
$default = array();
|
||||
$remote_array = apply_filters('wpvivid_archieve_remote_array', $default);
|
||||
$ret['remote_array'] = $remote_array;
|
||||
$success_msg = __('You have successfully added a remote storage.', 'wpvivid-backuprestore');
|
||||
$ret['notice'] = apply_filters('wpvivid_add_remote_notice', true, $success_msg);
|
||||
}
|
||||
else{
|
||||
$ret['notice'] = apply_filters('wpvivid_add_remote_notice', false, $ret['error']);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception $error) {
|
||||
$message = 'An exception has occurred. class: '.get_class($error).';msg: '.$error->getMessage().';code: '.$error->getCode().';line: '.$error->getLine().';in_file: '.$error->getFile().';';
|
||||
error_log($message);
|
||||
echo wp_json_encode(array('result'=>'failed','error'=>$message));
|
||||
die();
|
||||
}
|
||||
echo wp_json_encode($ret);
|
||||
die();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
include_once WPVIVID_PLUGIN_DIR.'/vendor/autoload.php';
|
||||
class WPvivid_Net_SFTP extends Net_SFTP
|
||||
{
|
||||
function get($remote_file, $local_file = false, $offset = 0, $length = -1, $callback = null)
|
||||
{
|
||||
if (!($this->bitmap & NET_SSH2_MASK_LOGIN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$remote_file = $this->_realpath($remote_file);
|
||||
if ($remote_file === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0);
|
||||
if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$response = $this->_get_sftp_packet();
|
||||
switch ($this->packet_type) {
|
||||
case NET_SFTP_HANDLE:
|
||||
$handle = substr($response, 4);
|
||||
break;
|
||||
case NET_SFTP_STATUS:
|
||||
$this->_logError($response);
|
||||
return false;
|
||||
default:
|
||||
user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_resource($local_file)) {
|
||||
$fp = $local_file;
|
||||
$stat = fstat($fp);
|
||||
$res_offset = $stat['size'];
|
||||
} else {
|
||||
$res_offset = 0;
|
||||
if ($local_file !== false) {
|
||||
$fp = fopen($local_file, 'wb');
|
||||
if (!$fp) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$content = '';
|
||||
}
|
||||
}
|
||||
|
||||
$fclose_check = $local_file !== false && !is_resource($local_file);
|
||||
|
||||
$start = $offset;
|
||||
$read = 0;
|
||||
while (true) {
|
||||
$i = 0;
|
||||
|
||||
while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
|
||||
$tempoffset = $start + $read;
|
||||
|
||||
$packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
|
||||
$packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
|
||||
if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet)) {
|
||||
if ($fclose_check) {
|
||||
fclose($fp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$packet = null;
|
||||
$read+= $packet_size;
|
||||
$i++;
|
||||
}
|
||||
|
||||
if (!$i) {
|
||||
break;
|
||||
}
|
||||
|
||||
$clear_responses = false;
|
||||
while ($i > 0) {
|
||||
$i--;
|
||||
|
||||
if ($clear_responses) {
|
||||
$this->_get_sftp_packet();
|
||||
continue;
|
||||
} else {
|
||||
$response = $this->_get_sftp_packet();
|
||||
}
|
||||
|
||||
switch ($this->packet_type) {
|
||||
case NET_SFTP_DATA:
|
||||
$temp = substr($response, 4);
|
||||
$offset+= strlen($temp);
|
||||
if ($local_file === false) {
|
||||
$content.= $temp;
|
||||
} else {
|
||||
fputs($fp, $temp);
|
||||
}
|
||||
|
||||
if( is_callable($callback)){
|
||||
call_user_func_array($callback,array($offset));
|
||||
}
|
||||
|
||||
$temp = null;
|
||||
break;
|
||||
case NET_SFTP_STATUS:
|
||||
$this->_logError($response);
|
||||
$clear_responses = true;
|
||||
break;
|
||||
default:
|
||||
if ($fclose_check) {
|
||||
fclose($fp);
|
||||
}
|
||||
user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
|
||||
}
|
||||
$response = null;
|
||||
}
|
||||
|
||||
if ($clear_responses) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($length > 0 && $length <= $offset - $start) {
|
||||
if ($local_file === false) {
|
||||
$content = substr($content, 0, $length);
|
||||
} else {
|
||||
ftruncate($fp, $length + $res_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if ($fclose_check) {
|
||||
fclose($fp);
|
||||
}
|
||||
|
||||
if (!$this->_close_handle($handle)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset($content) ? $content : true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,694 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
if(!defined('WPVIVID_REMOTE_FTP'))
|
||||
define('WPVIVID_REMOTE_FTP','ftp');
|
||||
|
||||
require_once WPVIVID_PLUGIN_DIR .'/includes/customclass/class-wpvivid-remote.php';
|
||||
class WPvivid_FTPClass extends WPvivid_Remote{
|
||||
private $time_out = 20;
|
||||
private $callback;
|
||||
private $options=array();
|
||||
|
||||
public function __construct($options=array())
|
||||
{
|
||||
if(empty($options))
|
||||
{
|
||||
add_action('wpvivid_add_storage_tab',array($this,'wpvivid_add_storage_tab_ftp'), 15);
|
||||
add_action('wpvivid_add_storage_page',array($this,'wpvivid_add_storage_page_ftp'), 15);
|
||||
add_action('wpvivid_edit_remote_page',array($this,'wpvivid_edit_storage_page_ftp'), 15);
|
||||
add_filter('wpvivid_remote_pic',array($this,'wpvivid_remote_pic_ftp'),9);
|
||||
add_filter('wpvivid_get_out_of_date_remote',array($this,'wpvivid_get_out_of_date_ftp'),10,2);
|
||||
add_filter('wpvivid_storage_provider_tran',array($this,'wpvivid_storage_provider_ftp'),10);
|
||||
|
||||
}else{
|
||||
$this->options = $options;
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_tab_ftp()
|
||||
{
|
||||
?>
|
||||
<div class="storage-providers" remote_type="ftp" onclick="select_remote_storage(event, 'storage_account_ftp');">
|
||||
<img src="<?php echo esc_url(WPVIVID_PLUGIN_URL.'/admin/partials/images/storage-ftp.png'); ?>" style="vertical-align:middle;"/><?php esc_html_e('FTP', 'wpvivid-backuprestore'); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_page_ftp()
|
||||
{
|
||||
?>
|
||||
<div id="storage_account_ftp" class="storage-account-page" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;"><strong><?php esc_html_e('Enter Your FTP Account', 'wpvivid-backuprestore'); ?></strong></div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" option="ftp" name="name" placeholder="<?php esc_attr_e('Enter an unique alias: e.g. FTP-001', 'wpvivid-backuprestore'); ?>" class="regular-text" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" option="ftp" name="server" placeholder="<?php esc_attr_e('FTP server (server\'s port 21)','wpvivid-backuprestore'); ?>" class="regular-text"/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i style="margin-right: 10px;"><?php esc_html_e('Enter the FTP server.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" class="regular-text" value="21" readonly="readonly" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<a href="https://docs.wpvivid.com/wpvivid-backup-pro-ftp-change-ftp-default-port.html"><?php esc_html_e('Pro feature: Change the FTP default port number', 'wpvivid-backuprestore'); ?></a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="ftp" name="username" placeholder="<?php esc_attr_e('FTP login', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your FTP server user name.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="ftp" name="password" placeholder="<?php esc_attr_e('FTP password', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the FTP server password.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" option="ftp" name="path" placeholder="<?php esc_attr_e('Absolute path must exist(e.g. /home/username)', 'wpvivid-backuprestore'); ?>" class="regular-text"/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter an absolute path and a custom subdirectory (optional) for holding the backups of current website. For example, /home/username/customfolder', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="ftp" name="default" checked /><?php esc_html_e('Set as the default remote storage.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Once checked, all this sites backups sent to a remote storage destination will be uploaded to this storage by default.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="ftp" name="passive" checked /><?php esc_html_e('Uncheck this to enable FTP active mode.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Uncheck the option to use FTP active mode when transferring files. Make sure the FTP server you are configuring supports the active FTP mode.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" type="submit" option="add-remote" value="<?php esc_attr_e('Test and Add', 'wpvivid-backuprestore'); ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to connect to FTP server and add it to the storage list below.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_edit_storage_page_ftp()
|
||||
{
|
||||
?>
|
||||
<div id="remote_storage_edit_ftp" class="postbox storage-account-block remote-storage-edit" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;"><strong><?php esc_html_e('Enter Your FTP Account', 'wpvivid-backuprestore'); ?></strong></div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" option="edit-ftp" name="name" placeholder="<?php esc_attr_e('Enter an unique alias: e.g. FTP-001', 'wpvivid-backuprestore'); ?>" class="regular-text" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" option="edit-ftp" name="server" placeholder="<?php esc_attr_e('FTP server (server\'s port 21)', 'wpvivid-backuprestore'); ?>" class="regular-text"/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i style="margin-right: 10px;"><?php esc_html_e('Enter the FTP server.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-ftp" name="username" placeholder="<?php esc_attr_e('FTP login', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your FTP server user name.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="edit-ftp" name="password" placeholder="<?php esc_attr_e('FTP password', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the FTP server password.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" autocomplete="off" option="edit-ftp" name="path" placeholder="<?php esc_attr_e('Absolute path must exist(e.g. /home/username)', 'wpvivid-backuprestore'); ?>" class="regular-text"/>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter an absolute path and a custom subdirectory (optional) for holding the backups of current website. For example, /home/username/customfolder', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="edit-ftp" name="passive" checked /><?php esc_html_e('Uncheck this to enable FTP active mode.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Uncheck the option to use FTP active mode when transferring files. Make sure the FTP server you are configuring supports the active FTP mode.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" type="submit" option="edit-remote" value="<?php esc_attr_e('Save Changes', 'wpvivid-backuprestore'); ?>">
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to save the changes.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_remote_pic_ftp($remote){
|
||||
$remote['ftp']['default_pic'] = '/admin/partials/images/storage-ftp(gray).png';
|
||||
$remote['ftp']['selected_pic'] = '/admin/partials/images/storage-ftp.png';
|
||||
$remote['ftp']['title'] = 'FTP';
|
||||
return $remote;
|
||||
}
|
||||
|
||||
public function test_connect()
|
||||
{
|
||||
$passive =$this->options['passive'];
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
$port = empty($this->options['port'])?21:$this->options['port'];
|
||||
$conn = $this -> do_connect($host,$username,$password,$port);
|
||||
if(is_array($conn) && array_key_exists('result',$conn))
|
||||
return $conn;
|
||||
ftp_pasv($conn,$passive);
|
||||
return $this->do_chdir($conn,$path);
|
||||
}
|
||||
|
||||
|
||||
public function sanitize_options($skip_name='')
|
||||
{
|
||||
$ret['result']=WPVIVID_FAILED;
|
||||
if(!isset($this->options['name']))
|
||||
{
|
||||
$ret['error']=__('Warning: An alias for remote storage is required.','wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['name']=sanitize_text_field($this->options['name']);
|
||||
|
||||
if(empty($this->options['name']))
|
||||
{
|
||||
$ret['error']=__('Warning: An alias for remote storage is required.','wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$remoteslist=WPvivid_Setting::get_all_remote_options();
|
||||
foreach ($remoteslist as $key=>$value)
|
||||
{
|
||||
if(isset($value['name'])&&$value['name'] == $this->options['name']&&$skip_name!=$value['name'])
|
||||
{
|
||||
$ret['error']="Warning: The alias already exists in storage list.";
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
$this->options['server']=sanitize_text_field($this->options['server']);
|
||||
|
||||
if(empty($this->options['server']))
|
||||
{
|
||||
$ret['error']="Warning: The FTP server is required.";
|
||||
return $ret;
|
||||
}
|
||||
$res = explode(':',$this -> options['server']);
|
||||
if(sizeof($res) > 1){
|
||||
$this ->options['host'] = $res[0];
|
||||
if($res[1] != 21){
|
||||
$ret['error']='Currently, only port 21 is supported.';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}else{
|
||||
$this -> options['host'] = $res[0];
|
||||
}
|
||||
|
||||
|
||||
if(!isset($this->options['username']))
|
||||
{
|
||||
$ret['error']="Warning: The FTP login is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['username']=sanitize_text_field($this->options['username']);
|
||||
|
||||
if(empty($this->options['username']))
|
||||
{
|
||||
$ret['error']="Warning: The FTP login is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['password'])||empty($this->options['password']))
|
||||
{
|
||||
$ret['error']="Warning: The FTP password is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['password']=sanitize_text_field($this->options['password']);
|
||||
|
||||
if(empty($this->options['password']))
|
||||
{
|
||||
$ret['error']="Warning: The FTP password is required.";
|
||||
return $ret;
|
||||
}
|
||||
$this->options['password'] = base64_encode($this->options['password']);
|
||||
$this->options['is_encrypt'] = 1;
|
||||
|
||||
if(!isset($this->options['path'])||empty($this->options['path']))
|
||||
{
|
||||
$ret['error']="Warning: The storage path is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['path']=sanitize_text_field($this->options['path']);
|
||||
|
||||
if(empty($this->options['path']))
|
||||
{
|
||||
$ret['error']="Warning: The storage path is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if($this->options['path']=='/')
|
||||
{
|
||||
$ret['error']= __('Warning: Root directory is forbidden to set to \'/\'.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
$ret['options']=$this->options;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function do_connect($server,$username,$password,$port = 21)
|
||||
{
|
||||
$conn = ftp_connect( $server, $port, $this ->time_out );
|
||||
|
||||
if($conn)
|
||||
{
|
||||
if(ftp_login($conn,$username,$password))
|
||||
{
|
||||
return $conn;
|
||||
}
|
||||
else
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Login failed. You have entered the incorrect credential(s). Please try again.');
|
||||
}
|
||||
}
|
||||
else{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Login failed. The connection has timed out. Please try again later.');
|
||||
}
|
||||
}
|
||||
public function do_chdir($conn,$path){
|
||||
@ftp_chdir($conn,'/');
|
||||
if(!@ftp_chdir($conn,$path))
|
||||
{
|
||||
$parts = explode('/',$path);
|
||||
foreach($parts as $part){
|
||||
if($part !== '') {
|
||||
if (!@ftp_chdir($conn, $part)) {
|
||||
if (!ftp_mkdir($conn, $part)) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Failed to create a backup. Make sure you have sufficient privileges to perform the operation.');
|
||||
}
|
||||
|
||||
if (!@ftp_chdir($conn, $part)) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Failed to create a backup. Make sure you have sufficient privileges to perform the operation.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*if ( ! ftp_mkdir( $conn, $path ) )
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Failed to create a backup. Make sure you have sufficient privileges to perform the operation.');
|
||||
}
|
||||
if (!@ftp_chdir($conn,$path))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Failed to create a backup. Make sure you have sufficient privileges to perform the operation.');
|
||||
}*/
|
||||
}
|
||||
$temp_file = md5(wp_rand());
|
||||
$temp_path = trailingslashit(WP_CONTENT_DIR).WPvivid_Setting::get_backupdir().DIRECTORY_SEPARATOR.$temp_file;
|
||||
file_put_contents($temp_path,print_r($temp_file,true));
|
||||
if(! ftp_put($conn,trailingslashit($path).$temp_file,$temp_path,FTP_BINARY)){
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Failed to add FTP storage. It can be because the FTP folder permissions are insufficient, or calling PHP ftp_put function of your web server failed. Please make sure the folder has write permission and the ftp_put function works properly.');
|
||||
}
|
||||
@wp_delete_file($temp_path);
|
||||
@ftp_delete($conn,trailingslashit($path).$temp_file);
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function upload($task_id,$files,$callback = '')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$this -> callback = $callback;
|
||||
|
||||
$passive =$this->options['passive'];
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
$port = empty($this->options['port'])?21:$this->options['port'];
|
||||
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_FTP);
|
||||
if(empty($upload_job))
|
||||
{
|
||||
$job_data=array();
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if(!file_exists($file))
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$file.' not found. The file might has been moved, renamed or deleted. Please back it up again.');
|
||||
$file_data['size']=filesize($file);
|
||||
$file_data['uploaded']=0;
|
||||
$job_data[basename($file)]=$file_data;
|
||||
}
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_FTP,WPVIVID_UPLOAD_UNDO,'Start uploading.',$job_data);
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_FTP);
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Connecting to server '.$host,'notice');
|
||||
$conn = $this -> do_connect($host,$username,$password,$port);
|
||||
if(is_array($conn) && array_key_exists('result',$conn))
|
||||
return $conn;
|
||||
ftp_pasv($conn,$passive);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('chdir '.$path,'notice');
|
||||
$str = $this -> do_chdir($conn , $path);
|
||||
if($str['result'] !== WPVIVID_SUCCESS)
|
||||
return $str;
|
||||
|
||||
$flag = true;
|
||||
$error = '';
|
||||
foreach ($files as $key => $file)
|
||||
{
|
||||
if(is_array($upload_job['job_data']) && array_key_exists(basename($file),$upload_job['job_data']))
|
||||
{
|
||||
if($upload_job['job_data'][basename($file)]['uploaded']==1)
|
||||
continue;
|
||||
}
|
||||
$this ->last_time = time();
|
||||
$this -> last_size = 0;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Start uploading '.basename($file),'notice');
|
||||
$remote_file = trailingslashit($path).basename($file);
|
||||
if(!file_exists($file))
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$file.' not found. The file might has been moved, renamed or deleted. Please back it up again.');
|
||||
|
||||
$wpvivid_plugin->set_time_limit($task_id);
|
||||
|
||||
for($i =0;$i <WPVIVID_REMOTE_CONNECT_RETRY_TIMES;$i ++)
|
||||
{
|
||||
$this -> current_file_name = basename($file);
|
||||
$this -> current_file_size = filesize($file);
|
||||
$this -> last_time = time();
|
||||
$this -> last_size = 0;
|
||||
$local_handle = fopen($file,'rb');
|
||||
if(!$local_handle)
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Failed to open '.$this->current_file_name.'.');
|
||||
}
|
||||
$status = ftp_nb_fput($conn,$remote_file,$local_handle,FTP_BINARY,0);
|
||||
while ($status == FTP_MOREDATA)
|
||||
{
|
||||
$status = ftp_nb_continue($conn);
|
||||
if((time() - $this -> last_time) >3)
|
||||
{
|
||||
if(is_callable($callback)){
|
||||
call_user_func_array($callback,array(ftell($local_handle),$this -> current_file_name,
|
||||
$this->current_file_size,$this -> last_time,$this -> last_size));
|
||||
}
|
||||
$this -> last_size = ftell($local_handle);
|
||||
$this -> last_time = time();
|
||||
}
|
||||
}
|
||||
if ($status != FTP_FINISHED)
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Uploading '.$remote_file.' to FTP server failed. '.$remote_file.' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
|
||||
if($status == FTP_FINISHED)
|
||||
{
|
||||
WPvivid_taskmanager::wpvivid_reset_backup_retry_times($task_id);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Finished uploading '.basename($file),'notice');
|
||||
$upload_job['job_data'][basename($file)]['uploaded']=1;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_FTP,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
|
||||
break;
|
||||
}
|
||||
|
||||
if($status != FTP_FINISHED && $i == (WPVIVID_REMOTE_CONNECT_RETRY_TIMES - 1))
|
||||
{
|
||||
$flag = false;
|
||||
$error = 'Uploading '.basename($file).' to FTP server failed. '.basename($file).' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.';
|
||||
break 2;
|
||||
}
|
||||
sleep(WPVIVID_REMOTE_CONNECT_RETRY_INTERVAL);
|
||||
}
|
||||
}
|
||||
|
||||
if($flag){
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}else{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$error);
|
||||
}
|
||||
}
|
||||
|
||||
public function download($file,$local_path,$callback = '')
|
||||
{
|
||||
try {
|
||||
global $wpvivid_plugin;
|
||||
$passive = $this->options['passive'];
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
$port = empty($this->options['port']) ? 21 : $this->options['port'];
|
||||
|
||||
$local_path = trailingslashit($local_path) . $file['file_name'];
|
||||
$remote_file = trailingslashit($path) . $file['file_name'];
|
||||
|
||||
$this->current_file_name = $file['file_name'];
|
||||
$this->current_file_size = $file['size'];
|
||||
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Connecting FTP server.','notice');
|
||||
$conn = $this->do_connect($host, $username, $password, $port);
|
||||
if (is_array($conn) && array_key_exists('result', $conn)) {
|
||||
return $conn;
|
||||
}
|
||||
|
||||
ftp_pasv($conn, $passive);
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Create local file.','notice');
|
||||
$local_handle = fopen($local_path, 'ab');
|
||||
if (!$local_handle) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Unable to create the local file. Please make sure the folder is writable and try again.');
|
||||
}
|
||||
|
||||
$stat = fstat($local_handle);
|
||||
$offset = $stat['size'];
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Downloading file ' . $file['file_name'] . ', Size: ' . $file['size'] ,'notice');
|
||||
$status = ftp_nb_fget($conn, $local_handle, $remote_file, FTP_BINARY, $offset);
|
||||
while ($status == FTP_MOREDATA) {
|
||||
$status = ftp_nb_continue($conn);
|
||||
if ((time() - $this->last_time) > 3) {
|
||||
if (is_callable($callback)) {
|
||||
call_user_func_array($callback, array(ftell($local_handle), $this->current_file_name,
|
||||
$this->current_file_size, $this->last_time, $this->last_size));
|
||||
}
|
||||
$this->last_size = ftell($local_handle);
|
||||
$this->last_time = time();
|
||||
}
|
||||
}
|
||||
|
||||
if(filesize($local_path) == $file['size']){
|
||||
if($wpvivid_plugin->wpvivid_check_zip_valid()) {
|
||||
$res = TRUE;
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
|
||||
if ($status != FTP_FINISHED || $res !== TRUE) {
|
||||
@wp_delete_file($local_path);
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . $remote_file . ' failed. ' . $remote_file . ' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
|
||||
ftp_close($conn);
|
||||
fclose($local_handle);
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
catch (Exception $error){
|
||||
$message = 'An exception has occurred. class: '.get_class($error).';msg: '.$error->getMessage().';code: '.$error->getCode().';line: '.$error->getLine().';in_file: '.$error->getFile().';';
|
||||
error_log($message);
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>$message);
|
||||
}
|
||||
}
|
||||
|
||||
public function cleanup($file){
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
$port = empty($this->options['port'])?21:$this->options['port'];
|
||||
|
||||
$conn = $this -> do_connect($host,$username,$password,$port);
|
||||
if(is_array($conn) && array_key_exists('result',$conn))
|
||||
return $conn;
|
||||
|
||||
foreach ($file as $value){
|
||||
@ftp_delete($conn,trailingslashit($path).$value);
|
||||
}
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function init_remotes($remote_collection){
|
||||
$remote_collection[WPVIVID_REMOTE_FTP] = 'WPvivid_FTPClass';
|
||||
return $remote_collection;
|
||||
}
|
||||
|
||||
public function wpvivid_get_out_of_date_ftp($out_of_date_remote, $remote)
|
||||
{
|
||||
if($remote['type'] == WPVIVID_REMOTE_FTP){
|
||||
$out_of_date_remote = $remote['path'];
|
||||
}
|
||||
return $out_of_date_remote;
|
||||
}
|
||||
|
||||
public function wpvivid_storage_provider_ftp($storage_type)
|
||||
{
|
||||
if($storage_type == WPVIVID_REMOTE_FTP){
|
||||
$storage_type = 'FTP';
|
||||
}
|
||||
return $storage_type;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
if(!defined('WPVIVID_UPLOAD_SUCCESS'))
|
||||
{
|
||||
define('WPVIVID_UPLOAD_SUCCESS',1);
|
||||
}
|
||||
|
||||
if(!defined('WPVIVID_UPLOAD_FAILED'))
|
||||
{
|
||||
define('WPVIVID_UPLOAD_FAILED',2);
|
||||
}
|
||||
|
||||
if(!defined('WPVIVID_UPLOAD_UNDO'))
|
||||
{
|
||||
define('WPVIVID_UPLOAD_UNDO',0);
|
||||
}
|
||||
|
||||
require_once WPVIVID_PLUGIN_DIR .'/includes/customclass/class-wpvivid-remote.php';
|
||||
class WPvivid_Remote_Defult extends WPvivid_Remote{
|
||||
public function test_connect()
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error'=> 'Type incorrect.');
|
||||
}
|
||||
|
||||
public function upload($task_id, $files, $callback = '')
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error'=> 'Type incorrect.');
|
||||
}
|
||||
|
||||
public function download( $file, $local_path, $callback = '')
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error'=> 'Type incorrect.');
|
||||
}
|
||||
|
||||
public function cleanup($files)
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error'=> 'Type incorrect.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
abstract class WPvivid_Remote{
|
||||
public $current_file_name = '';
|
||||
public $current_file_size = '';
|
||||
public $last_time = 0;
|
||||
public $last_size = 0;
|
||||
|
||||
public $object;
|
||||
public $remote;
|
||||
|
||||
abstract public function test_connect();
|
||||
abstract public function upload($task_id,$files,$callback = ''); // $files = array();
|
||||
abstract public function download($file,$local_path,$callback = ''); // $file = array('file_name' => ,'size' =>,'md5' =>)
|
||||
abstract public function cleanup($files); // $files = array();
|
||||
|
||||
public function formatBytes($bytes, $precision = 2)
|
||||
{
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
$bytes /= (1 << (10 * $pow));
|
||||
return round($bytes, $precision) . '' . $units[$pow];
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,766 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
if(!defined('WPVIVID_REMOTE_S3COMPAT')){
|
||||
define('WPVIVID_REMOTE_S3COMPAT','s3compat');
|
||||
}
|
||||
if(!defined('WPVIVID_S3COMPAT_DEFAULT_FOLDER'))
|
||||
define('WPVIVID_S3COMPAT_DEFAULT_FOLDER','/wpvivid_backup');
|
||||
if(!defined('WPVIVID_S3COMPAT_NEED_PHP_VERSION'))
|
||||
define('WPVIVID_S3COMPAT_NEED_PHP_VERSION','5.3.9');
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-remote.php';
|
||||
use Aws\S3\S3Client;
|
||||
use Aws\S3\Exception\S3Exception;
|
||||
class Wpvivid_S3Compat extends WPvivid_Remote{
|
||||
private $options;
|
||||
private $bucket;
|
||||
private $region;
|
||||
|
||||
private $upload_chunk_size = 5242880; // All parts except the last part must be no smaller than 5MB
|
||||
private $download_chunk_size = 2097152;
|
||||
|
||||
public function __construct($options = array())
|
||||
{
|
||||
if(empty($options)){
|
||||
add_action('wpvivid_add_storage_tab',array($this,'wpvivid_add_storage_tab_s3compat'), 14);
|
||||
add_action('wpvivid_add_storage_page',array($this,'wpvivid_add_storage_page_s3compat'), 14);
|
||||
add_action('wpvivid_edit_remote_page',array($this,'wpvivid_edit_storage_page_s3compat'), 14);
|
||||
add_filter('wpvivid_remote_pic',array($this,'wpvivid_remote_pic_s3compat'),11);
|
||||
add_filter('wpvivid_get_out_of_date_remote',array($this,'wpvivid_get_out_of_date_s3compat'),10,2);
|
||||
add_filter('wpvivid_storage_provider_tran',array($this,'wpvivid_storage_provider_s3compat'),10);
|
||||
|
||||
}else{
|
||||
$this -> options = $options;
|
||||
}
|
||||
}
|
||||
|
||||
public function getClient(){
|
||||
$res = $this -> compare_php_version();
|
||||
if($res['result'] == WPVIVID_FAILED)
|
||||
return $res;
|
||||
|
||||
if(isset($this->options['s3directory']))
|
||||
{
|
||||
$path_temp = str_replace('s3generic://','',$this->options['s3directory'].$this -> options['path']);
|
||||
if (preg_match("#^/*([^/]+)/(.*)$#", $path_temp, $bmatches))
|
||||
{
|
||||
$this->bucket = $bmatches[1];
|
||||
} else {
|
||||
$this->bucket = $path_temp;
|
||||
}
|
||||
$this->options['path']=ltrim($this -> options['path'],'/');
|
||||
$endpoint_temp = str_replace('https://','',$this->options['endpoint']);
|
||||
$explodes = explode('.',$endpoint_temp);
|
||||
$this -> region = $explodes[0];
|
||||
$this -> options['endpoint'] = 'https://'.trailingslashit($endpoint_temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
$endpoint_temp = str_replace('https://','',$this->options['endpoint']);
|
||||
$explodes = explode('.',$endpoint_temp);
|
||||
$this -> region = $explodes[0];
|
||||
$this -> options['endpoint'] = 'https://'.trailingslashit($endpoint_temp);
|
||||
$this -> bucket=$this->options['bucket'];
|
||||
}
|
||||
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$secret = base64_decode($this->options['secret']);
|
||||
}
|
||||
else {
|
||||
$secret = $this->options['secret'];
|
||||
}
|
||||
include_once WPVIVID_PLUGIN_DIR.'/vendor/autoload.php';
|
||||
$s3compat = S3Client::factory(
|
||||
array(
|
||||
'credentials' => array(
|
||||
'key' => $this -> options['access'],
|
||||
'secret' => $secret,
|
||||
),
|
||||
'version' => 'latest',
|
||||
'region' => $this -> region,
|
||||
'endpoint' => $this -> options['endpoint'],
|
||||
)
|
||||
);
|
||||
return $s3compat;
|
||||
}
|
||||
|
||||
public function test_connect()
|
||||
{
|
||||
$s3compat = $this -> getClient();
|
||||
if(is_array($s3compat) && $s3compat['result'] == WPVIVID_FAILED)
|
||||
{
|
||||
return $s3compat;
|
||||
}
|
||||
|
||||
$temp_file = md5(wp_rand());
|
||||
|
||||
try
|
||||
{
|
||||
$result = $s3compat->putObject(
|
||||
array(
|
||||
'Bucket'=>$this->bucket,
|
||||
'Key' => $this->options['path'].'/'.$temp_file,
|
||||
'Body' => $temp_file,
|
||||
)
|
||||
);
|
||||
$etag = $result->get('ETag');
|
||||
if(!isset($etag))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'We successfully accessed the bucket, but create test file failed.');
|
||||
}
|
||||
$result = $s3compat->deleteObject(array(
|
||||
'Bucket' => $this -> bucket,
|
||||
'Key' => $this -> options['path'].'/'.$temp_file,
|
||||
));
|
||||
if(empty($result))
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'We successfully accessed the bucket, and create test file succeed, but delete test file failed.');
|
||||
}
|
||||
}
|
||||
catch(S3Exception $e)
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getAwsErrorCode().$e -> getMessage());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getMessage());
|
||||
}
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function upload($task_id, $files, $callback = '')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$s3compat = $this -> getClient();
|
||||
if(is_array($s3compat) && $s3compat['result'] == WPVIVID_FAILED)
|
||||
{
|
||||
return $s3compat;
|
||||
}
|
||||
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_S3COMPAT);
|
||||
if(empty($upload_job))
|
||||
{
|
||||
$job_data=array();
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$file_data['size']=filesize($file);
|
||||
$file_data['uploaded']=0;
|
||||
$job_data[basename($file)]=$file_data;
|
||||
}
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_S3COMPAT,WPVIVID_UPLOAD_UNDO,'Start uploading',$job_data);
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_S3COMPAT);
|
||||
}
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if(is_array($upload_job['job_data'])&&array_key_exists(basename($file),$upload_job['job_data']))
|
||||
{
|
||||
if($upload_job['job_data'][basename($file)]['uploaded']==1)
|
||||
continue;
|
||||
}
|
||||
$this->last_time = time();
|
||||
$this->last_size = 0;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Start uploading '.basename($file),'notice');
|
||||
$wpvivid_plugin->set_time_limit($task_id);
|
||||
if(!file_exists($file)){
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploading '.basename($file).' failed.','notice');
|
||||
return array('result' =>WPVIVID_FAILED,'error' =>$file.' not found. The file might has been moved, renamed or deleted. Please reload the list and verify the file exists.');
|
||||
}
|
||||
$result = $this->_put($task_id,$s3compat,$file,$callback);
|
||||
if($result['result'] !==WPVIVID_SUCCESS)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploading '.basename($file).' failed.','notice');
|
||||
return $result;
|
||||
}
|
||||
else
|
||||
{
|
||||
WPvivid_taskmanager::wpvivid_reset_backup_retry_times($task_id);
|
||||
}
|
||||
$upload_job['job_data'][basename($file)]['uploaded']=1;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Finished uploading '.basename($file),'notice');
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_S3COMPAT,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
|
||||
}
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
public function _put($task_id,$s3compat,$file,$callback){
|
||||
$path = $this->options['path'].'/'.basename($file);
|
||||
$this->current_file_size = filesize($file);
|
||||
$this->current_file_name = basename($file);
|
||||
|
||||
try
|
||||
{
|
||||
if($this->current_file_size > $this->upload_chunk_size)
|
||||
{
|
||||
$result = $s3compat ->createMultipartUpload(array(
|
||||
'Bucket' => $this -> bucket,
|
||||
'Key' => $path,
|
||||
));
|
||||
if(!isset($result['UploadId']))
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Creating upload task failed. Please try again.');
|
||||
|
||||
$uploadId = $result['UploadId'];
|
||||
$fh = fopen($file,'rb');
|
||||
$partNumber = 1;
|
||||
$parts = array();
|
||||
$offset = 0;
|
||||
while(!feof($fh))
|
||||
{
|
||||
$data = fread($fh,$this -> upload_chunk_size);
|
||||
$result = $this -> _upload_loop($s3compat,$uploadId,$path,$data,$partNumber,$parts);
|
||||
if($result['result'] === WPVIVID_FAILED)
|
||||
break;
|
||||
|
||||
$partNumber ++;
|
||||
$offset += $this -> upload_chunk_size;
|
||||
if((time() - $this -> last_time) >3)
|
||||
{
|
||||
if(is_callable($callback))
|
||||
{
|
||||
call_user_func_array($callback,array(min($offset,$this -> current_file_size),$this -> current_file_name,
|
||||
$this->current_file_size,$this -> last_time,$this -> last_size));
|
||||
}
|
||||
$this -> last_size = $offset;
|
||||
$this -> last_time = time();
|
||||
}
|
||||
}
|
||||
fclose($fh);
|
||||
|
||||
if($result['result'] === WPVIVID_SUCCESS)
|
||||
{
|
||||
$ret = $s3compat ->completeMultipartUpload
|
||||
(
|
||||
array(
|
||||
'Bucket' => $this -> bucket,
|
||||
'Key' => $path,
|
||||
'Parts' => $parts,
|
||||
'UploadId' => $uploadId,
|
||||
)
|
||||
);
|
||||
if(!isset($ret['Location']))
|
||||
{
|
||||
$result = array('result' => WPVIVID_FAILED, 'error' => 'Merging multipart failed. File name: '.$this -> current_file_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$res = $s3compat ->putObject(
|
||||
array(
|
||||
'Bucket'=>$this -> bucket,
|
||||
'Key' => $path,
|
||||
'SourceFile' => $file,
|
||||
)
|
||||
);
|
||||
$etag = $res -> get('ETag');
|
||||
if(isset($etag))
|
||||
{
|
||||
$result = array('result' => WPVIVID_SUCCESS);
|
||||
}else {
|
||||
$result = array('result' => WPVIVID_FAILED , 'error' => 'upload '.$this -> current_file_name.' failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(S3Exception $e)
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getAwsErrorCode().$e -> getMessage());
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getMessage());
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
public function _upload_loop($s3compat,$uploadId,$path,$data,$partNumber,&$parts){
|
||||
for($i =0;$i <WPVIVID_REMOTE_CONNECT_RETRY_TIMES;$i ++)
|
||||
{
|
||||
$ret = $s3compat ->uploadPart(array(
|
||||
'Bucket' => $this ->bucket,
|
||||
'Key' => $path,
|
||||
'UploadId' => $uploadId,
|
||||
'PartNumber' => $partNumber,
|
||||
'Body' => $data,
|
||||
));
|
||||
if(isset($ret['ETag']))
|
||||
{
|
||||
$parts[] = array(
|
||||
'ETag' => $ret['ETag'],
|
||||
'PartNumber' => $partNumber,
|
||||
);
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
}
|
||||
return array('result' => WPVIVID_FAILED,'error' =>'Multipart upload failed. File name: '.$this -> current_file_name);
|
||||
}
|
||||
|
||||
public function download($file, $local_path, $callback = '')
|
||||
{
|
||||
try {
|
||||
global $wpvivid_plugin;
|
||||
$this->current_file_name = $file['file_name'];
|
||||
$this->current_file_size = $file['size'];
|
||||
$file_path = trailingslashit($local_path) . $this->current_file_name;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Get s3compat client.','notice');
|
||||
$s3compat = $this->getClient();
|
||||
if (is_array($s3compat) && $s3compat['result'] == WPVIVID_FAILED) {
|
||||
return $s3compat;
|
||||
}
|
||||
|
||||
$start_offset = file_exists($file_path) ? filesize($file_path) : 0;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Create local file.','notice');
|
||||
$fh = fopen($file_path, 'a');
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Downloading file ' . $file['file_name'] . ', Size: ' . $file['size'] ,'notice');
|
||||
while ($start_offset < $this->current_file_size)
|
||||
{
|
||||
$last_byte = min($start_offset + $this->download_chunk_size - 1, $this->current_file_size - 1);
|
||||
$range = "bytes=$start_offset-$last_byte";
|
||||
$response = $this->_download_loop($s3compat, $range, $fh);
|
||||
if ($response['result'] === WPVIVID_FAILED)
|
||||
{
|
||||
return $response;
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
$state = stat($file_path);
|
||||
$start_offset = $state['size'];
|
||||
if ((time() - $this->last_time) > 3)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
call_user_func_array($callback, array($start_offset, $this->current_file_name,
|
||||
$this->current_file_size, $this->last_time, $this->last_size));
|
||||
}
|
||||
$this->last_size = $start_offset;
|
||||
$this->last_time = time();
|
||||
}
|
||||
}
|
||||
@fclose($fh);
|
||||
|
||||
if(filesize($file_path) == $file['size'])
|
||||
{
|
||||
if($wpvivid_plugin->wpvivid_check_zip_valid())
|
||||
{
|
||||
$res = TRUE;
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
|
||||
if ($res !== TRUE) {
|
||||
@wp_delete_file($file_path);
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . $file['file_name'] . ' failed. ' . $file['file_name'] . ' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
catch (S3Exception $e) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => $e->getAwsErrorCode() . $e->getMessage());
|
||||
}
|
||||
catch (Exception $error){
|
||||
$message = 'An exception has occurred. class: '.get_class($error).';msg: '.$error->getMessage().';code: '.$error->getCode().';line: '.$error->getLine().';in_file: '.$error->getFile().';';
|
||||
error_log($message);
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>$message);
|
||||
}
|
||||
}
|
||||
|
||||
public function _download_loop($s3compat,$range,$fh){
|
||||
try{
|
||||
for($i =0;$i <WPVIVID_REMOTE_CONNECT_RETRY_TIMES;$i ++){
|
||||
$response = $s3compat -> getObject(array(
|
||||
'Bucket' => $this -> bucket,
|
||||
'Key' => $this -> options['path'].'/'.$this -> current_file_name,
|
||||
'Range' => $range
|
||||
));
|
||||
if(isset($response['Body']) && fwrite($fh,$response['Body'])) {
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
}
|
||||
return array('result'=>WPVIVID_FAILED, 'error' => 'download '.$this -> current_file_name.' failed.');
|
||||
}catch(S3Exception $e){
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getAwsErrorCode().$e -> getMessage());
|
||||
}catch(Exception $e){
|
||||
return array('result' => WPVIVID_FAILED,'error' => $e -> getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function cleanup($files)
|
||||
{
|
||||
$s3compat = $this -> getClient();
|
||||
if(is_array($s3compat) && $s3compat['result'] == WPVIVID_FAILED){
|
||||
return $s3compat;
|
||||
}
|
||||
|
||||
$keys = array();
|
||||
foreach ($files as $file){
|
||||
$keys[] = array('Key' => $this -> options['path'].'/'.basename($file));
|
||||
}
|
||||
try{
|
||||
$result = $s3compat -> deleteObjects(array(
|
||||
// Bucket is required
|
||||
'Bucket' => $this -> bucket,
|
||||
// Objects is required
|
||||
'Objects' => $keys
|
||||
));
|
||||
}catch (S3Exception $e){}catch (Exception $e){}
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_tab_s3compat(){
|
||||
?>
|
||||
<div class="storage-providers" remote_type="s3compat" onclick="select_remote_storage(event, 'storage_account_s3compat');">
|
||||
<img src="<?php echo esc_url(WPVIVID_PLUGIN_URL.'/admin/partials/images/storage-digitalocean.png'); ?>" style="vertical-align:middle;"/><?php esc_html_e('DigitalOcean Spaces', 'wpvivid-backuprestore'); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_page_s3compat(){
|
||||
?>
|
||||
<div id="storage_account_s3compat" class="storage-account-page" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your DigitalOcean Spaces Account', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="s3compat" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. DOS-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="s3compat" name="access" placeholder="<?php esc_attr_e('DigitalOcean Spaces access key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your DigitalOcean Spaces access key', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="s3compat" name="secret" placeholder="<?php esc_attr_e('DigitalOcean Spaces secret key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your DigitalOcean Spaces secret key', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="s3compat" name="bucket" placeholder="<?php esc_attr_e('Space Name(e.g. test)', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Enter an existed Space to create a custom backup storage directory.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="s3compat" name="path" placeholder="<?php esc_attr_e('Custom Path', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Customize the directory where you want to store backups within the Space.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="s3compat" name="endpoint" placeholder="<?php esc_attr_e('region.digitaloceanspaces.com', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the DigitalOcean Endpoint for the storage', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="s3compat" name="default" checked /><?php esc_html_e('Set as the default remote storage.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Once checked, all this sites backups sent to a remote storage destination will be uploaded to this storage by default.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" option="add-remote" type="submit" value="<?php esc_attr_e('Test and Add', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to connect to DigitalOcean Spaces storage and add it to the storage list below.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_edit_storage_page_s3compat()
|
||||
{
|
||||
?>
|
||||
<div id="remote_storage_edit_s3compat" class="postbox storage-account-block remote-storage-edit" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your DigitalOcean Spaces Account', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-s3compat" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. DOS-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-s3compat" name="access" placeholder="<?php esc_attr_e('DigitalOcean Spaces access key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your DigitalOcean Spaces access key', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="edit-s3compat" name="secret" placeholder="<?php esc_attr_e('DigitalOcean Spaces secret key', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter your DigitalOcean Spaces secret key', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-s3compat" name="bucket" placeholder="<?php esc_attr_e('Space Name(e.g. test)', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Enter an existed Space to create a custom backup storage directory.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-s3compat" name="path" placeholder="<?php esc_attr_e('Custom Path', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><span><?php esc_html_e('Customize the directory where you want to store backups within the Space.', 'wpvivid-backuprestore'); ?></span></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-s3compat" name="endpoint" placeholder="<?php esc_attr_e('region.digitaloceanspaces.com', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the DigitalOcean Endpoint for the storage', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" option="edit-remote" type="submit" value="<?php esc_attr_e('Save Changes', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to save the changes.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
jQuery("input:text[option=edit-s3compat][name=s3directory]").keyup(function(){
|
||||
var value = jQuery(this).val();
|
||||
if(value == ''){
|
||||
value = '*';
|
||||
}
|
||||
value = value + '/wpvivid_backup';
|
||||
jQuery('#wpvivid_edit_dos_root_path').html(value);
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_remote_pic_s3compat($remote){
|
||||
$remote['s3compat']['default_pic'] = '/admin/partials/images/storage-digitalocean(gray).png';
|
||||
$remote['s3compat']['selected_pic'] = '/admin/partials/images/storage-digitalocean.png';
|
||||
$remote['s3compat']['title'] = 'DigitalOcean Spaces';
|
||||
return $remote;
|
||||
}
|
||||
|
||||
public function sanitize_options($skip_name='')
|
||||
{
|
||||
$ret['result']=WPVIVID_FAILED;
|
||||
if(!isset($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['name']=sanitize_text_field($this->options['name']);
|
||||
|
||||
if(empty($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$remoteslist=WPvivid_Setting::get_all_remote_options();
|
||||
foreach ($remoteslist as $key=>$value)
|
||||
{
|
||||
if(isset($value['name'])&&$value['name'] == $this->options['name']&&$skip_name!=$value['name'])
|
||||
{
|
||||
$ret['error']="Warning: The alias already exists in storage list.";
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($this->options['access']))
|
||||
{
|
||||
$ret['error']="Warning: The access key for S3-Compatible is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['access']=sanitize_text_field($this->options['access']);
|
||||
|
||||
if(empty($this->options['access']))
|
||||
{
|
||||
$ret['error']="Warning: The access key for S3-Compatible is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['secret']))
|
||||
{
|
||||
$ret['error']="Warning: The storage secret key is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['secret']=sanitize_text_field($this->options['secret']);
|
||||
|
||||
if(empty($this->options['secret']))
|
||||
{
|
||||
$ret['error']="Warning: The storage secret key is required.";
|
||||
return $ret;
|
||||
}
|
||||
$this->options['secret'] = base64_encode($this->options['secret']);
|
||||
$this->options['is_encrypt'] = 1;
|
||||
|
||||
if(empty($this->options['bucket']))
|
||||
{
|
||||
$ret['error']="Warning: A Digital Space is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['path']))
|
||||
{
|
||||
$ret['error']="Warning: A directory name is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['path']=sanitize_text_field($this->options['path']);
|
||||
|
||||
if(empty($this->options['path'])){
|
||||
$ret['error']="Warning: A directory name is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['endpoint']))
|
||||
{
|
||||
$ret['error']="Warning: The end-point is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['endpoint']=sanitize_text_field($this->options['endpoint']);
|
||||
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
$ret['options']=$this->options;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_get_out_of_date_s3compat($out_of_date_remote, $remote)
|
||||
{
|
||||
if($remote['type'] == WPVIVID_REMOTE_S3COMPAT)
|
||||
{
|
||||
if(isset($remote['s3directory']))
|
||||
$out_of_date_remote = $remote['s3directory'].$remote['path'];
|
||||
else
|
||||
$out_of_date_remote = $remote['path'];
|
||||
}
|
||||
return $out_of_date_remote;
|
||||
}
|
||||
|
||||
public function wpvivid_storage_provider_s3compat($storage_type)
|
||||
{
|
||||
if($storage_type == WPVIVID_REMOTE_S3COMPAT){
|
||||
$storage_type = 'DigitalOcean Spaces';
|
||||
}
|
||||
return $storage_type;
|
||||
}
|
||||
private function compare_php_version(){
|
||||
if(version_compare(WPVIVID_GOOGLE_NEED_PHP_VERSION,phpversion()) > 0){
|
||||
return array('result' => WPVIVID_FAILED,'error' => 'The required PHP version is higher than '.WPVIVID_S3COMPAT_NEED_PHP_VERSION.'. After updating your PHP version, please try again.');
|
||||
}
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,721 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
if(!defined('WPVIVID_REMOTE_SFTP'))
|
||||
define('WPVIVID_REMOTE_SFTP','sftp');
|
||||
require_once WPVIVID_PLUGIN_DIR .'/includes/customclass/class-wpvivid-remote.php';
|
||||
|
||||
class WPvivid_SFTPClass extends WPvivid_Remote{
|
||||
private $package_size = 10;
|
||||
private $timeout = 20;
|
||||
private $error_str=false;
|
||||
private $callback;
|
||||
private $options=array();
|
||||
|
||||
public function __construct($options=array())
|
||||
{
|
||||
if(empty($options))
|
||||
{
|
||||
add_action('wpvivid_add_storage_tab',array($this,'wpvivid_add_storage_tab_sftp'), 16);
|
||||
add_action('wpvivid_add_storage_page',array($this,'wpvivid_add_storage_page_sftp'), 16);
|
||||
add_action('wpvivid_edit_remote_page',array($this,'wpvivid_edit_storage_page_sftp'), 16);
|
||||
add_filter('wpvivid_remote_pic',array($this,'wpvivid_remote_pic_sftp'),10);
|
||||
add_filter('wpvivid_get_out_of_date_remote',array($this,'wpvivid_get_out_of_date_sftp'),10,2);
|
||||
add_filter('wpvivid_storage_provider_tran',array($this,'wpvivid_storage_provider_sftp'),10);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->options=$options;
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_tab_sftp()
|
||||
{
|
||||
?>
|
||||
<div class="storage-providers" remote_type="sftp" onclick="select_remote_storage(event, 'storage_account_sftp');">
|
||||
<img src="<?php echo esc_url(WPVIVID_PLUGIN_URL.'/admin/partials/images/storage-sftp.png'); ?>" style="vertical-align:middle;"/><?php esc_html_e('SFTP', 'wpvivid-backuprestore'); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_add_storage_page_sftp()
|
||||
{
|
||||
?>
|
||||
<div id="storage_account_sftp" class="storage-account-page" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your SFTP Account', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="sftp" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. SFTP-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="sftp" name="host" placeholder="<?php esc_attr_e('Server Address', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the server address.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="sftp" name="username" placeholder="<?php esc_attr_e('User Name', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the user name.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="sftp" name="password" placeholder="<?php esc_attr_e('User Password', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the user password.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="sftp" name="port" placeholder="<?php esc_attr_e('Port', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/\D/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the server port.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="sftp" name="path" placeholder="<?php esc_attr_e('Absolute path must exist(e.g. /var)', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter an absolute path and a custom subdirectory (optional) for holding the backups of current website. For example, /var/customfolder/', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-select">
|
||||
<label>
|
||||
<input type="checkbox" option="sftp" name="default" checked /><?php esc_html_e('Set as the default remote storage.', 'wpvivid-backuprestore'); ?>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Once checked, all this sites backups sent to a remote storage destination will be uploaded to this storage by default.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" option="add-remote" type="submit" value="<?php esc_attr_e('Test and Add', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to connect to SFTP server and add it to the storage list below.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_edit_storage_page_sftp()
|
||||
{
|
||||
?>
|
||||
<div id="remote_storage_edit_sftp" class="postbox storage-account-block remote-storage-edit" style="display:none;">
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<strong><?php esc_html_e('Enter Your SFTP Account', 'wpvivid-backuprestore'); ?></strong>
|
||||
</div>
|
||||
<table class="wp-list-table widefat plugins" style="width:100%;">
|
||||
<tbody>
|
||||
<form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-sftp" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. SFTP-001', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/[^a-zA-Z0-9\-_]/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('A name to help you identify the storage if you have multiple remote storage connected.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-sftp" name="host" placeholder="<?php esc_attr_e('Server Address', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the server address.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-sftp" name="username" placeholder="<?php esc_attr_e('User Name', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the user name.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="password" class="regular-text" autocomplete="new-password" option="edit-sftp" name="password" placeholder="<?php esc_attr_e('User Password', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the user password.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-sftp" name="port" placeholder="<?php esc_attr_e('Port', 'wpvivid-backuprestore'); ?>" onkeyup="value=value.replace(/\D/g,'')" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter the server port.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input type="text" class="regular-text" autocomplete="off" option="edit-sftp" name="path" placeholder="<?php esc_attr_e('Absolute path must exist(e.g. /var)', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Enter an absolute path and a custom subdirectory (optional) for holding the backups of current website. For example, /var/customfolder/', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</form>
|
||||
<tr>
|
||||
<td class="plugin-title column-primary">
|
||||
<div class="wpvivid-storage-form">
|
||||
<input class="button-primary" option="edit-remote" type="submit" value="<?php esc_attr_e('Save Changes', 'wpvivid-backuprestore'); ?>" />
|
||||
</div>
|
||||
</td>
|
||||
<td class="column-description desc">
|
||||
<div class="wpvivid-storage-form-desc">
|
||||
<i><?php esc_html_e('Click the button to save the changes.', 'wpvivid-backuprestore'); ?></i>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function wpvivid_remote_pic_sftp($remote)
|
||||
{
|
||||
$remote['sftp']['default_pic'] = '/admin/partials/images/storage-sftp(gray).png';
|
||||
$remote['sftp']['selected_pic'] = '/admin/partials/images/storage-sftp.png';
|
||||
$remote['sftp']['title'] = 'SFTP';
|
||||
return $remote;
|
||||
}
|
||||
|
||||
public function test_connect()
|
||||
{
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
|
||||
$port = empty($this->options['port'])?22:$this->options['port'];
|
||||
|
||||
$conn = $this->do_connect($host,$username,$password,$port);
|
||||
if(!is_subclass_of($conn,'Net_SSH2'))
|
||||
{
|
||||
return $conn;
|
||||
}
|
||||
$str = $this->do_chdir($conn,$path);
|
||||
if($str['result'] == WPVIVID_SUCCESS)
|
||||
{
|
||||
if($conn->put(trailingslashit($path) . 'testfile', 'test data', NET_SFTP_STRING))
|
||||
{
|
||||
$this -> _delete($conn ,trailingslashit($path) . 'testfile');
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Failed to create a test file. Please try again later.');
|
||||
}else{
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
public function sanitize_options($skip_name='')
|
||||
{
|
||||
$ret['result']=WPVIVID_FAILED;
|
||||
if(!isset($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['name']=sanitize_text_field($this->options['name']);
|
||||
|
||||
if(empty($this->options['name']))
|
||||
{
|
||||
$ret['error']="Warning: An alias for remote storage is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$remoteslist=WPvivid_Setting::get_all_remote_options();
|
||||
foreach ($remoteslist as $key=>$value)
|
||||
{
|
||||
if(isset($value['name'])&&$value['name'] == $this->options['name']&&$skip_name!=$value['name'])
|
||||
{
|
||||
$ret['error']="Warning: The alias already exists in storage list.";
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isset($this->options['host']))
|
||||
{
|
||||
$ret['error']="Warning: The IP Address is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['host']=sanitize_text_field($this->options['host']);
|
||||
|
||||
if(empty($this->options['host']))
|
||||
{
|
||||
$ret['error']="Warning: The IP Address is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['username']))
|
||||
{
|
||||
$ret['error']="Warning: The username is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['username']=sanitize_text_field($this->options['username']);
|
||||
|
||||
if(empty($this->options['username']))
|
||||
{
|
||||
$ret['error']="Warning: The username is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['password'])||empty($this->options['password']))
|
||||
{
|
||||
$ret['error']="Warning: The password is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
//$this->options['password']=sanitize_text_field($this->options['password']);
|
||||
|
||||
if(empty($this->options['password']))
|
||||
{
|
||||
$ret['error']="Warning: The password is required.";
|
||||
return $ret;
|
||||
}
|
||||
$this->options['password'] = base64_encode($this->options['password']);
|
||||
$this->options['is_encrypt'] = 1;
|
||||
|
||||
if(!isset($this->options['port']))
|
||||
{
|
||||
$ret['error']="Warning: The port number is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['port']=sanitize_text_field($this->options['port']);
|
||||
|
||||
if(empty($this->options['port']))
|
||||
{
|
||||
$ret['error']="Warning: The port number is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($this->options['path'])||empty($this->options['path']))
|
||||
{
|
||||
$ret['error']="Warning: The storage path is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$this->options['path']=sanitize_text_field($this->options['path']);
|
||||
|
||||
if(empty($this->options['path']))
|
||||
{
|
||||
$ret['error']="Warning: The storage path is required.";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
$ret['options']=$this->options;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function do_connect($host,$username,$password,$port)
|
||||
{
|
||||
include_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-extend-sftp.php';
|
||||
$conn = new WPvivid_Net_SFTP($host,$port,$this -> timeout);
|
||||
$conn -> setTimeout($this->timeout);
|
||||
$ret = $conn->login($username,$password);
|
||||
if(!$ret)
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'The connection failed because of incorrect credentials or server connection timeout. Please try again.');
|
||||
}
|
||||
|
||||
return $conn;
|
||||
}
|
||||
|
||||
function do_chdir($conn,$path)
|
||||
{
|
||||
@$conn->mkdir($path);
|
||||
// See if the directory now exists
|
||||
if (!$conn->chdir($path))
|
||||
{
|
||||
@$conn->disconnect();
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Failed to create a backup. Make sure you have sufficient privileges to perform the operation.');
|
||||
}
|
||||
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
function _delete($conn , $file)
|
||||
{
|
||||
$result = $conn ->delete($file , true);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function upload($task_id,$files,$callback='')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$this -> callback = $callback;
|
||||
if(empty($this->options['port']))
|
||||
$this->options['port'] = 22;
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
$port = $this->options['port'];
|
||||
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_SFTP);
|
||||
|
||||
if(empty($upload_job))
|
||||
{
|
||||
$job_data=array();
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$file_data['size']=filesize($file);
|
||||
$file_data['uploaded']=0;
|
||||
$job_data[basename($file)]=$file_data;
|
||||
}
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_SFTP,WPVIVID_UPLOAD_UNDO,'Start uploading',$job_data);
|
||||
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_SFTP);
|
||||
}
|
||||
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Connecting to server '.$host,'notice');
|
||||
$conn = $this->do_connect($host,$username,$password,$port);
|
||||
|
||||
if(is_array($conn) && $conn['result'] ==WPVIVID_FAILED)
|
||||
{
|
||||
return $conn;
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('chdir '.$path,'notice');
|
||||
$str = $this->do_chdir($conn,$path);
|
||||
if($str['result'] == WPVIVID_FAILED)
|
||||
return $str;
|
||||
|
||||
foreach ($files as $key => $file)
|
||||
{
|
||||
if(is_array($upload_job['job_data']) &&array_key_exists(basename($file),$upload_job['job_data']))
|
||||
{
|
||||
if($upload_job['job_data'][basename($file)]['uploaded']==1)
|
||||
continue;
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Start uploading '.basename($file),'notice');
|
||||
$this -> last_time = time();
|
||||
$this -> last_size = 0;
|
||||
|
||||
if(!file_exists($file))
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$file.' not found. The file might has been moved, renamed or deleted. Please back it up again.');
|
||||
|
||||
$wpvivid_plugin->set_time_limit($task_id);
|
||||
|
||||
for($i =0;$i <WPVIVID_REMOTE_CONNECT_RETRY_TIMES;$i ++)
|
||||
{
|
||||
$this -> last_time = time();
|
||||
$this->current_file_name=basename($file);
|
||||
$this -> current_file_size = filesize($file);
|
||||
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_SFTP,WPVIVID_UPLOAD_UNDO,'Start uploading '.basename($file).'.',$upload_job['job_data']);
|
||||
|
||||
$result = $conn->put(trailingslashit($path) . basename($file), $file, NET_SFTP_LOCAL_FILE| NET_SFTP_RESUME_START, -1, -1, array($this , 'upload_callback'));
|
||||
|
||||
if($result)
|
||||
{
|
||||
WPvivid_taskmanager::wpvivid_reset_backup_retry_times($task_id);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Finished uploading '.basename($file),'notice');
|
||||
$upload_job['job_data'][basename($file)]['uploaded']=1;
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_SFTP,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$last_error = error_get_last();
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Upload failed, get last error: '.json_encode($last_error).', retry times: '.$i, 'notice');
|
||||
$sftperrors=$conn->getSFTPErrors();
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('getSFTPErrors: '.json_encode($sftperrors), 'notice');
|
||||
$lastsftperror=$conn->getLastSFTPError();
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('getLastSFTPError: '.json_encode($lastsftperror), 'notice');
|
||||
|
||||
$is_status_failure = false;
|
||||
if (is_string($lastsftperror) && stripos($lastsftperror, 'NET_SFTP_STATUS_FAILURE') !== false)
|
||||
{
|
||||
$is_status_failure = true;
|
||||
}
|
||||
|
||||
if (!$is_status_failure && is_array($sftperrors))
|
||||
{
|
||||
foreach ($sftperrors as $e)
|
||||
{
|
||||
if (is_string($e) && stripos($e, 'NET_SFTP_STATUS_FAILURE') !== false)
|
||||
{
|
||||
$is_status_failure = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == (WPVIVID_REMOTE_CONNECT_RETRY_TIMES - 1))
|
||||
{
|
||||
@$conn -> disconnect();
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Uploading '.$file.' to SFTP server failed. '.$file.' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
|
||||
if($is_status_failure)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('disconnect sftp', 'notice');
|
||||
@$conn->disconnect();
|
||||
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('reconnect sftp', 'notice');
|
||||
$conn = $this->do_connect($host,$username,$password,$port);
|
||||
if(is_array($conn) && $conn['result'] ==WPVIVID_FAILED)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('connect sftp failed', 'notice');
|
||||
return $conn;
|
||||
}
|
||||
|
||||
$str = $this->do_chdir($conn, $path);
|
||||
if ($str['result'] == WPVIVID_FAILED)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('do_chdir failed', 'notice');
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Upload failed but not status failure, keep connection and retry normally', 'notice');
|
||||
}
|
||||
}
|
||||
|
||||
sleep(WPVIVID_REMOTE_CONNECT_RETRY_INTERVAL);
|
||||
}
|
||||
}
|
||||
$conn -> disconnect();
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
|
||||
public function download($file,$local_path,$callback = '')
|
||||
{
|
||||
try {
|
||||
global $wpvivid_plugin;
|
||||
$this->callback = $callback;
|
||||
$this->current_file_name = $file['file_name'];
|
||||
$this->current_file_size = $file['size'];
|
||||
|
||||
$host = $this->options['host'];
|
||||
$username = $this->options['username'];
|
||||
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1){
|
||||
$password = base64_decode($this->options['password']);
|
||||
}
|
||||
else {
|
||||
$password = $this->options['password'];
|
||||
}
|
||||
$path = $this->options['path'];
|
||||
$port = empty($this->options['port']) ? 22 : $this->options['port'];
|
||||
$local_path = trailingslashit($local_path) . $file['file_name'];
|
||||
$file_size = $file['size'];
|
||||
$remote_file_name = trailingslashit($path) . $file['file_name'];
|
||||
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Connecting SFTP server.','notice');
|
||||
$conn = $this->do_connect($host, $username, $password, $port);
|
||||
$progress = 0;
|
||||
if (!is_subclass_of($conn, 'Net_SSH2')) {
|
||||
return $conn;
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Create local file.','notice');
|
||||
$local_file = fopen($local_path, 'ab');
|
||||
if (!$local_file) {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Unable to create the local file. Please make sure the folder is writable and try again.');
|
||||
}
|
||||
$stat = fstat($local_file);
|
||||
$offset = $stat['size'];
|
||||
$progress = floor(($offset / $file_size) * 100);
|
||||
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Downloading file ' . $file['file_name'] . ', Size: ' . $file['size'] ,'notice');
|
||||
$result = $conn->get($remote_file_name, $local_file, $offset, -1, array($this, 'download_callback'));
|
||||
@fclose($local_file);
|
||||
|
||||
if(filesize($local_path) == $file['size']){
|
||||
if($wpvivid_plugin->wpvivid_check_zip_valid()) {
|
||||
$res = TRUE;
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$res = FALSE;
|
||||
}
|
||||
|
||||
if ($result && $res) {
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
} else {
|
||||
return array('result' => WPVIVID_FAILED, 'error' => 'Downloading ' . $remote_file_name . ' failed. ' . $remote_file_name . ' might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
|
||||
}
|
||||
}
|
||||
catch (Exception $error){
|
||||
$message = 'An exception has occurred. class: '.get_class($error).';msg: '.$error->getMessage().';code: '.$error->getCode().';line: '.$error->getLine().';in_file: '.$error->getFile().';';
|
||||
error_log($message);
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>$message);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete($remote,$files){
|
||||
$host = $remote['options']['host'];
|
||||
$username = $remote['options']['username'];
|
||||
if(isset($remote['options']['is_encrypt']) && $remote['options']['is_encrypt'] == 1){
|
||||
$password = base64_decode($remote['options']['password']);
|
||||
}
|
||||
else {
|
||||
$password = $remote['options']['password'];
|
||||
}
|
||||
$path = $remote['options']['path'];
|
||||
$port = empty($remote['options']['port'])?22:$remote['options']['port'];
|
||||
|
||||
$conn = $this->do_connect($host,$username,$password,$port);
|
||||
if(!is_subclass_of($conn,'Net_SSH2')){
|
||||
return $conn;
|
||||
}
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$file=trailingslashit($path).$file;
|
||||
$this -> _delete($conn , $file);
|
||||
}
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
public function get_last_error()
|
||||
{
|
||||
if($this->error_str===false)
|
||||
{
|
||||
$this->error_str='connection time out.';
|
||||
}
|
||||
return $this->error_str;
|
||||
}
|
||||
public function upload_callback($offset){
|
||||
if((time() - $this -> last_time) >3)
|
||||
{
|
||||
if(is_callable($this -> callback)){
|
||||
call_user_func_array($this -> callback,array($offset,$this -> current_file_name,
|
||||
$this->current_file_size,$this -> last_time,$this -> last_size));
|
||||
}
|
||||
$this -> last_size = $offset;
|
||||
$this -> last_time = time();
|
||||
}
|
||||
}
|
||||
public function download_callback($offset){
|
||||
if((time() - $this -> last_time) >3){
|
||||
if(is_callable($this -> callback)){
|
||||
call_user_func_array($this -> callback,array($offset,$this -> current_file_name,
|
||||
$this->current_file_size,$this -> last_time,$this -> last_size));
|
||||
}
|
||||
$this -> last_size = $offset;
|
||||
$this -> last_time = time();
|
||||
}
|
||||
}
|
||||
|
||||
public function cleanup($files)
|
||||
{
|
||||
$remote['options'] = $this -> options;
|
||||
return $this -> delete($remote,$files);
|
||||
}
|
||||
|
||||
public function wpvivid_get_out_of_date_sftp($out_of_date_remote, $remote)
|
||||
{
|
||||
if($remote['type'] == WPVIVID_REMOTE_SFTP){
|
||||
$out_of_date_remote = $remote['path'];
|
||||
}
|
||||
return $out_of_date_remote;
|
||||
}
|
||||
|
||||
public function wpvivid_storage_provider_sftp($storage_type)
|
||||
{
|
||||
if($storage_type == WPVIVID_REMOTE_SFTP){
|
||||
$storage_type = 'SFTP';
|
||||
}
|
||||
return $storage_type;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user