Files
wingedit.pl/wp-content/plugins/wpvivid-backuprestore/includes/customclass/class-wpvivid-google-drive.php
2026-03-11 15:57:27 +01:00

1322 lines
59 KiB
PHP

<?php
if (!defined('WPVIVID_PLUGIN_DIR')){
die;
}
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-remote.php';
if(!defined('WPVIVID_REMOTE_GOOGLEDRIVE'))
define('WPVIVID_REMOTE_GOOGLEDRIVE','googledrive');
if(!defined('WPVIVID_GOOGLEDRIVE_DEFAULT_FOLDER'))
define('WPVIVID_GOOGLEDRIVE_DEFAULT_FOLDER','wpvivid_backup');
if(!defined('WPVIVID_GOOGLEDRIVE_UPLOAD_SIZE'))
define('WPVIVID_GOOGLEDRIVE_UPLOAD_SIZE',1024*1024*2);
if(!defined('WPVIVID_GOOGLE_NEED_PHP_VERSION'))
define('WPVIVID_GOOGLE_NEED_PHP_VERSION','5.5');
class Wpvivid_Google_drive extends WPvivid_Remote
{
public $options;
public $google_drive_secrets;
public $add_remote;
public function __construct($options=array())
{
if(empty($options))
{
if(!defined('WPVIVID_INIT_STORAGE_TAB_GOOGLE_DRIVE'))
{
add_action('init', array($this, 'handle_auth_actions'));
//wpvivid_google_drive_add_remote
add_action('wp_ajax_wpvivid_google_drive_add_remote',array( $this,'finish_add_remote'));
add_action('wpvivid_add_storage_tab',array($this,'wpvivid_add_storage_tab_google_drive'), 10);
add_action('wpvivid_add_storage_page',array($this,'wpvivid_add_storage_page_google_drive'), 10);
add_filter('wpvivid_pre_add_remote',array($this, 'pre_add_remote'),10,2);
add_action('wpvivid_edit_remote_page',array($this,'wpvivid_edit_storage_page_google_drive'), 10);
add_filter('wpvivid_remote_pic',array($this,'wpvivid_remote_pic_google_drive'),10);
add_filter('wpvivid_get_out_of_date_remote',array($this,'wpvivid_get_out_of_date_google_drive'),10,2);
add_filter('wpvivid_storage_provider_tran',array($this,'wpvivid_storage_provider_google_drive'),10);
add_filter('wpvivid_get_root_path',array($this,'wpvivid_get_root_path_google_drive'),10);
define('WPVIVID_INIT_STORAGE_TAB_GOOGLE_DRIVE',1);
}
}
else
{
$this->options=$options;
}
$this->add_remote=false;
$this->google_drive_secrets = array("web"=>array(
"client_id"=>"134809148507-32crusepgace4h6g47ota99jjrvf4j1u.apps.googleusercontent.com",
"project_id"=>"wpvivid-auth",
"auth_uri"=>"https://accounts.google.com/o/oauth2/auth",
"token_uri"=>"https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url"=>"https://www.googleapis.com/oauth2/v1/certs",
"client_secret"=>"",
"redirect_uris"=>array("https://auth.wpvivid.com/google_drive_v2/")
));
}
public function pre_add_remote($remote,$id)
{
if($remote['type']==WPVIVID_REMOTE_GOOGLEDRIVE)
{
$remote['id']=$id;
}
return $remote;
}
public function handle_auth_actions()
{
if(isset($_GET['action']) && isset($_GET['page']))
{
if($_GET['page'] === 'WPvivid')
{
if($_GET['action']=='wpvivid_google_drive_auth')
{
$check=current_user_can('manage_options');
if(!$check)
{
return;
}
$rand_id = substr(md5(time().rand()), 0,13);
$auth_id = 'wpvivid-auth-'.$rand_id;
$res = $this -> compare_php_version();
if($res['result'] == WPVIVID_FAILED){
echo '<div class="notice notice-warning is-dismissible"><p>'.esc_html($res['error']).'</p></div>';
return ;
}
try {
include_once WPVIVID_PLUGIN_DIR . '/vendor/autoload.php';
$client = new WPvivid_Google_Client();
$client->setAuthConfig($this->google_drive_secrets);
$client->setApprovalPrompt('force');
$client->addScope(WPvivid_Google_Service_Drive::DRIVE_FILE);
$client->setAccessType('offline');
$client->setState(admin_url() . 'admin.php?page=WPvivid' . '&action=wpvivid_google_drive_finish_auth&main_tab=storage&sub_tab=googledrive&sub_page=storage_account_google_drive&auth_id='.$auth_id);
$auth_url = $client->createAuthUrl();
$remote_options['auth_id']=$auth_id;
set_transient('google_drive_auth_id', $remote_options, 900);
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}
catch (Exception $e){
if($e->getMessage() === 'file does not exist'){
$error_msg = __('Authentication failed, the client_secrets.json file is missing. Please make sure the client_secrets.json file is in wpvivid-backuprestore\includes\customclass directory.', 'wpvivid-backuprestore');
echo '<div class="notice notice-error"><p>'.esc_html($error_msg).'</p></div>';
}
else if($e->getMessage() === 'invalid json for auth config'){
$error_msg = __('Authentication failed, the format of the client_secrets.json file is incorrect. Please delete and re-install the plugin to recreate the file.', 'wpvivid-backuprestore');
echo '<div class="notice notice-error"><p>'.esc_html($error_msg).'</p></div>';
}
else{
echo '<div class="notice notice-error"><p>'.esc_html($e->getMessage()).'</p></div>';
}
}
}
else if($_GET['action']=='wpvivid_google_drive_finish_auth')
{
$tmp_options = get_transient('google_drive_auth_id');
if($tmp_options === false)
{
return;
}
else if($tmp_options['auth_id'] !== $_GET['auth_id'])
{
delete_transient('google_drive_auth_id');
return;
}
try
{
if(isset($_GET['error']))
{
header('Location: '.admin_url().'admin.php?page='.WPVIVID_PLUGIN_SLUG.'&action=wpvivid_google_drive&main_tab=storage&sub_tab=googledrive&sub_page=storage_account_google_drive&result=error&resp_msg='.sanitize_text_field($_GET['error']));
return;
}
$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 Google Drive account as your remote storage.', 'wpvivid-backuprestore');
echo '</p></div>';
return;
}
}
if(empty($_POST['refresh_token']))
{
if(empty($tmp_options['token']['refresh_token']))
{
$err = 'No refresh token was received from Google, which means that you entered client secret incorrectly, or that you did not re-authenticated yet after you corrected it. Please authenticate again.';
header('Location: '.admin_url().'admin.php?page='.WPVIVID_PLUGIN_SLUG.'&action=wpvivid_google_drive&main_tab=storage&sub_tab=googledrive&sub_page=storage_account_google_drive&result=error&resp_msg='.$err);
return;
}
}
else
{
$tmp_options['type'] = WPVIVID_REMOTE_GOOGLEDRIVE;
$tmp_options['token']['access_token'] = base64_encode(sanitize_text_field($_POST['access_token']));
$tmp_options['token']['expires_in'] = sanitize_text_field($_POST['expires_in']);
$tmp_options['token']['refresh_token'] = base64_encode(sanitize_text_field($_POST['refresh_token']));
$tmp_options['token']['scope'] = sanitize_text_field($_POST['scope']);
$tmp_options['token']['token_type'] = sanitize_text_field($_POST['token_type']);
$tmp_options['token']['created'] = sanitize_text_field($_POST['created']);
$tmp_options['is_encrypt'] = 1;
set_transient('google_drive_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_google_drive')
{
try {
if (isset($_GET['result'])) {
if ($_GET['result'] == 'success') {
add_action('show_notice', array($this, 'wpvivid_show_notice_add_google_drive_success'));
} else if ($_GET['result'] == 'error') {
add_action('show_notice', array($this, 'wpvivid_show_notice_add_google_drive_error'));
}
}
}
catch (Exception $e){
echo '<div class="notice notice-error"><p>'.esc_html($e->getMessage()).'</p></div>';
}
}
}
}
}
public function wpvivid_show_notice_add_google_drive_success(){
echo '<div class="notice notice-success is-dismissible"><p>';
esc_html_e('You have authenticated the Google Drive account as your remote storage.', 'wpvivid-backuprestore');
echo '</p></div>';
}
public function wpvivid_show_notice_add_google_drive_error(){
global $wpvivid_plugin;
$wpvivid_plugin->wpvivid_handle_remote_storage_error($_GET['resp_msg'], 'Add Google Drive Remote');
echo '<div class="notice notice-error"><p>'.esc_html($_GET['resp_msg']).'</p></div>';
}
public function wpvivid_add_storage_tab_google_drive()
{
?>
<div class="storage-providers storage-providers-active" remote_type="googledrive" onclick="select_remote_storage(event, 'storage_account_google_drive');">
<img src="<?php echo esc_url(WPVIVID_PLUGIN_URL.'/admin/partials/images/stroage-google-drive.png'); ?>" style="vertical-align:middle;"/><?php esc_html_e('Google Drive', 'wpvivid-backuprestore'); ?>
</div>
<?php
}
public function wpvivid_add_storage_page_google_drive()
{
global $wpvivid_plugin;
$root_path=apply_filters('wpvivid_get_root_path', WPVIVID_REMOTE_GOOGLEDRIVE);
if($this->add_remote)
{
?>
<div id="storage_account_google_drive" class="storage-account-page">
<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 Google Drive authorization app (none of your backup data is sent to us).
</div>
<div style="color:#8bc34a; padding: 10px 10px 10px 0;">
<strong>Authentication is done, please continue to enter the storage information, then click 'Add Now' button to save it.</strong>
</div>
<div style="padding: 10px 10px 10px 0;">
<strong><?php esc_html_e('Enter Your Google Drive 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="googledrive" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. Google Drive-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" name="path" value="<?php echo esc_attr($root_path.WPVIVID_GOOGLEDRIVE_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-google-drive-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="googledrive" 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_google_drive_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_google_drive_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_google_drive_auth').click(function()
{
wpvivid_google_drive_auth();
});
function wpvivid_google_drive_auth()
{
wpvivid_settings_changed = false;
var name='';
var path='';
jQuery('input:text[option=googledrive]').each(function()
{
var key = jQuery(this).prop('name');
if(key==='name')
{
name = jQuery(this).val();
}
});
var remote_default='0';
jQuery('input:checkbox[option=googledrive]').each(function()
{
if(jQuery(this).prop('checked')) {
remote_default='1';
}
else {
remote_default='0';
}
});
if(name == ''){
alert(wpvividlion.remotealias);
}
else if(wpvivid_check_google_drive_storage_alias(name) === -1)
{
alert(wpvividlion.remoteexist);
}
else
{
var ajax_data;
var remote_from = wpvivid_ajax_data_transfer('googledrive');
ajax_data = {
'action': 'wpvivid_google_drive_add_remote',
'remote': remote_from
};
jQuery('#wpvivid_google_drive_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_google_drive_auth').css({'pointer-events': 'auto', 'opacity': '1'});
jQuery('input:text[option=googledrive]').each(function(){
jQuery(this).val('');
});
jQuery('input:password[option=googledrive]').each(function(){
jQuery(this).val('');
});
wpvivid_handle_remote_storage_data(data);
location.href='admin.php?page=WPvivid&action=wpvivid_google_drive&main_tab=storage&sub_tab=googledrive&sub_page=storage_account_google_drive&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_google_drive_auth').css({'pointer-events': 'auto', 'opacity': '1'});
});
}
}
</script>
<?php
}
else
{
?>
<div id="storage_account_google_drive" class="storage-account-page">
<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 Google Drive 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 Google Drive, please get Google 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_google_drive_auth();" class="button-primary" type="submit" value="<?php esc_attr_e('Authenticate with Google Drive', 'wpvivid-backuprestore'); ?>" />
</div>
</td>
<td class="column-description desc">
<div class="wpvivid-storage-form-desc">
<i><?php esc_html_e('Click to get Google 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_google_drive_auth()
{
location.href = '<?php echo esc_url(admin_url()) . 'admin.php?page=WPvivid' . '&action=wpvivid_google_drive_auth'?>';
}
</script>
<?php
}
}
public function wpvivid_edit_storage_page_google_drive()
{
?>
<div id="remote_storage_edit_googledrive" 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 Google Drive 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="edit-googledrive" name="name" placeholder="<?php esc_attr_e('Enter a unique alias: e.g. Google Drive-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_google_drive_update_auth()
{
var name='';
jQuery('input:text[option=edit-googledrive]').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_google_drive_update_auth&name='?>' + name + '&id=' + wpvivid_editing_storage_id;
}
}
</script>
<?php
}
public function wpvivid_remote_pic_google_drive($remote)
{
$remote['googledrive']['default_pic'] = '/admin/partials/images/stroage-google-drive(gray).png';
$remote['googledrive']['selected_pic'] = '/admin/partials/images/stroage-google-drive.png';
$remote['googledrive']['title'] = 'Google Drive';
return $remote;
}
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 test_connect()
{
return array('result' => WPVIVID_SUCCESS);
}
public function upload($task_id, $files, $callback = '')
{
global $wpvivid_plugin;
$client=$this->get_client();
if($client['result'] == WPVIVID_FAILED){
return $client;
}
$client = $client['data'];
if($client===false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Token refresh failed.');
}
$service = new WPvivid_Google_Service_Drive($client);
$path=$this->options['path'];
$wpvivid_plugin->wpvivid_log->WriteLog('Check upload folder '.$path,'notice');
$folder_id=$this->get_folder($service,$path);
if($folder_id==false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Unable to create the local file. Please make sure the folder is writable and try again.');
}
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE);
if(empty($upload_job))
{
$job_data=array();
foreach ($files as $file)
{
$file_data['size']=filesize($file);
$file_data['uploaded']=0;
$file_data['resumeUri']=false;
$file_data['progress']=false;
$job_data[basename($file)]=$file_data;
}
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE,WPVIVID_UPLOAD_UNDO,'Start uploading',$job_data);
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE);
}
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;
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.');
$wpvivid_plugin->wpvivid_log->WriteLog('Start uploading '.basename($file),'notice');
$wpvivid_plugin->set_time_limit($task_id);
$result=$this->_upload($task_id, $file,$client,$service,$folder_id, $callback);
if($result['result'] !==WPVIVID_SUCCESS){
return $result;
}
else
{
WPvivid_taskmanager::wpvivid_reset_backup_retry_times($task_id);
}
$ref=$this->check_token($client, $service);
if($ref['result']=!WPVIVID_SUCCESS)
{
return $ref;
}
}
return array('result' =>WPVIVID_SUCCESS);
}
public function check_token(&$client, &$service)
{
if ($client->isAccessTokenExpired())
{
// Refresh the token if possible, else fetch a new one.
global $wpvivid_plugin;
$wpvivid_plugin->wpvivid_log->WriteLog('Refresh the token.','notice');
if ($client->getRefreshToken())
{
$tmp_refresh_token = $client->getRefreshToken();
/*
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$token=$client->getAccessToken();
*/
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1) {
$tmp_refresh_token = base64_decode($tmp_refresh_token);
}
$args = array(
'refresh_token' => $tmp_refresh_token
);
$result = wp_remote_post("https://auth.wpvivid.com/google_drive_v2/", array(
'timeout' => 60,
'body' => $args
));
if (is_wp_error($result))
{
return array('result' => WPVIVID_SUCCESS,'data' => false);
}
else
{
$token = wp_remote_retrieve_body($result);
$token = json_decode($token, true);
if(!is_null($token))
{
$client->setAccessToken($token);
}
else
{
return array('result' => WPVIVID_SUCCESS,'data' => false);
}
}
$remote_options=WPvivid_Setting::get_remote_option($this->options['id']);
$this->options['token']=json_decode(wp_json_encode($token),1);
$this->options['token']['access_token']=base64_encode($this->options['token']['access_token']);
$this->options['is_encrypt']=1;
if($remote_options!==false)
{
if(!isset($this->options['token']['refresh_token'])){
$this->options['token']['refresh_token'] = base64_encode($tmp_refresh_token);
}
else{
$this->options['token']['refresh_token']=base64_encode($this->options['token']['refresh_token']);
}
$remote_options['token']=$this->options['token'];
$remote_options['is_encrypt']=1;
WPvivid_Setting::update_remote_option($this->options['id'],$remote_options);
$client=$this->get_client();
if($client['result'] == WPVIVID_FAILED){
return $client;
}
$client = $client['data'];
if($client===false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Token refresh failed.');
}
$service = new WPvivid_Google_Service_Drive($client);
}
return array('result' => WPVIVID_SUCCESS);
}
else
{
return array('result' => WPVIVID_FAILED,'error'=>'get refresh token failed');
}
}
else
{
return array('result' => WPVIVID_SUCCESS);
}
}
public function _upload($task_id, $file,$client,$service,$folder_id, $callback = '', $retry_times=0)
{
global $wpvivid_plugin;
$wpvivid_plugin->wpvivid_log->WriteLog('Check if the server already has the same name file.','notice');
try{
if(!$this->delete_exist_file($folder_id,basename($file),$service))
{
return array('result' =>WPVIVID_FAILED,'error'=>'Uploading '.$file.' to Google Drive 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.');
}
$upload_job=WPvivid_taskmanager::get_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE);
$this -> current_file_size = filesize($file);
$this -> current_file_name = basename($file);
$fileMetadata = new WPvivid_Google_Service_Drive_DriveFile(array(
'name' => basename($file),
'parents' => array($folder_id)));
$chunk_size = 1 * 1024 * 1024;
$client->setDefer(true);
$request = $service->files->create($fileMetadata);
$media = new WPvivid_Google_Http_MediaFileUpload(
$client,
$request,
'text/plain',
null,
true,
$chunk_size
);
$media->setFileSize(filesize($file));
$status = false;
$handle = fopen($file, "rb");
if(!empty($upload_job['job_data'][basename($file)]['resumeUri']))
{
$media->resume( $upload_job['job_data'][basename($file)]['resumeUri'] );
$media->setResumeUri($upload_job['job_data'][basename($file)]['resumeUri'] );
$media->setProgress($upload_job['job_data'][basename($file)]['progress'] );
$wpvivid_plugin->wpvivid_log->WriteLog('Resume uploading '.basename($file).'.','notice');
$wpvivid_plugin->wpvivid_log->WriteLog('resumeUri:'.$media->getResumeUri().'.','notice');
$wpvivid_plugin->wpvivid_log->WriteLog('progress:'.$media->getProgress().'.','notice');
$offset = $upload_job['job_data'][basename($file)]['progress'];
fseek($handle, $offset);
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE,WPVIVID_UPLOAD_UNDO,'Resume uploading '.basename($file).'.',$upload_job['job_data']);
}
else
{
$wpvivid_plugin->wpvivid_log->WriteLog('Initiate a resumable upload session.','notice');
$offset=0;
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE,WPVIVID_UPLOAD_UNDO,'Start uploading '.basename($file).'.',$upload_job['job_data']);
}
while (!$status && !feof($handle))
{
$chunk = fread($handle, $chunk_size);
$status = $media->nextChunk($chunk);
$offset+=strlen($chunk);
$retry_times=0;
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();
}
$upload_job['job_data'][basename($file)]['resumeUri']=$media->getResumeUri();
$upload_job['job_data'][basename($file)]['progress']=$media->getProgress();
//$wpvivid_plugin->wpvivid_log->WriteLog('resumeUri:'.$media->getResumeUri().'.','notice');
$wpvivid_plugin->wpvivid_log->WriteLog('progress:'.$media->getProgress().'.','notice');
WPvivid_taskmanager::update_backup_sub_task_progress($task_id,'upload',WPVIVID_REMOTE_GOOGLEDRIVE,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file),$upload_job['job_data']);
}
fclose($handle);
$client->setDefer(false);
if ($status != false)
{
$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_GOOGLEDRIVE,WPVIVID_UPLOAD_SUCCESS,'Uploading '.basename($file).' completed.',$upload_job['job_data']);
$wpvivid_plugin->wpvivid_log->WriteLog('Upload success.','notice');
return array('result' =>WPVIVID_SUCCESS);
}
else
{
$wpvivid_plugin->wpvivid_log->WriteLog('Upload failed.','notice');
return array('result' =>WPVIVID_FAILED,'error'=>'Uploading '.$file.' to Google Drive 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.');
}
}
catch (WPvivid_Google_Service_Exception $e)
{
$retry_times++;
fclose($handle);
$client->setDefer(false);
$message = 'A exception ('.get_class($e).') occurred '.esc_html($e->getMessage()).' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().') ';
if($retry_times < 15)
{
$wpvivid_plugin->wpvivid_log->WriteLog('Upload Google_Service_Exception, '.$message.', retry times: '.$retry_times,'notice');
return $this->_upload($task_id, $file,$client,$service,$folder_id, $callback, $retry_times);
}
else
{
$wpvivid_plugin->wpvivid_log->WriteLog('Upload Google_Service_Exception, retry times: '.$retry_times,'notice');
return array('result' =>WPVIVID_FAILED,'error'=>$message);
}
}
catch (InvalidArgumentException $e)
{
//need refresh token
$retry_times++;
$message = 'A exception ('.get_class($e).') occurred '.esc_html($e->getMessage()).' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().') ';
$wpvivid_plugin->wpvivid_log->WriteLog('Upload InvalidArgumentException, '.$message.', refresh token','notice');
$ref=$this->check_token($client, $service);
if($ref['result']=!WPVIVID_SUCCESS)
{
$wpvivid_plugin->wpvivid_log->WriteLog('refresh token failed, error: '.json_encode($ref),'notice');
return $ref;
}
fclose($handle);
$client->setDefer(false);
if($retry_times < 15)
{
$wpvivid_plugin->wpvivid_log->WriteLog('Refresh token completed, continue upload.','notice');
return $this->_upload($task_id, $file,$client,$service,$folder_id, $callback, $retry_times);
}
else
{
return array('result' =>WPVIVID_FAILED,'error'=>$message);
}
}
}
public function get_client()
{
$res = $this -> compare_php_version();
if($res['result'] == WPVIVID_FAILED){
return $res;
}
$token=$this->options['token'];
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1) {
$token['access_token'] = base64_decode($this->options['token']['access_token']);
}
include_once WPVIVID_PLUGIN_DIR.'/vendor/autoload.php';
$client = new WPvivid_Google_Client();
$client->setConfig('access_type','offline');
$client->setAuthConfig($this->google_drive_secrets);
$client->addScope(WPvivid_Google_Service_Drive::DRIVE_FILE);//
$client->setAccessToken($token);
if ($client->isAccessTokenExpired())
{
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken())
{
$tmp_refresh_token = $client->getRefreshToken();
/*
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
$token=$client->getAccessToken();
*/
if(isset($this->options['is_encrypt']) && $this->options['is_encrypt'] == 1) {
$tmp_refresh_token = base64_decode($tmp_refresh_token);
}
$args = array(
'refresh_token' => $tmp_refresh_token
);
$result = wp_remote_post("https://auth.wpvivid.com/google_drive_v2/", array(
'timeout' => 60,
'body' => $args
));
if (is_wp_error($result))
{
return array('result' => WPVIVID_SUCCESS,'data' => false);
}
else
{
$token = wp_remote_retrieve_body($result);
$token = json_decode($token, true);
if(!is_null($token))
{
$client->setAccessToken($token);
}
else
{
return array('result' => WPVIVID_SUCCESS,'data' => false);
}
}
$this->options['token']=json_decode(wp_json_encode($token),1);
$this->options['token']['access_token']=base64_encode($this->options['token']['access_token']);
$this->options['is_encrypt']=1;
if(!isset($this->options['token']['refresh_token'])){
$this->options['token']['refresh_token'] = base64_encode($tmp_refresh_token);
}
else{
$this->options['token']['refresh_token']=base64_encode($this->options['token']['refresh_token']);
}
WPvivid_Setting::update_remote_option($this->options['id'],$this->options);
return array('result' => WPVIVID_SUCCESS,'data' => $client);
}
else
{
return array('result' => WPVIVID_SUCCESS,'data' => false);
}
}
else
{
return array('result' => WPVIVID_SUCCESS,'data' => $client);
}
}
private function get_folder($service,$path)
{
$response = $service->files->listFiles(array(
'q' => "name ='".$path."' and 'root' in parents and mimeType = 'application/vnd.google-apps.folder'",
'fields' => 'nextPageToken, files(id, name,mimeType)',
));
if(sizeof($response->getFiles())==0)
{
$fileMetadata = new WPvivid_Google_Service_Drive_DriveFile(array(
'name' => $path,
'mimeType' => 'application/vnd.google-apps.folder'));
$file = $service->files->create($fileMetadata, array(
'fields' => 'id'));
return $file->id;
}
else
{
foreach ($response->getFiles() as $file)
{
return $file->getId();
}
}
return false;
}
public function set_token()
{
$remote_options=WPvivid_Setting::get_remote_option($this->options['id']);
if($remote_options!==false)
{
$this->options['token']=$remote_options['token'];
if(isset($remote_options['is_encrypt']))
{
$this->options['is_encrypt']=$remote_options['is_encrypt'];
}
}
}
public function download( $file, $local_path, $callback = '')
{
try
{
global $wpvivid_plugin;
$this -> current_file_name = $file['file_name'];
$this -> current_file_size = $file['size'];
$this->set_token();
$wpvivid_plugin->wpvivid_download_log->WriteLog('Google Drive get client.','notice');
$client=$this->get_client();
if($client['result'] == WPVIVID_FAILED) {
return $client;
}
$client = $client['data'];
if($client===false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Token refresh failed.');
}
$service = new WPvivid_Google_Service_Drive($client);
$path=$this->options['path'];
$wpvivid_plugin->wpvivid_download_log->WriteLog('Create local file.','notice');
$folder_id=$this->get_folder($service,$path);
if($folder_id==false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Unable to create the local file. Please make sure the folder is writable and try again.');
}
$response = $service->files->listFiles(array(
'q' => "name='".$file['file_name']."' and '".$folder_id."' in parents",
'fields' => 'files(id,size,webContentLink)'
));
if(sizeof($response->getFiles())==0)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Downloading file failed. The file might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
}
else
{
$fileSize=$file['size'];
$file_id='';
foreach ($response->getFiles() as $file)
{
$file_id=$file->getId();
break;
}
$wpvivid_plugin->wpvivid_download_log->WriteLog('Get download url.','notice');
$download_url=$this->get_download_url($client,$file_id);
if(!empty($file_id)||!empty($download_url))
{
$file_path = trailingslashit($local_path).$this -> current_file_name;
if(file_exists($file_path))
{
$offset = filesize($file_path);
}
else
{
$offset=0;
}
$fh = fopen($file_path, 'a');
$upload_size = WPVIVID_GOOGLEDRIVE_UPLOAD_SIZE;
$http = $client->authorize();
$wpvivid_plugin->wpvivid_download_log->WriteLog('Downloading file ' . $file['file_name'] . ', Size: ' . $file['size'] ,'notice');
while ($offset < $fileSize)
{
$upload_end=min($offset+$upload_size-1,$fileSize-1);
if ($offset > 0)
{
$options['headers']['Range']='bytes='.$offset.'-'.$upload_end;
} else {
$options['headers']['Range']='bytes=0-'.$upload_end;
}
$request = new WPvividGuzzleHttp\Psr7\Request('GET', $download_url,$options['headers']);
$http_request = $http->send($request);
$http_response=$http_request->getStatusCode();
if (200 == $http_response || 206 == $http_response)
{
fwrite($fh, $http_request->getBody()->getContents(),$upload_size);
$offset=$upload_end + 1;
}
else
{
throw new Exception('Failed to obtain any new data at size: '.$offset.' http code:'.$http_response);
}
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();
}
}
fclose($fh);
}
else
{
return array('result' => WPVIVID_FAILED,'error'=> 'Downloading file failed. The file might be deleted or network doesn\'t work properly. Please verify the file and confirm the network connection and try again later.');
}
}
}catch(Exception $e)
{
return array('result' => WPVIVID_FAILED,'error' => $e -> getMessage());
}
return array('result' => WPVIVID_SUCCESS);
}
public function get_download_url($client,$file_id)
{
$http = $client->authorize();
$url='https://www.googleapis.com/drive/v2/files/'.$file_id;
$request = new WPvividGuzzleHttp\Psr7\Request('GET', $url);
$http_request = $http->send($request);
$http_response=$http_request->getStatusCode();
if (200 == $http_response)
{
$json=$http_request->getBody()->getContents();
$json=json_decode($json,1);
$download_url=$json['downloadUrl'];
return $download_url;
}
else
{
throw new Exception('Failed to use v2 api');
}
}
public function delete_exist_file($folder_id,$file,$service)
{
global $wpvivid_plugin;
$client=$this->get_client();
if($client['result'] == WPVIVID_FAILED)
return false;
$client = $client['data'];
if($client===false)
{
return false;
}
try{
$delete_files = $service->files->listFiles(array(
'q' => "name='".$file."' and '".$folder_id."' in parents",
'fields' => 'nextPageToken, files(id, name,mimeType)',
));
if(sizeof($delete_files->getFiles())==0)
{
return true;
}
else
{
foreach ($delete_files->getFiles() as $file_google_drive)
{
$file_id=$file_google_drive->getId();
$service->files->delete($file_id);
return true;
}
}
}
catch(Exception $error)
{
$wpvivid_plugin->wpvivid_log->WriteLog('listFiles exception.','notice');
return true;
}
return false;
}
public function cleanup($files)
{
$client=$this->get_client();
if($client['result'] == WPVIVID_FAILED)
return $client;
$client = $client['data'];
if($client===false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Token refresh failed.');
}
$service = new WPvivid_Google_Service_Drive($client);
$path=$this->options['path'];
$folder_id=$this->get_folder($service,$path);
if($folder_id==false)
{
return array('result' => WPVIVID_FAILED,'error'=> 'Unable to create the local file. Please make sure the folder is writable and try again.');
}
foreach ($files as $file)
{
$delete_files = $service->files->listFiles(array(
'q' => "name='".$file."' and '".$folder_id."' in parents",
'fields' => 'nextPageToken, files(id, name,mimeType)',
));
if(sizeof($delete_files->getFiles())==0)
{
continue;
}
else
{
foreach ($delete_files->getFiles() as $file_google_drive)
{
$file_id=$file_google_drive->getId();
$service->files->delete($file_id);
}
}
}
return array('result' =>WPVIVID_SUCCESS);
}
public function wpvivid_get_out_of_date_google_drive($out_of_date_remote, $remote)
{
if($remote['type'] == WPVIVID_REMOTE_GOOGLEDRIVE){
$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_google_drive($storage_type)
{
if($storage_type == WPVIVID_REMOTE_GOOGLEDRIVE){
$storage_type = 'Google Drive';
}
return $storage_type;
}
public function wpvivid_get_root_path_google_drive($storage_type){
if($storage_type == WPVIVID_REMOTE_GOOGLEDRIVE){
$storage_type = 'root/';
}
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_GOOGLE_NEED_PHP_VERSION.'. After updating your PHP version, please try again.');
}
return array('result' => WPVIVID_SUCCESS);
}
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('google_drive_auth_id');
if($tmp_remote_options === false)
{
die();
}
delete_transient('google_drive_auth_id');
if(empty($tmp_remote_options)||$tmp_remote_options['type']!==WPVIVID_REMOTE_GOOGLEDRIVE)
{
die();
}
$json = sanitize_text_field($_POST['remote']);
$json = stripslashes($json);
$remote_options = json_decode($json, true);
if (is_null($remote_options)) {
die();
}
$remote_options['path'] = WPVIVID_GOOGLEDRIVE_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();
}
}