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 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 '

'.esc_html($e->getMessage()).'

'; } } 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 '

'; esc_html_e('You have authenticated the Dropbox account as your remote storage.', 'wpvivid-backuprestore'); echo '

'; 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 '

'.esc_html($e->getMessage()).'

'; } } 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 '

'.esc_html($e->getMessage()).'

'; } } } } } public function wpvivid_show_notice_add_dropbox_success(){ echo '

'; esc_html_e('You have authenticated the Dropbox account as your remote storage.', 'wpvivid-backuprestore'); echo '

'; } 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 '

'.esc_html($_GET['resp_msg']).'

'; } public function wpvivid_add_storage_tab_dropbox(){ ?>
add_remote) { ?> 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(); } }