update
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
class WPvivid_Additional_DB_Method
|
||||
{
|
||||
private $dbuser;
|
||||
private $dbpass;
|
||||
private $dbhost;
|
||||
private $use_mysqli = false;
|
||||
private $dbh;
|
||||
private $has_connected = false;
|
||||
public $charset;
|
||||
public $collate;
|
||||
|
||||
public function __construct($dbuser, $dbpass, $dbhost){
|
||||
$this->dbuser = $dbuser;
|
||||
$this->dbpass = $dbpass;
|
||||
$this->dbhost = $dbhost;
|
||||
|
||||
if ( function_exists( 'mysqli_connect' ) ) {
|
||||
$this->use_mysqli = true;
|
||||
|
||||
if ( defined( 'WP_USE_EXT_MYSQL' ) ) {
|
||||
$this->use_mysqli = ! WP_USE_EXT_MYSQL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_parse_db_host( $host ) {
|
||||
$port = null;
|
||||
$socket = null;
|
||||
$is_ipv6 = false;
|
||||
|
||||
// First peel off the socket parameter from the right, if it exists.
|
||||
$socket_pos = strpos( $host, ':/' );
|
||||
if ( $socket_pos !== false ) {
|
||||
$socket = substr( $host, $socket_pos + 1 );
|
||||
$host = substr( $host, 0, $socket_pos );
|
||||
}
|
||||
|
||||
// We need to check for an IPv6 address first.
|
||||
// An IPv6 address will always contain at least two colons.
|
||||
if ( substr_count( $host, ':' ) > 1 ) {
|
||||
$pattern = '#^(?:\[)?(?P<host>[0-9a-fA-F:]+)(?:\]:(?P<port>[\d]+))?#';
|
||||
$is_ipv6 = true;
|
||||
} else {
|
||||
// We seem to be dealing with an IPv4 address.
|
||||
$pattern = '#^(?P<host>[^:/]*)(?::(?P<port>[\d]+))?#';
|
||||
}
|
||||
|
||||
$matches = array();
|
||||
$result = preg_match( $pattern, $host, $matches );
|
||||
|
||||
if ( 1 !== $result ) {
|
||||
// Couldn't parse the address, bail.
|
||||
return false;
|
||||
}
|
||||
|
||||
$host = '';
|
||||
foreach ( array( 'host', 'port' ) as $component ) {
|
||||
if ( ! empty( $matches[ $component ] ) ) {
|
||||
$$component = $matches[ $component ];
|
||||
}
|
||||
}
|
||||
|
||||
return array( $host, $port, $socket, $is_ipv6 );
|
||||
}
|
||||
|
||||
public function db_version() {
|
||||
if ( $this->use_mysqli ) {
|
||||
$server_info = mysqli_get_server_info( $this->dbh );
|
||||
} else {
|
||||
$server_info = mysql_get_server_info( $this->dbh );
|
||||
}
|
||||
return preg_replace( '/[^0-9.].*/', '', $server_info );
|
||||
}
|
||||
|
||||
public function has_cap( $db_cap ) {
|
||||
$version = $this->db_version();
|
||||
|
||||
switch ( strtolower( $db_cap ) ) {
|
||||
case 'collation': // @since 2.5.0
|
||||
case 'group_concat': // @since 2.7.0
|
||||
case 'subqueries': // @since 2.7.0
|
||||
return version_compare( $version, '4.1', '>=' );
|
||||
case 'set_charset':
|
||||
return version_compare( $version, '5.0.7', '>=' );
|
||||
case 'utf8mb4': // @since 4.1.0
|
||||
if ( version_compare( $version, '5.5.3', '<' ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( $this->use_mysqli ) {
|
||||
$client_version = mysqli_get_client_info();
|
||||
} else {
|
||||
$client_version = mysql_get_client_info();
|
||||
}
|
||||
|
||||
/*
|
||||
* libmysql has supported utf8mb4 since 5.5.3, same as the MySQL server.
|
||||
* mysqlnd has supported utf8mb4 since 5.0.9.
|
||||
*/
|
||||
if ( false !== strpos( $client_version, 'mysqlnd' ) ) {
|
||||
$client_version = preg_replace( '/^\D+([\d.]+).*/', '$1', $client_version );
|
||||
return version_compare( $client_version, '5.0.9', '>=' );
|
||||
} else {
|
||||
return version_compare( $client_version, '5.5.3', '>=' );
|
||||
}
|
||||
case 'utf8mb4_520': // @since 4.6.0
|
||||
return version_compare( $version, '5.6', '>=' );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function determine_charset( $charset, $collate ) {
|
||||
if ( ( $this->use_mysqli && ! ( $this->dbh instanceof mysqli ) ) || empty( $this->dbh ) ) {
|
||||
return compact( 'charset', 'collate' );
|
||||
}
|
||||
|
||||
if ( 'utf8' === $charset && $this->has_cap( 'utf8mb4' ) ) {
|
||||
$charset = 'utf8mb4';
|
||||
}
|
||||
|
||||
if ( 'utf8mb4' === $charset && ! $this->has_cap( 'utf8mb4' ) ) {
|
||||
$charset = 'utf8';
|
||||
$collate = str_replace( 'utf8mb4_', 'utf8_', $collate );
|
||||
}
|
||||
|
||||
if ( 'utf8mb4' === $charset ) {
|
||||
// _general_ is outdated, so we can upgrade it to _unicode_, instead.
|
||||
if ( ! $collate || 'utf8_general_ci' === $collate ) {
|
||||
$collate = 'utf8mb4_unicode_ci';
|
||||
} else {
|
||||
$collate = str_replace( 'utf8_', 'utf8mb4_', $collate );
|
||||
}
|
||||
}
|
||||
|
||||
// _unicode_520_ is a better collation, we should use that when it's available.
|
||||
if ( $this->has_cap( 'utf8mb4_520' ) && 'utf8mb4_unicode_ci' === $collate ) {
|
||||
$collate = 'utf8mb4_unicode_520_ci';
|
||||
}
|
||||
|
||||
return compact( 'charset', 'collate' );
|
||||
}
|
||||
|
||||
public function init_charset() {
|
||||
$charset = '';
|
||||
$collate = '';
|
||||
|
||||
if ( function_exists( 'is_multisite' ) && is_multisite() ) {
|
||||
$charset = 'utf8';
|
||||
if ( defined( 'DB_COLLATE' ) && DB_COLLATE ) {
|
||||
$collate = DB_COLLATE;
|
||||
} else {
|
||||
$collate = 'utf8_general_ci';
|
||||
}
|
||||
} elseif ( defined( 'DB_COLLATE' ) ) {
|
||||
$collate = DB_COLLATE;
|
||||
}
|
||||
|
||||
if ( defined( 'DB_CHARSET' ) ) {
|
||||
$charset = DB_CHARSET;
|
||||
}
|
||||
|
||||
$charset_collate = $this->determine_charset( $charset, $collate );
|
||||
|
||||
$this->charset = $charset_collate['charset'];
|
||||
$this->collate = $charset_collate['collate'];
|
||||
}
|
||||
|
||||
public function wpvivid_do_connect($allow_bail = true){
|
||||
$new_link = defined( 'MYSQL_NEW_LINK' ) ? MYSQL_NEW_LINK : true;
|
||||
$client_flags = defined( 'MYSQL_CLIENT_FLAGS' ) ? MYSQL_CLIENT_FLAGS : 0;
|
||||
|
||||
$error_code = '';
|
||||
$error = 'Unknown Error.';
|
||||
|
||||
if ( $this->use_mysqli ) {
|
||||
$this->dbh = mysqli_init();
|
||||
|
||||
$host = $this->dbhost;
|
||||
$port = null;
|
||||
$socket = null;
|
||||
$is_ipv6 = false;
|
||||
|
||||
if ( $host_data = $this->wpvivid_parse_db_host( $this->dbhost ) ) {
|
||||
list( $host, $port, $socket, $is_ipv6 ) = $host_data;
|
||||
}
|
||||
|
||||
if ( $is_ipv6 && extension_loaded( 'mysqlnd' ) ) {
|
||||
$host = "[$host]";
|
||||
}
|
||||
|
||||
@mysqli_real_connect( $this->dbh, $host, $this->dbuser, $this->dbpass, null, $port, $socket, $client_flags );
|
||||
|
||||
if ( $this->dbh->connect_errno ) {
|
||||
$error_code = $this->dbh->connect_errno;
|
||||
$error = $this->dbh->connect_error;
|
||||
$this->dbh = null;
|
||||
$attempt_fallback = true;
|
||||
|
||||
if ( $this->has_connected ) {
|
||||
$attempt_fallback = false;
|
||||
} elseif ( defined( 'WP_USE_EXT_MYSQL' ) && ! WP_USE_EXT_MYSQL ) {
|
||||
$attempt_fallback = false;
|
||||
} elseif ( ! function_exists( 'mysql_connect' ) ) {
|
||||
$attempt_fallback = false;
|
||||
}
|
||||
|
||||
if ( $attempt_fallback ) {
|
||||
$this->use_mysqli = false;
|
||||
return $this->wpvivid_do_connect( $allow_bail );
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
$this->dbh = @mysql_connect( $this->dbhost, $this->dbuser, $this->dbpass, $new_link, $client_flags );
|
||||
}
|
||||
|
||||
if($this->dbh){
|
||||
$this->has_connected = true;
|
||||
$ret['result'] = WPVIVID_SUCCESS;
|
||||
}
|
||||
else{
|
||||
$ret['result'] = WPVIVID_FAILED;
|
||||
$ret['error'] = $error_code.': '.$error;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_show_additional_databases(){
|
||||
$query = 'SHOW DATABASES;';
|
||||
$result = '';
|
||||
if ( ! empty( $this->dbh ) && $this->use_mysqli ) {
|
||||
$result = mysqli_query( $this->dbh, $query );
|
||||
} elseif ( ! empty( $this->dbh ) ) {
|
||||
$result = mysql_query( $query, $this->dbh );
|
||||
}
|
||||
if ( $this->use_mysqli && $result instanceof mysqli_result ) {
|
||||
while ( $row = mysqli_fetch_object( $result ) ) {
|
||||
$database_array[] = $row;
|
||||
}
|
||||
} elseif ( is_resource( $result ) ) {
|
||||
while ( $row = mysql_fetch_object( $result ) ) {
|
||||
$database_array[] = $row;
|
||||
}
|
||||
}
|
||||
if(!empty($database_array)){
|
||||
foreach ($database_array as $key => $value){
|
||||
$last_result[] = $value->Database;
|
||||
}
|
||||
}
|
||||
return $last_result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
define('NECESSARY','1');
|
||||
define('OPTION','0');
|
||||
class WPvivid_Backup_Database
|
||||
{
|
||||
private $task_id;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function wpvivid_archieve_database_info($databases, $data)
|
||||
{
|
||||
if(isset($data['dump_db']))
|
||||
{
|
||||
$sql_info['file_name'] =$data['sql_file_name'];
|
||||
$sql_info['database'] = DB_NAME;
|
||||
$sql_info['host'] = DB_HOST;
|
||||
$sql_info['user'] = DB_USER;
|
||||
$sql_info['pass'] = DB_PASSWORD;
|
||||
$databases[] = $sql_info;
|
||||
}
|
||||
return $databases;
|
||||
}
|
||||
|
||||
public function backup_database($data,$task_id = '')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$dump=null;
|
||||
|
||||
try
|
||||
{
|
||||
$this->task_id=$task_id;
|
||||
|
||||
//$backup_file =$data['sql_file_name'];
|
||||
|
||||
require_once 'class-wpvivid-mysqldump-method.php';
|
||||
require_once 'class-wpvivid-mysqldump.php';
|
||||
include_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-db-method.php';
|
||||
|
||||
$db_method=new WPvivid_DB_Method();
|
||||
$version =$db_method->get_mysql_version();
|
||||
|
||||
if(version_compare('4.1.0',$version) > 0)
|
||||
{
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Your MySQL version is too old. Please upgrade at least to MySQL 4.1.0.');
|
||||
}
|
||||
|
||||
if(version_compare('5.3.0',phpversion()) > 0){
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>'Your PHP version is too old. Please upgrade at least to PHP 5.3.0.');
|
||||
}
|
||||
|
||||
$db_method->check_max_allowed_packet();
|
||||
add_filter('wpvivid_exclude_db_table', array($this, 'exclude_table'),10,2);
|
||||
$exclude=array();
|
||||
$exclude = apply_filters('wpvivid_exclude_db_table',$exclude, $data);
|
||||
$include=array();
|
||||
$include = apply_filters('wpvivid_include_db_table',$include, $data);
|
||||
|
||||
$site_url = apply_filters('wpvivid_dump_set_site_url',get_site_url(), $data);
|
||||
$home_url = apply_filters('wpvivid_dump_set_home_url',get_home_url(), $data);
|
||||
$content_url=apply_filters('wpvivid_dump_set_content_url',content_url(), $data);
|
||||
|
||||
global $wpdb;
|
||||
if (is_multisite() && !defined('MULTISITE'))
|
||||
{
|
||||
$prefix = $wpdb->base_prefix;
|
||||
} else {
|
||||
$prefix = $wpdb->get_blog_prefix(0);
|
||||
}
|
||||
$prefix=apply_filters('wpvivid_dump_set_prefix',$prefix, $data);
|
||||
|
||||
add_filter('wpvivid_archieve_database_info', array($this, 'wpvivid_archieve_database_info'), 10, 2);
|
||||
$databases=array();
|
||||
$databases = apply_filters('wpvivid_archieve_database_info', $databases, $data);
|
||||
$is_additional_db = false;
|
||||
if($data['key'] === 'backup_additional_db')
|
||||
{
|
||||
$is_additional_db = true;
|
||||
}
|
||||
|
||||
$backup_files = array();
|
||||
foreach ($databases as $sql_info)
|
||||
{
|
||||
$database_name = $sql_info['database'];
|
||||
$backup_file = $sql_info['file_name'];
|
||||
$backup_files[] = $backup_file;
|
||||
$host = $sql_info['host'];
|
||||
$user = $sql_info['user'];
|
||||
$pass = $sql_info['pass'];
|
||||
|
||||
$dumpSettings=array();
|
||||
$dumpSettings['exclude-tables']=$exclude;
|
||||
$dumpSettings['include-tables']=$include;
|
||||
$dumpSettings['add-drop-table']=true;
|
||||
$dumpSettings['extended-insert']=false;
|
||||
|
||||
$dumpSettings['site_url']=$site_url;
|
||||
$dumpSettings['home_url']=$home_url;
|
||||
$dumpSettings['content_url']=$content_url;
|
||||
$dumpSettings['prefix']=$prefix;
|
||||
|
||||
$dump = new WPvivid_Mysqldump($host, $database_name, $user, $pass, $is_additional_db, $dumpSettings);
|
||||
|
||||
if (file_exists($backup_file))
|
||||
@wp_delete_file($backup_file);
|
||||
|
||||
$dump->task_id=$task_id;
|
||||
$dump->start($backup_file);
|
||||
}
|
||||
|
||||
unset($pdo);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$str_last_query_string='';
|
||||
if(!is_null($dump))
|
||||
{
|
||||
$str_last_query_string=$dump->last_query_string;
|
||||
}
|
||||
if(!empty($str_last_query_string))
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('last query string:'.$str_last_query_string,'error');
|
||||
}
|
||||
$message = 'A exception ('.get_class($e).') occurred '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
return array('result'=>WPVIVID_FAILED,'error'=>$message);
|
||||
}
|
||||
|
||||
$files = array();
|
||||
$files = $backup_files;
|
||||
return array('result'=>WPVIVID_SUCCESS,'files'=>$files);
|
||||
}
|
||||
|
||||
public function exclude_table($exclude,$data)
|
||||
{
|
||||
global $wpdb;
|
||||
if (is_multisite() && !defined('MULTISITE'))
|
||||
{
|
||||
$prefix = $wpdb->base_prefix;
|
||||
} else {
|
||||
$prefix = $wpdb->get_blog_prefix(0);
|
||||
}
|
||||
$exclude = array('/^(?!' . $prefix . ')/i');
|
||||
return $exclude;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/class-wpvivid-zipclass.php';
|
||||
class WPvivid_Backup_Site
|
||||
{
|
||||
private $tools_collection=array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
add_filter('wpvivid_tools_register', array($this, 'init_tools'),10);
|
||||
$this->tools_collection=apply_filters('wpvivid_tools_register',$this->tools_collection);
|
||||
$this->load_hooks();
|
||||
}
|
||||
|
||||
public function init_tools($tools_collection){
|
||||
$tools_collection['zip'][WPVIVID_COMPRESS_ZIPCLASS] = 'WPvivid_ZipClass';
|
||||
return $tools_collection;
|
||||
}
|
||||
|
||||
public function get_tools($type){
|
||||
if(array_key_exists($type,$this->tools_collection))
|
||||
{
|
||||
foreach ($this -> tools_collection[$type] as $class_name){
|
||||
if(class_exists($class_name)){
|
||||
$object = new $class_name();
|
||||
$last_error = $object -> getLastError();
|
||||
if(empty($last_error))
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
}
|
||||
$class_name = $this -> tools_collection['zip'][WPVIVID_COMPRESS_ZIPCLASS];
|
||||
$object = new $class_name();
|
||||
$last_error = $object -> getLastError();
|
||||
if(empty($last_error)){
|
||||
return $object;
|
||||
}else{
|
||||
return array('result' => WPVIVID_FAILED,'error' => $last_error);
|
||||
}
|
||||
}
|
||||
|
||||
public function load_hooks(){
|
||||
foreach ($this -> tools_collection as $compressType){
|
||||
foreach ($compressType as $className){
|
||||
$object = new $className();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,417 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
class WPvivid_Backuplist
|
||||
{
|
||||
public static function get_backup_by_id($id)
|
||||
{
|
||||
$lists[]='wpvivid_backup_list';
|
||||
$lists=apply_filters('wpvivid_get_backuplist_name',$lists);
|
||||
foreach ($lists as $list_name)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option($list_name);
|
||||
if(!empty($list))
|
||||
{
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if ($id == $k)
|
||||
{
|
||||
return $backup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function update_backup_option($backup_id,$backup_new)
|
||||
{
|
||||
$lists[]='wpvivid_backup_list';
|
||||
$lists=apply_filters('wpvivid_get_backuplist_name',$lists);
|
||||
foreach ($lists as $list_name)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option($list_name);
|
||||
if(!empty($list))
|
||||
{
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if ($backup_id == $k)
|
||||
{
|
||||
$list[$backup_id]=$backup_new;
|
||||
WPvivid_Setting::update_option($list_name,$list);
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_backuplist($list_name='')
|
||||
{
|
||||
$list=array();
|
||||
add_filter('wpvivid_get_backuplist',array('WPvivid_Backuplist','get_backup_list'),10,2);
|
||||
$list=apply_filters('wpvivid_get_backuplist',$list,$list_name);
|
||||
return $list;
|
||||
}
|
||||
|
||||
public static function get_backup_list($list,$list_name)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
$list =self::sort_list($list);
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public static function get_backuplist_by_id($id){
|
||||
$list = array();
|
||||
add_filter('wpvivid_get_backuplist_by_id',array('WPvivid_Backuplist','get_backup_list_by_id'), 10 , 2);
|
||||
$ret=apply_filters('wpvivid_get_backuplist_by_id',$list,$id);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function get_backup_list_by_id($list, $id)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if ($id == $k)
|
||||
{
|
||||
$ret['list_name'] = 'wpvivid_backup_list';
|
||||
$ret['list_data'] = $list;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function get_backuplist_by_key($key)
|
||||
{
|
||||
add_filter('wpvivid_get_backuplist_item',array('WPvivid_Backuplist','get_backuplist_item'),10,2);
|
||||
$backup=false;
|
||||
$backup=apply_filters('wpvivid_get_backuplist_item',$backup,$key);
|
||||
return $backup;
|
||||
}
|
||||
|
||||
public static function get_backuplist_item($backup,$key)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if ($key == $k)
|
||||
{
|
||||
return $backup;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function update_backup($id,$key,$data)
|
||||
{
|
||||
add_action('wpvivid_update_backup',array('WPvivid_Backuplist', 'update_backup_item'),10,3);
|
||||
do_action('wpvivid_update_backup',$id,$key,$data);
|
||||
}
|
||||
|
||||
public static function update_backup_item($id,$key,$data)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
if(array_key_exists($id,$list))
|
||||
{
|
||||
$list[$id][$key]=$data;
|
||||
WPvivid_Setting::update_option('wpvivid_backup_list',$list);
|
||||
}
|
||||
}
|
||||
|
||||
public static function add_new_upload_backup($task_id,$backup,$time,$log='')
|
||||
{
|
||||
$backup_data=array();
|
||||
$backup_data['type']='Upload';
|
||||
$backup_data['create_time']=$time;
|
||||
$backup_data['manual_delete']=0;
|
||||
$backup_data['local']['path']=WPvivid_Setting::get_backupdir();
|
||||
$backup_data['compress']['compress_type']='zip';
|
||||
$backup_data['save_local']=1;
|
||||
$backup_data['log']=$log;
|
||||
|
||||
$backup_data['backup']=$backup;
|
||||
$backup_data['remote']=array();
|
||||
$backup_data['lock']=0;
|
||||
$backup_list='wpvivid_backup_list';
|
||||
|
||||
$backup_list=apply_filters('get_wpvivid_backup_list_name',$backup_list,$task_id,$backup_data);
|
||||
|
||||
$list = WPvivid_Setting::get_option($backup_list);
|
||||
$list[$task_id]=$backup_data;
|
||||
WPvivid_Setting::update_option($backup_list,$list);
|
||||
}
|
||||
|
||||
public static function delete_backup($key)
|
||||
{
|
||||
$lists[]='wpvivid_backup_list';
|
||||
$lists=apply_filters('wpvivid_get_backuplist_name',$lists);
|
||||
foreach ($lists as $list_name)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option($list_name);
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if ($key == $k)
|
||||
{
|
||||
unset($list[$key]);
|
||||
WPvivid_Setting::update_option($list_name, $list);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function sort_list($list)
|
||||
{
|
||||
if($list !== false)
|
||||
{
|
||||
uasort ($list,function($a, $b)
|
||||
{
|
||||
if($a['create_time']>$b['create_time'])
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if($a['create_time']===$b['create_time'])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
public static function get_oldest_backup_id($list)
|
||||
{
|
||||
$oldest_id='';
|
||||
$oldest=0;
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if(!array_key_exists('lock',$backup) || (isset($backup['lock']) && $backup['lock'] == '0'))
|
||||
{
|
||||
if ($oldest == 0)
|
||||
{
|
||||
$oldest = $backup['create_time'];
|
||||
$oldest_id = $k;
|
||||
} else {
|
||||
if ($oldest > $backup['create_time'])
|
||||
{
|
||||
$oldest_id = $k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $oldest_id;
|
||||
}
|
||||
|
||||
public static function check_backuplist_limit($max_count)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
foreach ($list as $key=>$value)
|
||||
{
|
||||
if(isset($value['lock']) && $value['lock'] == 1)
|
||||
{
|
||||
unset($list[$key]);
|
||||
}
|
||||
}
|
||||
if($list !== false)
|
||||
{
|
||||
$size=sizeof($list);
|
||||
}
|
||||
else
|
||||
{
|
||||
$size = 0;
|
||||
}
|
||||
if($size>=$max_count)
|
||||
{
|
||||
$oldest_id=self::get_oldest_backup_id($list);
|
||||
if(empty($oldest_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $oldest_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_out_of_date_backuplist($max_count)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
foreach ($list as $key=>$value)
|
||||
{
|
||||
if(isset($value['lock']) && $value['lock'] == 1)
|
||||
{
|
||||
unset($list[$key]);
|
||||
}
|
||||
}
|
||||
if($list !== false)
|
||||
{
|
||||
$size=sizeof($list);
|
||||
}
|
||||
else
|
||||
{
|
||||
$size = 0;
|
||||
}
|
||||
$out_of_date_list=array();
|
||||
|
||||
if($max_count==0)
|
||||
return $out_of_date_list;
|
||||
|
||||
while($size>$max_count)
|
||||
{
|
||||
$oldest_id=self::get_oldest_backup_id($list);
|
||||
|
||||
if(!empty($oldest_id))
|
||||
{
|
||||
$out_of_date_list[]=$oldest_id;
|
||||
unset($list[$oldest_id]);
|
||||
}
|
||||
$new_size=sizeof($list);
|
||||
if($new_size==$size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$size=$new_size;
|
||||
}
|
||||
}
|
||||
|
||||
return $out_of_date_list;
|
||||
}
|
||||
|
||||
public static function get_out_of_date_backuplist_info($max_count)
|
||||
{
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
if($list !== false)
|
||||
{
|
||||
$size=sizeof($list);
|
||||
}
|
||||
else
|
||||
{
|
||||
$size = 0;
|
||||
}
|
||||
$out_of_date_list['size']=0;
|
||||
$out_of_date_list['count']=0;
|
||||
|
||||
if($max_count==0)
|
||||
return $out_of_date_list;
|
||||
|
||||
while($size>$max_count)
|
||||
{
|
||||
$oldest_id=self::get_oldest_backup_id($list);
|
||||
|
||||
if(!empty($oldest_id))
|
||||
{
|
||||
$out_of_date_list['size']+=self::get_size($oldest_id);
|
||||
$out_of_date_list['count']++;
|
||||
unset($list[$oldest_id]);
|
||||
}
|
||||
$new_size=sizeof($list);
|
||||
if($new_size==$size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
$size=$new_size;
|
||||
}
|
||||
}
|
||||
|
||||
return $out_of_date_list;
|
||||
}
|
||||
|
||||
public static function get_size($backup_id)
|
||||
{
|
||||
$size=0;
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
$backup=$list[$backup_id];
|
||||
if(isset($backup['backup']['files'])){
|
||||
foreach ($backup['backup']['files'] as $file) {
|
||||
$size+=$file['size'];
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(isset($backup['backup']['data']['type'])){
|
||||
foreach ($backup['backup']['data']['type'] as $type) {
|
||||
foreach ($type['files'] as $file) {
|
||||
$size+=$file['size'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
public static function set_security_lock($backup_id,$lock)
|
||||
{
|
||||
//$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
$ret = self::get_backuplist_by_id($backup_id);
|
||||
if($ret !== false) {
|
||||
$list = $ret['list_data'];
|
||||
if (array_key_exists($backup_id, $list)) {
|
||||
if ($lock == 1) {
|
||||
$list[$backup_id]['lock'] = 1;
|
||||
}
|
||||
else {
|
||||
if (array_key_exists('lock', $list[$backup_id])) {
|
||||
unset($list[$backup_id]['lock']);
|
||||
}
|
||||
}
|
||||
}
|
||||
WPvivid_Setting::update_option($ret['list_name'], $list);
|
||||
}
|
||||
|
||||
$ret['result'] = 'success';
|
||||
$list = WPvivid_Setting::get_option($ret['list_name']);
|
||||
if (array_key_exists($backup_id, $list)) {
|
||||
if (isset($list[$backup_id]['lock'])) {
|
||||
if ($list[$backup_id]['lock'] == 1) {
|
||||
$backup_lock = '/admin/partials/images/locked.png';
|
||||
$lock_status = 'lock';
|
||||
$ret['html'] = '<img src="' . esc_url(WPVIVID_PLUGIN_URL . $backup_lock) . '" name="' . esc_attr($lock_status, 'wpvivid-backuprestore') . '" onclick="wpvivid_set_backup_lock(\''.$backup_id.'\', \''.$lock_status.'\');" style="vertical-align:middle; cursor:pointer;"/>';
|
||||
} else {
|
||||
$backup_lock = '/admin/partials/images/unlocked.png';
|
||||
$lock_status = 'unlock';
|
||||
$ret['html'] = '<img src="' . esc_url(WPVIVID_PLUGIN_URL . $backup_lock) . '" name="' . esc_attr($lock_status, 'wpvivid-backuprestore') . '" onclick="wpvivid_set_backup_lock(\''.$backup_id.'\', \''.$lock_status.'\');" style="vertical-align:middle; cursor:pointer;"/>';
|
||||
}
|
||||
} else {
|
||||
$backup_lock = '/admin/partials/images/unlocked.png';
|
||||
$lock_status = 'unlock';
|
||||
$ret['html'] = '<img src="' . esc_url(WPVIVID_PLUGIN_URL . $backup_lock) . '" name="' . esc_attr($lock_status, 'wpvivid-backuprestore') . '" onclick="wpvivid_set_backup_lock(\''.$backup_id.'\', \''.$lock_status.'\');" style="vertical-align:middle; cursor:pointer;"/>';
|
||||
}
|
||||
} else {
|
||||
$backup_lock = '/admin/partials/images/unlocked.png';
|
||||
$lock_status = 'unlock';
|
||||
$ret['html'] = '<img src="' . esc_url(WPVIVID_PLUGIN_URL . $backup_lock) . '" name="' . esc_attr($lock_status, 'wpvivid-backuprestore') . '" onclick="wpvivid_set_backup_lock(\''.$backup_id.'\', \''.$lock_status.'\');" style="vertical-align:middle; cursor:pointer;"/>';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function get_has_remote_backuplist()
|
||||
{
|
||||
$backup_id_list=array();
|
||||
$list = WPvivid_Setting::get_option('wpvivid_backup_list');
|
||||
foreach ($list as $k=>$backup)
|
||||
{
|
||||
if(!empty($backup['remote']))
|
||||
{
|
||||
$backup_id_list[]=$k;
|
||||
}
|
||||
}
|
||||
return $backup_id_list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-ftpclass.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-sftpclass.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-amazons3-plus.php';
|
||||
class WPvivid_Backup_Remote
|
||||
{
|
||||
|
||||
public function backup_with_ftp($data = array())
|
||||
{
|
||||
$host = $data['options']['host'];
|
||||
$username = $data['options']['username'];
|
||||
$password = $data['options']['password'];
|
||||
$path = $data['options']['path'];
|
||||
$passive = $data['options']['passive'];
|
||||
$port = empty($data['options']['port'])?21:$data['options']['port'];
|
||||
|
||||
$ftpclass = new WPvivid_FTPClass();
|
||||
$res = $ftpclass -> upload($host,$username,$password,$path,$data['files'],$data['task_id'],$passive,$port,$data['log']);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function backup_with_sftp($data)
|
||||
{
|
||||
if(empty($data['port']))
|
||||
$data['options']['port'] = 22;
|
||||
$host = $data['options']['host'];
|
||||
$username = $data['options']['username'];
|
||||
$password = $data['options']['password'];
|
||||
$path = $data['options']['path'];
|
||||
$port = $data['options']['port'];
|
||||
$scp = $data['options']['scp'];
|
||||
|
||||
$sftpclass = new WPvivid_SFTPClass();
|
||||
$result = $sftpclass -> upload($host,$username,$password,$path,$data['files'],$data['task_id'],$port,$scp,$data['log']);
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function backup_with_amazonS3($data = array())
|
||||
{
|
||||
$files = $data['files'];
|
||||
$access = $data['options']['access'];
|
||||
$secret = $data['options']['secret'];
|
||||
$s3Path = $data['options']['s3Path'];
|
||||
$region = $data['options']['region'];
|
||||
$amazonS3 = new WPvivid_AMAZONS3Class();
|
||||
$amazonS3 ->init($access,$secret,$region);
|
||||
$res = $amazonS3 -> upload($files,$s3Path,$data['task_id'],$data['log']);
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
abstract class Wpvivid_Compress_Default{
|
||||
public $last_error = '';
|
||||
|
||||
abstract public function compress($data);
|
||||
abstract public function extract($files,$path = '');
|
||||
abstract public function extract_by_files($files,$zip,$path = '');
|
||||
abstract public function get_include_zip($files,$allpackages);
|
||||
abstract public function listcontent($path);
|
||||
abstract public function listnum($path , $includeFolder = false);
|
||||
|
||||
public function getLastError(){
|
||||
return $this -> last_error;
|
||||
}
|
||||
public function getBasename($basename){
|
||||
$basename = basename($basename);
|
||||
$arr = explode('.',$basename);
|
||||
return $arr[0];
|
||||
}
|
||||
public function _in_array($file,$lists){
|
||||
foreach ($lists as $item){
|
||||
if(strstr($file,$item)){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function filesplit($max_size,$files){
|
||||
$packages = array();
|
||||
if($max_size == 0 || $max_size === '0M' || empty($max_size)){
|
||||
$packages[] = $files;
|
||||
}else{
|
||||
$sizenum = 0;
|
||||
$max_size = str_replace('M', '', $max_size);
|
||||
$size = $max_size * 1024 * 1024;
|
||||
$package = array();
|
||||
$flag = false;
|
||||
|
||||
usort($files, function ($a, $b)
|
||||
{
|
||||
$a_size=filesize($a);
|
||||
$b_size=filesize($b);
|
||||
if ($a_size == $b_size)
|
||||
return 0;
|
||||
|
||||
if ($a_size < $b_size)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
});
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$sizenum += filesize($file);
|
||||
if($sizenum > $size)
|
||||
{
|
||||
if(empty($package))
|
||||
{
|
||||
$package[] = $file;
|
||||
$packages[] = $package;
|
||||
$package = array();
|
||||
$sizenum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$packages[] = $package;
|
||||
$package = array();
|
||||
$package[] = $file;
|
||||
$sizenum = filesize($file);
|
||||
}
|
||||
|
||||
}else{
|
||||
$package[] = $file;
|
||||
}
|
||||
}
|
||||
if(!empty($package))
|
||||
$packages[] = $package;
|
||||
}
|
||||
return $packages;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
class WPvivid_crypt
|
||||
{
|
||||
private $public_key;
|
||||
private $sym_key;
|
||||
|
||||
private $rij;
|
||||
private $rsa;
|
||||
|
||||
public function __construct($public_key)
|
||||
{
|
||||
$this->public_key=$public_key;
|
||||
include_once WPVIVID_PLUGIN_DIR . '/vendor/autoload.php';
|
||||
$this->rij= new Crypt_Rijndael();
|
||||
$this->rsa= new Crypt_RSA();
|
||||
}
|
||||
|
||||
public function generate_key()
|
||||
{
|
||||
$this->sym_key = crypt_random_string(32);
|
||||
$this->rij->setKey($this->sym_key);
|
||||
}
|
||||
|
||||
public function encrypt_message($message)
|
||||
{
|
||||
$this->generate_key();
|
||||
$key=$this->encrypt_key();
|
||||
$len=str_pad(dechex(strlen($key)),3,'0', STR_PAD_LEFT);
|
||||
$message=$this->rij->encrypt($message);
|
||||
if($message===false)
|
||||
return false;
|
||||
$message_len = str_pad(dechex(strlen($message)), 16, '0', STR_PAD_LEFT);
|
||||
return $len.$key.$message_len.$message;
|
||||
}
|
||||
|
||||
public function encrypt_key()
|
||||
{
|
||||
$this->rsa->loadKey($this->public_key);
|
||||
return $this->rsa->encrypt($this->sym_key);
|
||||
}
|
||||
|
||||
public function decrypt_message($message)
|
||||
{
|
||||
$len = substr($message, 0, 3);
|
||||
$len = hexdec($len);
|
||||
$key = substr($message, 3, $len);
|
||||
|
||||
$cipherlen = substr($message, ($len + 3), 16);
|
||||
$cipherlen = hexdec($cipherlen);
|
||||
|
||||
$data = substr($message, ($len + 19), $cipherlen);
|
||||
$rsa = new Crypt_RSA();
|
||||
$rsa->loadKey($this->public_key);
|
||||
$key=$rsa->decrypt($key);
|
||||
if ($key === false || empty($key))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
$rij = new Crypt_Rijndael();
|
||||
$rij->setKey($key);
|
||||
return $rij->decrypt($data);
|
||||
}
|
||||
|
||||
public function encrypt_user_info($user,$pw)
|
||||
{
|
||||
$user_info['user']=$user;
|
||||
$user_info['pw']=$pw;
|
||||
$info=wp_json_encode($user_info);
|
||||
$this->rsa->loadKey($this->public_key);
|
||||
return $this->rsa->encrypt($info);
|
||||
}
|
||||
|
||||
public function encrypt_user_token($user,$token)
|
||||
{
|
||||
$user_info['user']=$user;
|
||||
$user_info['token']=$token;
|
||||
$info=wp_json_encode($user_info);
|
||||
$this->rsa->loadKey($this->public_key);
|
||||
return $this->rsa->encrypt($info);
|
||||
}
|
||||
|
||||
public function encrypt_token($token)
|
||||
{
|
||||
$this->rsa->loadKey($this->public_key);
|
||||
return $this->rsa->encrypt($token);
|
||||
}
|
||||
}
|
||||
|
||||
class WPvivid_Crypt_File
|
||||
{
|
||||
private $key;
|
||||
private $rij;
|
||||
|
||||
public function __construct($key)
|
||||
{
|
||||
include_once WPVIVID_PLUGIN_DIR . '/vendor/autoload.php';
|
||||
$this->rij= new Crypt_Rijndael();
|
||||
$this->key=$key;
|
||||
}
|
||||
|
||||
public function encrypt($file)
|
||||
{
|
||||
$encrypted_path = dirname($file).'/encrypt_'.basename($file).'.tmp';
|
||||
|
||||
$data_encrypted = 0;
|
||||
$buffer_size = 2097152;
|
||||
|
||||
$file_size = filesize($file);
|
||||
|
||||
$this->rij->setKey($this->key);
|
||||
$this->rij->disablePadding();
|
||||
$this->rij->enableContinuousBuffer();
|
||||
|
||||
if (file_exists($encrypted_path))
|
||||
{
|
||||
@wp_delete_file($encrypted_path);
|
||||
}
|
||||
$encrypted_handle = fopen($encrypted_path, 'wb+');
|
||||
|
||||
$file_handle = fopen($file, 'rb');
|
||||
|
||||
if($file_handle===false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=$file.' file not found';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
while ($data_encrypted < $file_size)
|
||||
{
|
||||
$file_part = fread($file_handle, $buffer_size);
|
||||
|
||||
$length = strlen($file_part);
|
||||
if (0 != $length % 16)
|
||||
{
|
||||
$pad = 16 - ($length % 16);
|
||||
$file_part = str_pad($file_part, $length + $pad, chr($pad));
|
||||
}
|
||||
|
||||
$encrypted_data = $this->rij->encrypt($file_part);
|
||||
|
||||
fwrite($encrypted_handle, $encrypted_data);
|
||||
|
||||
$data_encrypted += $buffer_size;
|
||||
}
|
||||
|
||||
fclose($encrypted_handle);
|
||||
fclose($file_handle);
|
||||
|
||||
$result_path = $file.'.crypt';
|
||||
|
||||
@rename($encrypted_path, $result_path);
|
||||
|
||||
$ret['result']='success';
|
||||
$ret['file_path']=$result_path;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function decrypt($file)
|
||||
{
|
||||
$file_handle = fopen($file, 'rb');
|
||||
|
||||
if($file_handle===false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=$file.' file not found';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$decrypted_path = dirname($file).'/decrypt_'.basename($file).'.tmp';
|
||||
|
||||
$decrypted_handle = fopen($decrypted_path, 'wb+');
|
||||
|
||||
$this->rij->setKey($this->key);
|
||||
$this->rij->disablePadding();
|
||||
$this->rij->enableContinuousBuffer();
|
||||
|
||||
$file_size = filesize($file);
|
||||
$bytes_decrypted = 0;
|
||||
$buffer_size =2097152;
|
||||
|
||||
while ($bytes_decrypted < $file_size)
|
||||
{
|
||||
$file_part = fread($file_handle, $buffer_size);
|
||||
|
||||
$length = strlen($file_part);
|
||||
if (0 != $length % 16) {
|
||||
$pad = 16 - ($length % 16);
|
||||
$file_part = str_pad($file_part, $length + $pad, chr($pad));
|
||||
}
|
||||
|
||||
$decrypted_data = $this->rij->decrypt($file_part);
|
||||
|
||||
$is_last_block = ($bytes_decrypted + strlen($decrypted_data) >= $file_size);
|
||||
|
||||
$write_bytes = min($file_size - $bytes_decrypted, strlen($decrypted_data));
|
||||
if ($is_last_block)
|
||||
{
|
||||
$is_padding = false;
|
||||
$last_byte = ord(substr($decrypted_data, -1, 1));
|
||||
if ($last_byte < 16)
|
||||
{
|
||||
$is_padding = true;
|
||||
for ($j = 1; $j<=$last_byte; $j++)
|
||||
{
|
||||
if (substr($decrypted_data, -$j, 1) != chr($last_byte))
|
||||
$is_padding = false;
|
||||
}
|
||||
}
|
||||
if ($is_padding)
|
||||
{
|
||||
$write_bytes -= $last_byte;
|
||||
}
|
||||
}
|
||||
|
||||
fwrite($decrypted_handle, $decrypted_data, $write_bytes);
|
||||
$bytes_decrypted += $buffer_size;
|
||||
}
|
||||
|
||||
// close the main file handle
|
||||
fclose($decrypted_handle);
|
||||
// close original file
|
||||
fclose($file_handle);
|
||||
|
||||
$fullpath_new = preg_replace('/\.crypt$/', '', $file, 1).'.decrypted.zip';
|
||||
|
||||
@rename($decrypted_path, $fullpath_new);
|
||||
$ret['result']='success';
|
||||
$ret['file_path']=$fullpath_new;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
class WPvivid_DB_Method
|
||||
{
|
||||
public $db_handle;
|
||||
public $type;
|
||||
|
||||
public function connect_db()
|
||||
{
|
||||
$common_setting = WPvivid_Setting::get_setting(false, 'wpvivid_common_setting');
|
||||
$db_connect_method = isset($common_setting['options']['wpvivid_common_setting']['db_connect_method']) ? $common_setting['options']['wpvivid_common_setting']['db_connect_method'] : 'wpdb';
|
||||
if($db_connect_method === 'wpdb'){
|
||||
global $wpdb;
|
||||
$this->db_handle=$wpdb;
|
||||
$this->type='wpdb';
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
else{
|
||||
if(class_exists('PDO')) {
|
||||
$extensions=get_loaded_extensions();
|
||||
if(array_search('pdo_mysql',$extensions)) {
|
||||
$res = explode(':',DB_HOST);
|
||||
$db_host = $res[0];
|
||||
$db_port = empty($res[1])?'':$res[1];
|
||||
|
||||
if(!empty($db_port)) {
|
||||
$dsn='mysql:host=' . $db_host . ';port=' . $db_port . ';dbname=' . DB_NAME;
|
||||
}
|
||||
else{
|
||||
$dsn='mysql:host=' . $db_host . ';dbname=' . DB_NAME;
|
||||
}
|
||||
|
||||
$this->db_handle=new PDO($dsn, DB_USER, DB_PASSWORD);
|
||||
|
||||
$this->type='pdo_mysql';
|
||||
return array('result'=>WPVIVID_SUCCESS);
|
||||
}
|
||||
else{
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>'The pdo_mysql extension is not detected. Please install the extension first or choose wpdb option for Database connection method.');
|
||||
}
|
||||
}
|
||||
else{
|
||||
return array('result'=>WPVIVID_FAILED, 'error'=>'The pdo_mysql extension is not detected. Please install the extension first or choose wpdb option for Database connection method.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function check_db($fcgi)
|
||||
{
|
||||
$ret=$this->connect_db();
|
||||
|
||||
if($ret['result']==WPVIVID_FAILED)
|
||||
{
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if($this->type=='pdo_mysql')
|
||||
{
|
||||
return $this->check_db_pdo($fcgi);
|
||||
}
|
||||
else if($this->type=='wpdb')
|
||||
{
|
||||
return $this->check_db_wpdb($fcgi);
|
||||
}
|
||||
|
||||
return array('result' => WPVIVID_FAILED,'error' => 'db handle type not found.');
|
||||
}
|
||||
|
||||
public function check_db_pdo($fcgi)
|
||||
{
|
||||
$ret['alert_db']=false;
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
$ret['big_tables']=array();
|
||||
$db_info=array();
|
||||
|
||||
$sth = $this->db_handle->query('SHOW TABLE STATUS');
|
||||
$dbSize = 0;
|
||||
$sum_rows=0;
|
||||
$rows = $sth->fetchAll();
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
global $wpdb;
|
||||
if (is_multisite() && !defined('MULTISITE'))
|
||||
{
|
||||
$prefix = $wpdb->base_prefix;
|
||||
} else {
|
||||
$prefix = $wpdb->get_blog_prefix(0);
|
||||
}
|
||||
if(preg_match('/^(?!'.$prefix.')/', $row["Name"]) == 1){
|
||||
continue;
|
||||
}
|
||||
|
||||
$db_info[$row["Name"]]["Rows"]=$row["Rows"];
|
||||
$db_info[$row["Name"]]["Data_length"]=size_format($row["Data_length"]+$row["Index_length"],2);
|
||||
if($row["Rows"]>1000000)
|
||||
{
|
||||
$ret['big_tables'][$row["Name"]]['Rows']=$row["Rows"];
|
||||
$ret['big_tables'][$row["Name"]]['Data_length']=size_format($row["Data_length"]+$row["Index_length"],2);
|
||||
}
|
||||
|
||||
$sum_rows+=$row["Rows"];
|
||||
$dbSize+=$row["Data_length"]+$row["Index_length"];
|
||||
}
|
||||
if($fcgi)
|
||||
{
|
||||
$alter_sum_rows=4000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
$alter_sum_rows=4000000*3;
|
||||
}
|
||||
|
||||
$memory_limit = ini_get('memory_limit');
|
||||
$ret['memory_limit']=$memory_limit;
|
||||
$memory_limit = trim($memory_limit);
|
||||
$memory_limit_int = (int) $memory_limit;
|
||||
$last = strtolower(substr($memory_limit, -1));
|
||||
|
||||
if($last == 'g')
|
||||
$memory_limit_int = $memory_limit_int*1024*1024*1024;
|
||||
if($last == 'm')
|
||||
$memory_limit_int = $memory_limit_int*1024*1024;
|
||||
if($last == 'k')
|
||||
$memory_limit_int = $memory_limit_int*1024;
|
||||
|
||||
if($dbSize>($memory_limit_int*0.9))
|
||||
{
|
||||
$max_rows=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$max_rows=(($memory_limit_int*0.9)-$dbSize)/49;
|
||||
}
|
||||
|
||||
$max_rows=max($max_rows,1048576);
|
||||
|
||||
if($sum_rows>$alter_sum_rows||$sum_rows>$max_rows)
|
||||
{
|
||||
//big db alert
|
||||
$ret['alert_db']=true;
|
||||
$ret['sum_rows']=$sum_rows;
|
||||
$ret['db_size']=size_format($dbSize,2);
|
||||
if($fcgi)
|
||||
$ret['alter_fcgi']=true;
|
||||
}
|
||||
|
||||
$ret['db_size']=size_format($dbSize,2);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function check_db_wpdb($fcgi)
|
||||
{
|
||||
$ret['alert_db']=false;
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
$ret['big_tables']=array();
|
||||
$db_info=array();
|
||||
|
||||
global $wpdb;
|
||||
$result=$wpdb->get_results('SHOW TABLE STATUS',ARRAY_A);
|
||||
|
||||
//$sth = $this->db_handle->query('SHOW TABLE STATUS');
|
||||
$dbSize = 0;
|
||||
$sum_rows=0;
|
||||
//$rows = $sth->fetchAll();
|
||||
foreach ($result as $row)
|
||||
{
|
||||
global $wpdb;
|
||||
if (is_multisite() && !defined('MULTISITE'))
|
||||
{
|
||||
$prefix = $wpdb->base_prefix;
|
||||
} else {
|
||||
$prefix = $wpdb->get_blog_prefix(0);
|
||||
}
|
||||
if(preg_match('/^(?!'.$prefix.')/', $row["Name"]) == 1){
|
||||
continue;
|
||||
}
|
||||
|
||||
$db_info[$row["Name"]]["Rows"]=$row["Rows"];
|
||||
$db_info[$row["Name"]]["Data_length"]=size_format($row["Data_length"]+$row["Index_length"],2);
|
||||
if($row["Rows"]>1000000)
|
||||
{
|
||||
$ret['big_tables'][$row["Name"]]['Rows']=$row["Rows"];
|
||||
$ret['big_tables'][$row["Name"]]['Data_length']=size_format($row["Data_length"]+$row["Index_length"],2);
|
||||
}
|
||||
|
||||
$sum_rows+=$row["Rows"];
|
||||
$dbSize+=$row["Data_length"]+$row["Index_length"];
|
||||
}
|
||||
if($fcgi)
|
||||
{
|
||||
$alter_sum_rows=4000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
$alter_sum_rows=4000000*3;
|
||||
}
|
||||
|
||||
$memory_limit = ini_get('memory_limit');
|
||||
$ret['memory_limit']=$memory_limit;
|
||||
$memory_limit = trim($memory_limit);
|
||||
$memory_limit_int = (int) $memory_limit;
|
||||
$last = strtolower(substr($memory_limit, -1));
|
||||
|
||||
if($last == 'g')
|
||||
$memory_limit_int = $memory_limit_int*1024*1024*1024;
|
||||
if($last == 'm')
|
||||
$memory_limit_int = $memory_limit_int*1024*1024;
|
||||
if($last == 'k')
|
||||
$memory_limit_int = $memory_limit_int*1024;
|
||||
|
||||
if($dbSize>($memory_limit_int*0.9))
|
||||
{
|
||||
$max_rows=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$max_rows=(($memory_limit_int*0.9)-$dbSize)/49;
|
||||
}
|
||||
|
||||
$max_rows=max($max_rows,1048576);
|
||||
|
||||
if($sum_rows>$alter_sum_rows||$sum_rows>$max_rows)
|
||||
{
|
||||
//big db alert
|
||||
$ret['alert_db']=true;
|
||||
$ret['sum_rows']=$sum_rows;
|
||||
$ret['db_size']=size_format($dbSize,2);
|
||||
if($fcgi)
|
||||
$ret['alter_fcgi']=true;
|
||||
}
|
||||
|
||||
$ret['db_size']=size_format($dbSize,2);
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_sql_mode()
|
||||
{
|
||||
try {
|
||||
$ret['result'] = WPVIVID_SUCCESS;
|
||||
$ret['mysql_mode'] = '';
|
||||
|
||||
global $wpdb;
|
||||
$result = $wpdb->get_results('SELECT @@SESSION.sql_mode', ARRAY_A);
|
||||
foreach ($result as $row) {
|
||||
$ret['mysql_mode'] = $row["@@SESSION.sql_mode"];
|
||||
}
|
||||
}
|
||||
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'=>'failed','error'=>$message);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_mysql_version()
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$mysql_version = $wpdb->db_version();
|
||||
|
||||
return $mysql_version;
|
||||
}
|
||||
|
||||
public function check_max_allowed_packet()
|
||||
{
|
||||
global $wpvivid_plugin,$wpdb;
|
||||
|
||||
$max_allowed_packet = (int) $wpdb->get_var("SELECT @@session.max_allowed_packet");
|
||||
|
||||
if($max_allowed_packet<1048576)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('warning: max_allowed_packet less than 1M :'.size_format($max_allowed_packet,2),'notice');
|
||||
}
|
||||
else if($max_allowed_packet<33554432)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('max_allowed_packet less than 32M :'.size_format($max_allowed_packet,2),'notice');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
class WPvivid_downloader
|
||||
{
|
||||
private $task;
|
||||
|
||||
public function ready_download($download_info)
|
||||
{
|
||||
$backup=WPvivid_Backuplist::get_backup_by_id($download_info['backup_id']);
|
||||
if(!$backup)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$file_info=false;
|
||||
|
||||
if(isset($backup['backup']['files']))
|
||||
{
|
||||
foreach ($backup['backup']['files'] as $file)
|
||||
{
|
||||
if ($file['file_name'] == $download_info['file_name'])
|
||||
{
|
||||
$file_info= $file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($backup['backup']['ismerge'] == 1)
|
||||
{
|
||||
$backup_files = $backup['backup']['data']['meta']['files'];
|
||||
foreach ($backup_files as $file)
|
||||
{
|
||||
if ($file['file_name'] == $download_info['file_name'])
|
||||
{
|
||||
$file_info = $file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($backup['backup']['data']['type'] as $type)
|
||||
{
|
||||
$backup_files = $type['files'];
|
||||
foreach ($backup_files as $file) {
|
||||
if ($file['file_name'] == $download_info['file_name'])
|
||||
{
|
||||
$file_info = $file;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($file_info==false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$backup_dir = WPvivid_Setting::get_backupdir();
|
||||
$local_path=WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$backup_dir.DIRECTORY_SEPARATOR;
|
||||
//$local_path=WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$backup['local']['path'].DIRECTORY_SEPARATOR;
|
||||
$need_download_files=array();
|
||||
|
||||
$local_file=$local_path.$file_info['file_name'];
|
||||
if(file_exists($local_file))
|
||||
{
|
||||
if(filesize($local_file)!=$file_info['size'])
|
||||
{
|
||||
if(filesize($local_file)>$file_info['size'])
|
||||
{
|
||||
@wp_delete_file($local_file);
|
||||
}
|
||||
$need_download_files[$file_info['file_name']]=$file_info;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$need_download_files[$file_info['file_name']]=$file_info;
|
||||
}
|
||||
|
||||
|
||||
if(empty($need_download_files))
|
||||
{
|
||||
delete_option('wpvivid_download_cache');
|
||||
}
|
||||
else
|
||||
{
|
||||
if(WPvivid_taskmanager::is_download_task_running_v2($download_info['file_name']))
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('has a downloading task,exit download.','test');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
WPvivid_taskmanager::delete_download_task_v2($download_info['file_name']);
|
||||
$task=WPvivid_taskmanager::new_download_task_v2($download_info['file_name']);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($need_download_files as $file)
|
||||
{
|
||||
$ret=$this->download_ex($task,$backup['remote'],$file,$local_path);
|
||||
if($ret['result']==WPVIVID_FAILED)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function download_ex(&$task,$remotes,$file,$local_path)
|
||||
{
|
||||
$this->task=$task;
|
||||
|
||||
$remote_option=array_shift($remotes);
|
||||
|
||||
if(is_null($remote_option))
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED ,'error'=>'Retrieving the cloud storage information failed while downloading backups. Please try again later.');
|
||||
}
|
||||
|
||||
global $wpvivid_plugin;
|
||||
|
||||
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();
|
||||
}
|
||||
$remote=$wpvivid_plugin->remote_collection->get_remote($remote_option);
|
||||
|
||||
$ret=$remote->download($file,$local_path,array($this,'download_callback_v2'));
|
||||
|
||||
if($ret['result']==WPVIVID_SUCCESS)
|
||||
{
|
||||
$progress=100;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Download completed.', 'notice');
|
||||
WPvivid_taskmanager::update_download_task_v2( $task,$progress,'completed');
|
||||
return $ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
$progress=0;
|
||||
$message=$ret['error'];
|
||||
if($wpvivid_plugin->wpvivid_download_log)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Download failed, ' . $message ,'error');
|
||||
$wpvivid_plugin->wpvivid_download_log->CloseFile();
|
||||
WPvivid_error_log::create_error_log($wpvivid_plugin->wpvivid_download_log->log_file);
|
||||
}
|
||||
else {
|
||||
$id = uniqid('wpvivid-');
|
||||
$log_file_name = $id . '_download';
|
||||
$log = new WPvivid_Log();
|
||||
$log->CreateLogFile($log_file_name, 'no_folder', 'download');
|
||||
$log->WriteLog($message, 'notice');
|
||||
$log->CloseFile();
|
||||
WPvivid_error_log::create_error_log($log->log_file);
|
||||
}
|
||||
WPvivid_taskmanager::update_download_task_v2($task,$progress,'error',$message);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
public function download_callback_v2($offset,$current_name,$current_size,$last_time,$last_size)
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$progress= floor(($offset/$current_size)* 100) ;
|
||||
$text='Total size:'.size_format($current_size,2).' downloaded:'.size_format($offset,2);
|
||||
$this->task['download_descript']=$text;
|
||||
$wpvivid_plugin->wpvivid_download_log->WriteLog('Total Size: '.$current_size.', Downloaded Size: '.$offset ,'notice');
|
||||
WPvivid_taskmanager::update_download_task_v2( $this->task,$progress,'running');
|
||||
}
|
||||
|
||||
public static function delete($remote , $files)
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
|
||||
@set_time_limit(60);
|
||||
|
||||
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();
|
||||
}
|
||||
$remote=$wpvivid_plugin->remote_collection->get_remote($remote);
|
||||
|
||||
$result =$remote->cleanup($files);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
class WPvivid_error_log
|
||||
{
|
||||
public static function create_error_log($log_file_name)
|
||||
{
|
||||
$dir=dirname($log_file_name);
|
||||
$file=basename($log_file_name);
|
||||
if(!is_dir($dir.DIRECTORY_SEPARATOR.'error'))
|
||||
{
|
||||
@mkdir($dir.DIRECTORY_SEPARATOR.'error',0777,true);
|
||||
//@fopen($dir.DIRECTORY_SEPARATOR.'error'.'/index.html', 'x');
|
||||
$tempfile=@fopen($dir.DIRECTORY_SEPARATOR.'error'.'/.htaccess', 'x');
|
||||
if($tempfile)
|
||||
{
|
||||
//$text="deny from all";
|
||||
$text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";
|
||||
fwrite($tempfile,$text );
|
||||
@fclose($tempfile);
|
||||
}
|
||||
}
|
||||
|
||||
if(!file_exists($log_file_name))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if(file_exists($dir.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.$file))
|
||||
{
|
||||
@wp_delete_file($dir.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.$file);
|
||||
}
|
||||
|
||||
@rename($log_file_name,$dir.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.$file);
|
||||
|
||||
//self::delete_oldest_error_log();
|
||||
}
|
||||
|
||||
public static function create_restore_error_log($log_file_name)
|
||||
{
|
||||
$dir=dirname($log_file_name);
|
||||
if(!is_dir($dir.DIRECTORY_SEPARATOR.'wpvivid_log'.DIRECTORY_SEPARATOR.'error'))
|
||||
{
|
||||
@mkdir($dir.DIRECTORY_SEPARATOR.'wpvivid_log'.DIRECTORY_SEPARATOR.'error',0777,true);
|
||||
//@fopen($dir.DIRECTORY_SEPARATOR.'wpvivid_log'.DIRECTORY_SEPARATOR.'error'.'/index.html', 'x');
|
||||
$tempfile=@fopen($dir.DIRECTORY_SEPARATOR.'wpvivid_log'.DIRECTORY_SEPARATOR.'error'.'/.htaccess', 'x');
|
||||
if($tempfile)
|
||||
{
|
||||
//$text="deny from all";
|
||||
$text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";
|
||||
fwrite($tempfile,$text );
|
||||
@fclose($tempfile);
|
||||
}
|
||||
}
|
||||
$id = uniqid('wpvivid-');
|
||||
$file=$id.'_restore_log.txt';
|
||||
if(file_exists($dir.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.$file))
|
||||
{
|
||||
@wp_delete_file($dir.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.$file);
|
||||
}
|
||||
|
||||
@copy($log_file_name,$dir.DIRECTORY_SEPARATOR.'wpvivid_log'.DIRECTORY_SEPARATOR.'error'.DIRECTORY_SEPARATOR.$file);
|
||||
//self::delete_oldest_error_log();
|
||||
}
|
||||
|
||||
public static function delete_oldest_error_log()
|
||||
{
|
||||
$files=array();
|
||||
$log=new WPvivid_Log();
|
||||
$dir=$log->GetSaveLogFolder();
|
||||
$dir=$dir.'error';
|
||||
@$handler=opendir($dir);
|
||||
if($handler===false)
|
||||
return;
|
||||
$regex='#^wpvivid.*_log.txt#';
|
||||
while(($filename=readdir($handler))!==false)
|
||||
{
|
||||
if($filename != "." && $filename != "..")
|
||||
{
|
||||
if(is_dir($dir.DIRECTORY_SEPARATOR.$filename))
|
||||
{
|
||||
continue;
|
||||
}else{
|
||||
if(preg_match($regex,$filename))
|
||||
{
|
||||
$files[$filename] = $dir.DIRECTORY_SEPARATOR.$filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($handler)
|
||||
@closedir($handler);
|
||||
$oldest=0;
|
||||
$oldest_filename='';
|
||||
$max_count=5;
|
||||
if(sizeof($files)>$max_count)
|
||||
{
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if($oldest==0)
|
||||
{
|
||||
$oldest=filemtime($file);
|
||||
$oldest_filename=$file;
|
||||
}
|
||||
else
|
||||
{
|
||||
if($oldest>filemtime($file))
|
||||
{
|
||||
$oldest=filemtime($file);
|
||||
$oldest_filename=$file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($oldest_filename!='')
|
||||
{
|
||||
@wp_delete_file($oldest_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_error_log()
|
||||
{
|
||||
$log=new WPvivid_Log();
|
||||
$dir=$log->GetSaveLogFolder();
|
||||
$dir=$dir.'error';
|
||||
$files=array();
|
||||
$handler=opendir($dir);
|
||||
if($handler === false){
|
||||
return $files;
|
||||
}
|
||||
$regex='#^wpvivid.*_log.txt#';
|
||||
while(($filename=readdir($handler))!==false)
|
||||
{
|
||||
if($filename != "." && $filename != "..")
|
||||
{
|
||||
if(is_dir($dir.$filename))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
if(preg_match($regex,$filename))
|
||||
{
|
||||
$files[] = $dir.DIRECTORY_SEPARATOR.$filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($handler)
|
||||
@closedir($handler);
|
||||
return $files;
|
||||
}
|
||||
|
||||
public static function get_staging_error_log()
|
||||
{
|
||||
if(!class_exists('WPvivid_Staging_Log_Free'))
|
||||
include_once WPVIVID_PLUGIN_DIR . '/includes/staging/class-wpvivid-staging-log.php';
|
||||
$log=new WPvivid_Staging_Log_Free();
|
||||
$dir=$log->GetSaveLogFolder();
|
||||
$dir=$dir.'error';
|
||||
$files=array();
|
||||
if(is_dir($dir) && file_exists($dir))
|
||||
{
|
||||
$handler=opendir($dir);
|
||||
if($handler === false){
|
||||
return $files;
|
||||
}
|
||||
$regex='#^wpvivid.*_log.txt#';
|
||||
while(($filename=readdir($handler))!==false)
|
||||
{
|
||||
if($filename != "." && $filename != "..")
|
||||
{
|
||||
if(is_dir($dir.$filename))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
if(preg_match($regex,$filename))
|
||||
{
|
||||
$files[] = $dir.DIRECTORY_SEPARATOR.$filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($handler)
|
||||
@closedir($handler);
|
||||
return $files;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $files;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
class WPvivid_Function_Realize
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function _backup_cancel($task_id = '')
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
|
||||
try
|
||||
{
|
||||
$tasks = WPvivid_taskmanager::get_tasks();
|
||||
$no_responds=false;
|
||||
$task_id='';
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
$task_id = $task['id'];
|
||||
$backup_task=new WPvivid_Backup_Task_2($task['id']);
|
||||
$status=$backup_task->get_status();
|
||||
|
||||
$file_name=$backup_task->task['options']['file_prefix'];
|
||||
$path=$backup_task->task['options']['dir'];
|
||||
$file =$path. DIRECTORY_SEPARATOR . $file_name . '_cancel';
|
||||
touch($file);
|
||||
|
||||
$last_active_time=time()-$status['run_time'];
|
||||
if($last_active_time>180)
|
||||
{
|
||||
$no_responds=true;
|
||||
}
|
||||
|
||||
$timestamp = wp_next_scheduled('wpvivid_task_monitor_event_2', array($task_id));
|
||||
|
||||
if ($timestamp === false)
|
||||
{
|
||||
$wpvivid_plugin->backup2->add_monitor_event($task_id);
|
||||
}
|
||||
}
|
||||
|
||||
if($no_responds)
|
||||
{
|
||||
$ret['result'] = 'success';
|
||||
$ret['no_response'] = true;
|
||||
$ret['task_id'] = $task_id;
|
||||
$ret['msg'] = __('The backup is not responding for a while, do you want to force cancel it?', 'wpvivid-backuprestore');
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret['result'] = 'success';
|
||||
$ret['no_response'] = false;
|
||||
$ret['task_id'] = $task_id;
|
||||
$ret['msg'] = __('The backup will be canceled after backing up the current chunk ends.', 'wpvivid-backuprestore');
|
||||
}
|
||||
|
||||
}
|
||||
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'=>'failed','error'=>$message);
|
||||
}
|
||||
|
||||
/*
|
||||
try
|
||||
{
|
||||
$tasks = WPvivid_taskmanager::get_tasks();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
$task_id = $task['id'];
|
||||
$status=WPvivid_taskmanager::get_backup_task_status($task_id);
|
||||
$time_spend=$status['run_time']-$status['start_time'];
|
||||
$options=WPvivid_Setting::get_option('wpvivid_common_setting');
|
||||
if(isset($options['max_execution_time']))
|
||||
{
|
||||
$limit=$options['max_execution_time'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$limit=WPVIVID_MAX_EXECUTION_TIME;
|
||||
}
|
||||
|
||||
if($time_spend > $limit * 2)
|
||||
{
|
||||
$file_name = WPvivid_taskmanager::get_task_options($task_id, 'file_prefix');
|
||||
$backup_options = WPvivid_taskmanager::get_task_options($task_id, 'backup_options');
|
||||
$file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . $backup_options['dir'] . DIRECTORY_SEPARATOR . $file_name . '_cancel';
|
||||
touch($file);
|
||||
|
||||
if($wpvivid_plugin->wpvivid_log->log_file_handle==false)
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->OpenLogFile(WPvivid_taskmanager::get_task_options($task_id,'log_file_name'));
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Backup cancelled. Twice the setting time.','notice');
|
||||
$task=new WPvivid_Backup_Task($task_id);
|
||||
$task->update_status('cancel');
|
||||
$wpvivid_plugin->clean_backing_up_data_event($task_id);
|
||||
WPvivid_Schedule::clear_monitor_schedule($task_id);
|
||||
WPvivid_taskmanager::delete_task($task_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
$file_name = WPvivid_taskmanager::get_task_options($task_id, 'file_prefix');
|
||||
$backup_options = WPvivid_taskmanager::get_task_options($task_id, 'backup_options');
|
||||
$file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . $backup_options['dir'] . DIRECTORY_SEPARATOR . $file_name . '_cancel';
|
||||
touch($file);
|
||||
|
||||
$timestamp = wp_next_scheduled(WPVIVID_TASK_MONITOR_EVENT, array($task_id));
|
||||
|
||||
if ($timestamp === false) {
|
||||
$wpvivid_plugin->add_monitor_event($task_id, 10);
|
||||
}
|
||||
}
|
||||
$wpvivid_plugin->wpvivid_check_clear_litespeed_rule($task_id);
|
||||
}
|
||||
|
||||
if (WPvivid_taskmanager::get_task($task_id) !== false) {
|
||||
$file_name = WPvivid_taskmanager::get_task_options($task_id, 'file_prefix');
|
||||
$backup_options = WPvivid_taskmanager::get_task_options($task_id, 'backup_options');
|
||||
$file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . $backup_options['dir'] . DIRECTORY_SEPARATOR . $file_name . '_cancel';
|
||||
touch($file);
|
||||
}
|
||||
|
||||
$timestamp = wp_next_scheduled(WPVIVID_TASK_MONITOR_EVENT, array($task_id));
|
||||
|
||||
if ($timestamp === false) {
|
||||
$wpvivid_plugin->add_monitor_event($task_id, 10);
|
||||
}
|
||||
$ret['result'] = 'success';
|
||||
$ret['msg'] = __('The backup will be canceled after backing up the current chunk ends.', 'wpvivid-backuprestore');
|
||||
}
|
||||
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'=>'failed','error'=>$message);
|
||||
}
|
||||
catch (Error $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'=>'failed','error'=>$message);
|
||||
}*/
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function _get_log_file($read_type, $param){
|
||||
global $wpvivid_plugin;
|
||||
$ret['result']='failed';
|
||||
if($read_type == 'backuplist'){
|
||||
$backup_id = $param;
|
||||
$backup = WPvivid_Backuplist::get_backup_by_id($backup_id);
|
||||
if(!$backup) {
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Retrieving the backup information failed while showing log. Please try again later.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
if(!file_exists($backup['log'])) {
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('The log not found.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$ret['result']='success';
|
||||
$ret['log_file']=$backup['log'];
|
||||
}
|
||||
else if($read_type == 'lastlog'){
|
||||
$option = $param;
|
||||
$log_file_name= $wpvivid_plugin->wpvivid_log->GetSaveLogFolder().$option.'_log.txt';
|
||||
if(!file_exists($log_file_name))
|
||||
{
|
||||
$information['result']='failed';
|
||||
$information['error']=__('The log not found.', 'wpvivid-backuprestore');
|
||||
return $information;
|
||||
}
|
||||
$ret['result']='success';
|
||||
$ret['log_file']=$log_file_name;
|
||||
}
|
||||
else if($read_type == 'tasklog'){
|
||||
$backup_task_id = $param;
|
||||
$option=WPvivid_taskmanager::get_task_options($backup_task_id,'log_file_name');
|
||||
if(!$option) {
|
||||
$information['result']='failed';
|
||||
$information['error']=__('Retrieving the backup information failed while showing log. Please try again later.', 'wpvivid-backuprestore');
|
||||
return $information;
|
||||
}
|
||||
$log_file_name= $wpvivid_plugin->wpvivid_log->GetSaveLogFolder().$option.'_log.txt';
|
||||
if(!file_exists($log_file_name)) {
|
||||
$information['result']='failed';
|
||||
$information['error']=__('The log not found.', 'wpvivid-backuprestore');
|
||||
return $information;
|
||||
}
|
||||
$ret['result']='success';
|
||||
$ret['log_file']=$log_file_name;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function _set_remote($remote){
|
||||
WPvivid_Setting::update_option('wpvivid_upload_setting',$remote['upload']);
|
||||
$history=WPvivid_Setting::get_option('wpvivid_user_history');
|
||||
$history['remote_selected']=$remote['history']['remote_selected'];
|
||||
WPvivid_Setting::update_option('wpvivid_user_history',$history);
|
||||
}
|
||||
|
||||
public function _get_default_remote_storage(){
|
||||
$remote_storage_type = '';
|
||||
$remoteslist=WPvivid_Setting::get_all_remote_options();
|
||||
$default_remote_storage='';
|
||||
foreach ($remoteslist['remote_selected'] as $value) {
|
||||
$default_remote_storage=$value;
|
||||
}
|
||||
foreach ($remoteslist as $key=>$value)
|
||||
{
|
||||
if($key === $default_remote_storage)
|
||||
{
|
||||
$remote_storage_type=$value['type'];
|
||||
}
|
||||
}
|
||||
return $remote_storage_type;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
/**
|
||||
* Define the internationalization functionality
|
||||
*
|
||||
* Loads and defines the internationalization files for this plugin
|
||||
* so that it is ready for translation.
|
||||
*
|
||||
* @link https://wpvivid.com
|
||||
* @since 0.9.1
|
||||
*
|
||||
* @package wpvivid
|
||||
* @subpackage wpvivid/includes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define the internationalization functionality.
|
||||
*
|
||||
* Loads and defines the internationalization files for this plugin
|
||||
* so that it is ready for translation.
|
||||
*
|
||||
* @since 0.9.1
|
||||
* @package wpvivid
|
||||
* @subpackage wpvivid/includes
|
||||
* @author wpvivid team
|
||||
*/
|
||||
class WPvivid_i18n {
|
||||
|
||||
|
||||
/**
|
||||
* Load the plugin text domain for translation.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function load_plugin_textdomain() {
|
||||
|
||||
load_plugin_textdomain(
|
||||
'wpvivid-backuprestore',
|
||||
false,
|
||||
dirname( dirname( plugin_basename( __FILE__ ) ) ) . '/languages/'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,648 @@
|
||||
<?php
|
||||
|
||||
class WPvivid_Interface_MainWP
|
||||
{
|
||||
public function __construct(){
|
||||
$this->load_wpvivid_mainwp_backup_filter();
|
||||
$this->load_wpvivid_mainwp_side_bar_filter();
|
||||
$this->load_wpvivid_mainwp_backup_list_filter();
|
||||
$this->load_wpvivid_mainwp_schedule_filter();
|
||||
$this->load_wpvivid_mainwp_setting_filter();
|
||||
$this->load_wpvivid_mainwp_remote_filter();
|
||||
}
|
||||
|
||||
public function load_wpvivid_mainwp_backup_filter(){
|
||||
add_filter('wpvivid_get_status_mainwp', array($this, 'wpvivid_get_status_mainwp'));
|
||||
add_filter('wpvivid_get_backup_list_mainwp', array($this, 'wpvivid_get_backup_list_mainwp'));
|
||||
add_filter('wpvivid_get_backup_schedule_mainwp', array($this, 'wpvivid_get_backup_schedule_mainwp'));
|
||||
add_filter('wpvivid_get_default_remote_mainwp', array($this, 'wpvivid_get_default_remote_mainwp'));
|
||||
add_filter('wpvivid_prepare_backup_mainwp', array($this, 'wpvivid_prepare_backup_mainwp'));
|
||||
add_filter('wpvivid_backup_now_mainwp', array($this, 'wpvivid_backup_now_mainwp'));
|
||||
add_filter('wpvivid_view_backup_task_log_mainwp', array($this, 'wpvivid_view_backup_task_log_mainwp'));
|
||||
add_filter('wpvivid_backup_cancel_mainwp', array($this, 'wpvivid_backup_cancel_mainwp'));
|
||||
add_filter('wpvivid_set_backup_report_addon_mainwp', array($this, 'wpvivid_set_backup_report_addon_mainwp'));
|
||||
}
|
||||
|
||||
public function load_wpvivid_mainwp_side_bar_filter(){
|
||||
add_filter('wpvivid_read_last_backup_log_mainwp', array($this, 'wpvivid_read_last_backup_log_mainwp'));
|
||||
}
|
||||
|
||||
public function load_wpvivid_mainwp_backup_list_filter(){
|
||||
add_filter('wpvivid_set_security_lock_mainwp', array($this, 'wpvivid_set_security_lock_mainwp'));
|
||||
add_filter('wpvivid_view_log_mainwp', array($this, 'wpvivid_view_log_mainwp'));
|
||||
add_filter('wpvivid_init_download_page_mainwp', array($this, 'wpvivid_init_download_page_mainwp'));
|
||||
add_filter('wpvivid_prepare_download_backup_mainwp', array($this, 'wpvivid_prepare_download_backup_mainwp'));
|
||||
add_filter('wpvivid_get_download_task_mainwp', array($this, 'wpvivid_get_download_task_mainwp'));
|
||||
add_filter('wpvivid_download_backup_mainwp', array($this, 'wpvivid_download_backup_mainwp'));
|
||||
add_filter('wpvivid_delete_backup_mainwp', array($this, 'wpvivid_delete_backup_mainwp'));
|
||||
add_filter('wpvivid_delete_backup_array_mainwp', array($this, 'wpvivid_delete_backup_array_mainwp'));
|
||||
}
|
||||
|
||||
public function load_wpvivid_mainwp_schedule_filter(){
|
||||
add_filter('wpvivid_set_schedule_mainwp', array($this, 'wpvivid_set_schedule_mainwp'));
|
||||
}
|
||||
|
||||
public function load_wpvivid_mainwp_setting_filter(){
|
||||
add_filter('wpvivid_set_general_setting_mainwp', array($this, 'wpvivid_set_general_setting_mainwp'));
|
||||
}
|
||||
|
||||
public function load_wpvivid_mainwp_remote_filter(){
|
||||
add_filter('wpvivid_set_remote_mainwp', array($this, 'wpvivid_set_remote_mainwp'));
|
||||
}
|
||||
|
||||
public function wpvivid_get_status_mainwp($data){
|
||||
$ret['result']='success';
|
||||
$list_tasks=array();
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
$backup = new WPvivid_Backup_Task($task['id']);
|
||||
$list_tasks[$task['id']]=$backup->get_backup_task_info($task['id']);
|
||||
if($list_tasks[$task['id']]['task_info']['need_update_last_task']===true){
|
||||
$task_msg = WPvivid_taskmanager::get_task($task['id']);
|
||||
WPvivid_Setting::update_option('wpvivid_last_msg',$task_msg);
|
||||
apply_filters('wpvivid_set_backup_report_addon_mainwp', $task_msg);
|
||||
}
|
||||
}
|
||||
$ret['wpvivid']['task']=$list_tasks;
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$schedule=WPvivid_Schedule::get_schedule();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
$ret['wpvivid']['schedule']=$schedule;
|
||||
$ret['wpvivid']['schedule']['last_message']=WPvivid_Setting::get_last_backup_message('wpvivid_last_msg');
|
||||
WPvivid_taskmanager::delete_marked_task();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_get_backup_list_mainwp($data){
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['result']='success';
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_get_backup_schedule_mainwp($data){
|
||||
$schedule=WPvivid_Schedule::get_schedule();
|
||||
$ret['result']='success';
|
||||
$ret['wpvivid']['schedule']=$schedule;
|
||||
$ret['wpvivid']['schedule']['last_message']=WPvivid_Setting::get_last_backup_message('wpvivid_last_msg');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_get_default_remote_mainwp($data){
|
||||
global $wpvivid_plugin;
|
||||
$ret['result']='success';
|
||||
$ret['remote_storage_type']=$wpvivid_plugin->function_realize->_get_default_remote_storage();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_prepare_backup_mainwp($data){
|
||||
$backup_options = $data['backup'];
|
||||
|
||||
global $wpvivid_plugin;
|
||||
if(isset($backup_options)&&!empty($backup_options))
|
||||
{
|
||||
if (is_null($backup_options))
|
||||
{
|
||||
$ret['error']='Invalid parameter param:'.$backup_options;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($backup_options['type']))
|
||||
{
|
||||
$backup_options['type']='Manual';
|
||||
}
|
||||
|
||||
if(!isset($backup_options['backup_files'])||empty($backup_options['backup_files']))
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('A backup type is required.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(!isset($backup_options['local'])||!isset($backup_options['remote']))
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Choose at least one storage location for backups.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(empty($backup_options['local']) && empty($backup_options['remote']))
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Choose at least one storage location for backups.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($backup_options['remote'] === '1')
|
||||
{
|
||||
$remote_storage = WPvivid_Setting::get_remote_options();
|
||||
if ($remote_storage == false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error'] = __('There is no default remote storage configured. Please set it up first.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(apply_filters('wpvivid_need_clean_oldest_backup',true,$backup_options))
|
||||
{
|
||||
$wpvivid_plugin->clean_oldest_backup();
|
||||
}
|
||||
do_action('wpvivid_clean_oldest_backup',$backup_options);
|
||||
|
||||
if($wpvivid_plugin->backup2->is_tasks_backup_running())
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('A task is already running. Please wait until the running task is complete, and try again.', 'wpvivid-backuprestore');
|
||||
echo wp_json_encode($ret);
|
||||
die();
|
||||
}
|
||||
|
||||
$settings=$wpvivid_plugin->backup2->get_backup_settings($backup_options);
|
||||
|
||||
$backup=new WPvivid_Backup_Task_2();
|
||||
$ret=$backup->new_backup_task($backup_options,$settings);
|
||||
}
|
||||
else{
|
||||
$ret['error']='Error occurred while parsing the request data. Please try to run backup again.';
|
||||
return $ret;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_backup_now_mainwp($data){
|
||||
global $wpvivid_plugin;
|
||||
try{
|
||||
$task_id = $data['task_id'];
|
||||
$task_id=sanitize_key($task_id);
|
||||
if (!isset($task_id)||empty($task_id)||!is_string($task_id))
|
||||
{
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error']=__('Error occurred while parsing the request data. Please try to run backup again.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if ($wpvivid_plugin->backup2->is_tasks_backup_running($task_id))
|
||||
{
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('We detected that there is already a running backup task. Please wait until it completes then try again.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
$wpvivid_plugin->backup2->update_backup_task_status($task_id,true,'running');
|
||||
$wpvivid_plugin->flush($task_id, true);
|
||||
$wpvivid_plugin->backup2->add_monitor_event($task_id);
|
||||
$wpvivid_plugin->backup2->task=new WPvivid_Backup_Task_2($task_id);
|
||||
$wpvivid_plugin->backup2->task->set_memory_limit();
|
||||
$wpvivid_plugin->backup2->task->set_time_limit();
|
||||
|
||||
$wpvivid_plugin->wpvivid_log->OpenLogFile($wpvivid_plugin->backup2->task->task['options']['log_file_name']);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Start backing up.','notice');
|
||||
$wpvivid_plugin->wpvivid_log->WriteLogHander();
|
||||
|
||||
if(!$wpvivid_plugin->backup2->task->is_backup_finished())
|
||||
{
|
||||
$ret=$wpvivid_plugin->backup2->backup();
|
||||
$wpvivid_plugin->backup2->task->clear_cache();
|
||||
if($ret['result']!='success')
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Backup the file ends with an error '. $ret['error'],'error');
|
||||
$wpvivid_plugin->backup2->task->update_backup_task_status(false,'error',false,false,$ret['error']);
|
||||
do_action('wpvivid_handle_backup_2_failed', $task_id);
|
||||
$wpvivid_plugin->backup2->clear_monitor_schedule($task_id);
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error']='Backup the file ends with an error '. $ret['error'];
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
if($wpvivid_plugin->backup2->task->need_upload())
|
||||
{
|
||||
$ret=$wpvivid_plugin->backup2->upload($task_id);
|
||||
if($ret['result'] == WPVIVID_SUCCESS)
|
||||
{
|
||||
do_action('wpvivid_handle_backup_2_succeed',$task_id);
|
||||
$wpvivid_plugin->backup2->update_backup_task_status($task_id,false,'completed');
|
||||
}
|
||||
else
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Uploading the file ends with an error '. $ret['error'], 'error');
|
||||
do_action('wpvivid_handle_backup_2_failed',$task_id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog('Backup completed.','notice');
|
||||
do_action('wpvivid_handle_backup_2_succeed', $task_id);
|
||||
$wpvivid_plugin->backup2->update_backup_task_status($task_id,false,'completed');
|
||||
}
|
||||
$wpvivid_plugin->backup2->clear_monitor_schedule($task_id);
|
||||
$ret['result']='success';
|
||||
return $ret;
|
||||
}
|
||||
catch (Exception $error)
|
||||
{
|
||||
//catch error and stop task recording history
|
||||
$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);
|
||||
WPvivid_taskmanager::update_backup_task_status($task_id,false,'error',false,false,$message);
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog($message,'error');
|
||||
do_action('wpvivid_handle_backup_2_failed',$task_id);
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error']=$message;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_view_backup_task_log_mainwp($data){
|
||||
$backup_task_id = $data['id'];
|
||||
global $wpvivid_plugin;
|
||||
if (!isset($backup_task_id)||empty($backup_task_id)||!is_string($backup_task_id)){
|
||||
$ret['error']='Reading the log failed. Please try again.';
|
||||
return $ret;
|
||||
}
|
||||
$backup_task_id = sanitize_key($backup_task_id);
|
||||
$ret=$wpvivid_plugin->function_realize->_get_log_file('tasklog', $backup_task_id);
|
||||
if($ret['result'] == 'success') {
|
||||
$file = fopen($ret['log_file'], 'r');
|
||||
if (!$file) {
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('Unable to open the log file.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$buffer = '';
|
||||
while (!feof($file)) {
|
||||
$buffer .= fread($file, 1024);
|
||||
}
|
||||
fclose($file);
|
||||
$ret['result'] = 'success';
|
||||
$ret['data'] = $buffer;
|
||||
}
|
||||
else{
|
||||
$ret['error']='Unknown error';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_backup_cancel_mainwp($data){
|
||||
global $wpvivid_plugin;
|
||||
$ret=$wpvivid_plugin->function_realize->_backup_cancel();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_set_backup_report_addon_mainwp($data){
|
||||
if(isset($data['id']))
|
||||
{
|
||||
$task_id = $data['id'];
|
||||
$option = array();
|
||||
$option[$task_id]['task_id'] = $task_id;
|
||||
$option[$task_id]['backup_time'] = $data['status']['start_time'];
|
||||
if($data['status']['str'] == 'completed'){
|
||||
$option[$task_id]['status'] = 'Succeeded';
|
||||
}
|
||||
elseif($data['status']['str'] == 'error'){
|
||||
$option[$task_id]['status'] = 'Failed, '.$data['status']['error'];
|
||||
}
|
||||
elseif($data['status']['str'] == 'cancel'){
|
||||
$option[$task_id]['status'] = 'Canceled';
|
||||
}
|
||||
else{
|
||||
$option[$task_id]['status'] = 'The last backup message not found.';
|
||||
}
|
||||
|
||||
$backup_reports = get_option('wpvivid_backup_reports', array());
|
||||
if(!empty($backup_reports)){
|
||||
foreach ($option as $key => $value){
|
||||
$backup_reports[$key] = $value;
|
||||
update_option('wpvivid_backup_reports', $backup_reports, 'no');
|
||||
}
|
||||
}
|
||||
else{
|
||||
update_option('wpvivid_backup_reports', $option, 'no');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_read_last_backup_log_mainwp($data){
|
||||
$log_file_name = $data['log_file_name'];
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($log_file_name)||empty($log_file_name)||!is_string($log_file_name))
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Reading the log failed. Please try again.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$log_file_name=sanitize_text_field($log_file_name);
|
||||
$ret=$wpvivid_plugin->function_realize->_get_log_file('lastlog', $log_file_name);
|
||||
if($ret['result'] == 'success') {
|
||||
$file = fopen($ret['log_file'], 'r');
|
||||
if (!$file) {
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('Unable to open the log file.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$buffer = '';
|
||||
while (!feof($file)) {
|
||||
$buffer .= fread($file, 1024);
|
||||
}
|
||||
fclose($file);
|
||||
$ret['result'] = 'success';
|
||||
$ret['data'] = $buffer;
|
||||
}
|
||||
else{
|
||||
$ret['error']='Unknown error';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_set_security_lock_mainwp($data){
|
||||
$backup_id = $data['backup_id'];
|
||||
$lock = $data['lock'];
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)){
|
||||
$ret['error']='Backup id not found';
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($lock)){
|
||||
$ret['error']='Invalid parameter param: lock';
|
||||
return $ret;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
if($lock==0||$lock==1) {
|
||||
}
|
||||
else {
|
||||
$lock=0;
|
||||
}
|
||||
WPvivid_Backuplist::set_security_lock($backup_id,$lock);
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_view_log_mainwp($data){
|
||||
$backup_id = $data['id'];
|
||||
global $wpvivid_plugin;
|
||||
if (!isset($backup_id)||empty($backup_id)||!is_string($backup_id)){
|
||||
$ret['error']='Backup id not found';
|
||||
return $ret;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$ret=$wpvivid_plugin->function_realize->_get_log_file('backuplist', $backup_id);
|
||||
if($ret['result'] == 'success') {
|
||||
$file = fopen($ret['log_file'], 'r');
|
||||
if (!$file) {
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('Unable to open the log file.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$buffer = '';
|
||||
while (!feof($file)) {
|
||||
$buffer .= fread($file, 1024);
|
||||
}
|
||||
fclose($file);
|
||||
$ret['data'] = $buffer;
|
||||
}
|
||||
else{
|
||||
$ret['error']='Unknown error';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_init_download_page_mainwp($data){
|
||||
$backup_id = $data['backup_id'];
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param:'.$backup_id;
|
||||
return $ret;
|
||||
}
|
||||
else {
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
return $wpvivid_plugin->init_download($backup_id);
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_prepare_download_backup_mainwp($data){
|
||||
$backup_id = $data['backup_id'];
|
||||
$file_name = $data['file_name'];
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id))
|
||||
{
|
||||
$ret['error']='Invalid parameter param:'.$backup_id;
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($file_name)||empty($file_name)||!is_string($file_name))
|
||||
{
|
||||
$ret['error']='Invalid parameter param:'.$file_name;
|
||||
return $ret;
|
||||
}
|
||||
$download_info=array();
|
||||
$download_info['backup_id']=sanitize_key($backup_id);
|
||||
$download_info['file_name'] = $file_name;
|
||||
|
||||
@set_time_limit(600);
|
||||
if (session_id())
|
||||
session_write_close();
|
||||
try
|
||||
{
|
||||
$downloader=new WPvivid_downloader();
|
||||
$downloader->ready_download($download_info);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$message = 'A exception ('.get_class($e).') occurred '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
error_log($message);
|
||||
return array('error'=>$message);
|
||||
}
|
||||
catch (Error $e)
|
||||
{
|
||||
$message = 'A error ('.get_class($e).') has occurred: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
error_log($message);
|
||||
return array('error'=>$message);
|
||||
}
|
||||
|
||||
$ret['result']='success';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_get_download_task_mainwp($data){
|
||||
$backup_id = $data['backup_id'];
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param:'.$backup_id;
|
||||
return $ret;
|
||||
}
|
||||
else {
|
||||
$backup = WPvivid_Backuplist::get_backup_by_id($backup_id);
|
||||
if ($backup === false) {
|
||||
$ret['result'] = WPVIVID_FAILED;
|
||||
$ret['error'] = 'backup id not found';
|
||||
return $ret;
|
||||
}
|
||||
$backup_item = new WPvivid_Backup_Item($backup);
|
||||
$ret = $backup_item->update_download_page($backup_id);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
public function wpvivid_download_backup_mainwp($data){
|
||||
$backup_id = $data['backup_id'];
|
||||
$file_name = $data['file_name'];
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param: backup_id';
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($file_name)||empty($file_name)||!is_string($file_name)) {
|
||||
$ret['error']='Invalid parameter param: file_name';
|
||||
return $ret;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$cache=WPvivid_taskmanager::get_download_cache($backup_id);
|
||||
if($cache===false) {
|
||||
$wpvivid_plugin->init_download($backup_id);
|
||||
$cache=WPvivid_taskmanager::get_download_cache($backup_id);
|
||||
}
|
||||
$path=false;
|
||||
if(array_key_exists($file_name,$cache['files'])) {
|
||||
if($cache['files'][$file_name]['status']=='completed') {
|
||||
$path=$cache['files'][$file_name]['download_path'];
|
||||
$download_url = $cache['files'][$file_name]['download_url'];
|
||||
}
|
||||
}
|
||||
if($path!==false) {
|
||||
if (file_exists($path)) {
|
||||
$ret['download_url'] = $download_url;
|
||||
$ret['size'] = filesize($path);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_delete_backup_mainwp($data){
|
||||
$backup_id = $data['backup_id'];
|
||||
$force_del = $data['force'];
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param: backup_id.';
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($force_del)){
|
||||
$ret['error']='Invalid parameter param: force.';
|
||||
return $ret;
|
||||
}
|
||||
if($force_del==0||$force_del==1) {
|
||||
}
|
||||
else {
|
||||
$force_del=0;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$ret=$wpvivid_plugin->delete_backup_by_id($backup_id, $force_del);
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_delete_backup_array_mainwp($data){
|
||||
$backup_id_array = $data['backup_id'];
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id_array)||empty($backup_id_array)||!is_array($backup_id_array)) {
|
||||
$ret['error']='Invalid parameter param: backup_id';
|
||||
return $ret;
|
||||
}
|
||||
$ret=array();
|
||||
foreach($backup_id_array as $backup_id)
|
||||
{
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$ret=$wpvivid_plugin->delete_backup_by_id($backup_id);
|
||||
}
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_set_schedule_mainwp($data){
|
||||
$schedule = $data['schedule'];
|
||||
$ret=array();
|
||||
try {
|
||||
if(isset($schedule)&&!empty($schedule)) {
|
||||
$json = $schedule;
|
||||
$json = stripslashes($json);
|
||||
$schedule = json_decode($json, true);
|
||||
if (is_null($schedule)) {
|
||||
$ret['error']='bad parameter';
|
||||
return $ret;
|
||||
}
|
||||
$ret=WPvivid_Schedule::set_schedule_ex($schedule);
|
||||
if($ret['result']!='success') {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
$ret['result']='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('error'=>$message);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_set_general_setting_mainwp($data){
|
||||
$setting = $data['setting'];
|
||||
$ret=array();
|
||||
try {
|
||||
if(isset($setting)&&!empty($setting)) {
|
||||
$json_setting = $setting;
|
||||
$json_setting = stripslashes($json_setting);
|
||||
$setting = json_decode($json_setting, true);
|
||||
if (is_null($setting)) {
|
||||
$ret['error']='bad parameter';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if(isset($setting['wpvivid_compress_setting']['max_file_size']))
|
||||
{
|
||||
$setting['wpvivid_common_setting']['max_file_size'] = str_replace('M', '', $setting['wpvivid_compress_setting']['max_file_size']);
|
||||
}
|
||||
|
||||
if(isset($setting['wpvivid_compress_setting']['exclude_file_size']))
|
||||
{
|
||||
$setting['wpvivid_common_setting']['exclude_file_size'] = $setting['wpvivid_compress_setting']['exclude_file_size'];
|
||||
}
|
||||
|
||||
WPvivid_Setting::update_setting($setting);
|
||||
}
|
||||
|
||||
$ret['result']='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('error'=>$message);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function wpvivid_set_remote_mainwp($data){
|
||||
$remote = $data['remote'];
|
||||
global $wpvivid_plugin;
|
||||
$ret=array();
|
||||
try {
|
||||
if(isset($remote)&&!empty($remote)) {
|
||||
$json = $remote;
|
||||
$json = stripslashes($json);
|
||||
$remote = json_decode($json, true);
|
||||
if (is_null($remote)) {
|
||||
$ret['error']='bad parameter';
|
||||
return $ret;
|
||||
}
|
||||
$wpvivid_plugin->function_realize->_set_remote($remote);
|
||||
}
|
||||
$ret['result']='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('error'=>$message);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
class WPvivid_Log
|
||||
{
|
||||
public $log_file;
|
||||
public $log_file_handle;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->log_file_handle=false;
|
||||
}
|
||||
|
||||
public function CreateLogFile($file_name,$type,$describe)
|
||||
{
|
||||
if($type=='has_folder')
|
||||
{
|
||||
$this->log_file=$file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->log_file=$this->GetSaveLogFolder().$file_name.'_log.txt';
|
||||
}
|
||||
if(file_exists($this->log_file))
|
||||
{
|
||||
@wp_delete_file( $this->log_file);
|
||||
}
|
||||
$this->log_file_handle = fopen($this->log_file, 'a');
|
||||
$offset=get_option('gmt_offset');
|
||||
$time =gmdate("Y-m-d H:i:s",time()+$offset*60*60);
|
||||
$text='Log created: '.$time."\n";
|
||||
$text.='Type: '.$describe."\n";
|
||||
fwrite($this->log_file_handle,$text);
|
||||
|
||||
return $this->log_file;
|
||||
}
|
||||
|
||||
public function OpenLogFile($file_name,$type='no_folder',$delete=0)
|
||||
{
|
||||
if($type=='has_folder')
|
||||
{
|
||||
$this->log_file=$file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->log_file=$this->GetSaveLogFolder().$file_name.'_log.txt';
|
||||
}
|
||||
if($delete==1)
|
||||
{
|
||||
wp_delete_file( $this->log_file);
|
||||
}
|
||||
$this->log_file_handle = fopen($this->log_file, 'a');
|
||||
|
||||
return $this->log_file;
|
||||
}
|
||||
|
||||
public function WriteLog($log,$type)
|
||||
{
|
||||
if ($this->log_file_handle)
|
||||
{
|
||||
$offset=get_option('gmt_offset');
|
||||
$time =gmdate("Y-m-d H:i:s",time()+$offset*60*60);
|
||||
$text='['.$time.']'.'['.$type.']'.$log."\n";
|
||||
fwrite($this->log_file_handle,$text );
|
||||
}
|
||||
}
|
||||
|
||||
public function CloseFile()
|
||||
{
|
||||
if ($this->log_file_handle)
|
||||
{
|
||||
fclose($this->log_file_handle);
|
||||
$this->log_file_handle=false;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetSaveLogFolder()
|
||||
{
|
||||
include_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wpvivid-setting.php';
|
||||
|
||||
$options = WPvivid_Setting::get_option('wpvivid_common_setting');
|
||||
|
||||
if(!isset($options['log_save_location']))
|
||||
{
|
||||
//WPvivid_Setting::set_default_common_option();
|
||||
$options['log_save_location']=WPVIVID_DEFAULT_LOG_DIR;
|
||||
update_option('wpvivid_common_setting', $options, 'no');
|
||||
|
||||
$options = WPvivid_Setting::get_option('wpvivid_common_setting');
|
||||
}
|
||||
|
||||
if(!is_dir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location']))
|
||||
{
|
||||
@mkdir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'],0777,true);
|
||||
//@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'].DIRECTORY_SEPARATOR.'index.html', 'x');
|
||||
$tempfile=@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'].DIRECTORY_SEPARATOR.'.htaccess', 'x');
|
||||
if($tempfile)
|
||||
{
|
||||
//$text="deny from all";
|
||||
$text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";
|
||||
fwrite($tempfile,$text );
|
||||
}
|
||||
}
|
||||
|
||||
return WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'].DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
public function WriteLogHander()
|
||||
{
|
||||
if ($this->log_file_handle)
|
||||
{
|
||||
global $wp_version;
|
||||
global $wpdb;
|
||||
|
||||
$sapi_type=php_sapi_name();
|
||||
if($sapi_type=='cgi-fcgi'||$sapi_type==' fpm-fcgi') {
|
||||
$fcgi='On';
|
||||
}
|
||||
else {
|
||||
$fcgi='Off';
|
||||
}
|
||||
|
||||
$options=WPvivid_Setting::get_option('wpvivid_common_setting');
|
||||
if(isset($options['max_execution_time'])) {
|
||||
$max_execution_time=$options['max_execution_time'];
|
||||
}
|
||||
else {
|
||||
$max_execution_time=WPVIVID_MAX_EXECUTION_TIME;
|
||||
}
|
||||
|
||||
$log='server info fcgi:'.$fcgi.' max execution time: '.$max_execution_time.' wp version:'.$wp_version.' php version:'.phpversion().' db version:'.$wpdb->db_version().' php ini:safe_mode:'.ini_get('safe_mode').' ';
|
||||
$log.='memory_limit:'.ini_get('memory_limit').' memory_get_usage:'.size_format(memory_get_usage(),2).' memory_get_peak_usage:'.size_format(memory_get_peak_usage(),2);
|
||||
$log.=' extensions:';
|
||||
$loaded_extensions = get_loaded_extensions();
|
||||
if(!in_array('PDO', $loaded_extensions))
|
||||
{
|
||||
$log.='PDO not enabled ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$log.='PDO enabled ';
|
||||
}
|
||||
if(!in_array('curl', $loaded_extensions))
|
||||
{
|
||||
$log.='curl not enabled ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$log.='curl enabled ';
|
||||
}
|
||||
|
||||
if(!in_array('zlib', $loaded_extensions)) {
|
||||
$log .= 'zlib not enabled ';
|
||||
}
|
||||
else
|
||||
{
|
||||
$log.='zlib enabled ';
|
||||
}
|
||||
|
||||
$log.=' ';
|
||||
if(is_multisite())
|
||||
{
|
||||
$log.=' is_multisite:1';
|
||||
}
|
||||
else
|
||||
{
|
||||
$log.=' is_multisite:0';
|
||||
}
|
||||
|
||||
$offset=get_option('gmt_offset');
|
||||
$time =gmdate("Y-m-d H:i:s",time()+$offset*60*60);
|
||||
$text='['.$time.']'.'[notice]'.$log."\n";
|
||||
fwrite($this->log_file_handle,$text );
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,431 @@
|
||||
<?php
|
||||
|
||||
class WPvivid_Public_Interface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function mainwp_data($data){
|
||||
$action = sanitize_text_field($data['mwp_action']);
|
||||
if (has_filter($action)) {
|
||||
$ret = apply_filters($action, $data);
|
||||
} else {
|
||||
$ret['result'] = WPVIVID_FAILED;
|
||||
$ret['error'] = 'Unknown function';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function prepare_backup($backup_options){
|
||||
global $wpvivid_plugin;
|
||||
if(isset($backup_options)&&!empty($backup_options)){
|
||||
if (is_null($backup_options)) {
|
||||
$ret['error']='Invalid parameter param:'.$backup_options;
|
||||
return $ret;
|
||||
}
|
||||
$backup_options = apply_filters('wpvivid_custom_backup_options', $backup_options);
|
||||
|
||||
if(!isset($backup_options['type']))
|
||||
{
|
||||
$backup_options['type']=__('Manual', 'wpvivid-backuprestore');
|
||||
$backup_options['action']='backup';
|
||||
}
|
||||
$ret = $wpvivid_plugin->check_backup_option($backup_options, $backup_options['type']);
|
||||
if($ret['result']!='success') {
|
||||
return $ret;
|
||||
}
|
||||
$ret=$wpvivid_plugin->pre_backup($backup_options);
|
||||
if($ret['result']=='success') {
|
||||
//Check the website data to be backed up
|
||||
$ret['check']=$wpvivid_plugin->check_backup($ret['task_id'],$backup_options);
|
||||
if(isset($ret['check']['result']) && $ret['check']['result'] == 'failed') {
|
||||
$ret['error']=$ret['check']['error'];
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
$ret['error']='Error occurred while parsing the request data. Please try to run backup again.';
|
||||
return $ret;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_status(){
|
||||
$ret['result']='success';
|
||||
$list_tasks=array();
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
$backup = new WPvivid_Backup_Task($task['id']);
|
||||
$list_tasks[$task['id']]=$backup->get_backup_task_info($task['id']);
|
||||
if($list_tasks[$task['id']]['task_info']['need_update_last_task']===true){
|
||||
$task_msg = WPvivid_taskmanager::get_task($task['id']);
|
||||
WPvivid_Setting::update_option('wpvivid_last_msg',$task_msg);
|
||||
apply_filters('wpvivid_set_backup_report_addon_mainwp', $task_msg);
|
||||
}
|
||||
}
|
||||
$ret['wpvivid']['task']=$list_tasks;
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$schedule=WPvivid_Schedule::get_schedule();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
$ret['wpvivid']['schedule']=$schedule;
|
||||
$ret['wpvivid']['schedule']['last_message']=WPvivid_Setting::get_last_backup_message('wpvivid_last_msg');
|
||||
WPvivid_taskmanager::delete_marked_task();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_backup_schedule(){
|
||||
$schedule=WPvivid_Schedule::get_schedule();
|
||||
$ret['result']='success';
|
||||
$ret['wpvivid']['schedule']=$schedule;
|
||||
$ret['wpvivid']['schedule']['last_message']=WPvivid_Setting::get_last_backup_message('wpvivid_last_msg');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_backup_list(){
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['result']='success';
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_default_remote(){
|
||||
global $wpvivid_plugin;
|
||||
$ret['result']='success';
|
||||
$ret['remote_storage_type']=$wpvivid_plugin->function_realize->_get_default_remote_storage();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function delete_backup($backup_id, $force_del){
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param: backup_id.';
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($force_del)){
|
||||
$ret['error']='Invalid parameter param: force.';
|
||||
return $ret;
|
||||
}
|
||||
if($force_del==0||$force_del==1) {
|
||||
}
|
||||
else {
|
||||
$force_del=0;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$ret=$wpvivid_plugin->delete_backup_by_id($backup_id, $force_del);
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function delete_backup_array($backup_id_array){
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id_array)||empty($backup_id_array)||!is_array($backup_id_array)) {
|
||||
$ret['error']='Invalid parameter param: backup_id';
|
||||
return $ret;
|
||||
}
|
||||
$ret=array();
|
||||
foreach($backup_id_array as $backup_id)
|
||||
{
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$ret=$wpvivid_plugin->delete_backup_by_id($backup_id);
|
||||
}
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function set_security_lock($backup_id, $lock){
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)){
|
||||
$ret['error']='Backup id not found';
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($lock)){
|
||||
$ret['error']='Invalid parameter param: lock';
|
||||
return $ret;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
if($lock==0||$lock==1) {
|
||||
}
|
||||
else {
|
||||
$lock=0;
|
||||
}
|
||||
WPvivid_Backuplist::set_security_lock($backup_id,$lock);
|
||||
$backuplist=WPvivid_Backuplist::get_backuplist();
|
||||
$ret['wpvivid']['backup_list']=$backuplist;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function view_log($backup_id){
|
||||
global $wpvivid_plugin;
|
||||
if (!isset($backup_id)||empty($backup_id)||!is_string($backup_id)){
|
||||
$ret['error']='Backup id not found';
|
||||
return $ret;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$ret=$wpvivid_plugin->function_realize->_get_log_file('backuplist', $backup_id);
|
||||
if($ret['result'] == 'success') {
|
||||
$file = fopen($ret['log_file'], 'r');
|
||||
if (!$file) {
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('Unable to open the log file.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$buffer = '';
|
||||
while (!feof($file)) {
|
||||
$buffer .= fread($file, 1024);
|
||||
}
|
||||
fclose($file);
|
||||
$ret['data'] = $buffer;
|
||||
}
|
||||
else{
|
||||
$ret['error']='Unknown error';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function read_last_backup_log($log_file_name){
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($log_file_name)||empty($log_file_name)||!is_string($log_file_name))
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Reading the log failed. Please try again.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$log_file_name=sanitize_text_field($log_file_name);
|
||||
$ret=$wpvivid_plugin->function_realize->_get_log_file('lastlog', $log_file_name);
|
||||
if($ret['result'] == 'success') {
|
||||
$file = fopen($ret['log_file'], 'r');
|
||||
if (!$file) {
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('Unable to open the log file.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$buffer = '';
|
||||
while (!feof($file)) {
|
||||
$buffer .= fread($file, 1024);
|
||||
}
|
||||
fclose($file);
|
||||
$ret['result'] = 'success';
|
||||
$ret['data'] = $buffer;
|
||||
}
|
||||
else{
|
||||
$ret['error']='Unknown error';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function view_backup_task_log($backup_task_id){
|
||||
global $wpvivid_plugin;
|
||||
if (!isset($backup_task_id)||empty($backup_task_id)||!is_string($backup_task_id)){
|
||||
$ret['error']='Reading the log failed. Please try again.';
|
||||
return $ret;
|
||||
}
|
||||
$backup_task_id = sanitize_key($backup_task_id);
|
||||
$ret=$wpvivid_plugin->function_realize->_get_log_file('tasklog', $backup_task_id);
|
||||
if($ret['result'] == 'success') {
|
||||
$file = fopen($ret['log_file'], 'r');
|
||||
if (!$file) {
|
||||
$ret['result'] = 'failed';
|
||||
$ret['error'] = __('Unable to open the log file.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
$buffer = '';
|
||||
while (!feof($file)) {
|
||||
$buffer .= fread($file, 1024);
|
||||
}
|
||||
fclose($file);
|
||||
$ret['result'] = 'success';
|
||||
$ret['data'] = $buffer;
|
||||
}
|
||||
else{
|
||||
$ret['error']='Unknown error';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function backup_cancel($task_id = ''){
|
||||
global $wpvivid_plugin;
|
||||
$ret=$wpvivid_plugin->function_realize->_backup_cancel();
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function init_download_page($backup_id){
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param:'.$backup_id;
|
||||
return $ret;
|
||||
}
|
||||
else {
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
return $wpvivid_plugin->init_download($backup_id);
|
||||
}
|
||||
}
|
||||
|
||||
public function prepare_download_backup($backup_id, $file_name){
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id))
|
||||
{
|
||||
$ret['error']='Invalid parameter param:'.$backup_id;
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($file_name)||empty($file_name)||!is_string($file_name))
|
||||
{
|
||||
$ret['error']='Invalid parameter param:'.$file_name;
|
||||
return $ret;
|
||||
}
|
||||
$download_info=array();
|
||||
$download_info['backup_id']=sanitize_key($backup_id);
|
||||
$download_info['file_name'] = $file_name;
|
||||
|
||||
@set_time_limit(600);
|
||||
if (session_id())
|
||||
session_write_close();
|
||||
try
|
||||
{
|
||||
$downloader=new WPvivid_downloader();
|
||||
$downloader->ready_download($download_info);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
$message = 'A exception ('.get_class($e).') occurred '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
error_log($message);
|
||||
return array('error'=>$message);
|
||||
}
|
||||
catch (Error $e)
|
||||
{
|
||||
$message = 'A error ('.get_class($e).') has occurred: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
||||
error_log($message);
|
||||
return array('error'=>$message);
|
||||
}
|
||||
|
||||
$ret['result']='success';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_download_task($backup_id){
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param:'.$backup_id;
|
||||
return $ret;
|
||||
}
|
||||
else {
|
||||
$backup = WPvivid_Backuplist::get_backup_by_id($backup_id);
|
||||
if ($backup === false) {
|
||||
$ret['result'] = WPVIVID_FAILED;
|
||||
$ret['error'] = 'backup id not found';
|
||||
return $ret;
|
||||
}
|
||||
$backup_item = new WPvivid_Backup_Item($backup);
|
||||
$ret = $backup_item->update_download_page($backup_id);
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
public function download_backup($backup_id, $file_name){
|
||||
global $wpvivid_plugin;
|
||||
if(!isset($backup_id)||empty($backup_id)||!is_string($backup_id)) {
|
||||
$ret['error']='Invalid parameter param: backup_id';
|
||||
return $ret;
|
||||
}
|
||||
if(!isset($file_name)||empty($file_name)||!is_string($file_name)) {
|
||||
$ret['error']='Invalid parameter param: file_name';
|
||||
return $ret;
|
||||
}
|
||||
$backup_id=sanitize_key($backup_id);
|
||||
$cache=WPvivid_taskmanager::get_download_cache($backup_id);
|
||||
if($cache===false) {
|
||||
$wpvivid_plugin->init_download($backup_id);
|
||||
$cache=WPvivid_taskmanager::get_download_cache($backup_id);
|
||||
}
|
||||
$path=false;
|
||||
if(array_key_exists($file_name,$cache['files'])) {
|
||||
if($cache['files'][$file_name]['status']=='completed') {
|
||||
$path=$cache['files'][$file_name]['download_path'];
|
||||
$download_url = $cache['files'][$file_name]['download_url'];
|
||||
}
|
||||
}
|
||||
if($path!==false) {
|
||||
if (file_exists($path)) {
|
||||
$ret['download_url'] = $download_url;
|
||||
$ret['size'] = filesize($path);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function set_general_setting($setting){
|
||||
$ret=array();
|
||||
try {
|
||||
if(isset($setting)&&!empty($setting)) {
|
||||
$json_setting = $setting;
|
||||
$json_setting = stripslashes($json_setting);
|
||||
$setting = json_decode($json_setting, true);
|
||||
if (is_null($setting)) {
|
||||
$ret['error']='bad parameter';
|
||||
return $ret;
|
||||
}
|
||||
WPvivid_Setting::update_setting($setting);
|
||||
}
|
||||
|
||||
$ret['result']='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('error'=>$message);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function set_schedule($schedule){
|
||||
$ret=array();
|
||||
try {
|
||||
if(isset($schedule)&&!empty($schedule)) {
|
||||
$json = $schedule;
|
||||
$json = stripslashes($json);
|
||||
$schedule = json_decode($json, true);
|
||||
if (is_null($schedule)) {
|
||||
$ret['error']='bad parameter';
|
||||
return $ret;
|
||||
}
|
||||
$ret=WPvivid_Schedule::set_schedule_ex($schedule);
|
||||
if($ret['result']!='success') {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
$ret['result']='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('error'=>$message);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function set_remote($remote){
|
||||
global $wpvivid_plugin;
|
||||
$ret=array();
|
||||
try {
|
||||
if(isset($remote)&&!empty($remote)) {
|
||||
$json = $remote;
|
||||
$json = stripslashes($json);
|
||||
$remote = json_decode($json, true);
|
||||
if (is_null($remote)) {
|
||||
$ret['error']='bad parameter';
|
||||
return $ret;
|
||||
}
|
||||
$wpvivid_plugin->function_realize->_set_remote($remote);
|
||||
}
|
||||
$ret['result']='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('error'=>$message);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: alienware`x
|
||||
* Date: 2019/1/22
|
||||
* Time: 9:19
|
||||
*/
|
||||
|
||||
require_once WPVIVID_PLUGIN_DIR .'/includes/customclass/class-wpvivid-remote-default.php';
|
||||
require_once WPVIVID_PLUGIN_DIR .'/includes/customclass/class-wpvivid-ftpclass.php';
|
||||
require_once WPVIVID_PLUGIN_DIR. '/includes/customclass/class-wpvivid-sftpclass.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-amazons3-plus.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-google-drive.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-dropbox.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-one-drive.php';
|
||||
require_once WPVIVID_PLUGIN_DIR . '/includes/customclass/class-wpvivid-s3compat.php';
|
||||
|
||||
|
||||
class WPvivid_Remote_collection
|
||||
{
|
||||
private $remote_collection=array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
add_filter('wpvivid_remote_register', array($this, 'init_remotes'),10);
|
||||
$this->remote_collection=apply_filters('wpvivid_remote_register',$this->remote_collection);
|
||||
$this->load_hooks();
|
||||
}
|
||||
|
||||
public function get_remote($remote)
|
||||
{
|
||||
if(is_array($remote)&&array_key_exists('type',$remote)&&array_key_exists($remote['type'],$this->remote_collection))
|
||||
{
|
||||
$class_name =$this->remote_collection[$remote['type']];
|
||||
|
||||
if(class_exists($class_name))
|
||||
{
|
||||
$object = new $class_name($remote);
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
$object = new $this ->remote_collection['default']();
|
||||
return $object;
|
||||
}
|
||||
|
||||
public function add_remote($remote_option)
|
||||
{
|
||||
$remote=$this->get_remote($remote_option);
|
||||
|
||||
$ret=$remote->sanitize_options();
|
||||
|
||||
if($ret['result']=='success')
|
||||
{
|
||||
$remote_option=$ret['options'];
|
||||
$ret=$remote->test_connect();
|
||||
if($ret['result']=='success')
|
||||
{
|
||||
$ret=array();
|
||||
$default=$remote_option['default'];
|
||||
$id=WPvivid_Setting::add_remote_options($remote_option);
|
||||
if($default==1)
|
||||
{
|
||||
$remote_ids[]=$id;
|
||||
$remote_ids=apply_filters('wpvivid_before_add_user_history',$remote_ids);
|
||||
WPvivid_Setting::update_user_history('remote_selected',$remote_ids);
|
||||
$schedule_data = WPvivid_Setting::get_option('wpvivid_schedule_setting');
|
||||
if(!empty($schedule_data['enable'])) {
|
||||
if ($schedule_data['enable'] == 1) {
|
||||
$schedule_data['backup']['local'] = 0;
|
||||
$schedule_data['backup']['remote'] = 1;
|
||||
}
|
||||
WPvivid_Setting::update_option('wpvivid_schedule_setting', $schedule_data);
|
||||
}
|
||||
}
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
}
|
||||
else {
|
||||
$id = uniqid('wpvivid-');
|
||||
$log_file_name = $id . '_add_remote';
|
||||
$log = new WPvivid_Log();
|
||||
$log->CreateLogFile($log_file_name, 'no_folder', 'Add Remote Test Connection');
|
||||
$log->WriteLog('Remote Type: '.$remote_option['type'], 'notice');
|
||||
if(isset($ret['error'])) {
|
||||
$log->WriteLog($ret['error'], 'notice');
|
||||
}
|
||||
$log->CloseFile();
|
||||
WPvivid_error_log::create_error_log($log->log_file);
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function update_remote($id,$remote_option)
|
||||
{
|
||||
$remote=$this->get_remote($remote_option);
|
||||
|
||||
$old_remote=WPvivid_Setting::get_remote_option($id);
|
||||
|
||||
$ret=$remote->sanitize_options($old_remote['name']);
|
||||
if($ret['result']=='success')
|
||||
{
|
||||
$remote_option=$ret['options'];
|
||||
$ret=$remote->test_connect();
|
||||
if($ret['result']=='success')
|
||||
{
|
||||
$ret=array();
|
||||
WPvivid_Setting::update_remote_option($id,$remote_option);
|
||||
$ret['result']=WPVIVID_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function init_remotes($remote_collection)
|
||||
{
|
||||
$remote_collection['default'] = 'WPvivid_Remote_Defult';
|
||||
$remote_collection['sftp']='WPvivid_SFTPClass';
|
||||
$remote_collection['ftp']='WPvivid_FTPClass';
|
||||
$remote_collection['amazons3']='WPvivid_AMAZONS3Class';
|
||||
$remote_collection[WPVIVID_REMOTE_GOOGLEDRIVE] = 'Wpvivid_Google_drive';
|
||||
$remote_collection['dropbox']='WPvivid_Dropbox';
|
||||
$remote_collection[WPVIVID_REMOTE_ONEDRIVE] = 'Wpvivid_one_drive';
|
||||
$remote_collection[WPVIVID_REMOTE_S3COMPAT] = 'Wpvivid_S3Compat';
|
||||
$remote_collection[WPVIVID_REMOTE_SEND_TO_SITE] = 'WPvivid_Send_to_site';
|
||||
return $remote_collection;
|
||||
}
|
||||
|
||||
public function load_hooks()
|
||||
{
|
||||
foreach ($this->remote_collection as $class_name)
|
||||
{
|
||||
$object = new $class_name();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
class WPvivid_restore_data
|
||||
{
|
||||
public $restore_data_file;
|
||||
public $restore_log_file;
|
||||
public $restore_log=false;
|
||||
public $restore_cache=false;
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$dir=WPvivid_Setting::get_backupdir();
|
||||
$this->restore_data_file= WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.'wpvivid_restoredata';
|
||||
$this->restore_log_file= WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir.DIRECTORY_SEPARATOR.'wpvivid_restore_log.txt';
|
||||
}
|
||||
|
||||
public function write_log($message,$type)
|
||||
{
|
||||
if($this->restore_log===false)
|
||||
{
|
||||
$this->restore_log=new WPvivid_Log();
|
||||
$this->restore_log->OpenLogFile($this->restore_log_file,'has_folder');
|
||||
}
|
||||
|
||||
clearstatcache();
|
||||
if(filesize($this->restore_log_file)>4*1024*1024)
|
||||
{
|
||||
$this->restore_log->CloseFile();
|
||||
wp_delete_file($this->restore_log_file);
|
||||
$this->restore_log=null;
|
||||
$this->restore_log=new WPvivid_Log();
|
||||
$this->restore_log->OpenLogFile($this->restore_log_file,'has_folder');
|
||||
}
|
||||
$this->restore_log->WriteLog($message,$type);
|
||||
}
|
||||
|
||||
public function get_log_content()
|
||||
{
|
||||
$file =fopen($this->restore_log_file,'r');
|
||||
|
||||
if(!$file)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$buffer='';
|
||||
while(!feof($file))
|
||||
{
|
||||
$buffer .= fread($file,1024);
|
||||
}
|
||||
fclose($file);
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
class WPvivid_Schedule
|
||||
{
|
||||
protected $schedule_type = array(
|
||||
'wpvivid_12hours' => '12Hours',
|
||||
'twicedaily' => '12Hours',
|
||||
'wpvivid_daily' => 'Daily',
|
||||
'daily' => 'Daily',
|
||||
'onceday' => 'Daily',
|
||||
'wpvivid_weekly' => 'Weekly',
|
||||
'weekly' => 'Weekly',
|
||||
'wpvivid_fortnightly' => 'Fortnightly',
|
||||
'fortnightly' => 'Fortnightly',
|
||||
'wpvivid_monthly' => 'Monthly',
|
||||
'monthly' => 'Monthly',
|
||||
'montly' => 'Monthly'
|
||||
);
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
add_action('wpvivid_reset_schedule', array($this, 'wpvivid_reset_schedule'), 10);
|
||||
}
|
||||
|
||||
public function wpvivid_cron_schedules($schedules)
|
||||
{
|
||||
if(!isset($schedules["wpvivid_12hours"])){
|
||||
$schedules["wpvivid_12hours"] = array(
|
||||
'interval' => 3600*12,
|
||||
'display' => __('12 Hours', 'wpvivid-backuprestore'));
|
||||
}
|
||||
|
||||
if(!isset($schedules["wpvivid_daily"])){
|
||||
$schedules["wpvivid_daily"] = array(
|
||||
'interval' => 86400 ,
|
||||
'display' => __('Daily', 'wpvivid-backuprestore'));
|
||||
}
|
||||
|
||||
if(!isset($schedules["wpvivid_weekly"])){
|
||||
$schedules["wpvivid_weekly"] = array(
|
||||
'interval' => 604800 ,
|
||||
'display' => __('Weekly', 'wpvivid-backuprestore'));
|
||||
}
|
||||
|
||||
if(!isset($schedules["wpvivid_fortnightly"])){
|
||||
$schedules["wpvivid_fortnightly"] = array(
|
||||
'interval' => 604800*2 ,
|
||||
'display' => __('Fortnightly', 'wpvivid-backuprestore'));
|
||||
}
|
||||
|
||||
if(!isset($schedules["wpvivid_monthly"])){
|
||||
$schedules["wpvivid_monthly"] = array(
|
||||
'interval' => 2592000 ,
|
||||
'display' => __('Monthly', 'wpvivid-backuprestore'));
|
||||
}
|
||||
|
||||
return $schedules;
|
||||
}
|
||||
|
||||
public function check_schedule_type($display){
|
||||
$schedules = wp_get_schedules();
|
||||
$check_res = false;
|
||||
$ret = array();
|
||||
foreach ($this->schedule_type as $key => $value){
|
||||
if($value == $display){
|
||||
if(isset($schedules[$key])){
|
||||
$check_res = true;
|
||||
$ret['type']=$key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$ret['result']=$check_res;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function output($html)
|
||||
{
|
||||
$html='';
|
||||
|
||||
$display_array = array("12Hours", "Daily", "Weekly", "Fortnightly", "Monthly");
|
||||
foreach($display_array as $display){
|
||||
$schedule_check = $this->check_schedule_type($display);
|
||||
if($schedule_check['result']){
|
||||
$html.=' <label><input type="radio" option="schedule" name="recurrence" value="'.$schedule_check['type'].'" />';
|
||||
if($display === '12Hours'){
|
||||
$html.='<span>'.__('12Hours', 'wpvivid-backuprestore').'</span></label><br>';
|
||||
}
|
||||
if($display === 'Daily'){
|
||||
$html.='<span>'.__('Daily', 'wpvivid-backuprestore').'</span></label><br>';
|
||||
}
|
||||
if($display === 'Weekly'){
|
||||
$html.='<span>'.__('Weekly', 'wpvivid-backuprestore').'</span></label><br>';
|
||||
}
|
||||
if($display === 'Fortnightly'){
|
||||
$html.='<span>'.__('Fortnightly', 'wpvivid-backuprestore').'</span></label><br>';
|
||||
}
|
||||
if($display === 'Monthly'){
|
||||
$html.='<span>'.__('Monthly', 'wpvivid-backuprestore').'</span></label><br>';
|
||||
}
|
||||
}
|
||||
else{
|
||||
$html.='<p>Warning: Unable to set '.$display.' backup schedule</p>';
|
||||
}
|
||||
}
|
||||
$html.='<label>';
|
||||
$html.='<div style="float: left;">';
|
||||
$html.='<input type="radio" disabled />';
|
||||
$html.='<span class="wpvivid-element-space-right" style="color: #ddd;">'.__('Custom', 'wpvivid-backuprestore').'</span>';
|
||||
$html.='</div>';
|
||||
$html.='<div style="float: left; height: 32px; line-height: 32px;">';
|
||||
$html.='<span class="wpvivid-feature-pro">';
|
||||
$html.='<a href="https://docs.wpvivid.com/wpvivid-backup-pro-customize-start-time.html" style="text-decoration: none; margin-top: 10px;">'.__('Pro feature: learn more', 'wpvivid-backuprestore').'</a>';
|
||||
$html.='</span>';
|
||||
$html.='</div>';
|
||||
$html.='</label><br>';
|
||||
return $html;
|
||||
}
|
||||
|
||||
public static function get_start_time($time)
|
||||
{
|
||||
if(!is_array( $time ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isset($time['type']))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$week=$time['start_time']['week'];
|
||||
$day=$time['start_time']['day'];
|
||||
$current_day=$time['start_time']['current_day'];
|
||||
|
||||
if(strtotime('now')>strtotime($current_day)){
|
||||
$daily_start_time = $current_day.' +1 day';
|
||||
}
|
||||
else{
|
||||
$daily_start_time = $current_day;
|
||||
}
|
||||
|
||||
$weekly_tmp = $week.' '.$current_day;
|
||||
if(strtotime('now')>strtotime($weekly_tmp)) {
|
||||
$weekly_start_time = $week.' '.$weekly_tmp.' next week';
|
||||
}
|
||||
else{
|
||||
$weekly_start_time = $weekly_tmp;
|
||||
}
|
||||
|
||||
$date_now = gmdate("Y-m-",time());
|
||||
$monthly_tmp = $date_now.$day.' '.$current_day;
|
||||
if(strtotime('now')>strtotime($monthly_tmp)){
|
||||
$date_now = gmdate("Y-m-",strtotime('+1 month'));
|
||||
$monthly_start_time = $date_now.$day.' '.$current_day;
|
||||
}
|
||||
else{
|
||||
$monthly_start_time = $monthly_tmp;
|
||||
}
|
||||
|
||||
$schedule_type_ex = array(
|
||||
'wpvivid_12hours' => '12Hours',
|
||||
'twicedaily' => '12Hours',
|
||||
'wpvivid_daily' => 'Daily',
|
||||
'daily' => 'Daily',
|
||||
'onceday' => 'Daily',
|
||||
'wpvivid_weekly' => 'Weekly',
|
||||
'weekly' => 'Weekly',
|
||||
'wpvivid_fortnightly' => 'Fortnightly',
|
||||
'fortnightly' => 'Fortnightly',
|
||||
'wpvivid_monthly' => 'Monthly',
|
||||
'monthly' => 'Monthly',
|
||||
'montly' => 'Monthly'
|
||||
);
|
||||
|
||||
$display_array = array(
|
||||
"12Hours" => $daily_start_time,
|
||||
"Daily" => $daily_start_time,
|
||||
"Weekly" => $weekly_start_time,
|
||||
"Fortnightly" => $weekly_start_time,
|
||||
"Monthly" => $monthly_start_time
|
||||
);
|
||||
foreach ($schedule_type_ex as $key => $value){
|
||||
if($key == $time['type']){
|
||||
foreach ($display_array as $display_key => $display_value){
|
||||
if($value == $display_key){
|
||||
$base_ts = strtotime($display_value);
|
||||
$jitter = function_exists('wp_rand') ? wp_rand(0, 15 * 60) : rand(0, 15 * 60);
|
||||
return $base_ts + $jitter;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function get_schedule($schedule_id = '')
|
||||
{
|
||||
add_filter('wpvivid_get_schedule', array('WPvivid_Schedule', 'get_schedule_ex'),10,2);
|
||||
$schedule=array();
|
||||
$schedule=apply_filters('wpvivid_get_schedule',$schedule,$schedule_id);
|
||||
return $schedule;
|
||||
}
|
||||
|
||||
public static function get_schedule_ex($schedule,$schedule_id)
|
||||
{
|
||||
$schedule=WPvivid_Setting::get_option('wpvivid_schedule_setting');
|
||||
|
||||
if(empty($schedule['backup']))
|
||||
{
|
||||
$schedule['backup']['backup_files']='files+db';
|
||||
$schedule['backup']['local']=1;
|
||||
$schedule['backup']['remote']=0;
|
||||
$schedule['backup']['ismerge']=1;
|
||||
$schedule['backup']['lock']=0;
|
||||
}
|
||||
|
||||
$recurrence = wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
|
||||
if(!wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT))
|
||||
{
|
||||
$schedule['enable']=false;
|
||||
return $schedule;
|
||||
}
|
||||
|
||||
$schedule['enable']=true;
|
||||
$schedule['recurrence']=$recurrence;
|
||||
$timestamp=wp_next_scheduled(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
|
||||
$schedule['next_start']=$timestamp;
|
||||
return $schedule;
|
||||
}
|
||||
|
||||
public static function set_schedule($schedule_data,$schedule)
|
||||
{
|
||||
if($schedule['enable']==1)
|
||||
{
|
||||
$schedule_data['enable']=$schedule['enable'];
|
||||
|
||||
$schedule_data['type']=$schedule['recurrence'];
|
||||
$schedule_data['event']=WPVIVID_MAIN_SCHEDULE_EVENT;
|
||||
$time['type']=$schedule['recurrence'];
|
||||
$time['start_time']['week']='mon';
|
||||
$time['start_time']['day']='01';
|
||||
$time['start_time']['current_day']="00:00";
|
||||
$timestamp=WPvivid_Schedule::get_start_time($time);
|
||||
$schedule_data['start_time']=$timestamp;
|
||||
|
||||
$schedule_data['backup']['backup_files']=$schedule['backup_type'];
|
||||
if($schedule['save_local_remote']=='remote')
|
||||
{
|
||||
$schedule_data['backup']['local']=0;
|
||||
$schedule_data['backup']['remote']=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$schedule_data['backup']['local']=1;
|
||||
$schedule_data['backup']['remote']=0;
|
||||
}
|
||||
$schedule_data['backup']['ismerge']=1;
|
||||
$schedule_data['backup']['lock']=$schedule['lock'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$schedule_data['enable']=$schedule['enable'];
|
||||
}
|
||||
|
||||
return $schedule_data;
|
||||
}
|
||||
|
||||
public static function set_schedule_ex($schedule)
|
||||
{
|
||||
add_filter('wpvivid_set_schedule', array('WPvivid_Schedule', 'set_schedule'),10,2);
|
||||
$schedule_data=array();
|
||||
$schedule_data= apply_filters('wpvivid_set_schedule',$schedule_data, $schedule);
|
||||
WPvivid_Setting::update_option('wpvivid_schedule_setting',$schedule_data);
|
||||
if($schedule_data===false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Creating scheduled tasks failed. Please try again later.', 'wpvivid-backuprestore');
|
||||
return $ret;
|
||||
}
|
||||
|
||||
if($schedule_data['enable']==1)
|
||||
{
|
||||
if(wp_get_schedule($schedule_data['event']))
|
||||
{
|
||||
$timestamp = wp_next_scheduled($schedule_data['event']);
|
||||
wp_unschedule_event($timestamp,$schedule_data['event']);
|
||||
}
|
||||
if(wp_schedule_event($schedule_data['start_time'], $schedule_data['type'], $schedule_data['event'])===false)
|
||||
{
|
||||
$ret['result']='failed';
|
||||
$ret['error']=__('Creating scheduled tasks failed. Please try again later.', 'wpvivid-backuprestore');
|
||||
$ret['data']=$schedule_data;
|
||||
return $ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret['result']='success';
|
||||
$ret['data']=$schedule_data;
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT))
|
||||
{
|
||||
wp_clear_scheduled_hook(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
$timestamp = wp_next_scheduled(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
wp_unschedule_event($timestamp,WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
}
|
||||
$ret['result']='success';
|
||||
$ret['data']=$schedule_data;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function wpvivid_reset_schedule()
|
||||
{
|
||||
self::reset_schedule();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function reset_schedule()
|
||||
{
|
||||
$schedule=WPvivid_Setting::get_option('wpvivid_schedule_setting');
|
||||
if(!empty($schedule))
|
||||
{
|
||||
if($schedule['enable'])
|
||||
{
|
||||
self::set_schedule_ex($schedule);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::disable_schedule();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self::disable_schedule();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function disable_schedule()
|
||||
{
|
||||
$schedule=WPvivid_Setting::get_option('wpvivid_schedule_setting');
|
||||
$schedule['enable']=false;
|
||||
WPvivid_Setting::update_option('wpvivid_schedule_setting',$schedule);
|
||||
if(wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT))
|
||||
{
|
||||
wp_clear_scheduled_hook(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
$timestamp = wp_next_scheduled(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
wp_unschedule_event($timestamp,WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
}
|
||||
}
|
||||
|
||||
public static function clear_monitor_schedule($id)
|
||||
{
|
||||
$timestamp =wp_next_scheduled(WPVIVID_TASK_MONITOR_EVENT,array($id));
|
||||
if($timestamp!==false)
|
||||
{
|
||||
wp_unschedule_event($timestamp,WPVIVID_TASK_MONITOR_EVENT,array($id));
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_next_resume_time($id)
|
||||
{
|
||||
$timestamp=wp_next_scheduled(WPVIVID_RESUME_SCHEDULE_EVENT,array($id));
|
||||
if($timestamp!==false)
|
||||
{
|
||||
return $timestamp-time();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
class WPvivid_Setting
|
||||
{
|
||||
public static function init_option()
|
||||
{
|
||||
$ret=self::get_option('wpvivid_email_setting');
|
||||
if(empty($ret))
|
||||
{
|
||||
self::set_default_email_option();
|
||||
}
|
||||
|
||||
$ret=self::get_option('wpvivid_compress_setting');
|
||||
if(empty($ret))
|
||||
{
|
||||
self::set_default_compress_option();
|
||||
}
|
||||
|
||||
$ret=self::get_option('wpvivid_local_setting');
|
||||
if(empty($ret))
|
||||
{
|
||||
self::set_default_local_option();
|
||||
}
|
||||
|
||||
$ret=self::get_option('wpvivid_upload_setting');
|
||||
if(empty($ret))
|
||||
{
|
||||
self::set_default_upload_option();
|
||||
}
|
||||
|
||||
$ret=self::get_option('wpvivid_common_setting');
|
||||
if(empty($ret))
|
||||
{
|
||||
self::set_default_common_option();
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_default_option($option_name)
|
||||
{
|
||||
$options=array();
|
||||
|
||||
switch ($option_name)
|
||||
{
|
||||
case 'wpvivid_compress_setting':
|
||||
$options=self::set_default_compress_option();
|
||||
break;
|
||||
case 'wpvivid_local_setting':
|
||||
$options=self::set_default_local_option();
|
||||
break;
|
||||
case 'wpvivid_upload_setting':
|
||||
$options=self::set_default_upload_option();
|
||||
break;
|
||||
case 'wpvivid_common_setting':
|
||||
$options=self::set_default_common_option();
|
||||
break;
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
public static function set_default_option()
|
||||
{
|
||||
self::set_default_compress_option();
|
||||
self::set_default_local_option();
|
||||
self::set_default_upload_option();
|
||||
self::set_default_common_option();
|
||||
}
|
||||
|
||||
public static function set_default_compress_option()
|
||||
{
|
||||
$compress_option['compress_type']=WPVIVID_DEFAULT_COMPRESS_TYPE;
|
||||
$compress_option['max_file_size']=WPVIVID_DEFAULT_MAX_FILE_SIZE;
|
||||
$compress_option['no_compress']=WPVIVID_DEFAULT_NO_COMPRESS;
|
||||
$compress_option['use_temp_file']=WPVIVID_DEFAULT_USE_TEMP;
|
||||
$compress_option['use_temp_size']=WPVIVID_DEFAULT_USE_TEMP_SIZE;
|
||||
$compress_option['exclude_file_size']=WPVIVID_DEFAULT_EXCLUDE_FILE_SIZE;
|
||||
$compress_option['subpackage_plugin_upload']=WPVIVID_DEFAULT_SUBPACKAGE_PLUGIN_UPLOAD;
|
||||
self::update_option('wpvivid_compress_setting',$compress_option);
|
||||
return $compress_option;
|
||||
}
|
||||
|
||||
public static function set_default_local_option()
|
||||
{
|
||||
$local_option['path']=WPVIVID_DEFAULT_BACKUP_DIR;
|
||||
$local_option['save_local']=1;
|
||||
self::update_option('wpvivid_local_setting',$local_option);
|
||||
return $local_option;
|
||||
}
|
||||
|
||||
public static function set_default_upload_option()
|
||||
{
|
||||
$upload_option=array();
|
||||
self::update_option('wpvivid_upload_setting',$upload_option);
|
||||
return $upload_option;
|
||||
}
|
||||
|
||||
public static function set_default_email_option()
|
||||
{
|
||||
$email_option['send_to']=array();
|
||||
$email_option['always']=true;
|
||||
$email_option['email_enable']=false;
|
||||
self::update_option('wpvivid_email_setting',$email_option);
|
||||
return $email_option;
|
||||
}
|
||||
|
||||
public static function set_default_common_option()
|
||||
{
|
||||
$sapi_type=php_sapi_name();
|
||||
|
||||
if($sapi_type=='cgi-fcgi'||$sapi_type==' fpm-fcgi')
|
||||
{
|
||||
$common_option['max_execution_time']=WPVIVID_MAX_EXECUTION_TIME_FCGI;
|
||||
}
|
||||
else
|
||||
{
|
||||
$common_option['max_execution_time']=WPVIVID_MAX_EXECUTION_TIME;
|
||||
}
|
||||
|
||||
$common_option['log_save_location']=WPVIVID_DEFAULT_LOG_DIR;
|
||||
$common_option['max_backup_count']=WPVIVID_DEFAULT_BACKUP_COUNT;
|
||||
$common_option['show_admin_bar']=WPVIVID_DEFAULT_ADMIN_BAR;
|
||||
//$common_option['show_tab_menu']=WPVIVID_DEFAULT_TAB_MENU;
|
||||
$common_option['domain_include']=WPVIVID_DEFAULT_DOMAIN_INCLUDE;
|
||||
$common_option['estimate_backup']=WPVIVID_DEFAULT_ESTIMATE_BACKUP;
|
||||
$common_option['max_resume_count']=WPVIVID_RESUME_RETRY_TIMES;
|
||||
$common_option['memory_limit']=WPVIVID_MEMORY_LIMIT;
|
||||
$common_option['restore_memory_limit']=WPVIVID_RESTORE_MEMORY_LIMIT;
|
||||
$common_option['migrate_size']=WPVIVID_MIGRATE_SIZE;
|
||||
self::update_option('wpvivid_common_setting',$common_option);
|
||||
return $common_option;
|
||||
}
|
||||
|
||||
public static function get_option($option_name, $default = array())
|
||||
{
|
||||
$ret = get_option($option_name, $default);
|
||||
if(empty($ret))
|
||||
{
|
||||
self::get_default_option($option_name);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function get_last_backup_message($option_name, $default = array()){
|
||||
$message = self::get_option($option_name, $default);
|
||||
$ret = array();
|
||||
if(!empty($message['id'])) {
|
||||
$ret['id'] = $message['id'];
|
||||
$ret['status'] = $message['status'];
|
||||
$ret['status']['start_time'] = gmdate("M d, Y H:i", $ret['status']['start_time']);
|
||||
$ret['status']['run_time'] = gmdate("M d, Y H:i", $ret['status']['run_time']);
|
||||
$ret['status']['timeout'] = gmdate("M d, Y H:i", $ret['status']['timeout']);
|
||||
if(isset($message['options']['log_file_name']))
|
||||
$ret['log_file_name'] = $message['options']['log_file_name'];
|
||||
else
|
||||
$ret['log_file_name'] ='';
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function get_backupdir()
|
||||
{
|
||||
$dir=self::get_option('wpvivid_local_setting');
|
||||
|
||||
if(!isset($dir['path']))
|
||||
{
|
||||
$dir=self::set_default_local_option();
|
||||
}
|
||||
if(!is_dir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir['path']))
|
||||
{
|
||||
@mkdir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir['path'],0777,true);
|
||||
//@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir['path'].DIRECTORY_SEPARATOR.'index.html', 'x');
|
||||
$tempfile=@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$dir['path'].DIRECTORY_SEPARATOR.'.htaccess', 'x');
|
||||
if($tempfile)
|
||||
{
|
||||
//$text="deny from all";
|
||||
$text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";
|
||||
fwrite($tempfile,$text );
|
||||
fclose($tempfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $dir['path'];
|
||||
}
|
||||
|
||||
public static function wpvivid_remove_directory($directory)
|
||||
{
|
||||
if(file_exists($directory))
|
||||
{
|
||||
if($dir_handle=@opendir($directory))
|
||||
{
|
||||
while($filename=readdir($dir_handle))
|
||||
{
|
||||
if($filename!='.' && $filename!='..')
|
||||
{
|
||||
$subFile=$directory."/".$filename;
|
||||
if(is_dir($subFile))
|
||||
{
|
||||
self::wpvivid_remove_directory($subFile);
|
||||
}
|
||||
if(is_file($subFile))
|
||||
{
|
||||
wp_delete_file($subFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dir_handle);
|
||||
rmdir($directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function wpvivid_write_htaccess_rule($wpvivid_backup_dir_htaccess)
|
||||
{
|
||||
$tempfile=@fopen($wpvivid_backup_dir_htaccess, 'x');
|
||||
if($tempfile)
|
||||
{
|
||||
$text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";
|
||||
fwrite($tempfile,$text );
|
||||
fclose($tempfile);
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_save_local()
|
||||
{
|
||||
$local=self::get_option('wpvivid_local_setting');
|
||||
|
||||
if(!isset($local['save_local']))
|
||||
{
|
||||
$local=self::set_default_local_option();
|
||||
}
|
||||
|
||||
return $local['save_local'];
|
||||
}
|
||||
|
||||
public static function update_option($option_name,$options)
|
||||
{
|
||||
update_option($option_name,$options,'no');
|
||||
}
|
||||
|
||||
public static function delete_option($option_name)
|
||||
{
|
||||
delete_option($option_name);
|
||||
}
|
||||
|
||||
public static function get_tasks()
|
||||
{
|
||||
$default = array();
|
||||
return $options = get_option('wpvivid_task_list', $default);
|
||||
}
|
||||
|
||||
public static function update_task($id,$task)
|
||||
{
|
||||
$default = array();
|
||||
$options = get_option('wpvivid_task_list', $default);
|
||||
$options[$id]=$task;
|
||||
self::update_option('wpvivid_task_list',$options);
|
||||
}
|
||||
|
||||
public static function delete_task($id)
|
||||
{
|
||||
$default = array();
|
||||
$options = get_option('wpvivid_task_list', $default);
|
||||
unset($options[$id]);
|
||||
self::update_option('wpvivid_task_list',$options);
|
||||
}
|
||||
|
||||
public static function check_compress_options()
|
||||
{
|
||||
$options =self::get_option('wpvivid_compress_setting');
|
||||
|
||||
if(!isset($options['compress_type'])||!isset($options['max_file_size'])||
|
||||
!isset($options['no_compress'])||!isset($options['exclude_file_size'])||
|
||||
!isset($options['use_temp_file'])||!isset($options['use_temp_size']))
|
||||
{
|
||||
self::set_default_compress_option();
|
||||
}
|
||||
}
|
||||
|
||||
public static function check_local_options()
|
||||
{
|
||||
$options =self::get_option('wpvivid_local_setting');
|
||||
|
||||
if(!isset($options['path'])||!isset($options['save_local']))
|
||||
{
|
||||
self::set_default_local_option();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*public static function get_backup_options($post)
|
||||
{
|
||||
self::check_compress_options();
|
||||
self::check_local_options();
|
||||
|
||||
if($post=='files+db')
|
||||
{
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_DB]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_THEMES]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_PLUGIN]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_UPLOADS]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_CONTENT]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_CORE]=0;
|
||||
}
|
||||
else if($post=='files')
|
||||
{
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_THEMES]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_PLUGIN]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_UPLOADS]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_CONTENT]=0;
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_CORE]=0;
|
||||
}
|
||||
else if($post=='db')
|
||||
{
|
||||
$backup_options['backup']['backup_type'][WPVIVID_BACKUP_TYPE_DB]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//return false;
|
||||
}
|
||||
|
||||
$backup_options['compress']=self::get_option('wpvivid_compress_setting');
|
||||
$backup_options['dir']=self::get_backupdir();
|
||||
return $backup_options;
|
||||
}*/
|
||||
|
||||
public static function get_remote_option($id)
|
||||
{
|
||||
$upload_options=self::get_option('wpvivid_upload_setting');
|
||||
if(array_key_exists($id,$upload_options))
|
||||
{
|
||||
return $upload_options[$id];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_remote_options($remote_ids=array())
|
||||
{
|
||||
if(empty($remote_ids))
|
||||
{
|
||||
$remote_ids=WPvivid_Setting::get_user_history('remote_selected');
|
||||
}
|
||||
|
||||
if(empty($remote_ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$options=array();
|
||||
$upload_options=WPvivid_Setting::get_option('wpvivid_upload_setting');
|
||||
foreach ($remote_ids as $id)
|
||||
{
|
||||
if(array_key_exists($id,$upload_options))
|
||||
{
|
||||
$options[$id]=$upload_options[$id];
|
||||
}
|
||||
}
|
||||
if(empty($options))
|
||||
return false;
|
||||
else
|
||||
return $options;
|
||||
}
|
||||
|
||||
public static function get_all_remote_options()
|
||||
{
|
||||
$upload_options=self::get_option('wpvivid_upload_setting');
|
||||
$upload_options['remote_selected']=WPvivid_Setting::get_user_history('remote_selected');
|
||||
return $upload_options;
|
||||
}
|
||||
|
||||
public static function add_remote_options($remote)
|
||||
{
|
||||
$upload_options=self::get_option('wpvivid_upload_setting');
|
||||
$id=uniqid('wpvivid-remote-');
|
||||
|
||||
$remote=apply_filters('wpvivid_pre_add_remote',$remote,$id);
|
||||
|
||||
$upload_options[$id]=$remote;
|
||||
self::update_option('wpvivid_upload_setting',$upload_options);
|
||||
return $id;
|
||||
}
|
||||
|
||||
public static function delete_remote_option($id)
|
||||
{
|
||||
do_action('wpvivid_delete_remote_token',$id);
|
||||
|
||||
$upload_options=self::get_option('wpvivid_upload_setting');
|
||||
|
||||
if(array_key_exists($id,$upload_options))
|
||||
{
|
||||
unset( $upload_options[$id]);
|
||||
|
||||
self::update_option('wpvivid_upload_setting',$upload_options);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function update_remote_option($remote_id,$remote)
|
||||
{
|
||||
$upload_options=self::get_option('wpvivid_upload_setting');
|
||||
|
||||
if(array_key_exists($remote_id,$upload_options))
|
||||
{
|
||||
$remote=apply_filters('wpvivid_pre_add_remote',$remote,$remote_id);
|
||||
$upload_options[$remote_id]=$remote;
|
||||
self::update_option('wpvivid_upload_setting',$upload_options);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_setting($all,$options_name)
|
||||
{
|
||||
$get_options=array();
|
||||
if($all==true)
|
||||
{
|
||||
$get_options[]='wpvivid_email_setting';
|
||||
$get_options[]='wpvivid_compress_setting';
|
||||
$get_options[]='wpvivid_local_setting';
|
||||
$get_options[]='wpvivid_common_setting';
|
||||
$get_options = apply_filters('wpvivid_get_setting_addon', $get_options);
|
||||
}
|
||||
else
|
||||
{
|
||||
$get_options[]=$options_name;
|
||||
}
|
||||
|
||||
$ret['result']='success';
|
||||
$ret['options']=array();
|
||||
|
||||
foreach ($get_options as $option_name)
|
||||
{
|
||||
$ret['options'][$option_name]=self::get_option($option_name);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function update_setting($options)
|
||||
{
|
||||
foreach ($options as $option_name=>$option)
|
||||
{
|
||||
self::update_option($option_name,$option);
|
||||
}
|
||||
$ret['result']='success';
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function export_setting_to_json($setting=true,$history=true,$review=true,$backup_list=true)
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$json['plugin']=$wpvivid_plugin->get_plugin_name();
|
||||
$json['version']=WPVIVID_PLUGIN_VERSION;
|
||||
$json['setting']=$setting;
|
||||
$json['history']=$history;
|
||||
$json['data']['wpvivid_init']=self::get_option('wpvivid_init');
|
||||
|
||||
if($setting)
|
||||
{
|
||||
$json['data']['wpvivid_schedule_setting']=self::get_option('wpvivid_schedule_setting');
|
||||
if(!empty( $json['data']['wpvivid_schedule_setting']))
|
||||
{
|
||||
if(isset($json['data']['wpvivid_schedule_setting']['backup']['backup_files']))
|
||||
$json['data']['wpvivid_schedule_setting']['backup_type']=$json['data']['wpvivid_schedule_setting']['backup']['backup_files'];
|
||||
if(isset($json['data']['wpvivid_schedule_setting']['backup']['local']))
|
||||
{
|
||||
if($json['data']['wpvivid_schedule_setting']['backup']['local'] == 1){
|
||||
$json['data']['wpvivid_schedule_setting']['save_local_remote']='local';
|
||||
}
|
||||
else{
|
||||
$json['data']['wpvivid_schedule_setting']['save_local_remote']='remote';
|
||||
}
|
||||
}
|
||||
|
||||
$json['data']['wpvivid_schedule_setting']['lock']=0;
|
||||
if(wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT))
|
||||
{
|
||||
$recurrence = wp_get_schedule(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
$timestamp = wp_next_scheduled(WPVIVID_MAIN_SCHEDULE_EVENT);
|
||||
$json['data']['wpvivid_schedule_setting']['recurrence']=$recurrence;
|
||||
$json['data']['wpvivid_schedule_setting']['next_start']=$timestamp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$json['data']['wpvivid_schedule_setting']=array();
|
||||
}
|
||||
$json['data']['wpvivid_compress_setting']=self::get_option('wpvivid_compress_setting');
|
||||
$json['data']['wpvivid_local_setting']=self::get_option('wpvivid_local_setting');
|
||||
$json['data']['wpvivid_upload_setting']=self::get_option('wpvivid_upload_setting');
|
||||
$json['data']['wpvivid_common_setting']=self::get_option('wpvivid_common_setting');
|
||||
$json['data']['wpvivid_email_setting']=self::get_option('wpvivid_email_setting');
|
||||
$json['data']['wpvivid_saved_api_token']=self::get_option('wpvivid_saved_api_token');
|
||||
$json = apply_filters('wpvivid_export_setting_addon', $json);
|
||||
/*if(isset($json['data']['wpvivid_local_setting']['path'])){
|
||||
unset($json['data']['wpvivid_local_setting']['path']);
|
||||
}*/
|
||||
if(isset($json['data']['wpvivid_common_setting']['log_save_location'])){
|
||||
unset($json['data']['wpvivid_common_setting']['log_save_location']);
|
||||
}
|
||||
if(isset($json['data']['wpvivid_common_setting']['backup_prefix'])){
|
||||
unset($json['data']['wpvivid_common_setting']['backup_prefix']);
|
||||
}
|
||||
}
|
||||
|
||||
if($history)
|
||||
{
|
||||
$json['data']['wpvivid_task_list']=self::get_option('wpvivid_task_list');
|
||||
$json['data']['wpvivid_last_msg']=self::get_option('wpvivid_last_msg');
|
||||
$json['data']['wpvivid_user_history']=self::get_option('wpvivid_user_history');
|
||||
$json = apply_filters('wpvivid_history_addon', $json);
|
||||
}
|
||||
|
||||
if($backup_list){
|
||||
$json['data']['wpvivid_backup_list']=self::get_option('wpvivid_backup_list');
|
||||
$json = apply_filters('wpvivid_backup_list_addon', $json);
|
||||
}
|
||||
else{
|
||||
if(isset($json['data']['wpvivid_new_remote_list']))
|
||||
{
|
||||
unset($json['data']['wpvivid_new_remote_list']);
|
||||
}
|
||||
}
|
||||
|
||||
if($review)
|
||||
{
|
||||
$json['data']['wpvivid_need_review']=self::get_option('wpvivid_need_review');
|
||||
$json['data']['cron_backup_count']=self::get_option('cron_backup_count');
|
||||
$json['data']['wpvivid_review_msg']=self::get_option('wpvivid_review_msg');
|
||||
$json['data']['wpvivid_review_time']=self::get_option('wpvivid_review_time', false);
|
||||
$json['data']['wpvivid_review_type']=self::get_option('wpvivid_review_type', false);
|
||||
$json = apply_filters('wpvivid_review_addon', $json);
|
||||
}
|
||||
return $json;
|
||||
}
|
||||
|
||||
public static function import_json_to_setting($json)
|
||||
{
|
||||
wp_cache_delete('notoptions', 'options');
|
||||
wp_cache_delete('alloptions', 'options');
|
||||
foreach ($json['data'] as $option_name=>$option)
|
||||
{
|
||||
wp_cache_delete($option_name, 'options');
|
||||
delete_option($option_name);
|
||||
self::update_option($option_name,$option);
|
||||
}
|
||||
}
|
||||
|
||||
public static function set_max_backup_count($count)
|
||||
{
|
||||
$options=self::get_option('wpvivid_common_setting');
|
||||
$options['max_backup_count']=$count;
|
||||
self::update_option('wpvivid_common_setting',$options);
|
||||
}
|
||||
|
||||
public static function get_max_backup_count()
|
||||
{
|
||||
$options=self::get_option('wpvivid_common_setting');
|
||||
if(isset($options['max_backup_count']))
|
||||
{
|
||||
return $options['max_backup_count'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return WPVIVID_MAX_BACKUP_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_mail_setting()
|
||||
{
|
||||
return self::get_option('wpvivid_email_setting');
|
||||
}
|
||||
|
||||
public static function get_admin_bar_setting(){
|
||||
$options=self::get_option('wpvivid_common_setting');
|
||||
if(isset($options['show_admin_bar']))
|
||||
{
|
||||
if($options['show_admin_bar']){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static function update_user_history($action,$value)
|
||||
{
|
||||
$options=self::get_option('wpvivid_user_history');
|
||||
$options[$action]=$value;
|
||||
self::update_option('wpvivid_user_history',$options);
|
||||
}
|
||||
|
||||
public static function get_user_history($action)
|
||||
{
|
||||
$options=self::get_option('wpvivid_user_history');
|
||||
if(array_key_exists($action,$options))
|
||||
{
|
||||
return $options[$action];
|
||||
}
|
||||
else
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_retain_local_status()
|
||||
{
|
||||
$options=self::get_option('wpvivid_common_setting');
|
||||
if(isset($options['retain_local']))
|
||||
{
|
||||
if($options['retain_local']){
|
||||
return true;
|
||||
}
|
||||
else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_sync_data()
|
||||
{
|
||||
$data['setting']['wpvivid_compress_setting']=self::get_option('wpvivid_compress_setting');
|
||||
$data['setting']['wpvivid_local_setting']=self::get_option('wpvivid_local_setting');
|
||||
$data['setting']['wpvivid_common_setting']=self::get_option('wpvivid_common_setting');
|
||||
$data['setting']['wpvivid_email_setting']=self::get_option('wpvivid_email_setting');
|
||||
$data['setting']['cron_backup_count']=self::get_option('cron_backup_count');
|
||||
$data['schedule']=self::get_option('wpvivid_schedule_setting');
|
||||
$data['remote']['upload']=self::get_option('wpvivid_upload_setting');
|
||||
$data['remote']['history']=self::get_option('wpvivid_user_history');
|
||||
$data['last_backup_report'] = get_option('wpvivid_backup_reports');
|
||||
|
||||
$data['setting_addon'] = $data['setting'];
|
||||
$data['setting_addon']['wpvivid_staging_options']=array();
|
||||
$data['backup_custom_setting']=array();
|
||||
$data['menu_capability']=array();
|
||||
$data['white_label_setting']=array();
|
||||
$data['incremental_backup_setting']=array();
|
||||
$data['schedule_addon']=array();
|
||||
$data['time_zone']=false;
|
||||
$data['is_pro']=false;
|
||||
$data['is_install']=false;
|
||||
$data['is_login']=false;
|
||||
$data['latest_version']='';
|
||||
$data['current_version']='';
|
||||
$data['dashboard_version'] = '';
|
||||
$data['addons_info'] = array();
|
||||
$data=apply_filters('wpvivid_get_wpvivid_info_addon_mainwp_ex', $data);
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
if (!defined('WPVIVID_PLUGIN_DIR'))
|
||||
{
|
||||
die;
|
||||
}
|
||||
class WPvivid_Tab_Page_Container
|
||||
{
|
||||
public $tabs;
|
||||
public $container_id;
|
||||
public $is_parent_tab=1;
|
||||
|
||||
public function __construct( $args = array() )
|
||||
{
|
||||
$this->tabs=array();
|
||||
$this->container_id=uniqid('tab-');
|
||||
}
|
||||
|
||||
public function add_tab($title,$slug,$callback,$args=array())
|
||||
{
|
||||
$new_tab['title']=$title;
|
||||
$new_tab['slug']=$slug;
|
||||
$new_tab['page']=$callback;
|
||||
foreach ($args as $key=>$arg)
|
||||
{
|
||||
$new_tab[$key]=$arg;
|
||||
if($key === 'is_parent_tab') {
|
||||
$this->is_parent_tab = $arg;
|
||||
}
|
||||
}
|
||||
|
||||
$this->tabs[]=$new_tab;
|
||||
}
|
||||
|
||||
public function set_tab($tabs)
|
||||
{
|
||||
foreach ($tabs as $tab)
|
||||
{
|
||||
$new_tab['title']=$tab['title'];
|
||||
$new_tab['slug']=$tab['slug'];
|
||||
$new_tab['page']=$tab['page'];
|
||||
$this->tabs[]=$new_tab;
|
||||
}
|
||||
}
|
||||
|
||||
public function display()
|
||||
{
|
||||
$class = '';
|
||||
?>
|
||||
<div id="<?php echo esc_attr($this->container_id)?>">
|
||||
<h2 class="nav-tab-wrapper <?php echo esc_attr($class); ?>" style="padding-bottom:0!important;">
|
||||
<?php
|
||||
$this->display_tabs();
|
||||
?>
|
||||
</h2>
|
||||
<?php
|
||||
if($this->is_parent_tab){
|
||||
?>
|
||||
<div style="margin: 10px 0 0 2px;">
|
||||
<div id="poststuff" style="padding-top: 0;">
|
||||
<div id="post-body" class="metabox-holder columns-2">
|
||||
<div id="post-body-content">
|
||||
<div class="inside" style="margin-top:0;">
|
||||
<div>
|
||||
<?php
|
||||
$this->display_page();
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="postbox-container-1" class="postbox-container">
|
||||
<div class="meta-box-sortables">
|
||||
<?php
|
||||
if(has_filter('wpvivid_add_side_bar')){
|
||||
$side_bar = '1';
|
||||
}
|
||||
else{
|
||||
$side_bar = '0';
|
||||
}
|
||||
//$side_bar = '';
|
||||
if(get_current_screen()->id=='wpvivid-backup_page_wpvivid-staging')
|
||||
{
|
||||
do_action('wpvivid_add_staging_side_bar_ex' ,$side_bar, false);
|
||||
}
|
||||
else if(get_current_screen()->id=='wpvivid-backup_page_wpvivid-snapshot-ex')
|
||||
{
|
||||
do_action('wpvivid_snapshot_add_sidebar_free');
|
||||
}
|
||||
else
|
||||
{
|
||||
do_action('wpvivid_add_side_bar' ,$side_bar, false);
|
||||
}
|
||||
//$side_bar = apply_filters('wpvivid_add_side_bar', $side_bar, false);
|
||||
//echo $side_bar;
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br class="clear">
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
else{
|
||||
?>
|
||||
<div>
|
||||
<?php
|
||||
$this->display_page();
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<script>
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').on("click",".<?php echo esc_attr($this->container_id)?>-tab",function()
|
||||
{
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').find( '.<?php echo esc_attr($this->container_id)?>-tab' ).each(function()
|
||||
{
|
||||
jQuery(this).removeClass( "nav-tab-active" );
|
||||
});
|
||||
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').find( '.<?php echo esc_attr($this->container_id)?>-content' ).each(function()
|
||||
{
|
||||
jQuery(this).hide();
|
||||
});
|
||||
|
||||
var id=jQuery(this).attr('id');
|
||||
id= id.substr(12);
|
||||
|
||||
jQuery("#wpvivid_page_"+id).show();
|
||||
jQuery(this).addClass( "nav-tab-active" );
|
||||
});
|
||||
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').on("click",".nav-tab-delete-img",function(event)
|
||||
{
|
||||
event.stopPropagation();
|
||||
var redirect=jQuery(this).attr('redirect');
|
||||
jQuery(this).parent().hide();
|
||||
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').find( '.<?php echo esc_attr($this->container_id)?>-tab' ).each(function()
|
||||
{
|
||||
jQuery(this).removeClass( "nav-tab-active" );
|
||||
});
|
||||
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').find( '.<?php echo esc_attr($this->container_id)?>-content' ).each(function()
|
||||
{
|
||||
jQuery(this).hide();
|
||||
});
|
||||
|
||||
jQuery("#wpvivid_page_"+redirect).show();
|
||||
jQuery("#wpvivid_tab_"+redirect).addClass( "nav-tab-active" );
|
||||
//jQuery(this).addClass( "nav-tab-active" );
|
||||
});
|
||||
|
||||
jQuery(document).ready(function($)
|
||||
{
|
||||
jQuery(document).on('<?php echo esc_attr($this->container_id)?>-show', function(event,id,redirect)
|
||||
{
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').find( '.<?php echo esc_attr($this->container_id)?>-tab' ).each(function()
|
||||
{
|
||||
jQuery(this).removeClass( "nav-tab-active" );
|
||||
});
|
||||
|
||||
jQuery('#<?php echo esc_attr($this->container_id)?>').find( '.<?php echo esc_attr($this->container_id)?>-content' ).each(function()
|
||||
{
|
||||
jQuery(this).hide();
|
||||
});
|
||||
|
||||
jQuery("#wpvivid_page_"+id).show();
|
||||
jQuery("#wpvivid_tab_"+id).show();
|
||||
jQuery("#wpvivid_tab_"+id).find( '.nav-tab-delete-img' ).each(function()
|
||||
{
|
||||
jQuery(this).attr('redirect',redirect);
|
||||
});
|
||||
jQuery("#wpvivid_tab_"+id).addClass( "nav-tab-active" );
|
||||
var top = jQuery("#wpvivid_tab_"+id).offset().top-jQuery("#wpvivid_tab_"+id).height();
|
||||
jQuery('html, body').animate({scrollTop:top}, 'slow');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function display_tabs()
|
||||
{
|
||||
$first=true;
|
||||
|
||||
foreach ($this->tabs as $tab)
|
||||
{
|
||||
$class='nav-tab '.$this->container_id.'-tab';
|
||||
if($first)
|
||||
{
|
||||
$class.=' nav-tab-active';
|
||||
$first=false;
|
||||
}
|
||||
|
||||
$style='cursor:pointer;';
|
||||
|
||||
if(isset($tab['hide']))
|
||||
{
|
||||
$style.=' display: none';
|
||||
}
|
||||
|
||||
if(isset($tab['can_delete']))
|
||||
{
|
||||
$class.=' delete';
|
||||
}
|
||||
if(isset($tab['transparency']))
|
||||
{
|
||||
$class.=' wpvivid-transparency-tab';
|
||||
}
|
||||
|
||||
echo '<a id="wpvivid_tab_'.esc_attr($tab['slug']).'" class="'.esc_attr($class).'" style="'.esc_attr($style).'">';
|
||||
|
||||
if(isset($tab['can_delete']))
|
||||
{
|
||||
echo '<div style="margin-right: 15px;">'.esc_html($tab['title']).'</div>';
|
||||
if(isset($tab['redirect']))
|
||||
{
|
||||
echo '<div class="nav-tab-delete-img" redirect="'.esc_url($tab['redirect']).'">
|
||||
<img src="'.esc_url( WPVIVID_PLUGIN_URL.'/admin/partials/images/delete-tab.png' ).'" style="vertical-align:middle; cursor:pointer;">
|
||||
</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo '<div class="nav-tab-delete-img">
|
||||
<img src="'.esc_url( WPVIVID_PLUGIN_URL.'/admin/partials/images/delete-tab.png' ).'" style="vertical-align:middle; cursor:pointer;">
|
||||
</div>';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
echo esc_html($tab['title']);
|
||||
}
|
||||
echo '</a>';
|
||||
}
|
||||
}
|
||||
|
||||
public function display_page()
|
||||
{
|
||||
$first=true;
|
||||
foreach ($this->tabs as $tab)
|
||||
{
|
||||
//delete
|
||||
$style='display: none;';
|
||||
if($first)
|
||||
{
|
||||
if(isset($tab['hide']))
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$style='';
|
||||
$first=false;
|
||||
}
|
||||
}
|
||||
|
||||
$class=$this->container_id.'-content';
|
||||
|
||||
echo '<div id="wpvivid_page_'.esc_attr($tab['slug']).'" class="'.esc_attr($class).'" style="'.esc_attr($style).'">';
|
||||
call_user_func($tab['page']);
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,747 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
class WPvivid_taskmanager
|
||||
{
|
||||
public static function new_backup_task($option,$type,$action='backup')
|
||||
{
|
||||
$id=uniqid('wpvivid-');
|
||||
$task['id']=$id;
|
||||
$task['action']=$action;
|
||||
$task['type']=$type;
|
||||
|
||||
$task['status']['start_time']=time();
|
||||
$task['status']['run_time']=time();
|
||||
$task['status']['timeout']=time();
|
||||
$task['status']['str']='ready';
|
||||
$task['status']['resume_count']=0;
|
||||
|
||||
$task['options']=$option;
|
||||
$task['options']['file_prefix']=$task['id'].'_'.gmdate('Y-m-d-H-i',$task['status']['start_time']);
|
||||
$task['options']['log_file_name']=$id.'_backup';
|
||||
$log=new WPvivid_Log();
|
||||
$log->CreateLogFile($task['options']['log_file_name'],'no_folder','backup');
|
||||
$log->CloseFile();
|
||||
|
||||
$task['data']['doing']='backup';
|
||||
$task['data']['backup']['doing']='';
|
||||
$task['data']['backup']['finished']=0;
|
||||
$task['data']['backup']['progress']=0;
|
||||
$task['data']['backup']['job_data']=array();
|
||||
$task['data']['backup']['sub_job']=array();
|
||||
$task['data']['backup']['db_size']='0';
|
||||
$task['data']['backup']['files_size']['sum']='0';
|
||||
$task['data']['upload']['doing']='';
|
||||
$task['data']['upload']['finished']=0;
|
||||
$task['data']['upload']['progress']=0;
|
||||
$task['data']['upload']['job_data']=array();
|
||||
$task['data']['upload']['sub_job']=array();
|
||||
WPvivid_Setting::update_task($id,$task);
|
||||
$ret['result']='success';
|
||||
$ret['task_id']=$task['id'];
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function get_backup_task_prefix($task_id)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
return $task['options']['file_prefix'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function new_upload_task($option,$type)
|
||||
{
|
||||
$id=uniqid('wpvivid-');
|
||||
$task['id']=$id;
|
||||
$task['action']='upload';
|
||||
$task['type']='Manual';
|
||||
$task['type']=$type;
|
||||
|
||||
$task['status']['start_time']=time();
|
||||
$task['status']['run_time']=time();
|
||||
$task['status']['timeout']=time();
|
||||
$task['status']['str']='ready';
|
||||
$task['status']['resume_count']=0;
|
||||
|
||||
$task['options']=$option;
|
||||
$task['options']['file_prefix']=$task['id'].'_'.gmdate('Y-m-d-H-i',$task['status']['start_time']);
|
||||
$task['options']['log_file_name']=$id.'_backup';
|
||||
$log=new WPvivid_Log();
|
||||
$log->CreateLogFile($task['options']['log_file_name'],'no_folder','backup');
|
||||
$log->CloseFile();
|
||||
|
||||
$task['data']['doing']='upload';
|
||||
$task['data']['doing']='backup';
|
||||
$task['data']['backup']['doing']='';
|
||||
$task['data']['backup']['finished']=1;
|
||||
$task['data']['backup']['progress']=100;
|
||||
$task['data']['backup']['job_data']=array();
|
||||
$task['data']['backup']['sub_job']=array();
|
||||
$task['data']['backup']['db_size']='0';
|
||||
$task['data']['backup']['files_size']['sum']='0';
|
||||
$task['data']['upload']['doing']='';
|
||||
$task['data']['upload']['finished']=0;
|
||||
$task['data']['upload']['progress']=0;
|
||||
$task['data']['upload']['job_data']=array();
|
||||
$task['data']['upload']['sub_job']=array();
|
||||
WPvivid_Setting::update_task($id,$task);
|
||||
$ret['result']='success';
|
||||
$ret['task_id']=$task['id'];
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function delete_ready_task()
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
$delete_ids=array();
|
||||
|
||||
if(!empty($tasks))
|
||||
{
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if($task['status']['str']=='ready')
|
||||
{
|
||||
$delete_ids[]=$task['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($delete_ids as $id)
|
||||
{
|
||||
unset($tasks[$id]);
|
||||
}
|
||||
if(!empty($delete_ids))
|
||||
WPvivid_Setting::update_option('wpvivid_task_list',$tasks);
|
||||
}
|
||||
|
||||
public static function is_task_canceled($task_id)
|
||||
{
|
||||
if(self::get_task($task_id)!==false)
|
||||
{
|
||||
$file_name = self::get_task_options($task_id, 'file_prefix');
|
||||
$backup_options = self::get_task_options($task_id, 'backup_options');
|
||||
|
||||
$file = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . $backup_options['dir'] . DIRECTORY_SEPARATOR . $file_name . '_cancel';
|
||||
|
||||
if (file_exists($file))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function get_backup_tasks_info($action){
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
$ret=array();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if($task['action']==$action)
|
||||
{
|
||||
$ret[$task['id']]['status']=self::get_backup_tasks_status($task['id']);
|
||||
$ret[$task['id']]['is_canceled']=self::is_task_canceled($task['id']);
|
||||
$ret[$task['id']]['size']=self::get_backup_size($task['id']);
|
||||
$ret[$task['id']]['data']=self::get_backup_tasks_progress($task['id']);
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function get_backup_tasks_status($task_id){
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
return $task['status'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_backup_size($task_id){
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
|
||||
if(array_key_exists('db_size',$task['data']['backup']))
|
||||
{
|
||||
$ret['db_size']=$task['data']['backup']['db_size'];
|
||||
$ret['files_size']=$task['data']['backup']['files_size'];
|
||||
return $ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_backup_tasks_progress($task_id){
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
$current_time=gmdate("Y-m-d H:i:s");
|
||||
$create_time=gmdate("Y-m-d H:i:s",$task['status']['start_time']);
|
||||
$time_diff=strtotime($current_time)-strtotime($create_time);
|
||||
$running_time='';
|
||||
if(gmdate("G",$time_diff) > 0){
|
||||
$running_time .= gmdate("G",$time_diff).' hour(s)';
|
||||
}
|
||||
if(intval(gmdate("i",$time_diff)) > 0){
|
||||
$running_time .= intval(gmdate("i",$time_diff)).' min(s)';
|
||||
}
|
||||
if(intval(gmdate("s",$time_diff)) > 0){
|
||||
$running_time .= intval(gmdate("s",$time_diff)).' second(s)';
|
||||
}
|
||||
$next_resume_time=WPvivid_Schedule::get_next_resume_time($task['id']);
|
||||
|
||||
$ret['type']=$task['data']['doing'];
|
||||
$ret['progress']=$task['data'][$ret['type']]['progress'];
|
||||
$ret['doing']=$task['data'][$ret['type']]['doing'];
|
||||
if(isset($task['data'][$ret['type']]['sub_job'][$ret['doing']]['progress']))
|
||||
$ret['descript']=$task['data'][$ret['type']]['sub_job'][$ret['doing']]['progress'];
|
||||
else
|
||||
$ret['descript']='';
|
||||
if(isset($task['data'][$ret['type']]['sub_job'][$ret['doing']]['upload_data']))
|
||||
$ret['upload_data']=$task['data'][$ret['type']]['sub_job'][$ret['doing']]['upload_data'];
|
||||
$task['data'][$ret['type']]['sub_job'][$ret['doing']]['upload_data']=false;
|
||||
$ret['running_time']=$running_time;
|
||||
$ret['running_stamp']=$time_diff;
|
||||
$ret['next_resume_time']=$next_resume_time;
|
||||
return $ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_backup_task_status($task_id)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
return $task['status'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function update_backup_task_status($task_id,$reset_start_time=false,$status='',$reset_timeout=false,$resume_count=false,$error='')
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
$task['status']['run_time']=time();
|
||||
if($reset_start_time)
|
||||
$task['status']['start_time']=time();
|
||||
if(!empty($status))
|
||||
{
|
||||
$task['status']['str']=$status;
|
||||
}
|
||||
if($reset_timeout)
|
||||
$task['status']['timeout']=time();
|
||||
if($resume_count!==false)
|
||||
{
|
||||
$task['status']['resume_count']=$resume_count;
|
||||
}
|
||||
|
||||
if(!empty($error))
|
||||
{
|
||||
$task['status']['error']=$error;
|
||||
}
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
return $task;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_backup_task_error($task_id)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task = $tasks[$task_id];
|
||||
return $task['status']['error'];
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_task_options($task_id,$option_names)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task=$tasks[$task_id];
|
||||
|
||||
if(is_array($option_names))
|
||||
{
|
||||
$options=array();
|
||||
foreach ($option_names as $name)
|
||||
{
|
||||
$options[$name]=$task['options'][$name];
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
else
|
||||
{
|
||||
return $task['options'][$option_names];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function update_task_options($task_id,$option_name,$option)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($task_id,$tasks))
|
||||
{
|
||||
$task=$tasks[$task_id];
|
||||
$task['options'][$option_name]=$option;
|
||||
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function update_backup_main_task_progress($task_id,$job_name,$progress,$finished,$job_data=array())
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
if($task!==false)
|
||||
{
|
||||
$task['status']['run_time']=time();
|
||||
$task['status']['str']='running';
|
||||
$task['data']['doing']=$job_name;
|
||||
$task['data'][$job_name]['finished']=$finished;
|
||||
$task['data'][$job_name]['progress']=$progress;
|
||||
$task['data'][$job_name]['job_data']=$job_data;
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
}
|
||||
}
|
||||
|
||||
public static function update_backup_sub_task_progress($task_id,$job_name,$sub_job_name,$finished,$progress,$job_data=array(),$upload_data=array())
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
if($task!==false)
|
||||
{
|
||||
$task['status']['run_time']=time();
|
||||
$task['status']['str']='running';
|
||||
$task['data']['doing']=$job_name;
|
||||
if(empty($sub_job_name))
|
||||
{
|
||||
$sub_job_name=$task['data'][$job_name]['doing'];
|
||||
}
|
||||
$task['data'][$job_name]['doing']=$sub_job_name;
|
||||
$task['data'][$job_name]['sub_job'][$sub_job_name]['finished']=$finished;
|
||||
if(!empty($progress))
|
||||
$task['data'][$job_name]['sub_job'][$sub_job_name]['progress']=$progress;
|
||||
if(!empty($job_data))
|
||||
{
|
||||
$task['data'][$job_name]['sub_job'][$sub_job_name]['job_data']=$job_data;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!isset($task['data'][$job_name]['sub_job'][$sub_job_name]['job_data']))
|
||||
{
|
||||
$task['data'][$job_name]['sub_job'][$sub_job_name]['job_data']=array();
|
||||
}
|
||||
}
|
||||
if(!empty($upload_data)){
|
||||
$task['data'][$job_name]['sub_job'][$sub_job_name]['upload_data']=$upload_data;
|
||||
}
|
||||
else{
|
||||
if(!isset($task['data'][$job_name]['sub_job'][$sub_job_name]['upload_data'])){
|
||||
$task['data'][$job_name]['sub_job'][$sub_job_name]['upload_data']=array();
|
||||
}
|
||||
}
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_backup_main_task_progress($task_id,$job_name='')
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
|
||||
if(empty($job_name))
|
||||
{
|
||||
$job_name=$task['data']['doing'];
|
||||
return $job_name;
|
||||
}
|
||||
|
||||
if(array_key_exists($job_name,$task['data']))
|
||||
{
|
||||
return $task['data'][$job_name];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function get_backup_sub_task_progress($task_id,$job_name,$sub_job_name)
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
if(array_key_exists($job_name,$task['data']))
|
||||
{
|
||||
if(array_key_exists($sub_job_name,$task['data'][$job_name]['sub_job']))
|
||||
{
|
||||
return $task['data'][$job_name]['sub_job'][$sub_job_name];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function update_backup_db_task_info($task_id,$db_info)
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
$task['data']['backup']['sub_job']['backup_db']['db_info']=$db_info;
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
}
|
||||
|
||||
public static function update_file_and_db_info($task_id,$db_size,$files_size)
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
$task['data']['backup']['db_size']=$db_size;
|
||||
$task['data']['backup']['files_size']=$files_size;
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
}
|
||||
|
||||
public static function update_download_cache($backup_id,$cache)
|
||||
{
|
||||
$default = array();
|
||||
|
||||
$options = get_option('wpvivid_download_cache', $default);
|
||||
$options[$backup_id]['cache']=$cache;
|
||||
WPvivid_Setting::update_option('wpvivid_download_cache',$options);
|
||||
}
|
||||
|
||||
public static function get_download_cache($backup_id)
|
||||
{
|
||||
$default = array();
|
||||
|
||||
$options = get_option('wpvivid_download_cache', $default);
|
||||
|
||||
if(array_key_exists($backup_id,$options))
|
||||
{
|
||||
return $options[$backup_id]['cache'];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function get_task($id)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($id,$tasks))
|
||||
{
|
||||
$task=$tasks[$id];
|
||||
return $task;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_tasks()
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
return $tasks;
|
||||
}
|
||||
|
||||
public static function get_tasks_by_action($action)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
$ret=array();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if($task['action']==$action)
|
||||
{
|
||||
$ret[$task['id']]=$task;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function is_tasks_backup_running()
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if ($task['status']['str']=='running'||$task['status']['str']=='no_responds')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function get_tasks_backup_running()
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
$ret=array();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if($task['action']=='backup')
|
||||
{
|
||||
if ($task['status']['str']=='running')
|
||||
{
|
||||
$ret[$task['id']]=$task;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public static function update_task($task)
|
||||
{
|
||||
WPvivid_Setting::update_task($task['id'],$task);
|
||||
}
|
||||
|
||||
public static function delete_task($id)
|
||||
{
|
||||
WPvivid_Setting::delete_task($id);
|
||||
}
|
||||
|
||||
public static function mark_task($id)
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
if(array_key_exists ($id,$tasks))
|
||||
{
|
||||
$task=$tasks[$id];
|
||||
$task['marked']=1;
|
||||
WPvivid_Setting::update_task($id,$task);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function delete_marked_task()
|
||||
{
|
||||
$has_marked = 0;
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
$delete_ids=array();
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if(isset($task['marked']))
|
||||
{
|
||||
$delete_ids[]=$task['id'];
|
||||
}
|
||||
}
|
||||
foreach ($delete_ids as $id)
|
||||
{
|
||||
unset($tasks[$id]);
|
||||
$has_marked = 1;
|
||||
}
|
||||
WPvivid_Setting::update_option('wpvivid_task_list',$tasks);
|
||||
return $has_marked;
|
||||
}
|
||||
|
||||
public static function delete_out_of_date_finished_task()
|
||||
{
|
||||
$tasks=WPvivid_Setting::get_tasks();
|
||||
$delete_ids=array();
|
||||
|
||||
if(!empty($tasks))
|
||||
{
|
||||
foreach ($tasks as $task)
|
||||
{
|
||||
if($task['status']['str']=='error'||$task['status']['str']=='completed')
|
||||
{
|
||||
if(time()-$task['status']['run_time']>60)
|
||||
{
|
||||
$delete_ids[]=$task['id'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($delete_ids as $id)
|
||||
{
|
||||
unset($tasks[$id]);
|
||||
}
|
||||
|
||||
WPvivid_Setting::update_option('wpvivid_task_list',$tasks);
|
||||
}
|
||||
|
||||
public static function delete_all_task()
|
||||
{
|
||||
WPvivid_Setting::delete_option('wpvivid_task_list');
|
||||
}
|
||||
|
||||
public static function is_backup_task_timeout($task)
|
||||
{
|
||||
$current_time=gmdate("Y-m-d H:i:s");
|
||||
$run_time=gmdate("Y-m-d H:i:s", $task['data']['run_time']);
|
||||
$running_time=strtotime($current_time)-strtotime($run_time);
|
||||
if($running_time>$task['data']['options']['max_execution_time'])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static function new_download_task_v2($file_name)
|
||||
{
|
||||
$default = array();
|
||||
wp_cache_delete('notoptions', 'options');
|
||||
wp_cache_delete('alloptions', 'options');
|
||||
wp_cache_delete('wpvivid_download_task_v2', 'options');
|
||||
|
||||
$options = get_option('wpvivid_download_task_v2', $default);
|
||||
|
||||
$task['file_name']=$file_name;
|
||||
$task['start_time']=time();
|
||||
$task['run_time']=time();
|
||||
$task['progress_text']='start download file:'.$file_name;
|
||||
$task['status']='running';
|
||||
$task['error']='';
|
||||
$options[$file_name]=$task;
|
||||
|
||||
WPvivid_Setting::update_option('wpvivid_download_task_v2',$options);
|
||||
return $task;
|
||||
}
|
||||
|
||||
public static function is_download_task_running_v2($file_name)
|
||||
{
|
||||
$default = array();
|
||||
$options = get_option('wpvivid_download_task_v2', $default);
|
||||
|
||||
if(empty($options))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(array_key_exists($file_name,$options))
|
||||
{
|
||||
$task=$options[$file_name];
|
||||
|
||||
if($task['status'] === 'error')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(time()-$task['run_time']>60)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function update_download_task_v2(&$task,$progress_text,$status='',$error='')
|
||||
{
|
||||
$default = array();
|
||||
wp_cache_delete('notoptions', 'options');
|
||||
wp_cache_delete('alloptions', 'options');
|
||||
wp_cache_delete('wpvivid_download_task_v2', 'options');
|
||||
|
||||
$options = get_option('wpvivid_download_task_v2', $default);
|
||||
|
||||
$file_name=$task['file_name'];
|
||||
$task['run_time']=time();
|
||||
$task['progress_text']=$progress_text;
|
||||
if($status!='')
|
||||
{
|
||||
$task['status']=$status;
|
||||
if($error!='')
|
||||
{
|
||||
$task['error']=$error;
|
||||
}
|
||||
}
|
||||
|
||||
$options[$file_name]=$task;
|
||||
|
||||
WPvivid_Setting::update_option('wpvivid_download_task_v2',$options);
|
||||
}
|
||||
|
||||
public static function get_download_task_v2($file_name)
|
||||
{
|
||||
$default = array();
|
||||
$options = get_option('wpvivid_download_task_v2', $default);
|
||||
|
||||
if(empty($options))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(array_key_exists($file_name,$options))
|
||||
{
|
||||
if(time()-$options[$file_name]['run_time']>60)
|
||||
{
|
||||
$options[$file_name]['status']='timeout';
|
||||
$options[$file_name]['error']='time out';
|
||||
}
|
||||
|
||||
return $options[$file_name];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function delete_download_task_v2($file_name)
|
||||
{
|
||||
$default = array();
|
||||
$options = get_option('wpvivid_download_task_v2', $default);
|
||||
|
||||
if(empty($options))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(array_key_exists($file_name,$options))
|
||||
{
|
||||
unset($options[$file_name]);
|
||||
WPvivid_Setting::update_option('wpvivid_download_task_v2',$options);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function wpvivid_reset_backup_retry_times($task_id)
|
||||
{
|
||||
$task=self::get_task($task_id);
|
||||
if($task!==false)
|
||||
{
|
||||
$task['status']['resume_count']=0;
|
||||
WPvivid_Setting::update_task($task_id,$task);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR')){
|
||||
die;
|
||||
}
|
||||
|
||||
class WPvivid_tools
|
||||
{
|
||||
public static function clean_junk_cache(){
|
||||
$home_url_prefix=get_home_url();
|
||||
$parse = wp_parse_url($home_url_prefix);
|
||||
$tmppath='';
|
||||
if(isset($parse['path'])) {
|
||||
$tmppath=str_replace('/','_',$parse['path']);
|
||||
}
|
||||
$home_url_prefix = $parse['host'].$tmppath;
|
||||
$path = WP_CONTENT_DIR.DIRECTORY_SEPARATOR.WPvivid_Setting::get_backupdir();
|
||||
$handler=opendir($path);
|
||||
if($handler===false)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
while(($filename=readdir($handler))!==false)
|
||||
{
|
||||
/*if(is_dir($path.DIRECTORY_SEPARATOR.$filename) && preg_match('#temp-'.$home_url_prefix.'_'.'#',$filename))
|
||||
{
|
||||
WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
|
||||
}
|
||||
if(is_dir($path.DIRECTORY_SEPARATOR.$filename) && preg_match('#temp-'.'#',$filename))
|
||||
{
|
||||
WPvivid_tools::deldir($path.DIRECTORY_SEPARATOR.$filename,'',true);
|
||||
}*/
|
||||
if(preg_match('#pclzip-.*\.tmp#', $filename)){
|
||||
@wp_delete_file($path.DIRECTORY_SEPARATOR.$filename);
|
||||
}
|
||||
if(preg_match('#pclzip-.*\.gz#', $filename)){
|
||||
@wp_delete_file($path.DIRECTORY_SEPARATOR.$filename);
|
||||
}
|
||||
}
|
||||
@closedir($handler);
|
||||
}
|
||||
|
||||
public static function deldir($path,$exclude='',$flag = false)
|
||||
{
|
||||
if(!is_dir($path))
|
||||
{
|
||||
return ;
|
||||
}
|
||||
$handler=opendir($path);
|
||||
if(empty($handler))
|
||||
return ;
|
||||
while(($filename=readdir($handler))!==false)
|
||||
{
|
||||
if($filename != "." && $filename != "..")
|
||||
{
|
||||
if(is_dir($path.DIRECTORY_SEPARATOR.$filename)){
|
||||
if(empty($exclude)||WPvivid_tools::regex_match($exclude['directory'],$path.DIRECTORY_SEPARATOR.$filename ,0)){
|
||||
self::deldir( $path.DIRECTORY_SEPARATOR.$filename ,$exclude, $flag);
|
||||
@rmdir( $path.DIRECTORY_SEPARATOR.$filename );
|
||||
}
|
||||
}else{
|
||||
if(empty($exclude)||WPvivid_tools::regex_match($exclude['file'],$path.DIRECTORY_SEPARATOR.$filename ,0)){
|
||||
@wp_delete_file($path.DIRECTORY_SEPARATOR.$filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($handler)
|
||||
@closedir($handler);
|
||||
if($flag)
|
||||
@rmdir($path);
|
||||
}
|
||||
|
||||
public static function regex_match($regex_array,$string,$mode)
|
||||
{
|
||||
if(empty($regex_array))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if($mode==0)
|
||||
{
|
||||
foreach ($regex_array as $regex)
|
||||
{
|
||||
if(preg_match($regex,$string))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if($mode==1)
|
||||
{
|
||||
foreach ($regex_array as $regex)
|
||||
{
|
||||
if(preg_match($regex,$string))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function GetSaveLogFolder()
|
||||
{
|
||||
$options = get_option('wpvivid_common_setting',array());
|
||||
|
||||
if(!isset($options['log_save_location']))
|
||||
{
|
||||
//WPvivid_Setting::set_default_common_option();
|
||||
$options['log_save_location']=WPVIVID_DEFAULT_LOG_DIR;
|
||||
update_option('wpvivid_common_setting', $options, 'no');
|
||||
|
||||
$options = get_option('wpvivid_common_setting',array());
|
||||
}
|
||||
|
||||
if(!is_dir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location']))
|
||||
{
|
||||
@mkdir(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'],0777,true);
|
||||
//@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'].DIRECTORY_SEPARATOR.'index.html', 'x');
|
||||
$tempfile=@fopen(WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'].DIRECTORY_SEPARATOR.'.htaccess', 'x');
|
||||
if($tempfile)
|
||||
{
|
||||
//$text="deny from all";
|
||||
$text="<IfModule mod_rewrite.c>\r\nRewriteEngine On\r\nRewriteRule .* - [F,L]\r\n</IfModule>";
|
||||
fwrite($tempfile,$text );
|
||||
}
|
||||
}
|
||||
|
||||
return WP_CONTENT_DIR.DIRECTORY_SEPARATOR.$options['log_save_location'].DIRECTORY_SEPARATOR;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
if (!defined('WPVIVID_PLUGIN_DIR'))
|
||||
{
|
||||
die;
|
||||
}
|
||||
|
||||
class WPvivid_Upload
|
||||
{
|
||||
public $task_id;
|
||||
|
||||
public function upload($task_id,$remote_option=null)
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
$this->task_id=$task_id;
|
||||
$task=new WPvivid_Backup_Task($task_id);
|
||||
$files=$task->get_backup_files();
|
||||
WPvivid_taskmanager::update_backup_main_task_progress($this->task_id,'upload',0,0);
|
||||
|
||||
if(is_null($remote_option))
|
||||
{
|
||||
$remote_options=WPvivid_taskmanager::get_task_options($this->task_id,'remote_options');
|
||||
|
||||
if(sizeof($remote_options)>1)
|
||||
{
|
||||
$result=array('result' => WPVIVID_FAILED , 'error' => 'not support multi remote storage');
|
||||
$result= apply_filters('wpvivid_upload_files_to_multi_remote',$result,$task_id);
|
||||
|
||||
if($result['result']==WPVIVID_SUCCESS)
|
||||
{
|
||||
WPvivid_taskmanager::update_backup_main_task_progress($this->task_id,'upload',100,1);
|
||||
WPvivid_taskmanager::update_backup_task_status($task_id,false,'completed');
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
WPvivid_taskmanager::update_backup_task_status($this->task_id,false,'error',false,false,$result['error']);
|
||||
return array('result' => WPVIVID_FAILED , 'error' => $result['error']);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote_option=array_shift($remote_options);
|
||||
|
||||
if(is_null($remote_option))
|
||||
{
|
||||
return array('result' => WPVIVID_FAILED , 'error' => 'not select remote storage');
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
$remote=$wpvivid_plugin->remote_collection->get_remote($remote_option);
|
||||
|
||||
$result=$remote->upload($this->task_id,$files,array($this,'upload_callback'));
|
||||
|
||||
if($result['result']==WPVIVID_SUCCESS)
|
||||
{
|
||||
WPvivid_taskmanager::update_backup_main_task_progress($this->task_id,'upload',100,1);
|
||||
WPvivid_taskmanager::update_backup_task_status($task_id,false,'completed');
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote ->cleanup($files);
|
||||
|
||||
WPvivid_taskmanager::update_backup_task_status($this->task_id,false,'error',false,false,$result['error']);
|
||||
return array('result' => WPVIVID_FAILED , 'error' => $result['error']);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
}
|
||||
$remote=$wpvivid_plugin->remote_collection->get_remote($remote_option);
|
||||
|
||||
$result=$remote->upload($this->task_id,$files,array($this,'upload_callback'));
|
||||
|
||||
if($result['result']==WPVIVID_SUCCESS)
|
||||
{
|
||||
WPvivid_taskmanager::update_backup_main_task_progress($this->task_id,'upload',100,1);
|
||||
WPvivid_taskmanager::update_backup_task_status($task_id,false,'completed');
|
||||
return array('result' => WPVIVID_SUCCESS);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote ->cleanup($files);
|
||||
|
||||
WPvivid_taskmanager::update_backup_task_status($this->task_id,false,'error',false,false,$result['error']);
|
||||
return array('result' => WPVIVID_FAILED , 'error' => $result['error']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function upload_callback($offset,$current_name,$current_size,$last_time,$last_size)
|
||||
{
|
||||
$job_data=array();
|
||||
$upload_data=array();
|
||||
$upload_data['offset']=$offset;
|
||||
$upload_data['current_name']=$current_name;
|
||||
$upload_data['current_size']=$current_size;
|
||||
$upload_data['last_time']=$last_time;
|
||||
$upload_data['last_size']=$last_size;
|
||||
$upload_data['descript']='Uploading '.$current_name;
|
||||
$v =( $offset - $last_size ) / (time() - $last_time);
|
||||
$v /= 1000;
|
||||
$v=round($v,2);
|
||||
|
||||
global $wpvivid_plugin;
|
||||
$wpvivid_plugin->check_cancel_backup($this->task_id);
|
||||
|
||||
$message='Uploading '.$current_name.' Total size: '.size_format($current_size,2).' Uploaded: '.size_format($offset,2).' speed:'.$v.'kb/s';
|
||||
$wpvivid_plugin->wpvivid_log->WriteLog($message,'notice');
|
||||
$progress=intval(($offset/$current_size)*100);
|
||||
WPvivid_taskmanager::update_backup_main_task_progress($this->task_id,'upload',$progress,0);
|
||||
WPvivid_taskmanager::update_backup_sub_task_progress($this->task_id,'upload','',WPVIVID_UPLOAD_UNDO,$message, $job_data, $upload_data);
|
||||
}
|
||||
|
||||
public function get_backup_files($backup)
|
||||
{
|
||||
$backup_item=new WPvivid_Backup_Item($backup);
|
||||
|
||||
return $backup_item->get_files();
|
||||
}
|
||||
|
||||
public function clean_remote_backup($remotes,$files)
|
||||
{
|
||||
$remote_option=array_shift($remotes);
|
||||
|
||||
if(!is_null($remote_option))
|
||||
{
|
||||
global $wpvivid_plugin;
|
||||
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();
|
||||
}
|
||||
$remote=$wpvivid_plugin->remote_collection->get_remote($remote_option);
|
||||
$remote ->cleanup($files);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
7726
wp-content/plugins/wpvivid-backuprestore/includes/class-wpvivid.php
Normal file
7726
wp-content/plugins/wpvivid-backuprestore/includes/class-wpvivid.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<?php // Silence is golden
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common;
|
||||
|
||||
use Aws\Common\Facade\Facade;
|
||||
use Guzzle\Service\Builder\ServiceBuilder;
|
||||
use Guzzle\Service\Builder\ServiceBuilderLoader;
|
||||
|
||||
/**
|
||||
* Base class for interacting with web service clients
|
||||
*/
|
||||
class Aws extends ServiceBuilder
|
||||
{
|
||||
/**
|
||||
* @var string Current version of the SDK
|
||||
*/
|
||||
const VERSION = '2.8.31';
|
||||
|
||||
/**
|
||||
* Create a new service locator for the AWS SDK
|
||||
*
|
||||
* You can configure the service locator is four different ways:
|
||||
*
|
||||
* 1. Use the default configuration file shipped with the SDK that wires class names with service short names and
|
||||
* specify global parameters to add to every definition (e.g. key, secret, credentials, etc)
|
||||
*
|
||||
* 2. Use a custom configuration file that extends the default config and supplies credentials for each service.
|
||||
*
|
||||
* 3. Use a custom config file that wires services to custom short names for services.
|
||||
*
|
||||
* 4. If you are on Amazon EC2, you can use the default configuration file and not provide any credentials so that
|
||||
* you are using InstanceProfile credentials.
|
||||
*
|
||||
* @param array|string $config The full path to a .php or .js|.json file, or an associative array of data
|
||||
* to use as global parameters to pass to each service.
|
||||
* @param array $globalParameters Global parameters to pass to every service as it is instantiated.
|
||||
*
|
||||
* @return Aws
|
||||
*/
|
||||
public static function factory($config = null, array $globalParameters = array())
|
||||
{
|
||||
if (!$config) {
|
||||
// If nothing is passed in, then use the default configuration file with credentials from the environment
|
||||
$config = self::getDefaultServiceDefinition();
|
||||
} elseif (is_array($config)) {
|
||||
// If an array was passed, then use the default configuration file with parameter overrides
|
||||
$globalParameters = $config;
|
||||
$config = self::getDefaultServiceDefinition();
|
||||
}
|
||||
|
||||
$loader = new ServiceBuilderLoader();
|
||||
$loader->addAlias('_aws', self::getDefaultServiceDefinition())
|
||||
->addAlias('_sdk1', __DIR__ . '/Resources/sdk1-config.php');
|
||||
|
||||
return $loader->load($config, $globalParameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full path to the default service builder definition file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getDefaultServiceDefinition()
|
||||
{
|
||||
return __DIR__ . '/Resources/aws-config.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration for the service builder
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return $this->builderConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the facades for the clients defined in the service builder
|
||||
*
|
||||
* @param string|null $namespace The namespace that the facades should be mounted to. Defaults to global namespace
|
||||
*
|
||||
* @return Aws
|
||||
* @deprecated "Facades" are being removed in version 3.0 of the SDK.
|
||||
*/
|
||||
public function enableFacades($namespace = null)
|
||||
{
|
||||
Facade::mountFacades($this, $namespace);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Aws;
|
||||
use Aws\Common\Credentials\CredentialsInterface;
|
||||
use Aws\Common\Enum\ClientOptions as Options;
|
||||
use Aws\Common\Exception\InvalidArgumentException;
|
||||
use Aws\Common\Exception\TransferException;
|
||||
use Aws\Common\RulesEndpointProvider;
|
||||
use Aws\Common\Signature\EndpointSignatureInterface;
|
||||
use Aws\Common\Signature\SignatureInterface;
|
||||
use Aws\Common\Signature\SignatureListener;
|
||||
use Aws\Common\Waiter\WaiterClassFactory;
|
||||
use Aws\Common\Waiter\CompositeWaiterFactory;
|
||||
use Aws\Common\Waiter\WaiterFactoryInterface;
|
||||
use Aws\Common\Waiter\WaiterConfigFactory;
|
||||
use Guzzle\Common\Collection;
|
||||
use Guzzle\Http\Exception\CurlException;
|
||||
use Guzzle\Http\QueryAggregator\DuplicateAggregator;
|
||||
use Guzzle\Service\Client;
|
||||
use Guzzle\Service\Description\ServiceDescriptionInterface;
|
||||
|
||||
/**
|
||||
* Abstract AWS client
|
||||
*/
|
||||
abstract class AbstractClient extends Client implements AwsClientInterface
|
||||
{
|
||||
/** @var CredentialsInterface AWS credentials */
|
||||
protected $credentials;
|
||||
|
||||
/** @var SignatureInterface Signature implementation of the service */
|
||||
protected $signature;
|
||||
|
||||
/** @var WaiterFactoryInterface Factory used to create waiter classes */
|
||||
protected $waiterFactory;
|
||||
|
||||
/** @var DuplicateAggregator Cached query aggregator*/
|
||||
protected $aggregator;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getAllEvents()
|
||||
{
|
||||
return array_merge(Client::getAllEvents(), array(
|
||||
'client.region_changed',
|
||||
'client.credentials_changed',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CredentialsInterface $credentials AWS credentials
|
||||
* @param SignatureInterface $signature Signature implementation
|
||||
* @param Collection $config Configuration options
|
||||
*
|
||||
* @throws InvalidArgumentException if an endpoint provider isn't provided
|
||||
*/
|
||||
public function __construct(CredentialsInterface $credentials, SignatureInterface $signature, Collection $config)
|
||||
{
|
||||
// Bootstrap with Guzzle
|
||||
parent::__construct($config->get(Options::BASE_URL), $config);
|
||||
$this->credentials = $credentials;
|
||||
$this->signature = $signature;
|
||||
$this->aggregator = new DuplicateAggregator();
|
||||
|
||||
// Make sure the user agent is prefixed by the SDK version
|
||||
$this->setUserAgent('aws-sdk-php2/' . Aws::VERSION, true);
|
||||
|
||||
// Add the event listener so that requests are signed before they are sent
|
||||
$dispatcher = $this->getEventDispatcher();
|
||||
$dispatcher->addSubscriber(new SignatureListener($credentials, $signature));
|
||||
|
||||
if ($backoff = $config->get(Options::BACKOFF)) {
|
||||
$dispatcher->addSubscriber($backoff, -255);
|
||||
}
|
||||
}
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (substr($method, 0, 3) === 'get' && substr($method, -8) === 'Iterator') {
|
||||
// Allow magic method calls for iterators (e.g. $client->get<CommandName>Iterator($params))
|
||||
$commandOptions = isset($args[0]) ? $args[0] : null;
|
||||
$iteratorOptions = isset($args[1]) ? $args[1] : array();
|
||||
return $this->getIterator(substr($method, 3, -8), $commandOptions, $iteratorOptions);
|
||||
} elseif (substr($method, 0, 9) == 'waitUntil') {
|
||||
// Allow magic method calls for waiters (e.g. $client->waitUntil<WaiterName>($params))
|
||||
return $this->waitUntil(substr($method, 9), isset($args[0]) ? $args[0]: array());
|
||||
} else {
|
||||
return parent::__call(ucfirst($method), $args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an endpoint for a specific region from a service description
|
||||
* @deprecated This function will no longer be updated to work with new regions.
|
||||
*/
|
||||
public static function getEndpoint(ServiceDescriptionInterface $description, $region, $scheme)
|
||||
{
|
||||
try {
|
||||
$service = $description->getData('endpointPrefix');
|
||||
$provider = RulesEndpointProvider::fromDefaults();
|
||||
$result = $provider(array(
|
||||
'service' => $service,
|
||||
'region' => $region,
|
||||
'scheme' => $scheme
|
||||
));
|
||||
return $result['endpoint'];
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException(esc_html($e->getMessage()), 0, esc_attr($e));
|
||||
}
|
||||
}
|
||||
|
||||
public function getCredentials()
|
||||
{
|
||||
return $this->credentials;
|
||||
}
|
||||
|
||||
public function setCredentials(CredentialsInterface $credentials)
|
||||
{
|
||||
$formerCredentials = $this->credentials;
|
||||
$this->credentials = $credentials;
|
||||
|
||||
// Dispatch an event that the credentials have been changed
|
||||
$this->dispatch('client.credentials_changed', array(
|
||||
'credentials' => $credentials,
|
||||
'former_credentials' => $formerCredentials,
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSignature()
|
||||
{
|
||||
return $this->signature;
|
||||
}
|
||||
|
||||
public function getRegions()
|
||||
{
|
||||
return $this->serviceDescription->getData('regions');
|
||||
}
|
||||
|
||||
public function getRegion()
|
||||
{
|
||||
return $this->getConfig(Options::REGION);
|
||||
}
|
||||
|
||||
public function setRegion($region)
|
||||
{
|
||||
$config = $this->getConfig();
|
||||
$formerRegion = $config->get(Options::REGION);
|
||||
$global = $this->serviceDescription->getData('globalEndpoint');
|
||||
$provider = $config->get('endpoint_provider');
|
||||
|
||||
if (!$provider) {
|
||||
throw new \RuntimeException('No endpoint provider configured');
|
||||
}
|
||||
|
||||
// Only change the region if the service does not have a global endpoint
|
||||
if (!$global || $this->serviceDescription->getData('namespace') === 'S3') {
|
||||
|
||||
$endpoint = call_user_func(
|
||||
$provider,
|
||||
array(
|
||||
'scheme' => $config->get(Options::SCHEME),
|
||||
'region' => $region,
|
||||
'service' => $config->get(Options::SERVICE)
|
||||
)
|
||||
);
|
||||
|
||||
$this->setBaseUrl($endpoint['endpoint']);
|
||||
$config->set(Options::BASE_URL, $endpoint['endpoint']);
|
||||
$config->set(Options::REGION, $region);
|
||||
|
||||
// Update the signature if necessary
|
||||
$signature = $this->getSignature();
|
||||
if ($signature instanceof EndpointSignatureInterface) {
|
||||
/** @var EndpointSignatureInterface $signature */
|
||||
$signature->setRegionName($region);
|
||||
}
|
||||
|
||||
// Dispatch an event that the region has been changed
|
||||
$this->dispatch('client.region_changed', array(
|
||||
'region' => $region,
|
||||
'former_region' => $formerRegion,
|
||||
));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function waitUntil($waiter, array $input = array())
|
||||
{
|
||||
$this->getWaiter($waiter, $input)->wait();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWaiter($waiter, array $input = array())
|
||||
{
|
||||
return $this->getWaiterFactory()->build($waiter)
|
||||
->setClient($this)
|
||||
->setConfig($input);
|
||||
}
|
||||
|
||||
public function setWaiterFactory(WaiterFactoryInterface $waiterFactory)
|
||||
{
|
||||
$this->waiterFactory = $waiterFactory;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWaiterFactory()
|
||||
{
|
||||
if (!$this->waiterFactory) {
|
||||
$clientClass = get_class($this);
|
||||
// Use a composite factory that checks for classes first, then config waiters
|
||||
$this->waiterFactory = new CompositeWaiterFactory(array(
|
||||
new WaiterClassFactory(substr($clientClass, 0, strrpos($clientClass, '\\')) . '\\Waiter')
|
||||
));
|
||||
if ($this->getDescription()) {
|
||||
$waiterConfig = $this->getDescription()->getData('waiters') ?: array();
|
||||
$this->waiterFactory->addFactory(new WaiterConfigFactory($waiterConfig));
|
||||
}
|
||||
}
|
||||
|
||||
return $this->waiterFactory;
|
||||
}
|
||||
|
||||
public function getApiVersion()
|
||||
{
|
||||
return $this->serviceDescription->getApiVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
* @throws \Aws\Common\Exception\TransferException
|
||||
*/
|
||||
public function send($requests)
|
||||
{
|
||||
try {
|
||||
return parent::send($requests);
|
||||
} catch (CurlException $e) {
|
||||
$wrapped = new TransferException($e->getMessage(), null, $e);
|
||||
$wrapped->setCurlHandle($e->getCurlHandle())
|
||||
->setCurlInfo($e->getCurlInfo())
|
||||
->setError($e->getError(), $e->getErrorNo())
|
||||
->setRequest($e->getRequest());
|
||||
throw $wrapped;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the duplicate query string aggregator is used so that
|
||||
* query string values are sent over the wire as foo=bar&foo=baz.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createRequest(
|
||||
$method = 'GET',
|
||||
$uri = null,
|
||||
$headers = null,
|
||||
$body = null,
|
||||
array $options = array()
|
||||
) {
|
||||
$request = parent::createRequest($method, $uri, $headers, $body, $options);
|
||||
$request->getQuery()->setAggregator($this->aggregator);
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Credentials\CredentialsInterface;
|
||||
use Aws\Common\Signature\SignatureInterface;
|
||||
use Aws\Common\Waiter\WaiterFactoryInterface;
|
||||
use Aws\Common\Waiter\WaiterInterface;
|
||||
use Guzzle\Service\ClientInterface;
|
||||
|
||||
/**
|
||||
* Interface that all AWS clients implement
|
||||
*/
|
||||
interface AwsClientInterface extends ClientInterface
|
||||
{
|
||||
/**
|
||||
* Returns the AWS credentials associated with the client
|
||||
*
|
||||
* @return CredentialsInterface
|
||||
*/
|
||||
public function getCredentials();
|
||||
|
||||
/**
|
||||
* Sets the credentials object associated with the client
|
||||
*
|
||||
* @param CredentialsInterface $credentials Credentials object to use
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setCredentials(CredentialsInterface $credentials);
|
||||
|
||||
/**
|
||||
* Returns the signature implementation used with the client
|
||||
*
|
||||
* @return SignatureInterface
|
||||
*/
|
||||
public function getSignature();
|
||||
|
||||
/**
|
||||
* Get a list of available regions and region data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getRegions();
|
||||
|
||||
/**
|
||||
* Get the name of the region to which the client is configured to send requests
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRegion();
|
||||
|
||||
/**
|
||||
* Change the region to which the client is configured to send requests
|
||||
*
|
||||
* @param string $region Name of the region
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setRegion($region);
|
||||
|
||||
/**
|
||||
* Get the waiter factory being used by the client
|
||||
*
|
||||
* @return WaiterFactoryInterface
|
||||
*/
|
||||
public function getWaiterFactory();
|
||||
|
||||
/**
|
||||
* Set the waiter factory to use with the client
|
||||
*
|
||||
* @param WaiterFactoryInterface $waiterFactory Factory used to create waiters
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setWaiterFactory(WaiterFactoryInterface $waiterFactory);
|
||||
|
||||
/**
|
||||
* Wait until a resource is available or an associated waiter returns true
|
||||
*
|
||||
* @param string $waiter Name of the waiter
|
||||
* @param array $input Values used as input for the underlying operation and to control the waiter
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function waitUntil($waiter, array $input = array());
|
||||
|
||||
/**
|
||||
* Get a named waiter object
|
||||
*
|
||||
* @param string $waiter Name of the waiter
|
||||
* @param array $input Values used as input for the underlying operation and to control the waiter
|
||||
*
|
||||
* @return WaiterInterface
|
||||
*/
|
||||
public function getWaiter($waiter, array $input = array());
|
||||
|
||||
/**
|
||||
* Get the API version of the client (e.g. 2006-03-01)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApiVersion();
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Credentials\Credentials;
|
||||
use Aws\Common\Credentials\CredentialsInterface;
|
||||
use Aws\Common\Credentials\NullCredentials;
|
||||
use Aws\Common\Enum\ClientOptions as Options;
|
||||
use Aws\Common\Exception\ExceptionListener;
|
||||
use Aws\Common\Exception\InvalidArgumentException;
|
||||
use Aws\Common\Exception\NamespaceExceptionFactory;
|
||||
use Aws\Common\Exception\Parser\DefaultXmlExceptionParser;
|
||||
use Aws\Common\Exception\Parser\ExceptionParserInterface;
|
||||
use Aws\Common\Iterator\AwsResourceIteratorFactory;
|
||||
use Aws\Common\RulesEndpointProvider;
|
||||
use Aws\Common\Signature\EndpointSignatureInterface;
|
||||
use Aws\Common\Signature\SignatureInterface;
|
||||
use Aws\Common\Signature\SignatureV2;
|
||||
use Aws\Common\Signature\SignatureV3Https;
|
||||
use Aws\Common\Signature\SignatureV4;
|
||||
use Guzzle\Common\Collection;
|
||||
use Guzzle\Plugin\Backoff\BackoffPlugin;
|
||||
use Guzzle\Plugin\Backoff\CurlBackoffStrategy;
|
||||
use Guzzle\Plugin\Backoff\ExponentialBackoffStrategy;
|
||||
use Guzzle\Plugin\Backoff\HttpBackoffStrategy;
|
||||
use Guzzle\Plugin\Backoff\TruncatedBackoffStrategy;
|
||||
use Guzzle\Service\Description\ServiceDescription;
|
||||
use Guzzle\Service\Resource\ResourceIteratorClassFactory;
|
||||
use Guzzle\Log\LogAdapterInterface;
|
||||
use Guzzle\Log\ClosureLogAdapter;
|
||||
use Guzzle\Plugin\Backoff\BackoffLogger;
|
||||
|
||||
/**
|
||||
* Builder for creating AWS service clients
|
||||
*/
|
||||
class ClientBuilder
|
||||
{
|
||||
/**
|
||||
* @var array Default client config
|
||||
*/
|
||||
protected static $commonConfigDefaults = array('scheme' => 'https');
|
||||
|
||||
/**
|
||||
* @var array Default client requirements
|
||||
*/
|
||||
protected static $commonConfigRequirements = array(Options::SERVICE_DESCRIPTION);
|
||||
|
||||
/**
|
||||
* @var string The namespace of the client
|
||||
*/
|
||||
protected $clientNamespace;
|
||||
|
||||
/**
|
||||
* @var array The config options
|
||||
*/
|
||||
protected $config = array();
|
||||
|
||||
/**
|
||||
* @var array The config defaults
|
||||
*/
|
||||
protected $configDefaults = array();
|
||||
|
||||
/**
|
||||
* @var array The config requirements
|
||||
*/
|
||||
protected $configRequirements = array();
|
||||
|
||||
/**
|
||||
* @var ExceptionParserInterface The Parser interface for the client
|
||||
*/
|
||||
protected $exceptionParser;
|
||||
|
||||
/**
|
||||
* @var array Array of configuration data for iterators available for the client
|
||||
*/
|
||||
protected $iteratorsConfig = array();
|
||||
|
||||
/** @var string */
|
||||
private $clientClass;
|
||||
|
||||
/** @var string */
|
||||
private $serviceName;
|
||||
|
||||
/**
|
||||
* Factory method for creating the client builder
|
||||
*
|
||||
* @param string $namespace The namespace of the client
|
||||
*
|
||||
* @return ClientBuilder
|
||||
*/
|
||||
public static function factory($namespace = null)
|
||||
{
|
||||
return new static($namespace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a client builder
|
||||
*
|
||||
* @param string $namespace The namespace of the client
|
||||
*/
|
||||
public function __construct($namespace = null)
|
||||
{
|
||||
$this->clientNamespace = $namespace;
|
||||
|
||||
// Determine service and class name
|
||||
$this->clientClass = 'Aws\Common\Client\DefaultClient';
|
||||
|
||||
if ($this->clientNamespace) {
|
||||
$this->serviceName = substr($this->clientNamespace, strrpos($this->clientNamespace, '\\') + 1);
|
||||
$this->clientClass = $this->clientNamespace . '\\' . $this->serviceName . 'Client';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config options
|
||||
*
|
||||
* @param array|Collection $config The config options
|
||||
*
|
||||
* @return ClientBuilder
|
||||
*/
|
||||
public function setConfig($config)
|
||||
{
|
||||
$this->config = $this->processArray($config);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config options' defaults
|
||||
*
|
||||
* @param array|Collection $defaults The default values
|
||||
*
|
||||
* @return ClientBuilder
|
||||
*/
|
||||
public function setConfigDefaults($defaults)
|
||||
{
|
||||
$this->configDefaults = $this->processArray($defaults);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the required config options
|
||||
*
|
||||
* @param array|Collection $required The required config options
|
||||
*
|
||||
* @return ClientBuilder
|
||||
*/
|
||||
public function setConfigRequirements($required)
|
||||
{
|
||||
$this->configRequirements = $this->processArray($required);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the exception parser. If one is not provided the builder will use
|
||||
* the default XML exception parser.
|
||||
*
|
||||
* @param ExceptionParserInterface $parser The exception parser
|
||||
*
|
||||
* @return ClientBuilder
|
||||
*/
|
||||
public function setExceptionParser(ExceptionParserInterface $parser)
|
||||
{
|
||||
$this->exceptionParser = $parser;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the configuration for the client's iterators
|
||||
*
|
||||
* @param array $config Configuration data for client's iterators
|
||||
*
|
||||
* @return ClientBuilder
|
||||
*/
|
||||
public function setIteratorsConfig(array $config)
|
||||
{
|
||||
$this->iteratorsConfig = $config;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the building logic using all of the parameters that have been
|
||||
* set and falling back to default values. Returns an instantiate service
|
||||
* client with credentials prepared and plugins attached.
|
||||
*
|
||||
* @return AwsClientInterface
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
// Resolve configuration
|
||||
$config = Collection::fromConfig(
|
||||
$this->config,
|
||||
array_merge(self::$commonConfigDefaults, $this->configDefaults),
|
||||
(self::$commonConfigRequirements + $this->configRequirements)
|
||||
);
|
||||
|
||||
if ($config[Options::VERSION] === 'latest') {
|
||||
$config[Options::VERSION] = constant("{$this->clientClass}::LATEST_API_VERSION");
|
||||
}
|
||||
|
||||
if (!isset($config['endpoint_provider'])) {
|
||||
$config['endpoint_provider'] = RulesEndpointProvider::fromDefaults();
|
||||
}
|
||||
|
||||
// Resolve the endpoint, signature, and credentials
|
||||
$description = $this->updateConfigFromDescription($config);
|
||||
$signature = $this->getSignature($description, $config);
|
||||
$credentials = $this->getCredentials($config);
|
||||
$this->extractHttpConfig($config);
|
||||
|
||||
// Resolve exception parser
|
||||
if (!$this->exceptionParser) {
|
||||
$this->exceptionParser = new DefaultXmlExceptionParser();
|
||||
}
|
||||
|
||||
// Resolve backoff strategy
|
||||
$backoff = $config->get(Options::BACKOFF);
|
||||
if ($backoff === null) {
|
||||
$retries = isset($config[Options::BACKOFF_RETRIES]) ? $config[Options::BACKOFF_RETRIES] : 3;
|
||||
$backoff = $this->createDefaultBackoff($retries);
|
||||
$config->set(Options::BACKOFF, $backoff);
|
||||
}
|
||||
|
||||
if ($backoff) {
|
||||
$this->addBackoffLogger($backoff, $config);
|
||||
}
|
||||
|
||||
/** @var AwsClientInterface $client */
|
||||
$client = new $this->clientClass($credentials, $signature, $config);
|
||||
$client->setDescription($description);
|
||||
|
||||
// Add exception marshaling so that more descriptive exception are thrown
|
||||
if ($this->clientNamespace) {
|
||||
$exceptionFactory = new NamespaceExceptionFactory(
|
||||
$this->exceptionParser,
|
||||
"{$this->clientNamespace}\\Exception",
|
||||
"{$this->clientNamespace}\\Exception\\{$this->serviceName}Exception"
|
||||
);
|
||||
$client->addSubscriber(new ExceptionListener($exceptionFactory));
|
||||
}
|
||||
|
||||
// Add the UserAgentPlugin to append to the User-Agent header of requests
|
||||
$client->addSubscriber(new UserAgentListener());
|
||||
|
||||
// Filters used for the cache plugin
|
||||
$client->getConfig()->set(
|
||||
'params.cache.key_filter',
|
||||
'header=date,x-amz-date,x-amz-security-token,x-amzn-authorization'
|
||||
);
|
||||
|
||||
// Set the iterator resource factory based on the provided iterators config
|
||||
$client->setResourceIteratorFactory(new AwsResourceIteratorFactory(
|
||||
$this->iteratorsConfig,
|
||||
new ResourceIteratorClassFactory($this->clientNamespace . '\\Iterator')
|
||||
));
|
||||
|
||||
// Disable parameter validation if needed
|
||||
if ($config->get(Options::VALIDATION) === false) {
|
||||
$params = $config->get('command.params') ?: array();
|
||||
$params['command.disable_validation'] = true;
|
||||
$config->set('command.params', $params);
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add backoff logging to the backoff plugin if needed
|
||||
*
|
||||
* @param BackoffPlugin $plugin Backoff plugin
|
||||
* @param Collection $config Configuration settings
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function addBackoffLogger(BackoffPlugin $plugin, Collection $config)
|
||||
{
|
||||
// The log option can be set to `debug` or an instance of a LogAdapterInterface
|
||||
if ($logger = $config->get(Options::BACKOFF_LOGGER)) {
|
||||
$format = $config->get(Options::BACKOFF_LOGGER_TEMPLATE);
|
||||
if ($logger === 'debug') {
|
||||
$logger = new ClosureLogAdapter(function ($message) {
|
||||
trigger_error(esc_html($message) . "\n");
|
||||
});
|
||||
} elseif (!($logger instanceof LogAdapterInterface)) {
|
||||
throw new InvalidArgumentException(
|
||||
esc_html(Options::BACKOFF_LOGGER) . ' must be set to `debug` or an instance of '
|
||||
. 'Guzzle\\Common\\Log\\LogAdapterInterface'
|
||||
);
|
||||
}
|
||||
// Create the plugin responsible for logging exponential backoff retries
|
||||
$logPlugin = new BackoffLogger($logger);
|
||||
// You can specify a custom format or use the default
|
||||
if ($format) {
|
||||
$logPlugin->setTemplate($format);
|
||||
}
|
||||
$plugin->addSubscriber($logPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that an array (e.g. for config data) is actually in array form
|
||||
*
|
||||
* @param array|Collection $array The array data
|
||||
*
|
||||
* @return array
|
||||
* @throws InvalidArgumentException if the arg is not an array or Collection
|
||||
*/
|
||||
protected function processArray($array)
|
||||
{
|
||||
if ($array instanceof Collection) {
|
||||
$array = $array->getAll();
|
||||
}
|
||||
|
||||
if (!is_array($array)) {
|
||||
throw new InvalidArgumentException('The config must be provided as an array or Collection.');
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a configuration object from a service description
|
||||
*
|
||||
* @param Collection $config Config to update
|
||||
*
|
||||
* @return ServiceDescription
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function updateConfigFromDescription(Collection $config)
|
||||
{
|
||||
$description = $config->get(Options::SERVICE_DESCRIPTION);
|
||||
if (!($description instanceof ServiceDescription)) {
|
||||
// Inject the version into the sprintf template if it is a string
|
||||
if (is_string($description)) {
|
||||
$description = sprintf($description, $config->get(Options::VERSION));
|
||||
}
|
||||
$description = ServiceDescription::factory($description);
|
||||
$config->set(Options::SERVICE_DESCRIPTION, $description);
|
||||
}
|
||||
|
||||
if (!$config->get(Options::SERVICE)) {
|
||||
$config->set(Options::SERVICE, $description->getData('endpointPrefix'));
|
||||
}
|
||||
|
||||
if ($iterators = $description->getData('iterators')) {
|
||||
$this->setIteratorsConfig($iterators);
|
||||
}
|
||||
|
||||
$this->handleRegion($config);
|
||||
$this->handleEndpoint($config);
|
||||
|
||||
return $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an appropriate signature object for a a client based on the
|
||||
* "signature" configuration setting, or the default signature specified in
|
||||
* a service description. The signature can be set to a valid signature
|
||||
* version identifier string or an instance of Aws\Common\Signature\SignatureInterface.
|
||||
*
|
||||
* @param ServiceDescription $description Description that holds a signature option
|
||||
* @param Collection $config Configuration options
|
||||
*
|
||||
* @return SignatureInterface
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function getSignature(ServiceDescription $description, Collection $config)
|
||||
{
|
||||
// If a custom signature has not been provided, then use the default
|
||||
// signature setting specified in the service description.
|
||||
$signature = $config->get(Options::SIGNATURE) ?: $description->getData('signatureVersion');
|
||||
|
||||
if (is_string($signature)) {
|
||||
if ($signature == 'v4') {
|
||||
$signature = new SignatureV4();
|
||||
} elseif ($signature == 'v2') {
|
||||
$signature = new SignatureV2();
|
||||
} elseif ($signature == 'v3https') {
|
||||
$signature = new SignatureV3Https();
|
||||
} else {
|
||||
throw new InvalidArgumentException(esc_html("Invalid signature type: {$signature}"));
|
||||
}
|
||||
} elseif (!($signature instanceof SignatureInterface)) {
|
||||
throw new InvalidArgumentException('The provided signature is not '
|
||||
. 'a signature version string or an instance of '
|
||||
. 'Aws\\Common\\Signature\\SignatureInterface');
|
||||
}
|
||||
|
||||
// Allow a custom service name or region value to be provided
|
||||
if ($signature instanceof EndpointSignatureInterface) {
|
||||
|
||||
// Determine the service name to use when signing
|
||||
$signature->setServiceName($config->get(Options::SIGNATURE_SERVICE)
|
||||
?: $description->getData('signingName')
|
||||
?: $description->getData('endpointPrefix'));
|
||||
|
||||
// Determine the region to use when signing requests
|
||||
$signature->setRegionName($config->get(Options::SIGNATURE_REGION) ?: $config->get(Options::REGION));
|
||||
}
|
||||
|
||||
return $signature;
|
||||
}
|
||||
|
||||
protected function getCredentials(Collection $config)
|
||||
{
|
||||
$credentials = $config->get(Options::CREDENTIALS);
|
||||
|
||||
if (is_array($credentials)) {
|
||||
$credentials = Credentials::factory($credentials);
|
||||
} elseif ($credentials === false) {
|
||||
$credentials = new NullCredentials();
|
||||
} elseif (!$credentials instanceof CredentialsInterface) {
|
||||
$credentials = Credentials::factory($config);
|
||||
}
|
||||
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
private function handleRegion(Collection $config)
|
||||
{
|
||||
// Make sure a valid region is set
|
||||
$region = $config[Options::REGION];
|
||||
$description = $config[Options::SERVICE_DESCRIPTION];
|
||||
$global = $description->getData('globalEndpoint');
|
||||
|
||||
if (!$global && !$region) {
|
||||
throw new InvalidArgumentException(
|
||||
'A region is required when using ' . esc_html($description->getData('serviceFullName'))
|
||||
);
|
||||
} elseif ($global && !$region) {
|
||||
$config[Options::REGION] = 'us-east-1';
|
||||
}
|
||||
}
|
||||
|
||||
private function handleEndpoint(Collection $config)
|
||||
{
|
||||
// Alias "endpoint" with "base_url" for forwards compatibility.
|
||||
if ($config['endpoint']) {
|
||||
$config[Options::BASE_URL] = $config['endpoint'];
|
||||
return;
|
||||
}
|
||||
|
||||
if ($config[Options::BASE_URL]) {
|
||||
return;
|
||||
}
|
||||
|
||||
$endpoint = call_user_func(
|
||||
$config['endpoint_provider'],
|
||||
array(
|
||||
'scheme' => $config[Options::SCHEME],
|
||||
'region' => $config[Options::REGION],
|
||||
'service' => $config[Options::SERVICE]
|
||||
)
|
||||
);
|
||||
|
||||
$config[Options::BASE_URL] = $endpoint['endpoint'];
|
||||
|
||||
// Set a signature if one was not explicitly provided.
|
||||
if (!$config->hasKey(Options::SIGNATURE)
|
||||
&& isset($endpoint['signatureVersion'])
|
||||
) {
|
||||
$config->set(Options::SIGNATURE, $endpoint['signatureVersion']);
|
||||
}
|
||||
|
||||
// The the signing region if endpoint rule specifies one.
|
||||
if (isset($endpoint['credentialScope'])) {
|
||||
$scope = $endpoint['credentialScope'];
|
||||
if (isset($scope['region'])) {
|
||||
$config->set(Options::SIGNATURE_REGION, $scope['region']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function createDefaultBackoff($retries = 3)
|
||||
{
|
||||
return new BackoffPlugin(
|
||||
// Retry failed requests up to 3 times if it is determined that the request can be retried
|
||||
new TruncatedBackoffStrategy($retries,
|
||||
// Retry failed requests with 400-level responses due to throttling
|
||||
new ThrottlingErrorChecker($this->exceptionParser,
|
||||
// Retry failed requests due to transient network or cURL problems
|
||||
new CurlBackoffStrategy(null,
|
||||
// Retry failed requests with 500-level responses
|
||||
new HttpBackoffStrategy(array(500, 503, 509),
|
||||
// Retry requests that failed due to expired credentials
|
||||
new ExpiredCredentialsChecker($this->exceptionParser,
|
||||
new ExponentialBackoffStrategy()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private function extractHttpConfig(Collection $config)
|
||||
{
|
||||
$http = $config['http'];
|
||||
|
||||
if (!is_array($http)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($http['verify'])) {
|
||||
$config[Options::SSL_CERT] = $http['verify'];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Enum\ClientOptions as Options;
|
||||
use Guzzle\Common\Collection;
|
||||
|
||||
/**
|
||||
* Generic client for interacting with an AWS service
|
||||
*/
|
||||
class DefaultClient extends AbstractClient
|
||||
{
|
||||
/**
|
||||
* Factory method to create a default client using an array of configuration options.
|
||||
*
|
||||
* The following array keys and values are available options:
|
||||
*
|
||||
* Credential options ((`key`, `secret`, and optional `token`) OR `credentials` is required):
|
||||
*
|
||||
* - key: AWS Access Key ID
|
||||
* - secret: AWS secret access key
|
||||
* - credentials: You can optionally provide a custom `Aws\Common\Credentials\CredentialsInterface` object
|
||||
* - token: Custom AWS security token to use with request authentication. Please note that not all services accept temporary credentials. See http://docs.aws.amazon.com/STS/latest/UsingSTS/UsingTokens.html
|
||||
* - token.ttd: UNIX timestamp for when the custom credentials expire
|
||||
* - credentials.cache.key: Optional custom cache key to use with the credentials
|
||||
* - credentials.client: Pass this option to specify a custom `Guzzle\Http\ClientInterface` to use if your credentials require a HTTP request (e.g. RefreshableInstanceProfileCredentials)
|
||||
*
|
||||
* Region and endpoint options (Some services do not require a region while others do. Check the service specific user guide documentation for details):
|
||||
*
|
||||
* - region: Region name (e.g. 'us-east-1', 'us-west-1', 'us-west-2', 'eu-west-1', etc...)
|
||||
* - scheme: URI Scheme of the base URL (e.g. 'https', 'http') used when endpoint is not supplied
|
||||
* - endpoint: Allows you to specify a custom endpoint instead of building one from the region and scheme
|
||||
*
|
||||
* Generic client options:
|
||||
*
|
||||
* - signature: Overrides the signature used by the client. Clients will always choose an appropriate default signature. However, it can be useful to override this with a custom setting. This can be set to "v4", "v3https", "v2" or an instance of Aws\Common\Signature\SignatureInterface.
|
||||
* - ssl.certificate_authority: Set to true to use the bundled CA cert or pass the full path to an SSL certificate bundle
|
||||
* - curl.options: Associative of CURLOPT_* cURL options to add to each request
|
||||
* - client.backoff.logger: `Guzzle\Log\LogAdapterInterface` object used to log backoff retries. Use 'debug' to emit PHP warnings when a retry is issued.
|
||||
* - client.backoff.logger.template: Optional template to use for exponential backoff log messages. See `Guzzle\Plugin\Backoff\BackoffLogger` for formatting information.
|
||||
*
|
||||
* @param array|Collection $config Client configuration data
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function factory($config = array())
|
||||
{
|
||||
return ClientBuilder::factory()
|
||||
->setConfig($config)
|
||||
->setConfigDefaults(array(Options::SCHEME => 'https'))
|
||||
->build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Credentials\AbstractRefreshableCredentials;
|
||||
use Aws\Common\Client\AwsClientInterface;
|
||||
use Aws\Common\Exception\Parser\ExceptionParserInterface;
|
||||
use Guzzle\Http\Exception\HttpException;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
use Guzzle\Plugin\Backoff\BackoffStrategyInterface;
|
||||
use Guzzle\Plugin\Backoff\AbstractBackoffStrategy;
|
||||
|
||||
/**
|
||||
* Backoff logic that handles retrying requests when credentials expire
|
||||
*/
|
||||
class ExpiredCredentialsChecker extends AbstractBackoffStrategy
|
||||
{
|
||||
/**
|
||||
* @var array Array of known retrying exception codes
|
||||
*/
|
||||
protected $retryable = array(
|
||||
'RequestExpired' => true,
|
||||
'ExpiredTokenException' => true,
|
||||
'ExpiredToken' => true
|
||||
);
|
||||
|
||||
/**
|
||||
* @var ExceptionParserInterface Exception parser used to parse exception responses
|
||||
*/
|
||||
protected $exceptionParser;
|
||||
|
||||
public function __construct(ExceptionParserInterface $exceptionParser, BackoffStrategyInterface $next = null) {
|
||||
$this->exceptionParser = $exceptionParser;
|
||||
$this->next = $next;
|
||||
}
|
||||
|
||||
public function makesDecision()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function getDelay($retries, RequestInterface $request, Response $response = null, HttpException $e = null)
|
||||
{
|
||||
if ($response && $response->isClientError()) {
|
||||
|
||||
$parts = $this->exceptionParser->parse($request, $response);
|
||||
if (!isset($this->retryable[$parts['code']]) || !$request->getClient()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var AwsClientInterface $client */
|
||||
$client = $request->getClient();
|
||||
// Only retry if the credentials can be refreshed
|
||||
if (!($client->getCredentials() instanceof AbstractRefreshableCredentials)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Resign the request using new credentials
|
||||
$client->getSignature()->signRequest($request, $client->getCredentials()->setExpiration(-1));
|
||||
|
||||
// Retry immediately with no delay
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Exception\Parser\ExceptionParserInterface;
|
||||
use Guzzle\Http\Exception\HttpException;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
use Guzzle\Plugin\Backoff\BackoffStrategyInterface;
|
||||
use Guzzle\Plugin\Backoff\AbstractBackoffStrategy;
|
||||
|
||||
/**
|
||||
* Backoff logic that handles throttling exceptions from services
|
||||
*/
|
||||
class ThrottlingErrorChecker extends AbstractBackoffStrategy
|
||||
{
|
||||
/** @var array Whitelist of exception codes (as indexes) that indicate throttling */
|
||||
protected static $throttlingExceptions = array(
|
||||
'RequestLimitExceeded' => true,
|
||||
'Throttling' => true,
|
||||
'ThrottlingException' => true,
|
||||
'ProvisionedThroughputExceededException' => true,
|
||||
'RequestThrottled' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var ExceptionParserInterface Exception parser used to parse exception responses
|
||||
*/
|
||||
protected $exceptionParser;
|
||||
|
||||
public function __construct(ExceptionParserInterface $exceptionParser, BackoffStrategyInterface $next = null)
|
||||
{
|
||||
$this->exceptionParser = $exceptionParser;
|
||||
if ($next) {
|
||||
$this->setNext($next);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function makesDecision()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getDelay(
|
||||
$retries,
|
||||
RequestInterface $request,
|
||||
Response $response = null,
|
||||
HttpException $e = null
|
||||
) {
|
||||
if ($response && $response->isClientError()) {
|
||||
$parts = $this->exceptionParser->parse($request, $response);
|
||||
return isset(self::$throttlingExceptions[$parts['code']]) ? true : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Aws\Common\Exception\InvalidArgumentException;
|
||||
use Guzzle\Common\Event;
|
||||
use Guzzle\Http\EntityBody;
|
||||
use Guzzle\Service\Command\AbstractCommand as Command;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Prepares the body parameter of a command such that the parameter is more flexible (e.g. accepts file handles) with
|
||||
* the value it accepts but converts it to the correct format for the command. Also looks for a "Filename" parameter.
|
||||
*/
|
||||
class UploadBodyListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var array The names of the commands of which to modify the body parameter
|
||||
*/
|
||||
protected $commands;
|
||||
|
||||
/**
|
||||
* @var string The key for the upload body parameter
|
||||
*/
|
||||
protected $bodyParameter;
|
||||
|
||||
/**
|
||||
* @var string The key for the source file parameter
|
||||
*/
|
||||
protected $sourceParameter;
|
||||
|
||||
/**
|
||||
* @param array $commands The commands to modify
|
||||
* @param string $bodyParameter The key for the body parameter
|
||||
* @param string $sourceParameter The key for the source file parameter
|
||||
*/
|
||||
public function __construct(array $commands, $bodyParameter = 'Body', $sourceParameter = 'SourceFile')
|
||||
{
|
||||
$this->commands = $commands;
|
||||
$this->bodyParameter = (string) $bodyParameter;
|
||||
$this->sourceParameter = (string) $sourceParameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array('command.before_prepare' => array('onCommandBeforePrepare'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts filenames and file handles into EntityBody objects before the command is validated
|
||||
*
|
||||
* @param Event $event Event emitted
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function onCommandBeforePrepare(Event $event)
|
||||
{
|
||||
/** @var Command $command */
|
||||
$command = $event['command'];
|
||||
if (in_array($command->getName(), $this->commands)) {
|
||||
// Get the interesting parameters
|
||||
$source = $command->get($this->sourceParameter);
|
||||
$body = $command->get($this->bodyParameter);
|
||||
|
||||
// If a file path is passed in then get the file handle
|
||||
if (is_string($source) && file_exists($source)) {
|
||||
$body = fopen($source, 'r');
|
||||
}
|
||||
|
||||
// Prepare the body parameter and remove the source file parameter
|
||||
if (null !== $body) {
|
||||
$command->remove($this->sourceParameter);
|
||||
$command->set($this->bodyParameter, EntityBody::factory($body));
|
||||
} else {
|
||||
throw new InvalidArgumentException(esc_html("You must specify a non-null value for the {$this->bodyParameter} or {$this->sourceParameter} parameters."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Client;
|
||||
|
||||
use Guzzle\Common\Event;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Listener used to append strings to the User-Agent header of a request based
|
||||
* on the `ua.append` option. `ua.append` can contain a string or array of values.
|
||||
*/
|
||||
class UserAgentListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var string Option used to store User-Agent modifiers
|
||||
*/
|
||||
const OPTION = 'ua.append';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array('command.before_send' => 'onBeforeSend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds strings to the User-Agent header using the `ua.append` parameter of a command
|
||||
*
|
||||
* @param Event $event Event emitted
|
||||
*/
|
||||
public function onBeforeSend(Event $event)
|
||||
{
|
||||
$command = $event['command'];
|
||||
if ($userAgentAppends = $command->get(self::OPTION)) {
|
||||
$request = $command->getRequest();
|
||||
$userAgent = (string) $request->getHeader('User-Agent');
|
||||
foreach ((array) $userAgentAppends as $append) {
|
||||
$append = ' ' . $append;
|
||||
if (strpos($userAgent, $append) === false) {
|
||||
$userAgent .= $append;
|
||||
}
|
||||
}
|
||||
$request->setHeader('User-Agent', $userAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
namespace Aws\Common\Command;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Service\Description\Parameter;
|
||||
use Guzzle\Service\Command\CommandInterface;
|
||||
use Guzzle\Service\Command\LocationVisitor\Request\AbstractRequestVisitor;
|
||||
|
||||
/**
|
||||
* Location visitor used to serialize AWS query parameters (e.g. EC2, SES, SNS, SQS, etc) as POST fields
|
||||
*/
|
||||
class AwsQueryVisitor extends AbstractRequestVisitor
|
||||
{
|
||||
private $fqname;
|
||||
|
||||
public function visit(CommandInterface $command, RequestInterface $request, Parameter $param, $value)
|
||||
{
|
||||
$this->fqname = $command->getName();
|
||||
$query = array();
|
||||
$this->customResolver($value, $param, $query, $param->getWireName());
|
||||
$request->addPostFields($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map nested parameters into the location_key based parameters
|
||||
*
|
||||
* @param array $value Value to map
|
||||
* @param Parameter $param Parameter that holds information about the current key
|
||||
* @param array $query Built up query string values
|
||||
* @param string $prefix String to prepend to sub query values
|
||||
*/
|
||||
protected function customResolver($value, Parameter $param, array &$query, $prefix = '')
|
||||
{
|
||||
switch ($param->getType()) {
|
||||
case 'object':
|
||||
$this->resolveObject($param, $value, $prefix, $query);
|
||||
break;
|
||||
case 'array':
|
||||
$this->resolveArray($param, $value, $prefix, $query);
|
||||
break;
|
||||
default:
|
||||
$query[$prefix] = $param->filter($value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom handling for objects
|
||||
*
|
||||
* @param Parameter $param Parameter for the object
|
||||
* @param array $value Value that is set for this parameter
|
||||
* @param string $prefix Prefix for the resulting key
|
||||
* @param array $query Query string array passed by reference
|
||||
*/
|
||||
protected function resolveObject(Parameter $param, array $value, $prefix, array &$query)
|
||||
{
|
||||
// Maps are implemented using additional properties
|
||||
$hasAdditionalProperties = ($param->getAdditionalProperties() instanceof Parameter);
|
||||
$additionalPropertyCount = 0;
|
||||
|
||||
foreach ($value as $name => $v) {
|
||||
if ($subParam = $param->getProperty($name)) {
|
||||
// if the parameter was found by name as a regular property
|
||||
$key = $prefix . '.' . $subParam->getWireName();
|
||||
$this->customResolver($v, $subParam, $query, $key);
|
||||
} elseif ($hasAdditionalProperties) {
|
||||
// Handle map cases like &Attribute.1.Name=<name>&Attribute.1.Value=<value>
|
||||
$additionalPropertyCount++;
|
||||
$data = $param->getData();
|
||||
$keyName = isset($data['keyName']) ? $data['keyName'] : 'key';
|
||||
$valueName = isset($data['valueName']) ? $data['valueName'] : 'value';
|
||||
$query["{$prefix}.{$additionalPropertyCount}.{$keyName}"] = $name;
|
||||
$newPrefix = "{$prefix}.{$additionalPropertyCount}.{$valueName}";
|
||||
if (is_array($v)) {
|
||||
$this->customResolver($v, $param->getAdditionalProperties(), $query, $newPrefix);
|
||||
} else {
|
||||
$query[$newPrefix] = $param->filter($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom handling for arrays
|
||||
*
|
||||
* @param Parameter $param Parameter for the object
|
||||
* @param array $value Value that is set for this parameter
|
||||
* @param string $prefix Prefix for the resulting key
|
||||
* @param array $query Query string array passed by reference
|
||||
*/
|
||||
protected function resolveArray(Parameter $param, array $value, $prefix, array &$query)
|
||||
{
|
||||
static $serializeEmpty = array(
|
||||
'SetLoadBalancerPoliciesForBackendServer' => 1,
|
||||
'SetLoadBalancerPoliciesOfListener' => 1,
|
||||
'UpdateStack' => 1
|
||||
);
|
||||
|
||||
// For BC, serialize empty lists for specific operations
|
||||
if (!$value) {
|
||||
if (isset($serializeEmpty[$this->fqname])) {
|
||||
if (substr($prefix, -7) === '.member') {
|
||||
$prefix = substr($prefix, 0, -7);
|
||||
}
|
||||
$query[$prefix] = '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$offset = $param->getData('offset') ?: 1;
|
||||
foreach ($value as $index => $v) {
|
||||
$index += $offset;
|
||||
if (is_array($v) && $items = $param->getItems()) {
|
||||
$this->customResolver($v, $items, $query, $prefix . '.' . $index);
|
||||
} else {
|
||||
$query[$prefix . '.' . $index] = $param->filter($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Command;
|
||||
|
||||
use Guzzle\Service\Command\OperationCommand;
|
||||
use Guzzle\Http\Curl\CurlHandle;
|
||||
|
||||
/**
|
||||
* Adds AWS JSON body functionality to dynamically generated HTTP requests
|
||||
*/
|
||||
class JsonCommand extends OperationCommand
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function build()
|
||||
{
|
||||
parent::build();
|
||||
|
||||
// Ensure that the body of the request ALWAYS includes some JSON. By default, this is an empty object.
|
||||
if (!$this->request->getBody()) {
|
||||
$this->request->setBody('{}');
|
||||
}
|
||||
|
||||
// Never send the Expect header when interacting with a JSON query service
|
||||
$this->request->removeHeader('Expect');
|
||||
|
||||
// Always send JSON requests as a raw string rather than using streams to avoid issues with
|
||||
// cURL error code 65: "necessary data rewind wasn't possible".
|
||||
// This could be removed after PHP addresses https://bugs.php.net/bug.php?id=47204
|
||||
$this->request->getCurlOptions()->set(CurlHandle::BODY_AS_STRING, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Command;
|
||||
|
||||
use Guzzle\Service\Command\OperationCommand;
|
||||
|
||||
/**
|
||||
* Adds AWS Query service serialization
|
||||
*/
|
||||
class QueryCommand extends OperationCommand
|
||||
{
|
||||
/**
|
||||
* @var AwsQueryVisitor
|
||||
*/
|
||||
protected static $queryVisitor;
|
||||
|
||||
/**
|
||||
* @var XmlResponseLocationVisitor
|
||||
*/
|
||||
protected static $xmlVisitor;
|
||||
|
||||
/**
|
||||
* Register the aws.query visitor
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!self::$queryVisitor) {
|
||||
self::$queryVisitor = new AwsQueryVisitor();
|
||||
}
|
||||
if (!self::$xmlVisitor) {
|
||||
self::$xmlVisitor = new XmlResponseLocationVisitor();
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$this->getRequestSerializer()->addVisitor('aws.query', self::$queryVisitor);
|
||||
$this->getResponseParser()->addVisitor('xml', self::$xmlVisitor);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Aws\Common\Command;
|
||||
|
||||
use Guzzle\Service\Description\Operation;
|
||||
use Guzzle\Service\Command\CommandInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
use Guzzle\Service\Description\Parameter;
|
||||
use Guzzle\Service\Command\LocationVisitor\Response\XmlVisitor;
|
||||
|
||||
/**
|
||||
* Class used for custom AWS XML response parsing of query services
|
||||
*/
|
||||
class XmlResponseLocationVisitor extends XmlVisitor
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function before(CommandInterface $command, array &$result)
|
||||
{
|
||||
parent::before($command, $result);
|
||||
|
||||
// Unwrapped wrapped responses
|
||||
$operation = $command->getOperation();
|
||||
if ($operation->getServiceDescription()->getData('resultWrapped')) {
|
||||
$wrappingNode = $operation->getName() . 'Result';
|
||||
if (isset($result[$wrappingNode])) {
|
||||
$result = $result[$wrappingNode] + $result;
|
||||
unset($result[$wrappingNode]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accounts for wrapper nodes
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function visit(
|
||||
CommandInterface $command,
|
||||
Response $response,
|
||||
Parameter $param,
|
||||
&$value,
|
||||
$context = null
|
||||
) {
|
||||
parent::visit($command, $response, $param, $value, $context);
|
||||
|
||||
// Account for wrapper nodes (e.g. RDS, ElastiCache, etc)
|
||||
if ($param->getData('wrapper')) {
|
||||
$wireName = $param->getWireName();
|
||||
$value += $value[$wireName];
|
||||
unset($value[$wireName]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter used when converting XML maps into associative arrays in service descriptions
|
||||
*
|
||||
* @param array $value Value to filter
|
||||
* @param string $entryName Name of each entry
|
||||
* @param string $keyName Name of each key
|
||||
* @param string $valueName Name of each value
|
||||
*
|
||||
* @return array Returns the map of the XML data
|
||||
*/
|
||||
public static function xmlMap($value, $entryName, $keyName, $valueName)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($value as $entry) {
|
||||
$result[$entry[$keyName]] = $entry[$valueName];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
/**
|
||||
* Abstract credentials decorator
|
||||
*/
|
||||
class AbstractCredentialsDecorator implements CredentialsInterface
|
||||
{
|
||||
/**
|
||||
* @var CredentialsInterface Wrapped credentials object
|
||||
*/
|
||||
protected $credentials;
|
||||
|
||||
/**
|
||||
* Constructs a new BasicAWSCredentials object, with the specified AWS
|
||||
* access key and AWS secret key
|
||||
*
|
||||
* @param CredentialsInterface $credentials
|
||||
*/
|
||||
public function __construct(CredentialsInterface $credentials)
|
||||
{
|
||||
$this->credentials = $credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return $this->credentials->serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$this->credentials = new Credentials('', '');
|
||||
$this->credentials->unserialize($serialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAccessKeyId()
|
||||
{
|
||||
return $this->credentials->getAccessKeyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSecretKey()
|
||||
{
|
||||
return $this->credentials->getSecretKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSecurityToken()
|
||||
{
|
||||
return $this->credentials->getSecurityToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExpiration()
|
||||
{
|
||||
return $this->credentials->getExpiration();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isExpired()
|
||||
{
|
||||
return $this->credentials->isExpired();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAccessKeyId($key)
|
||||
{
|
||||
$this->credentials->setAccessKeyId($key);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSecretKey($secret)
|
||||
{
|
||||
$this->credentials->setSecretKey($secret);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setSecurityToken($token)
|
||||
{
|
||||
$this->credentials->setSecurityToken($token);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setExpiration($timestamp)
|
||||
{
|
||||
$this->credentials->setExpiration($timestamp);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
/**
|
||||
* Abstract decorator to provide a foundation for refreshable credentials
|
||||
*/
|
||||
abstract class AbstractRefreshableCredentials extends AbstractCredentialsDecorator
|
||||
{
|
||||
/**
|
||||
* Get the underlying credentials, refreshing if necessary.
|
||||
*
|
||||
* @return Credentials
|
||||
*/
|
||||
public function getCredentials()
|
||||
{
|
||||
if ($this->credentials->isExpired()) {
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
return new Credentials(
|
||||
$this->credentials->getAccessKeyId(),
|
||||
$this->credentials->getSecretKey(),
|
||||
$this->credentials->getSecurityToken(),
|
||||
$this->credentials->getExpiration()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAccessKeyId()
|
||||
{
|
||||
if ($this->credentials->isExpired()) {
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
return $this->credentials->getAccessKeyId();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSecretKey()
|
||||
{
|
||||
if ($this->credentials->isExpired()) {
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
return $this->credentials->getSecretKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getSecurityToken()
|
||||
{
|
||||
if ($this->credentials->isExpired()) {
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
return $this->credentials->getSecurityToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
if ($this->credentials->isExpired()) {
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
return $this->credentials->serialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get new credentials
|
||||
*/
|
||||
abstract protected function refresh();
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
use Guzzle\Cache\CacheAdapterInterface;
|
||||
|
||||
/**
|
||||
* Credentials decorator used to implement caching credentials
|
||||
*/
|
||||
class CacheableCredentials extends AbstractRefreshableCredentials
|
||||
{
|
||||
/**
|
||||
* @var CacheAdapterInterface Cache adapter used to store credentials
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
/**
|
||||
* @var string Cache key used to store the credentials
|
||||
*/
|
||||
protected $cacheKey;
|
||||
|
||||
/**
|
||||
* CacheableCredentials is a decorator that decorates other credentials
|
||||
*
|
||||
* @param CredentialsInterface $credentials Credentials to adapt
|
||||
* @param CacheAdapterInterface $cache Cache to use to store credentials
|
||||
* @param string $cacheKey Cache key of the credentials
|
||||
*/
|
||||
public function __construct(CredentialsInterface $credentials, CacheAdapterInterface $cache, $cacheKey)
|
||||
{
|
||||
$this->cache = $cache;
|
||||
$this->cacheKey = $cacheKey;
|
||||
|
||||
parent::__construct($credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get new credentials from cache or from the adapted object
|
||||
*/
|
||||
protected function refresh()
|
||||
{
|
||||
if (!$cache = $this->cache->fetch($this->cacheKey)) {
|
||||
// The credentials were not found, so try again and cache if new
|
||||
$this->credentials->getAccessKeyId();
|
||||
if (!$this->credentials->isExpired()) {
|
||||
// The credentials were updated, so cache them
|
||||
$this->cache->save($this->cacheKey, $this->credentials, $this->credentials->getExpiration() - time());
|
||||
}
|
||||
} else {
|
||||
// The credentials were found in cache, so update the adapter object
|
||||
// if the cached credentials are not expired
|
||||
if (!$cache->isExpired()) {
|
||||
$this->credentials->setAccessKeyId($cache->getAccessKeyId());
|
||||
$this->credentials->setSecretKey($cache->getSecretKey());
|
||||
$this->credentials->setSecurityToken($cache->getSecurityToken());
|
||||
$this->credentials->setExpiration($cache->getExpiration());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
use Aws\Common\Enum\ClientOptions as Options;
|
||||
use Aws\Common\Exception\InvalidArgumentException;
|
||||
use Aws\Common\Exception\RequiredExtensionNotLoadedException;
|
||||
use Aws\Common\Exception\RuntimeException;
|
||||
use Guzzle\Common\FromConfigInterface;
|
||||
use Guzzle\Cache\CacheAdapterInterface;
|
||||
use Guzzle\Cache\DoctrineCacheAdapter;
|
||||
use Guzzle\Common\Collection;
|
||||
|
||||
/**
|
||||
* Basic implementation of the AWSCredentials interface that allows callers to
|
||||
* pass in the AWS access key and secret access in the constructor.
|
||||
*/
|
||||
class Credentials implements CredentialsInterface, FromConfigInterface
|
||||
{
|
||||
const ENV_KEY = 'AWS_ACCESS_KEY_ID';
|
||||
const ENV_SECRET = 'AWS_SECRET_KEY';
|
||||
const ENV_SECRET_ACCESS_KEY = 'AWS_SECRET_ACCESS_KEY';
|
||||
const ENV_PROFILE = 'AWS_PROFILE';
|
||||
|
||||
/** @var string AWS Access Key ID */
|
||||
protected $key;
|
||||
|
||||
/** @var string AWS Secret Access Key */
|
||||
protected $secret;
|
||||
|
||||
/** @var string AWS Security Token */
|
||||
protected $token;
|
||||
|
||||
/** @var int Time to die of token */
|
||||
protected $ttd;
|
||||
|
||||
/**
|
||||
* Get the available keys for the factory method
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getConfigDefaults()
|
||||
{
|
||||
return array(
|
||||
Options::KEY => null,
|
||||
Options::SECRET => null,
|
||||
Options::TOKEN => null,
|
||||
Options::TOKEN_TTD => null,
|
||||
Options::PROFILE => null,
|
||||
Options::CREDENTIALS_CACHE => null,
|
||||
Options::CREDENTIALS_CACHE_KEY => null,
|
||||
Options::CREDENTIALS_CLIENT => null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for creating new credentials. This factory method will
|
||||
* create the appropriate credentials object with appropriate decorators
|
||||
* based on the passed configuration options.
|
||||
*
|
||||
* @param array $config Options to use when instantiating the credentials
|
||||
*
|
||||
* @return CredentialsInterface
|
||||
* @throws InvalidArgumentException If the caching options are invalid
|
||||
* @throws RuntimeException If using the default cache and APC is disabled
|
||||
*/
|
||||
public static function factory($config = array())
|
||||
{
|
||||
// Add default key values
|
||||
foreach (self::getConfigDefaults() as $key => $value) {
|
||||
if (!isset($config[$key])) {
|
||||
$config[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the cache
|
||||
$cache = $config[Options::CREDENTIALS_CACHE];
|
||||
$cacheKey = $config[Options::CREDENTIALS_CACHE_KEY] ?:
|
||||
'credentials_' . ($config[Options::KEY] ?: crc32(gethostname()));
|
||||
|
||||
if (
|
||||
$cacheKey &&
|
||||
$cache instanceof CacheAdapterInterface &&
|
||||
$cached = self::createFromCache($cache, $cacheKey)
|
||||
) {
|
||||
return $cached;
|
||||
}
|
||||
|
||||
// Create the credentials object
|
||||
if (!$config[Options::KEY] || !$config[Options::SECRET]) {
|
||||
$credentials = self::createFromEnvironment($config);
|
||||
} else {
|
||||
// Instantiate using short or long term credentials
|
||||
$credentials = new static(
|
||||
$config[Options::KEY],
|
||||
$config[Options::SECRET],
|
||||
$config[Options::TOKEN],
|
||||
$config[Options::TOKEN_TTD]
|
||||
);
|
||||
}
|
||||
|
||||
// Check if the credentials are refreshable, and if so, configure caching
|
||||
$cache = $config[Options::CREDENTIALS_CACHE];
|
||||
if ($cacheKey && $cache) {
|
||||
$credentials = self::createCache($credentials, $cache, $cacheKey);
|
||||
}
|
||||
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create credentials from the credentials ini file in the HOME directory.
|
||||
*
|
||||
* @param string|null $profile Pass a specific profile to use. If no
|
||||
* profile is specified we will attempt to use
|
||||
* the value specified in the AWS_PROFILE
|
||||
* environment variable. If AWS_PROFILE is not
|
||||
* set, the "default" profile is used.
|
||||
* @param string|null $filename Pass a string to specify the location of the
|
||||
* credentials files. If null is passed, the
|
||||
* SDK will attempt to find the configuration
|
||||
* file at in your HOME directory at
|
||||
* ~/.aws/credentials.
|
||||
* @return CredentialsInterface
|
||||
* @throws \RuntimeException if the file cannot be found, if the file is
|
||||
* invalid, or if the profile is invalid.
|
||||
*/
|
||||
public static function fromIni($profile = null, $filename = null)
|
||||
{
|
||||
if (!$filename) {
|
||||
$filename = self::getHomeDir() . '/.aws/credentials';
|
||||
}
|
||||
|
||||
if (!$profile) {
|
||||
$profile = self::getEnvVar(self::ENV_PROFILE) ?: 'default';
|
||||
}
|
||||
|
||||
if (!is_readable($filename) || ($data = parse_ini_file($filename, true)) === false) {
|
||||
throw new \RuntimeException(esc_html("Invalid AWS credentials file: {$filename}."));
|
||||
}
|
||||
|
||||
if (!isset($data[$profile]['aws_access_key_id']) || !isset($data[$profile]['aws_secret_access_key'])) {
|
||||
throw new \RuntimeException(esc_html("Invalid AWS credentials profile {$profile} in {$filename}."));
|
||||
}
|
||||
|
||||
return new self(
|
||||
$data[$profile]['aws_access_key_id'],
|
||||
$data[$profile]['aws_secret_access_key'],
|
||||
isset($data[$profile]['aws_security_token'])
|
||||
? $data[$profile]['aws_security_token']
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new BasicAWSCredentials object, with the specified AWS
|
||||
* access key and AWS secret key
|
||||
*
|
||||
* @param string $accessKeyId AWS access key ID
|
||||
* @param string $secretAccessKey AWS secret access key
|
||||
* @param string $token Security token to use
|
||||
* @param int $expiration UNIX timestamp for when credentials expire
|
||||
*/
|
||||
public function __construct($accessKeyId, $secretAccessKey, $token = null, $expiration = null)
|
||||
{
|
||||
$this->key = trim($accessKeyId);
|
||||
$this->secret = trim($secretAccessKey);
|
||||
$this->token = $token;
|
||||
$this->ttd = $expiration;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return json_encode(array(
|
||||
Options::KEY => $this->key,
|
||||
Options::SECRET => $this->secret,
|
||||
Options::TOKEN => $this->token,
|
||||
Options::TOKEN_TTD => $this->ttd
|
||||
));
|
||||
}
|
||||
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$data = json_decode($serialized, true);
|
||||
$this->key = $data[Options::KEY];
|
||||
$this->secret = $data[Options::SECRET];
|
||||
$this->token = $data[Options::TOKEN];
|
||||
$this->ttd = $data[Options::TOKEN_TTD];
|
||||
}
|
||||
|
||||
public function getAccessKeyId()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getSecretKey()
|
||||
{
|
||||
return $this->secret;
|
||||
}
|
||||
|
||||
public function getSecurityToken()
|
||||
{
|
||||
return $this->token;
|
||||
}
|
||||
|
||||
public function getExpiration()
|
||||
{
|
||||
return $this->ttd;
|
||||
}
|
||||
|
||||
public function isExpired()
|
||||
{
|
||||
return $this->ttd !== null && time() >= $this->ttd;
|
||||
}
|
||||
|
||||
public function setAccessKeyId($key)
|
||||
{
|
||||
$this->key = $key;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSecretKey($secret)
|
||||
{
|
||||
$this->secret = $secret;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setSecurityToken($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setExpiration($timestamp)
|
||||
{
|
||||
$this->ttd = $timestamp;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* When no keys are provided, attempt to create them based on the
|
||||
* environment or instance profile credentials.
|
||||
*
|
||||
* @param array|Collection $config
|
||||
*
|
||||
* @return CredentialsInterface
|
||||
*/
|
||||
private static function createFromEnvironment($config)
|
||||
{
|
||||
// Get key and secret from ENV variables
|
||||
$envKey = self::getEnvVar(self::ENV_KEY);
|
||||
if (!($envSecret = self::getEnvVar(self::ENV_SECRET))) {
|
||||
// Use AWS_SECRET_ACCESS_KEY if AWS_SECRET_KEY was not set
|
||||
$envSecret = self::getEnvVar(self::ENV_SECRET_ACCESS_KEY);
|
||||
}
|
||||
|
||||
// Use credentials from the environment variables if available
|
||||
if ($envKey && $envSecret) {
|
||||
return new static($envKey, $envSecret);
|
||||
}
|
||||
|
||||
try {
|
||||
// Use credentials from the INI file in HOME directory if available
|
||||
return self::fromIni($config[Options::PROFILE]);
|
||||
} catch (\RuntimeException $e) {
|
||||
// Otherwise, try using instance profile credentials (available on EC2 instances)
|
||||
return new RefreshableInstanceProfileCredentials(
|
||||
new static('', '', '', 1),
|
||||
$config[Options::CREDENTIALS_CLIENT]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static function createFromCache(CacheAdapterInterface $cache, $cacheKey)
|
||||
{
|
||||
$cached = $cache->fetch($cacheKey);
|
||||
if ($cached instanceof CredentialsInterface && !$cached->isExpired()) {
|
||||
return new CacheableCredentials($cached, $cache, $cacheKey);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static function createCache(CredentialsInterface $credentials, $cache, $cacheKey)
|
||||
{
|
||||
if ($cache === 'true' || $cache === true) {
|
||||
// If no cache adapter was provided, then create one for the user
|
||||
// @codeCoverageIgnoreStart
|
||||
if (!extension_loaded('apc')) {
|
||||
throw new RequiredExtensionNotLoadedException('PHP has not been compiled with APC. Unable to cache '
|
||||
. 'the credentials.');
|
||||
} elseif (!class_exists('Doctrine\Common\Cache\ApcCache')) {
|
||||
throw new RuntimeException(
|
||||
'Cannot set ' . esc_html(Options::CREDENTIALS_CACHE) . ' to true because the Doctrine cache component is '
|
||||
. 'not installed. Either install doctrine/cache or pass in an instantiated '
|
||||
. 'Guzzle\Cache\CacheAdapterInterface object'
|
||||
);
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
$cache = new DoctrineCacheAdapter(new \Doctrine\Common\Cache\ApcCache());
|
||||
} elseif (!($cache instanceof CacheAdapterInterface)) {
|
||||
throw new InvalidArgumentException('Unable to utilize caching with the specified options');
|
||||
}
|
||||
|
||||
// Decorate the credentials with a cache
|
||||
return new CacheableCredentials($credentials, $cache, $cacheKey);
|
||||
}
|
||||
|
||||
private static function getHomeDir()
|
||||
{
|
||||
// On Linux/Unix-like systems, use the HOME environment variable
|
||||
if ($homeDir = self::getEnvVar('HOME')) {
|
||||
return $homeDir;
|
||||
}
|
||||
|
||||
// Get the HOMEDRIVE and HOMEPATH values for Windows hosts
|
||||
$homeDrive = self::getEnvVar('HOMEDRIVE');
|
||||
$homePath = self::getEnvVar('HOMEPATH');
|
||||
|
||||
return ($homeDrive && $homePath) ? $homeDrive . $homePath : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the value of an environment variable by checking $_SERVER and getenv().
|
||||
*
|
||||
* @param string $var Name of the environment variable
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
private static function getEnvVar($var)
|
||||
{
|
||||
return isset($_SERVER[$var]) ? $_SERVER[$var] : getenv($var);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
/**
|
||||
* Provides access to the AWS credentials used for accessing AWS services: AWS
|
||||
* access key ID, secret access key, and security token. These credentials are
|
||||
* used to securely sign requests to AWS services.
|
||||
*/
|
||||
interface CredentialsInterface extends \Serializable
|
||||
{
|
||||
/**
|
||||
* Returns the AWS access key ID for this credentials object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAccessKeyId();
|
||||
|
||||
/**
|
||||
* Returns the AWS secret access key for this credentials object.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSecretKey();
|
||||
|
||||
/**
|
||||
* Get the associated security token if available
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getSecurityToken();
|
||||
|
||||
/**
|
||||
* Get the UNIX timestamp in which the credentials will expire
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getExpiration();
|
||||
|
||||
/**
|
||||
* Set the AWS access key ID for this credentials object.
|
||||
*
|
||||
* @param string $key AWS access key ID
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setAccessKeyId($key);
|
||||
|
||||
/**
|
||||
* Set the AWS secret access key for this credentials object.
|
||||
*
|
||||
* @param string $secret AWS secret access key
|
||||
*
|
||||
* @return CredentialsInterface
|
||||
*/
|
||||
public function setSecretKey($secret);
|
||||
|
||||
/**
|
||||
* Set the security token to use with this credentials object
|
||||
*
|
||||
* @param string $token Security token
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setSecurityToken($token);
|
||||
|
||||
/**
|
||||
* Set the UNIX timestamp in which the credentials will expire
|
||||
*
|
||||
* @param int $timestamp UNIX timestamp expiration
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setExpiration($timestamp);
|
||||
|
||||
/**
|
||||
* Check if the credentials are expired
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isExpired();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
/**
|
||||
* A blank set of credentials. AWS clients must be provided credentials, but
|
||||
* there are some types of requests that do not need authentication. This class
|
||||
* can be used to pivot on that scenario, and also serve as a mock credentials
|
||||
* object when testing
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
class NullCredentials implements CredentialsInterface
|
||||
{
|
||||
public function getAccessKeyId()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getSecretKey()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getSecurityToken()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getExpiration()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isExpired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
return 'N;';
|
||||
}
|
||||
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
public function setAccessKeyId($key)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
public function setSecretKey($secret)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
public function setSecurityToken($token)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
|
||||
public function setExpiration($timestamp)
|
||||
{
|
||||
// Nothing to do here.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Credentials;
|
||||
|
||||
use Aws\Common\InstanceMetadata\InstanceMetadataClient;
|
||||
use Aws\Common\Exception\InstanceProfileCredentialsException;
|
||||
|
||||
/**
|
||||
* Credentials decorator used to implement retrieving credentials from the
|
||||
* EC2 metadata server
|
||||
*/
|
||||
class RefreshableInstanceProfileCredentials extends AbstractRefreshableCredentials
|
||||
{
|
||||
/**
|
||||
* @var InstanceMetadataClient
|
||||
*/
|
||||
protected $client;
|
||||
/** @var bool */
|
||||
private $customClient;
|
||||
|
||||
/**
|
||||
* Constructs a new instance profile credentials decorator
|
||||
*
|
||||
* @param CredentialsInterface $credentials Credentials to adapt
|
||||
* @param InstanceMetadataClient $client Client used to get new credentials
|
||||
*/
|
||||
public function __construct(CredentialsInterface $credentials, InstanceMetadataClient $client = null)
|
||||
{
|
||||
parent::__construct($credentials);
|
||||
$this->setClient($client);
|
||||
}
|
||||
|
||||
public function setClient(InstanceMetadataClient $client = null)
|
||||
{
|
||||
$this->customClient = null !== $client;
|
||||
$this->client = $client ?: InstanceMetadataClient::factory();
|
||||
}
|
||||
|
||||
public function serialize()
|
||||
{
|
||||
$serializable = array(
|
||||
'credentials' => parent::serialize(),
|
||||
'customClient' => $this->customClient,
|
||||
);
|
||||
|
||||
if ($this->customClient) {
|
||||
$serializable['client'] = serialize($this->client);
|
||||
}
|
||||
|
||||
return json_encode($serializable);
|
||||
}
|
||||
|
||||
public function unserialize($value)
|
||||
{
|
||||
$serialized = json_decode($value, true);
|
||||
parent::unserialize($serialized['credentials']);
|
||||
$this->customClient = $serialized['customClient'];
|
||||
$this->client = $this->customClient ?
|
||||
unserialize($serialized['client'])
|
||||
: InstanceMetadataClient::factory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get new credentials from the instance profile
|
||||
*
|
||||
* @throws InstanceProfileCredentialsException On error
|
||||
*/
|
||||
protected function refresh()
|
||||
{
|
||||
$credentials = $this->client->getInstanceProfileCredentials();
|
||||
// Expire the token 5 minutes early to pre-fetch before expiring.
|
||||
$this->credentials->setAccessKeyId($credentials->getAccessKeyId())
|
||||
->setSecretKey($credentials->getSecretKey())
|
||||
->setSecurityToken($credentials->getSecurityToken())
|
||||
->setExpiration($credentials->getExpiration() - 300);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common;
|
||||
|
||||
/**
|
||||
* Represents an enumerable set of values
|
||||
*/
|
||||
abstract class Enum
|
||||
{
|
||||
/**
|
||||
* @var array A cache of all enum values to increase performance
|
||||
*/
|
||||
protected static $cache = array();
|
||||
|
||||
/**
|
||||
* Returns the names (or keys) of all of constants in the enum
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function keys()
|
||||
{
|
||||
return array_keys(static::values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names and values of all the constants in the enum
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function values()
|
||||
{
|
||||
$class = get_called_class();
|
||||
|
||||
if (!isset(self::$cache[$class])) {
|
||||
$reflected = new \ReflectionClass($class);
|
||||
self::$cache[$class] = $reflected->getConstants();
|
||||
}
|
||||
|
||||
return self::$cache[$class];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Enum;
|
||||
|
||||
use Aws\Common\Enum;
|
||||
|
||||
/**
|
||||
* Contains enumerable default factory options that can be passed to a client's factory method
|
||||
*/
|
||||
class ClientOptions extends Enum
|
||||
{
|
||||
/**
|
||||
* AWS Access Key ID
|
||||
*
|
||||
* @deprecated Use "credentials" instead.
|
||||
*/
|
||||
const KEY = 'key';
|
||||
|
||||
/**
|
||||
* AWS secret access key
|
||||
*
|
||||
* @deprecated Use "credentials" instead.
|
||||
*/
|
||||
const SECRET = 'secret';
|
||||
|
||||
/**
|
||||
* Custom AWS security token to use with request authentication.
|
||||
*
|
||||
* @deprecated Use "credentials" instead.
|
||||
*/
|
||||
const TOKEN = 'token';
|
||||
|
||||
/**
|
||||
* Provide an array of "key", "secret", and "token" or an instance of
|
||||
* `Aws\Common\Credentials\CredentialsInterface`.
|
||||
*/
|
||||
const CREDENTIALS = 'credentials';
|
||||
|
||||
/**
|
||||
* @var string Name of a credential profile to read from your ~/.aws/credentials file
|
||||
*/
|
||||
const PROFILE = 'profile';
|
||||
|
||||
/**
|
||||
* @var string UNIX timestamp for when the custom credentials expire
|
||||
*/
|
||||
const TOKEN_TTD = 'token.ttd';
|
||||
|
||||
/**
|
||||
* @var string Used to cache credentials when using providers that require HTTP requests. Set the trueto use the
|
||||
* default APC cache or provide a `Guzzle\Cache\CacheAdapterInterface` object.
|
||||
*/
|
||||
const CREDENTIALS_CACHE = 'credentials.cache';
|
||||
|
||||
/**
|
||||
* @var string Optional custom cache key to use with the credentials
|
||||
*/
|
||||
const CREDENTIALS_CACHE_KEY = 'credentials.cache.key';
|
||||
|
||||
/**
|
||||
* @var string Pass this option to specify a custom `Guzzle\Http\ClientInterface` to use if your credentials require
|
||||
* a HTTP request (e.g. RefreshableInstanceProfileCredentials)
|
||||
*/
|
||||
const CREDENTIALS_CLIENT = 'credentials.client';
|
||||
|
||||
/**
|
||||
* @var string Region name (e.g. 'us-east-1', 'us-west-1', 'us-west-2', 'eu-west-1', etc...)
|
||||
*/
|
||||
const REGION = 'region';
|
||||
|
||||
/**
|
||||
* @var string URI Scheme of the base URL (e.g. 'https', 'http').
|
||||
*/
|
||||
const SCHEME = 'scheme';
|
||||
|
||||
/**
|
||||
* @var string Specify the name of the service
|
||||
*/
|
||||
const SERVICE = 'service';
|
||||
|
||||
/**
|
||||
* Instead of using a `region` and `scheme`, you can specify a custom base
|
||||
* URL for the client.
|
||||
*
|
||||
* @deprecated Use the "endpoint" option instead.
|
||||
*/
|
||||
const BASE_URL = 'base_url';
|
||||
|
||||
/**
|
||||
* @var string You can optionally provide a custom signature implementation used to sign requests
|
||||
*/
|
||||
const SIGNATURE = 'signature';
|
||||
|
||||
/**
|
||||
* @var string Set to explicitly override the service name used in signatures
|
||||
*/
|
||||
const SIGNATURE_SERVICE = 'signature.service';
|
||||
|
||||
/**
|
||||
* @var string Set to explicitly override the region name used in signatures
|
||||
*/
|
||||
const SIGNATURE_REGION = 'signature.region';
|
||||
|
||||
/**
|
||||
* @var string Option key holding an exponential backoff plugin
|
||||
*/
|
||||
const BACKOFF = 'client.backoff';
|
||||
|
||||
/**
|
||||
* @var string Option key holding the exponential backoff retries
|
||||
*/
|
||||
const BACKOFF_RETRIES = 'client.backoff.retries';
|
||||
|
||||
/**
|
||||
* @var string `Guzzle\Log\LogAdapterInterface` object used to log backoff retries. Use 'debug' to emit PHP
|
||||
* warnings when a retry is issued.
|
||||
*/
|
||||
const BACKOFF_LOGGER = 'client.backoff.logger';
|
||||
|
||||
/**
|
||||
* @var string Optional template to use for exponential backoff log messages. See
|
||||
* `Guzzle\Plugin\Backoff\BackoffLogger` for formatting information.
|
||||
*/
|
||||
const BACKOFF_LOGGER_TEMPLATE = 'client.backoff.logger.template';
|
||||
|
||||
/**
|
||||
* Set to true to use the bundled CA cert or pass the full path to an SSL
|
||||
* certificate bundle. This option should be modified when you encounter
|
||||
* curl error code 60. Set to "system" to use the cacert bundle on your
|
||||
* system.
|
||||
*/
|
||||
const SSL_CERT = 'ssl.certificate_authority';
|
||||
|
||||
/**
|
||||
* @var string Service description to use with the client
|
||||
*/
|
||||
const SERVICE_DESCRIPTION = 'service.description';
|
||||
|
||||
/**
|
||||
* @var string Whether or not modeled responses have transformations applied to them
|
||||
*/
|
||||
const MODEL_PROCESSING = 'command.model_processing';
|
||||
|
||||
/**
|
||||
* @var bool Set to false to disable validation
|
||||
*/
|
||||
const VALIDATION = 'validation';
|
||||
|
||||
/**
|
||||
* @var string API version used by the client
|
||||
*/
|
||||
const VERSION = 'version';
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Enum;
|
||||
|
||||
use Aws\Common\Enum;
|
||||
|
||||
/**
|
||||
* Contains enumerable date format values used in the SDK
|
||||
*/
|
||||
class DateFormat extends Enum
|
||||
{
|
||||
const ISO8601 = 'Ymd\THis\Z';
|
||||
const ISO8601_S3 = 'Y-m-d\TH:i:s\Z';
|
||||
const RFC1123 = 'D, d M Y H:i:s \G\M\T';
|
||||
const RFC2822 = \DateTime::RFC2822;
|
||||
const SHORT = 'Ymd';
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Enum;
|
||||
|
||||
use Aws\Common\Enum;
|
||||
|
||||
/**
|
||||
* Contains enumerable region code values. These should be useful in most cases,
|
||||
* with Amazon S3 being the most notable exception
|
||||
*
|
||||
* @link http://docs.aws.amazon.com/general/latest/gr/rande.html AWS Regions and Endpoints
|
||||
*/
|
||||
class Region extends Enum
|
||||
{
|
||||
const US_EAST_1 = 'us-east-1';
|
||||
const VIRGINIA = 'us-east-1';
|
||||
const NORTHERN_VIRGINIA = 'us-east-1';
|
||||
|
||||
const US_WEST_1 = 'us-west-1';
|
||||
const CALIFORNIA = 'us-west-1';
|
||||
const NORTHERN_CALIFORNIA = 'us-west-1';
|
||||
|
||||
const US_WEST_2 = 'us-west-2';
|
||||
const OREGON = 'us-west-2';
|
||||
|
||||
const EU_WEST_1 = 'eu-west-1';
|
||||
const IRELAND = 'eu-west-1';
|
||||
|
||||
const EU_CENTRAL_1 = 'eu-central-1';
|
||||
const FRANKFURT = 'eu-central-1';
|
||||
|
||||
const AP_SOUTHEAST_1 = 'ap-southeast-1';
|
||||
const SINGAPORE = 'ap-southeast-1';
|
||||
|
||||
const AP_SOUTHEAST_2 = 'ap-southeast-2';
|
||||
const SYDNEY = 'ap-southeast-2';
|
||||
|
||||
const AP_NORTHEAST_1 = 'ap-northeast-1';
|
||||
const TOKYO = 'ap-northeast-1';
|
||||
|
||||
const SA_EAST_1 = 'sa-east-1';
|
||||
const SAO_PAULO = 'sa-east-1';
|
||||
|
||||
const CN_NORTH_1 = 'cn-north-1';
|
||||
const BEIJING = 'cn-north-1';
|
||||
|
||||
const US_GOV_WEST_1 = 'us-gov-west-1';
|
||||
const GOV_CLOUD_US = 'us-gov-west-1';
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Enum;
|
||||
|
||||
use Aws\Common\Enum;
|
||||
|
||||
/**
|
||||
* Contains enumerable byte-size values
|
||||
*/
|
||||
class Size extends Enum
|
||||
{
|
||||
const B = 1;
|
||||
const BYTE = 1;
|
||||
const BYTES = 1;
|
||||
|
||||
const KB = 1024;
|
||||
const KILOBYTE = 1024;
|
||||
const KILOBYTES = 1024;
|
||||
|
||||
const MB = 1048576;
|
||||
const MEGABYTE = 1048576;
|
||||
const MEGABYTES = 1048576;
|
||||
|
||||
const GB = 1073741824;
|
||||
const GIGABYTE = 1073741824;
|
||||
const GIGABYTES = 1073741824;
|
||||
|
||||
const TB = 1099511627776;
|
||||
const TERABYTE = 1099511627776;
|
||||
const TERABYTES = 1099511627776;
|
||||
|
||||
const PB = 1125899906842624;
|
||||
const PETABYTE = 1125899906842624;
|
||||
const PETABYTES = 1125899906842624;
|
||||
|
||||
const EB = 1152921504606846976;
|
||||
const EXABYTE = 1152921504606846976;
|
||||
const EXABYTES = 1152921504606846976;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Enum;
|
||||
|
||||
use Aws\Common\Enum;
|
||||
|
||||
/**
|
||||
* Contains enumerable time values
|
||||
*/
|
||||
class Time extends Enum
|
||||
{
|
||||
const SECOND = 1;
|
||||
const SECONDS = 1;
|
||||
|
||||
const MINUTE = 60;
|
||||
const MINUTES = 60;
|
||||
|
||||
const HOUR = 3600;
|
||||
const HOURS = 3600;
|
||||
|
||||
const DAY = 86400;
|
||||
const DAYS = 86400;
|
||||
|
||||
const WEEK = 604800;
|
||||
const WEEKS = 604800;
|
||||
|
||||
const MONTH = 2592000;
|
||||
const MONTHS = 2592000;
|
||||
|
||||
const YEAR = 31557600;
|
||||
const YEARS = 31557600;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Enum;
|
||||
|
||||
use Aws\Common\Enum;
|
||||
|
||||
/**
|
||||
* User-Agent header strings for various high level operations
|
||||
*/
|
||||
class UaString extends Enum
|
||||
{
|
||||
/**
|
||||
* @var string Name of the option used to add to the UA string
|
||||
*/
|
||||
const OPTION = 'ua.append';
|
||||
|
||||
/**
|
||||
* @var string Resource iterator
|
||||
*/
|
||||
const ITERATOR = 'ITR';
|
||||
|
||||
/**
|
||||
* @var string Resource waiter
|
||||
*/
|
||||
const WAITER = 'WTR';
|
||||
|
||||
/**
|
||||
* @var string Session handlers (e.g. Amazon DynamoDB session handler)
|
||||
*/
|
||||
const SESSION = 'SES';
|
||||
|
||||
/**
|
||||
* @var string Multipart upload helper for Amazon S3
|
||||
*/
|
||||
const MULTIPART_UPLOAD = 'MUP';
|
||||
|
||||
/**
|
||||
* @var string Command executed during a batch transfer
|
||||
*/
|
||||
const BATCH = 'BAT';
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* "Marker Interface" implemented by every exception in the AWS SDK
|
||||
*/
|
||||
interface AwsExceptionInterface
|
||||
{
|
||||
public function getCode();
|
||||
public function getLine();
|
||||
public function getFile();
|
||||
public function getMessage();
|
||||
public function getPrevious();
|
||||
public function getTrace();
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL BadMethodCallException.
|
||||
*/
|
||||
class BadMethodCallException extends \BadMethodCallException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL DomainException.
|
||||
*/
|
||||
class DomainException extends \DomainException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Interface used to create AWS exception
|
||||
*/
|
||||
interface ExceptionFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Returns an AWS service specific exception
|
||||
*
|
||||
* @param RequestInterface $request Unsuccessful request
|
||||
* @param Response $response Unsuccessful response that was encountered
|
||||
*
|
||||
* @return \Exception|AwsExceptionInterface
|
||||
*/
|
||||
public function fromResponse(RequestInterface $request, Response $response);
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Guzzle\Common\Event;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* Converts generic Guzzle response exceptions into AWS specific exceptions
|
||||
*/
|
||||
class ExceptionListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var ExceptionFactoryInterface Factory used to create new exceptions
|
||||
*/
|
||||
protected $factory;
|
||||
|
||||
/**
|
||||
* @param ExceptionFactoryInterface $factory Factory used to create exceptions
|
||||
*/
|
||||
public function __construct(ExceptionFactoryInterface $factory)
|
||||
{
|
||||
$this->factory = $factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array('request.error' => array('onRequestError', -1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws a more meaningful request exception if available
|
||||
*
|
||||
* @param Event $event Event emitted
|
||||
*/
|
||||
public function onRequestError(Event $event)
|
||||
{
|
||||
$e = $this->factory->fromResponse($event['request'], $event['response']);
|
||||
$event->stopPropagation();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Aws\Common\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Exception thrown when an error occurs with instance profile credentials
|
||||
*/
|
||||
class InstanceProfileCredentialsException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $statusCode;
|
||||
|
||||
/**
|
||||
* Set the error response code received from the instance metadata
|
||||
*
|
||||
* @param string $code Response code
|
||||
*/
|
||||
public function setStatusCode($code)
|
||||
{
|
||||
$this->statusCode = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error response code from the service
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->statusCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL InvalidArgumentException.
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL LogicException.
|
||||
*/
|
||||
class LogicException extends \LogicException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Aws\Common\Model\MultipartUpload\TransferStateInterface;
|
||||
|
||||
/**
|
||||
* Thrown when a {@see Aws\Common\MultipartUpload\TransferInterface} object encounters an error during transfer
|
||||
*/
|
||||
class MultipartUploadException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var TransferStateInterface State of the transfer when the error was encountered
|
||||
*/
|
||||
protected $state;
|
||||
|
||||
/**
|
||||
* @param TransferStateInterface $state Transfer state
|
||||
* @param \Exception $exception Last encountered exception
|
||||
*/
|
||||
public function __construct(TransferStateInterface $state, \Exception $exception = null)
|
||||
{
|
||||
parent::__construct(
|
||||
'An error was encountered while performing a multipart upload: ' . $exception->getMessage(),
|
||||
0,
|
||||
$exception
|
||||
);
|
||||
|
||||
$this->state = $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of the transfer
|
||||
*
|
||||
* @return TransferStateInterface
|
||||
*/
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Aws\Common\Exception\Parser\ExceptionParserInterface;
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Attempts to create exceptions by inferring the name from the code and a base
|
||||
* namespace that contains exceptions. Exception classes are expected to be in
|
||||
* upper camelCase and always end in 'Exception'. 'Exception' will be appended
|
||||
* if it is not present in the exception code.
|
||||
*/
|
||||
class NamespaceExceptionFactory implements ExceptionFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @var ExceptionParserInterface $parser Parser used to parse responses
|
||||
*/
|
||||
protected $parser;
|
||||
|
||||
/**
|
||||
* @var string Base namespace containing exception classes
|
||||
*/
|
||||
protected $baseNamespace;
|
||||
|
||||
/**
|
||||
* @var string Default class to instantiate if a match is not found
|
||||
*/
|
||||
protected $defaultException;
|
||||
|
||||
/**
|
||||
* @param ExceptionParserInterface $parser Parser used to parse exceptions
|
||||
* @param string $baseNamespace Namespace containing exceptions
|
||||
* @param string $defaultException Default class to use if one is not mapped
|
||||
*/
|
||||
public function __construct(
|
||||
ExceptionParserInterface $parser,
|
||||
$baseNamespace,
|
||||
$defaultException = 'Aws\Common\Exception\ServiceResponseException'
|
||||
) {
|
||||
$this->parser = $parser;
|
||||
$this->baseNamespace = $baseNamespace;
|
||||
$this->defaultException = $defaultException;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function fromResponse(RequestInterface $request, Response $response)
|
||||
{
|
||||
$parts = $this->parser->parse($request, $response);
|
||||
|
||||
// Removing leading 'AWS.' and embedded periods
|
||||
$className = $this->baseNamespace . '\\' . str_replace(array('AWS.', '.'), '', $parts['code']);
|
||||
if (substr($className, -9) !== 'Exception') {
|
||||
$className .= 'Exception';
|
||||
}
|
||||
|
||||
$className = class_exists($className) ? $className : $this->defaultException;
|
||||
|
||||
return $this->createException($className, $request, $response, $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an prepare an exception object
|
||||
*
|
||||
* @param string $className Name of the class to create
|
||||
* @param RequestInterface $request Request
|
||||
* @param Response $response Response received
|
||||
* @param array $parts Parsed exception data
|
||||
*
|
||||
* @return \Exception
|
||||
*/
|
||||
protected function createException($className, RequestInterface $request, Response $response, array $parts)
|
||||
{
|
||||
$class = new $className($parts['message']);
|
||||
|
||||
if ($class instanceof ServiceResponseException) {
|
||||
$class->setExceptionCode($parts['code']);
|
||||
$class->setExceptionType($parts['type']);
|
||||
$class->setResponse($response);
|
||||
$class->setRequest($request);
|
||||
$class->setRequestId($parts['request_id']);
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL OverflowException.
|
||||
*/
|
||||
class OutOfBoundsException extends \OutOfBoundsException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL OverflowException.
|
||||
*/
|
||||
class OverflowException extends \OverflowException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception\Parser;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Parses JSON encoded exception responses
|
||||
*/
|
||||
abstract class AbstractJsonExceptionParser implements ExceptionParserInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function parse(RequestInterface $request, Response $response)
|
||||
{
|
||||
// Build array of default error data
|
||||
$data = array(
|
||||
'code' => null,
|
||||
'message' => null,
|
||||
'type' => $response->isClientError() ? 'client' : 'server',
|
||||
'request_id' => (string) $response->getHeader('x-amzn-RequestId'),
|
||||
'parsed' => null
|
||||
);
|
||||
|
||||
// Parse the json and normalize key casings
|
||||
if (null !== $json = json_decode($response->getBody(true), true)) {
|
||||
$data['parsed'] = array_change_key_case($json);
|
||||
}
|
||||
|
||||
// Do additional, protocol-specific parsing and return the result
|
||||
$data = $this->doParse($data, $response);
|
||||
|
||||
// Remove "Fault" suffix from exception names
|
||||
if (isset($data['code']) && strpos($data['code'], 'Fault')) {
|
||||
$data['code'] = preg_replace('/^([a-zA-Z]+)Fault$/', '$1', $data['code']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull relevant exception data out of the parsed json
|
||||
*
|
||||
* @param array $data The exception data
|
||||
* @param Response $response The response from the service containing the error
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract protected function doParse(array $data, Response $response);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception\Parser;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Parses default XML exception responses
|
||||
*/
|
||||
class DefaultXmlExceptionParser implements ExceptionParserInterface
|
||||
{
|
||||
public function parse(RequestInterface $request, Response $response)
|
||||
{
|
||||
$data = array(
|
||||
'code' => null,
|
||||
'message' => null,
|
||||
'type' => $response->isClientError() ? 'client' : 'server',
|
||||
'request_id' => null,
|
||||
'parsed' => null
|
||||
);
|
||||
|
||||
$body = $response->getBody(true);
|
||||
|
||||
if (!$body) {
|
||||
$this->parseHeaders($request, $response, $data);
|
||||
return $data;
|
||||
}
|
||||
|
||||
try {
|
||||
$xml = new \SimpleXMLElement($body);
|
||||
$this->parseBody($xml, $data);
|
||||
return $data;
|
||||
} catch (\Exception $e) {
|
||||
// Gracefully handle parse errors. This could happen when the
|
||||
// server responds with a non-XML response (e.g., private beta
|
||||
// services).
|
||||
$data['code'] = 'PhpInternalXmlParseError';
|
||||
$data['message'] = 'A non-XML response was received';
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses additional exception information from the response headers
|
||||
*
|
||||
* @param RequestInterface $request Request that was issued
|
||||
* @param Response $response The response from the request
|
||||
* @param array $data The current set of exception data
|
||||
*/
|
||||
protected function parseHeaders(RequestInterface $request, Response $response, array &$data)
|
||||
{
|
||||
$data['message'] = $response->getStatusCode() . ' ' . $response->getReasonPhrase();
|
||||
if ($requestId = $response->getHeader('x-amz-request-id')) {
|
||||
$data['request_id'] = $requestId;
|
||||
$data['message'] .= " (Request-ID: $requestId)";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses additional exception information from the response body
|
||||
*
|
||||
* @param \SimpleXMLElement $body The response body as XML
|
||||
* @param array $data The current set of exception data
|
||||
*/
|
||||
protected function parseBody(\SimpleXMLElement $body, array &$data)
|
||||
{
|
||||
$data['parsed'] = $body;
|
||||
|
||||
$namespaces = $body->getDocNamespaces();
|
||||
if (isset($namespaces[''])) {
|
||||
// Account for the default namespace being defined and PHP not being able to handle it :(
|
||||
$body->registerXPathNamespace('ns', $namespaces['']);
|
||||
$prefix = 'ns:';
|
||||
} else {
|
||||
$prefix = '';
|
||||
}
|
||||
|
||||
if ($tempXml = $body->xpath("//{$prefix}Code[1]")) {
|
||||
$data['code'] = (string) $tempXml[0];
|
||||
}
|
||||
|
||||
if ($tempXml = $body->xpath("//{$prefix}Message[1]")) {
|
||||
$data['message'] = (string) $tempXml[0];
|
||||
}
|
||||
|
||||
$tempXml = $body->xpath("//{$prefix}RequestId[1]");
|
||||
if (empty($tempXml)) {
|
||||
$tempXml = $body->xpath("//{$prefix}RequestID[1]");
|
||||
}
|
||||
if (isset($tempXml[0])) {
|
||||
$data['request_id'] = (string) $tempXml[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception\Parser;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Interface used to parse exceptions into an associative array of data
|
||||
*/
|
||||
interface ExceptionParserInterface
|
||||
{
|
||||
/**
|
||||
* Parses an exception into an array of data containing at minimum the
|
||||
* following array keys:
|
||||
* - type: Exception type
|
||||
* - code: Exception code
|
||||
* - message: Exception message
|
||||
* - request_id: Request ID
|
||||
* - parsed: The parsed representation of the data (array, SimpleXMLElement, etc)
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
* @param Response $response Unsuccessful response
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function parse(RequestInterface $request, Response $response);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception\Parser;
|
||||
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Parses JSON encoded exception responses from query services
|
||||
*/
|
||||
class JsonQueryExceptionParser extends AbstractJsonExceptionParser
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doParse(array $data, Response $response)
|
||||
{
|
||||
if ($json = $data['parsed']) {
|
||||
if (isset($json['__type'])) {
|
||||
$parts = explode('#', $json['__type']);
|
||||
$data['code'] = isset($parts[1]) ? $parts[1] : $parts[0];
|
||||
}
|
||||
$data['message'] = isset($json['message']) ? $json['message'] : null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception\Parser;
|
||||
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Parses JSON encoded exception responses from REST services
|
||||
*/
|
||||
class JsonRestExceptionParser extends AbstractJsonExceptionParser
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doParse(array $data, Response $response)
|
||||
{
|
||||
// Merge in error data from the JSON body
|
||||
if ($json = $data['parsed']) {
|
||||
$data = array_replace($data, $json);
|
||||
}
|
||||
|
||||
// Correct error type from services like Amazon Glacier
|
||||
if (!empty($data['type'])) {
|
||||
$data['type'] = strtolower($data['type']);
|
||||
}
|
||||
|
||||
// Retrieve the error code from services like Amazon Elastic Transcoder
|
||||
if ($code = (string) $response->getHeader('x-amzn-ErrorType')) {
|
||||
$data['code'] = substr($code, 0, strpos($code, ':'));
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when a particular PHP extension is required to execute the guarded logic, but the extension is not loaded
|
||||
*/
|
||||
class RequiredExtensionNotLoadedException extends RuntimeException {}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL RuntimeException.
|
||||
*/
|
||||
class RuntimeException extends \RuntimeException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Guzzle\Http\Message\RequestInterface;
|
||||
use Guzzle\Http\Message\Response;
|
||||
|
||||
/**
|
||||
* Default AWS exception
|
||||
*/
|
||||
class ServiceResponseException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* @var Response Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var RequestInterface Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var string Request ID
|
||||
*/
|
||||
protected $requestId;
|
||||
|
||||
/**
|
||||
* @var string Exception type (client / server)
|
||||
*/
|
||||
protected $exceptionType;
|
||||
|
||||
/**
|
||||
* @var string Exception code
|
||||
*/
|
||||
protected $exceptionCode;
|
||||
|
||||
/**
|
||||
* Set the exception code
|
||||
*
|
||||
* @param string $code Exception code
|
||||
*/
|
||||
public function setExceptionCode($code)
|
||||
{
|
||||
$this->exceptionCode = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception code
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExceptionCode()
|
||||
{
|
||||
return $this->exceptionCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the exception type
|
||||
*
|
||||
* @param string $type Exception type
|
||||
*/
|
||||
public function setExceptionType($type)
|
||||
{
|
||||
$this->exceptionType = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the exception type (one of client or server)
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getExceptionType()
|
||||
{
|
||||
return $this->exceptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the request ID
|
||||
*
|
||||
* @param string $id Request ID
|
||||
*/
|
||||
public function setRequestId($id)
|
||||
{
|
||||
$this->requestId = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Request ID
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRequestId()
|
||||
{
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated response
|
||||
*
|
||||
* @param Response $response Response
|
||||
*/
|
||||
public function setResponse(Response $response)
|
||||
{
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated response object
|
||||
*
|
||||
* @return Response|null
|
||||
*/
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the associated request
|
||||
*
|
||||
* @param RequestInterface $request
|
||||
*/
|
||||
public function setRequest(RequestInterface $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the associated request object
|
||||
*
|
||||
* @return RequestInterface|null
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the status code of the response
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getStatusCode()
|
||||
{
|
||||
return $this->response ? $this->response->getStatusCode() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$message = get_class($this) . ': '
|
||||
. 'AWS Error Code: ' . $this->getExceptionCode() . ', '
|
||||
. 'Status Code: ' . $this->getStatusCode() . ', '
|
||||
. 'AWS Request ID: ' . $this->getRequestId() . ', '
|
||||
. 'AWS Error Type: ' . $this->getExceptionType() . ', '
|
||||
. 'AWS Error Message: ' . $this->getMessage();
|
||||
|
||||
// Add the User-Agent if available
|
||||
if ($this->request) {
|
||||
$message .= ', ' . 'User-Agent: ' . $this->request->getHeader('User-Agent');
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the request ID of the error. This value is only present if a
|
||||
* response was received, and is not present in the event of a networking
|
||||
* error.
|
||||
*
|
||||
* Same as `getRequestId()` method, but matches the interface for SDKv3.
|
||||
*
|
||||
* @return string|null Returns null if no response was received
|
||||
*/
|
||||
public function getAwsRequestId()
|
||||
{
|
||||
return $this->requestId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AWS error type.
|
||||
*
|
||||
* Same as `getExceptionType()` method, but matches the interface for SDKv3.
|
||||
*
|
||||
* @return string|null Returns null if no response was received
|
||||
*/
|
||||
public function getAwsErrorType()
|
||||
{
|
||||
return $this->exceptionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the AWS error code.
|
||||
*
|
||||
* Same as `getExceptionCode()` method, but matches the interface for SDKv3.
|
||||
*
|
||||
* @return string|null Returns null if no response was received
|
||||
*/
|
||||
public function getAwsErrorCode()
|
||||
{
|
||||
return $this->exceptionCode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
use Guzzle\Http\Exception\CurlException;
|
||||
|
||||
/**
|
||||
* Transfer request exception
|
||||
*/
|
||||
class TransferException extends CurlException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Exception;
|
||||
|
||||
/**
|
||||
* AWS SDK namespaced version of the SPL UnexpectedValueException.
|
||||
*/
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements AwsExceptionInterface {}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Facade;
|
||||
|
||||
use Aws\Common\Aws;
|
||||
|
||||
/**
|
||||
* Base facade class that handles the delegation logic
|
||||
*
|
||||
* @deprecated "Facades" are being removed in version 3.0 of the SDK.
|
||||
*/
|
||||
abstract class Facade implements FacadeInterface
|
||||
{
|
||||
/** @var Aws */
|
||||
protected static $serviceBuilder;
|
||||
|
||||
/**
|
||||
* Mounts the facades by extracting information from the service builder config and using creating class aliases
|
||||
*
|
||||
* @param string|null $targetNamespace Namespace that the facades should be mounted to. Defaults to global namespace
|
||||
*
|
||||
* @param Aws $serviceBuilder
|
||||
*/
|
||||
public static function mountFacades(Aws $serviceBuilder, $targetNamespace = null)
|
||||
{
|
||||
self::$serviceBuilder = $serviceBuilder;
|
||||
require_once __DIR__ . '/facade-classes.php';
|
||||
foreach ($serviceBuilder->getConfig() as $service) {
|
||||
if (isset($service['alias'], $service['class'])) {
|
||||
$facadeClass = __NAMESPACE__ . '\\' . $service['alias'];
|
||||
$facadeAlias = ltrim($targetNamespace . '\\' . $service['alias'], '\\');
|
||||
if (!class_exists($facadeAlias) && class_exists($facadeClass)) {
|
||||
// @codeCoverageIgnoreStart
|
||||
class_alias($facadeClass, $facadeAlias);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of the client that the facade operates on
|
||||
*
|
||||
* @return \Aws\Common\Client\AwsClientInterface
|
||||
*/
|
||||
public static function getClient()
|
||||
{
|
||||
return self::$serviceBuilder->get(static::getServiceBuilderKey());
|
||||
}
|
||||
|
||||
public static function __callStatic($method, $args)
|
||||
{
|
||||
return call_user_func_array(array(self::getClient(), $method), $args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2010-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file is distributed
|
||||
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||
* express or implied. See the License for the specific language governing
|
||||
* permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
namespace Aws\Common\Facade;
|
||||
|
||||
/**
|
||||
* Interface that defines a client facade. Facades are convenient static classes that allow you to run client methods
|
||||
* statically on a default instance from the service builder. The facades themselves are aliased into the global
|
||||
* namespace for ease of use.
|
||||
*
|
||||
* @deprecated "Facades" are being removed in version 3.0 of the SDK.
|
||||
*/
|
||||
interface FacadeInterface
|
||||
{
|
||||
/**
|
||||
* Returns the key used to access the client instance from the Service Builder
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getServiceBuilderKey();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user