Version Description
- 12/29/2012 =
- Big code re-factoring; moving towards modularising cloud access methods
Download this release
Release Info
Developer | DavidAnderson |
Plugin | UpdraftPlus WordPress Backup Plugin |
Version | 1.0.20 |
Comparing to | |
See all releases |
Code changes from version 1.0.18 to 1.0.20
- methods/email.php +15 -7
- methods/ftp.php +68 -32
- methods/googledrive.php +285 -138
- methods/s3.php +146 -88
- readme.txt +2 -2
- updraftplus.php +103 -334
methods/email.php
CHANGED
@@ -2,17 +2,25 @@
|
|
2 |
|
3 |
// Files can easily get way too big for this method
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
}
|
14 |
|
15 |
-
$updraftplus->prune_retained_backups("local");
|
16 |
}
|
17 |
|
18 |
?>
|
2 |
|
3 |
// Files can easily get way too big for this method
|
4 |
|
5 |
+
class UpdraftPlus_BackupModule_email {
|
6 |
|
7 |
+
function backup($backup_array) {
|
8 |
|
9 |
+
global $updraftplus;
|
10 |
+
|
11 |
+
foreach ($backup_array as $type => $file) {
|
12 |
+
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
13 |
+
wp_mail(get_option('updraft_email'), "WordPress Backup ".date('Y-m-d H:i',$updraftplus->backup_time), "Backup is of the $type. Be wary; email backups may fail because of file size limitations on mail servers.", null, array($fullpath));
|
14 |
+
$updraftplus->uploaded_file($file);
|
15 |
+
}
|
16 |
+
|
17 |
+
$updraftplus->prune_retained_backups("local");
|
18 |
+
}
|
19 |
+
|
20 |
+
function config_print() {
|
21 |
+
return false;
|
22 |
}
|
23 |
|
|
|
24 |
}
|
25 |
|
26 |
?>
|
methods/ftp.php
CHANGED
@@ -1,44 +1,80 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
$
|
18 |
-
|
19 |
-
$
|
20 |
-
$
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
24 |
}
|
|
|
|
|
25 |
}
|
26 |
|
27 |
-
$
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
-
function updraftplus_download_ftp_backup($file) {
|
31 |
-
if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
|
32 |
-
|
33 |
-
//handle SSL and errors at some point TODO
|
34 |
-
$ftp = new ftp_wrapper(get_option('updraft_server_address'),get_option('updraft_ftp_login'),get_option('updraft_ftp_pass'));
|
35 |
-
$ftp->passive = true;
|
36 |
-
$ftp->connect();
|
37 |
-
//$ftp->make_dir(); we may need to recursively create dirs? TODO
|
38 |
-
|
39 |
-
$ftp_remote_path = trailingslashit(get_option('updraft_ftp_remote_path'));
|
40 |
-
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
41 |
-
$ftp->get($fullpath,$ftp_remote_path.$file,FTP_BINARY);
|
42 |
}
|
43 |
|
44 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
class UpdraftPlus_BackupModule_ftp {
|
4 |
|
5 |
+
function backup($backup_array) {
|
6 |
|
7 |
+
global $updraftplus;
|
8 |
|
9 |
+
if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
|
10 |
+
|
11 |
+
//handle SSL and errors at some point TODO
|
12 |
+
$ftp = new ftp_wrapper(get_option('updraft_server_address'), get_option('updraft_ftp_login'), get_option('updraft_ftp_pass'));
|
13 |
+
$ftp->passive = true;
|
14 |
+
$ftp->connect();
|
15 |
+
//$ftp->make_dir(); we may need to recursively create dirs? TODO
|
16 |
+
|
17 |
+
$ftp_remote_path = trailingslashit(get_option('updraft_ftp_remote_path'));
|
18 |
+
foreach($backup_array as $file) {
|
19 |
+
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
20 |
+
if ($ftp->put($fullpath,$ftp_remote_path.$file,FTP_BINARY)) {
|
21 |
+
$updraftplus->log("ERROR: $file_name: Successfully uploaded via FTP");
|
22 |
+
$updraftplus->uploaded_file($file);
|
23 |
+
} else {
|
24 |
+
$updraftplus->error("$file_name: Failed to upload to FTP" );
|
25 |
+
$updraftplus->log("ERROR: $file_name: Failed to upload to FTP" );
|
26 |
+
}
|
27 |
}
|
28 |
+
|
29 |
+
$updraftplus->prune_retained_backups("ftp", $this, array('ftp_object' => $ftp, 'ftp_remote_path' => $ftp_remote_path));
|
30 |
}
|
31 |
|
32 |
+
function delete($file, $ftparr) {
|
33 |
+
$ftp = $ftparr['ftp_object'];
|
34 |
+
$ftp_remote_path = $ftparr['ftp_remote_path'];
|
35 |
+
@$ftp->delete($ftp_remote_path.$file);
|
36 |
+
}
|
37 |
+
|
38 |
+
function download($file) {
|
39 |
+
if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
|
40 |
+
|
41 |
+
//handle SSL and errors at some point TODO
|
42 |
+
$ftp = new ftp_wrapper(get_option('updraft_server_address'),get_option('updraft_ftp_login'),get_option('updraft_ftp_pass'));
|
43 |
+
$ftp->passive = true;
|
44 |
+
$ftp->connect();
|
45 |
+
//$ftp->make_dir(); we may need to recursively create dirs? TODO
|
46 |
+
|
47 |
+
$ftp_remote_path = trailingslashit(get_option('updraft_ftp_remote_path'));
|
48 |
+
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
49 |
+
$ftp->get($fullpath,$ftp_remote_path.$file,FTP_BINARY);
|
50 |
+
}
|
51 |
+
|
52 |
+
function config_print() {
|
53 |
+
?>
|
54 |
+
<tr class="updraftplusmethod ftp">
|
55 |
+
<th>FTP Server:</th>
|
56 |
+
<td><input type="text" style="width:260px" name="updraft_server_address" value="<?php echo htmlspecialchars(get_option('updraft_server_address')); ?>" /></td>
|
57 |
+
</tr>
|
58 |
+
<tr class="updraftplusmethod ftp">
|
59 |
+
<th>FTP Login:</th>
|
60 |
+
<td><input type="text" autocomplete="off" name="updraft_ftp_login" value="<?php echo htmlspecialchars(get_option('updraft_ftp_login')) ?>" /></td>
|
61 |
+
</tr>
|
62 |
+
<tr class="updraftplusmethod ftp">
|
63 |
+
<th>FTP Password:</th>
|
64 |
+
<td><input type="text" autocomplete="off" style="width:260px" name="updraft_ftp_pass" value="<?php echo htmlspecialchars(get_option('updraft_ftp_pass')); ?>" /></td>
|
65 |
+
</tr>
|
66 |
+
<tr class="updraftplusmethod ftp">
|
67 |
+
<th>Remote Path:</th>
|
68 |
+
<td><input type="text" style="width:260px" name="updraft_ftp_remote_path" value="<?php echo htmlspecialchars(get_option('updraft_ftp_remote_path')); ?>" /></td>
|
69 |
+
</tr>
|
70 |
+
<?php
|
71 |
+
}
|
72 |
+
|
73 |
+
function file_delete() {
|
74 |
+
$this->log("$backup_datestamp: Delete remote ftp: $remote_path/$dofile");
|
75 |
+
@$remote_object->delete($remote_path.$dofile);
|
76 |
+
}
|
77 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
}
|
79 |
|
80 |
?>
|
methods/googledrive.php
CHANGED
@@ -1,190 +1,337 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
-
|
|
|
11 |
|
12 |
-
|
13 |
-
|
14 |
-
$updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
15 |
-
return new WP_Error( "no_access_token", "Have not yet obtained an access token from Google (has the user authorised?");
|
16 |
-
}
|
17 |
|
18 |
-
|
|
|
19 |
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
$timer_start = microtime(true);
|
25 |
-
if ( $id = updraftplus_googledrive_upload_file( $file_path, $file_name, get_option('updraft_googledrive_remotepath')) ) {
|
26 |
-
$updraftplus->log('OK: Archive ' . $file_name . ' uploaded to Google Drive in ' . ( round(microtime( true ) - $timer_start,2) ) . ' seconds (id: '.$id.')' );
|
27 |
-
$updraftplus->uploaded_file($file, $id);
|
28 |
} else {
|
29 |
-
$
|
30 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
}
|
32 |
}
|
33 |
-
$updraftplus->prune_retained_backups("googledrive",$access_token,get_option('updraft_googledrive_remotepath'));
|
34 |
-
}
|
35 |
|
36 |
-
//
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
$hash = md5($file);
|
49 |
-
$transkey = 'upd_'.$hash.'_gloc';
|
50 |
-
// This is unset upon completion, so if it is set then we are resuming
|
51 |
-
$possible_location = get_transient($transkey);
|
52 |
-
|
53 |
-
if ( empty( $possible_location ) ) {
|
54 |
-
$updraftplus->log("$file: Attempting to upload file to Google Drive.");
|
55 |
-
$location = $gdocs_object->prepare_upload( $file, $title, $parent );
|
56 |
-
} else {
|
57 |
-
$updraftplus->log("$file: Attempting to resume upload.");
|
58 |
-
$location = $gdocs_object->resume_upload( $file, $possible_location );
|
59 |
}
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
}
|
67 |
-
return false;
|
68 |
}
|
69 |
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
$
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
}
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
}
|
99 |
-
return false;
|
100 |
}
|
|
|
|
|
101 |
|
102 |
-
|
|
|
|
|
|
|
|
|
103 |
|
104 |
-
|
105 |
-
// unset( $this->options['backup_list'][$id]['location'], $this->options['backup_list'][$id]['attempt'] );
|
106 |
-
}
|
107 |
|
108 |
-
|
|
|
|
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
//
|
|
|
113 |
|
114 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
|
116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
|
122 |
-
// Do we have an access token?
|
123 |
-
if ( !$access_token = $updraftplus->access_token( get_option('updraft_googledrive_token'), get_option('updraft_googledrive_clientid'), get_option('updraft_googledrive_secret') )) {
|
124 |
-
$updraftplus->error('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
125 |
-
return false;
|
126 |
}
|
127 |
|
128 |
-
$
|
129 |
|
130 |
-
|
131 |
-
if ( is_wp_error( $e = updraftplus_need_gdocs() ) ) return false;
|
132 |
-
$gdocs_object = $updraftplus->gdocs;
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
$content_link = $gdocs_object->get_content_link( $ids[$file], $file );
|
140 |
-
if (is_wp_error($content_link)) {
|
141 |
-
$updraftplus->error("Could not find $file in order to download it (id: ".$ids[$file].")");
|
142 |
-
foreach ($content_link->get_error_messages() as $msg) $updraftplus->error($msg);
|
143 |
return false;
|
144 |
}
|
145 |
-
// Actually download the thing
|
146 |
-
$download_to = trailingslashit(get_option('updraft_dir')).$file;
|
147 |
-
$gdocs_object->download_data($content_link, $download_to);
|
148 |
|
149 |
-
|
150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
} else {
|
152 |
-
$
|
153 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
}
|
155 |
|
|
|
|
|
156 |
}
|
157 |
|
158 |
-
|
|
|
159 |
|
160 |
-
|
161 |
|
162 |
-
|
163 |
-
|
|
|
|
|
|
|
164 |
|
165 |
-
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
$
|
170 |
-
|
171 |
}
|
|
|
|
|
172 |
|
173 |
-
|
|
|
|
|
|
|
|
|
174 |
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
}
|
180 |
-
return true;
|
181 |
-
}
|
182 |
|
183 |
-
// This function taken from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
|
184 |
-
function updraftplus_is_gdocs( $thing ) {
|
185 |
-
if ( is_object( $thing ) && is_a( $thing, 'UpdraftPlus_GDocs' ) ) return true;
|
186 |
-
return false;
|
187 |
}
|
188 |
|
189 |
-
|
190 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
class UpdraftPlus_BackupModule_googledrive {
|
4 |
+
|
5 |
+
var $gdocs;
|
6 |
+
var $gdocs_access_token;
|
7 |
+
|
8 |
+
function action_auth() {
|
9 |
+
if ( isset( $_GET['state'] ) ) {
|
10 |
+
if ( $_GET['state'] == 'token' )
|
11 |
+
$this->gdrive_auth_token();
|
12 |
+
elseif ( $_GET['state'] == 'revoke' )
|
13 |
+
$this->gdrive_auth_revoke();
|
14 |
+
} elseif (isset($_GET['updraftplus_googleauth'])) {
|
15 |
+
$this->gdrive_auth_request();
|
16 |
+
}
|
17 |
+
}
|
18 |
|
19 |
+
// Get a Google account access token using the refresh token
|
20 |
+
function access_token( $token, $client_id, $client_secret ) {
|
21 |
|
22 |
+
global $updraftplus;
|
23 |
+
$updraftplus->log("Google Drive: requesting access token: client_id=$client_id");
|
|
|
|
|
|
|
24 |
|
25 |
+
$query_body = array( 'refresh_token' => $token, 'client_id' => $client_id, 'client_secret' => $client_secret, 'grant_type' => 'refresh_token' );
|
26 |
+
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => '15', 'method' => 'POST', 'body' => $query_body) );
|
27 |
|
28 |
+
if (is_wp_error($result)) {
|
29 |
+
$updraftplus->log("Google Drive error when requesting access token");
|
30 |
+
foreach ($result->get_error_messages() as $msg) { $updraftplus->log("Error message: $msg"); }
|
31 |
+
return false;
|
|
|
|
|
|
|
|
|
32 |
} else {
|
33 |
+
$json_values = json_decode( $result['body'], true );
|
34 |
+
if ( isset( $json_values['access_token'] ) ) {
|
35 |
+
$updraftplus->log("Google Drive: successfully obtained access token");
|
36 |
+
return $json_values['access_token'];
|
37 |
+
} else {
|
38 |
+
$updraftplus->log("Google Drive error when requesting access token: response does not contain access_token");
|
39 |
+
return false;
|
40 |
+
}
|
41 |
}
|
42 |
}
|
|
|
|
|
43 |
|
44 |
+
// Acquire single-use authorization code from Google OAuth 2.0
|
45 |
+
function gdrive_auth_request() {
|
46 |
+
$params = array(
|
47 |
+
'response_type' => 'code',
|
48 |
+
'client_id' => get_option('updraft_googledrive_clientid'),
|
49 |
+
'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'),
|
50 |
+
'scope' => 'https://www.googleapis.com/auth/drive.file https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/',
|
51 |
+
'state' => 'token',
|
52 |
+
'access_type' => 'offline',
|
53 |
+
'approval_prompt' => 'auto'
|
54 |
+
);
|
55 |
+
header('Location: https://accounts.google.com/o/oauth2/auth?'.http_build_query($params));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
+
// Revoke a Google account refresh token
|
59 |
+
function gdrive_auth_revoke() {
|
60 |
+
$ignore = wp_remote_get('https://accounts.google.com/o/oauth2/revoke?token='.get_option('updraft_googledrive_token'));
|
61 |
+
update_option('updraft_googledrive_token','');
|
62 |
+
header('Location: '.admin_url( 'options-general.php?page=updraftplus&message=Authorisation revoked'));
|
|
|
|
|
63 |
}
|
64 |
|
65 |
+
// Get a Google account refresh token using the code received from gdrive_auth_request
|
66 |
+
function gdrive_auth_token() {
|
67 |
+
if( isset( $_GET['code'] ) ) {
|
68 |
+
$post_vars = array(
|
69 |
+
'code' => $_GET['code'],
|
70 |
+
'client_id' => get_option('updraft_googledrive_clientid'),
|
71 |
+
'client_secret' => get_option('updraft_googledrive_secret'),
|
72 |
+
'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'),
|
73 |
+
'grant_type' => 'authorization_code'
|
74 |
+
);
|
75 |
+
|
76 |
+
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => 30, 'method' => 'POST', 'body' => $post_vars) );
|
77 |
+
|
78 |
+
if (is_wp_error($result)) {
|
79 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'Bad response!', 'backup' ) ) );
|
80 |
+
} else {
|
81 |
+
$json_values = json_decode( $result['body'], true );
|
82 |
+
if ( isset( $json_values['refresh_token'] ) ) {
|
83 |
+
update_option('updraft_googledrive_token',$json_values['refresh_token']); // Save token
|
84 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&message=' . __( 'Google Drive authorization was successful.', 'updraftplus' ) ) );
|
85 |
+
}
|
86 |
+
else {
|
87 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'No refresh token was received!', 'updraftplus' ) ) );
|
88 |
+
}
|
89 |
+
}
|
90 |
+
}
|
91 |
+
else {
|
92 |
+
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'Authorization failed!', 'updraftplus' ) ) );
|
93 |
+
}
|
94 |
}
|
95 |
|
96 |
+
// This function just does the formalities, and off-loads the main work to upload_file
|
97 |
+
function backup($backup_array) {
|
98 |
+
|
99 |
+
global $updraftplus;
|
100 |
+
|
101 |
+
if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
|
102 |
+
|
103 |
+
// Do we have an access token?
|
104 |
+
if ( !$access_token = $this->access_token( get_option('updraft_googledrive_token'), get_option('updraft_googledrive_clientid'), get_option('updraft_googledrive_secret') )) {
|
105 |
+
$updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
106 |
+
return new WP_Error( "no_access_token", "Have not yet obtained an access token from Google (has the user authorised?");
|
107 |
+
}
|
108 |
+
|
109 |
+
$this->gdocs_access_token = $access_token;
|
110 |
+
|
111 |
+
foreach ($backup_array as $file) {
|
112 |
+
$file_path = trailingslashit(get_option('updraft_dir')).$file;
|
113 |
+
$file_name = basename($file_path);
|
114 |
+
$updraftplus->log("$file_name: Attempting to upload to Google Drive");
|
115 |
+
$timer_start = microtime(true);
|
116 |
+
if ( $id = $this->upload_file( $file_path, $file_name, get_option('updraft_googledrive_remotepath')) ) {
|
117 |
+
$updraftplus->log('OK: Archive ' . $file_name . ' uploaded to Google Drive in ' . ( round(microtime( true ) - $timer_start,2) ) . ' seconds (id: '.$id.')' );
|
118 |
+
$updraftplus->uploaded_file($file, $id);
|
119 |
+
} else {
|
120 |
+
$updraftplus->error("$file_name: Failed to upload to Google Drive" );
|
121 |
+
$updraftplus->log("ERROR: $file_name: Failed to upload to Google Drive" );
|
122 |
}
|
123 |
+
}
|
124 |
+
$updraftplus->prune_retained_backups("googledrive", $this);
|
125 |
+
}
|
126 |
+
|
127 |
+
function delete($file) {
|
128 |
+
global $updraftplus;
|
129 |
+
$ids = get_option('updraft_file_ids', array());
|
130 |
+
if (!isset($ids[$file])) {
|
131 |
+
$updraftplus->log("Could not delete: could not find a record of the Google Drive file ID for this file");
|
132 |
+
return;
|
133 |
+
} else {
|
134 |
+
$del == $this->gdocs->delete_resource($ids[$file]);
|
135 |
+
if (is_wp_error($del)) {
|
136 |
+
foreach ($del->get_error_messages() as $msg) $updraftplus->log("Deletion failed: $msg");
|
137 |
+
} else {
|
138 |
+
$updraftplus->log("Deletion successful");
|
139 |
+
unset($ids[$file]);
|
140 |
+
update_option('updraft_file_ids', $ids);
|
141 |
}
|
|
|
142 |
}
|
143 |
+
return;
|
144 |
+
}
|
145 |
|
146 |
+
// Returns:
|
147 |
+
// true = already uploaded
|
148 |
+
// false = failure
|
149 |
+
// otherwise, the file ID
|
150 |
+
function upload_file( $file, $title, $parent = '') {
|
151 |
|
152 |
+
global $updraftplus;
|
|
|
|
|
153 |
|
154 |
+
// Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
|
155 |
+
if ( is_wp_error( $e = $this->need_gdocs() ) ) return false;
|
156 |
+
$gdocs_object = $this->gdocs;
|
157 |
|
158 |
+
$hash = md5($file);
|
159 |
+
$transkey = 'upd_'.$hash.'_gloc';
|
160 |
+
// This is unset upon completion, so if it is set then we are resuming
|
161 |
+
$possible_location = get_transient($transkey);
|
162 |
|
163 |
+
if ( empty( $possible_location ) ) {
|
164 |
+
$updraftplus->log("$file: Attempting to upload file to Google Drive.");
|
165 |
+
$location = $gdocs_object->prepare_upload( $file, $title, $parent );
|
166 |
+
} else {
|
167 |
+
$updraftplus->log("$file: Attempting to resume upload.");
|
168 |
+
$location = $gdocs_object->resume_upload( $file, $possible_location );
|
169 |
+
}
|
170 |
|
171 |
+
if ( is_wp_error( $location ) ) {
|
172 |
+
$updraftplus->log("GoogleDrive upload: an error occurred");
|
173 |
+
foreach ($location->get_error_messages() as $msg) {
|
174 |
+
$updraftplus->error($msg);
|
175 |
+
$updraftplus->log("Error details: ".$msg);
|
176 |
+
}
|
177 |
+
return false;
|
178 |
+
}
|
179 |
+
|
180 |
+
if (!is_string($location) && true == $location) {
|
181 |
+
$updraftplus->log("$file: this file is already uploaded");
|
182 |
+
return true;
|
183 |
+
}
|
184 |
|
185 |
+
if ( is_string( $location ) ) {
|
186 |
+
$res = $location;
|
187 |
+
$updraftplus->log("Uploading file with title ".$title);
|
188 |
+
$d = 0;
|
189 |
+
do {
|
190 |
+
$updraftplus->log("Google Drive upload: chunk d: $d, loc: $res");
|
191 |
+
$res = $gdocs_object->upload_chunk();
|
192 |
+
if (is_string($res)) set_transient($transkey, $res, 3600*3);
|
193 |
+
$p = $gdocs_object->get_upload_percentage();
|
194 |
+
if ( $p - $d >= 1 ) {
|
195 |
+
$b = intval( $p - $d );
|
196 |
+
// echo '<span style="width:' . $b . '%"></span>';
|
197 |
+
$d += $b;
|
198 |
+
}
|
199 |
+
// $this->options['backup_list'][$id]['speed'] = $this->gdocs->get_upload_speed();
|
200 |
+
} while ( is_string( $res ) );
|
201 |
+
// echo '</div>';
|
202 |
+
|
203 |
+
if ( is_wp_error( $res ) || $res !== true) {
|
204 |
+
$updraftplus->log( "An error occurred during GoogleDrive upload (2)" );
|
205 |
+
$updraftplus->error( "An error occurred during GoogleDrive upload (2)" );
|
206 |
+
if (is_wp_error( $res )) {
|
207 |
+
foreach ($res->get_error_messages() as $msg) $updraftplus->log($msg);
|
208 |
+
}
|
209 |
+
return false;
|
210 |
+
}
|
211 |
|
212 |
+
$updraftplus->log("The file was successfully uploaded to Google Drive in ".number_format_i18n( $gdocs_object->time_taken(), 3)." seconds at an upload speed of ".size_format( $gdocs_object->get_upload_speed() )."/s.");
|
213 |
+
|
214 |
+
delete_transient($transkey);
|
215 |
+
// unset( $this->options['backup_list'][$id]['location'], $this->options['backup_list'][$id]['attempt'] );
|
216 |
+
}
|
217 |
+
|
218 |
+
return $gdocs_object->get_file_id();
|
219 |
+
|
220 |
+
// $this->update_quota();
|
221 |
+
// Google's "user info" service
|
222 |
+
// if ( empty( $this->options['user_info'] ) ) $this->set_user_info();
|
223 |
|
|
|
|
|
|
|
|
|
224 |
}
|
225 |
|
226 |
+
function download($file) {
|
227 |
|
228 |
+
global $updraftplus;
|
|
|
|
|
229 |
|
230 |
+
if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
|
231 |
+
|
232 |
+
// Do we have an access token?
|
233 |
+
if ( !$access_token = $updraftplus->access_token( get_option('updraft_googledrive_token'), get_option('updraft_googledrive_clientid'), get_option('updraft_googledrive_secret') )) {
|
234 |
+
$updraftplus->error('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
|
|
|
|
|
|
|
|
|
235 |
return false;
|
236 |
}
|
|
|
|
|
|
|
237 |
|
238 |
+
$this->gdocs_access_token = $access_token;
|
239 |
+
|
240 |
+
// Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
|
241 |
+
if ( is_wp_error( $e = $this->need_gdocs() ) ) return false;
|
242 |
+
$gdocs_object = $this->gdocs;
|
243 |
+
|
244 |
+
$ids = get_option('updraft_file_ids', array());
|
245 |
+
if (!isset($ids[$file])) {
|
246 |
+
$this->error("Google Drive error: $file: could not download: could not find a record of the Google Drive file ID for this file");
|
247 |
+
return;
|
248 |
} else {
|
249 |
+
$content_link = $gdocs_object->get_content_link( $ids[$file], $file );
|
250 |
+
if (is_wp_error($content_link)) {
|
251 |
+
$updraftplus->error("Could not find $file in order to download it (id: ".$ids[$file].")");
|
252 |
+
foreach ($content_link->get_error_messages() as $msg) $updraftplus->error($msg);
|
253 |
+
return false;
|
254 |
+
}
|
255 |
+
// Actually download the thing
|
256 |
+
$download_to = trailingslashit(get_option('updraft_dir')).$file;
|
257 |
+
$gdocs_object->download_data($content_link, $download_to);
|
258 |
+
|
259 |
+
if (filesize($download_to) >0) {
|
260 |
+
return true;
|
261 |
+
} else {
|
262 |
+
$updraftplus->error("Google Drive error: zero-size file was downloaded");
|
263 |
+
return false;
|
264 |
+
}
|
265 |
+
|
266 |
}
|
267 |
|
268 |
+
return;
|
269 |
+
|
270 |
}
|
271 |
|
272 |
+
// This function modified from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
|
273 |
+
function need_gdocs() {
|
274 |
|
275 |
+
global $updraftplus;
|
276 |
|
277 |
+
if ( ! $this->is_gdocs($this->gdocs) ) {
|
278 |
+
if ( get_option('updraft_googledrive_token') == "" || get_option('updraft_googledrive_clientid') == "" || get_option('updraft_googledrive_secret') == "" ) {
|
279 |
+
$updraftplus->log("GoogleDrive: this account is not authorised");
|
280 |
+
return new WP_Error( "not_authorized", "Account is not authorized." );
|
281 |
+
}
|
282 |
|
283 |
+
if ( is_wp_error( $this->gdocs_access_token ) ) return $access_token;
|
284 |
|
285 |
+
$this->gdocs = new UpdraftPlus_GDocs( $this->gdocs_access_token );
|
286 |
+
$this->gdocs->set_option( 'chunk_size', 1 ); # 1Mb; change from default of 512Kb
|
287 |
+
$this->gdocs->set_option( 'request_timeout', 10 ); # Change from default of 10s
|
288 |
+
$this->gdocs->set_option( 'max_resume_attempts', 36 ); # Doesn't look like GDocs class actually uses this anyway
|
289 |
}
|
290 |
+
return true;
|
291 |
+
}
|
292 |
|
293 |
+
// This function taken from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
|
294 |
+
function is_gdocs( $thing ) {
|
295 |
+
if ( is_object( $thing ) && is_a( $thing, 'UpdraftPlus_GDocs' ) ) return true;
|
296 |
+
return false;
|
297 |
+
}
|
298 |
|
299 |
+
function config_print() {
|
300 |
+
?>
|
301 |
+
<tr class="updraftplusmethod googledrive">
|
302 |
+
<th>Google Drive:</th>
|
303 |
+
<td>
|
304 |
+
<p><a href="http://david.dw-perspective.org.uk/da/index.php/computer-resources/updraftplus-googledrive-authorisation/"><strong>For longer help, including screenshots, follow this link. The description below is sufficient for more expert users.</strong></a></p>
|
305 |
+
<p><a href="https://code.google.com/apis/console/">Follow this link to your Google API Console</a>, and there create a Client ID in the API Access section. Select 'Web Application' as the application type.</p><p>You must add <kbd><?php echo admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'); ?></kbd> as the authorised redirect URI when asked.
|
306 |
+
|
307 |
+
<?php
|
308 |
+
if (!class_exists('SimpleXMLElement')) { echo " <b>WARNING:</b> You do not have the SimpleXMLElement installed. Google Drive backups will <b>not</b> work until you do."; }
|
309 |
+
?>
|
310 |
+
</p>
|
311 |
+
</td>
|
312 |
+
</tr>
|
313 |
+
|
314 |
+
<tr class="updraftplusmethod googledrive">
|
315 |
+
<th>Google Drive Client ID:</th>
|
316 |
+
<td><input type="text" autocomplete="off" style="width:332px" name="updraft_googledrive_clientid" value="<?php echo htmlspecialchars(get_option('updraft_googledrive_clientid')) ?>" /></td>
|
317 |
+
</tr>
|
318 |
+
<tr class="updraftplusmethod googledrive">
|
319 |
+
<th>Google Drive Client Secret:</th>
|
320 |
+
<td><input type="text" style="width:332px" name="updraft_googledrive_secret" value="<?php echo htmlspecialchars(get_option('updraft_googledrive_secret')); ?>" /></td>
|
321 |
+
</tr>
|
322 |
+
<tr class="updraftplusmethod googledrive">
|
323 |
+
<th>Google Drive Folder ID:</th>
|
324 |
+
<td><input type="text" style="width:332px" name="updraft_googledrive_remotepath" value="<?php echo htmlspecialchars(get_option('updraft_googledrive_remotepath')); ?>" /> <em>(To get a folder's ID navigate to that folder in Google Drive in your web browser and copy the ID from your browser's address bar. It is the part that comes after <kbd>#folders/.</kbd> Leave empty to use your root folder)</em></td>
|
325 |
+
</tr>
|
326 |
+
<tr class="updraftplusmethod googledrive">
|
327 |
+
<th>Authenticate with Google:</th>
|
328 |
+
<td><p><?php if (get_option('updraft_googledrive_token','xyz') != 'xyz') echo "<strong>(You appear to be already authenticated).</strong>"; ?> <a href="?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit"><strong>After</strong> you have saved your settings (by clicking "Save Changes" below), then come back here once and click this link to complete authentication with Google.</a>
|
329 |
+
</p>
|
330 |
+
</td>
|
331 |
+
</tr>
|
332 |
+
<?php
|
333 |
}
|
|
|
|
|
334 |
|
|
|
|
|
|
|
|
|
335 |
}
|
336 |
|
|
|
337 |
?>
|
methods/s3.php
CHANGED
@@ -1,128 +1,186 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
|
5 |
-
|
6 |
|
7 |
-
|
8 |
|
9 |
-
|
10 |
|
11 |
-
|
12 |
-
$bucket_path = "";
|
13 |
-
$orig_bucket_name = $bucket_name;
|
14 |
|
15 |
-
|
16 |
-
$
|
17 |
-
$
|
18 |
-
}
|
19 |
|
20 |
-
|
21 |
-
|
|
|
|
|
22 |
|
23 |
-
|
|
|
24 |
|
25 |
-
|
26 |
-
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
27 |
-
$chunks = floor(filesize($fullpath) / 5242880)+1;
|
28 |
-
$hash = md5($file);
|
29 |
|
30 |
-
|
|
|
|
|
|
|
31 |
|
32 |
-
|
33 |
|
34 |
-
|
35 |
-
if ($chunks < 2) {
|
36 |
-
if (!$s3->putObjectFile($fullpath, $bucket_name, $filepath)) {
|
37 |
-
$updraftplus->log("S3 regular upload: failed");
|
38 |
-
$updraftplus->error("S3 Error: Failed to upload $fullpath.");
|
39 |
-
} else {
|
40 |
-
$updraftplus->log("S3 regular upload: success");
|
41 |
-
$updraftplus->uploaded_file($file);
|
42 |
-
}
|
43 |
-
} else {
|
44 |
|
45 |
-
//
|
46 |
-
$
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
$updraftplus->log("S3 upload: failed: could not get uploadId for multipart upload");
|
51 |
-
continue;
|
52 |
} else {
|
53 |
-
$updraftplus->log("S3
|
54 |
-
|
55 |
}
|
56 |
} else {
|
57 |
-
$updraftplus->log("S3 chunked upload: retrieved previously obtained multipart ID: $uploadId");
|
58 |
-
}
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
|
|
|
|
69 |
} else {
|
70 |
-
$
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
75 |
$successes++;
|
|
|
76 |
} else {
|
77 |
-
$
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
}
|
80 |
}
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
|
|
|
|
|
|
87 |
} else {
|
88 |
-
$updraftplus->log("S3 upload:
|
89 |
-
$updraftplus->error("S3 upload: re-assembly failed");
|
90 |
}
|
91 |
-
} else {
|
92 |
-
$updraftplus->log("S3 upload: upload was not completely successful on this run");
|
93 |
}
|
94 |
}
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
-
$updraftplus->prune_retained_backups('s3',$s3,$orig_bucket_name);
|
97 |
-
} else {
|
98 |
-
$updraftplus->log("S3 Error: Failed to create bucket $bucket_name.");
|
99 |
-
$updraftplus->error("S3 Error: Failed to create bucket $bucket_name. Check your permissions and credentials.");
|
100 |
}
|
101 |
-
}
|
102 |
|
103 |
-
function
|
104 |
|
105 |
-
|
106 |
-
if(!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
107 |
|
108 |
-
|
109 |
-
|
110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
|
112 |
-
if (preg_match("#^([^/]+)/(.*)$#",$bucket_name,$bmatches)) {
|
113 |
-
$bucket_name = $bmatches[1];
|
114 |
-
$bucket_path = $bmatches[2]."/";
|
115 |
}
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
121 |
}
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
}
|
125 |
|
126 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
|
|
|
128 |
?>
|
1 |
<?php
|
2 |
|
3 |
+
class UpdraftPlus_BackupModule_s3 {
|
4 |
|
5 |
+
function backup($backup_array) {
|
6 |
|
7 |
+
global $updraftplus;
|
8 |
|
9 |
+
if (!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
10 |
|
11 |
+
$s3 = new S3(get_option('updraft_s3_login'), get_option('updraft_s3_pass'));
|
|
|
|
|
12 |
|
13 |
+
$bucket_name = untrailingslashit(get_option('updraft_s3_remote_path'));
|
14 |
+
$bucket_path = "";
|
15 |
+
$orig_bucket_name = $bucket_name;
|
|
|
16 |
|
17 |
+
if (preg_match("#^([^/]+)/(.*)$#",$bucket_name,$bmatches)) {
|
18 |
+
$bucket_name = $bmatches[1];
|
19 |
+
$bucket_path = $bmatches[2]."/";
|
20 |
+
}
|
21 |
|
22 |
+
// See if we can detect the region (which implies the bucket exists and is ours), or if not create it
|
23 |
+
if (@$s3->getBucketLocation($bucket_name) || @$s3->putBucket($bucket_name, S3::ACL_PRIVATE)) {
|
24 |
|
25 |
+
foreach($backup_array as $file) {
|
|
|
|
|
|
|
26 |
|
27 |
+
// We upload in 5Mb chunks to allow more efficient resuming and hence uploading of larger files
|
28 |
+
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
29 |
+
$chunks = floor(filesize($fullpath) / 5242880)+1;
|
30 |
+
$hash = md5($file);
|
31 |
|
32 |
+
$updraftplus->log("S3 upload: $fullpath (chunks: $chunks) -> s3://$bucket_name/$bucket_path$file");
|
33 |
|
34 |
+
$filepath = $bucket_path.$file;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
+
// This is extra code for the 1-chunk case, but less overhead (no bothering with transients)
|
37 |
+
if ($chunks < 2) {
|
38 |
+
if (!$s3->putObjectFile($fullpath, $bucket_name, $filepath)) {
|
39 |
+
$updraftplus->log("S3 regular upload: failed");
|
40 |
+
$updraftplus->error("S3 Error: Failed to upload $fullpath.");
|
|
|
|
|
41 |
} else {
|
42 |
+
$updraftplus->log("S3 regular upload: success");
|
43 |
+
$updraftplus->uploaded_file($file);
|
44 |
}
|
45 |
} else {
|
|
|
|
|
46 |
|
47 |
+
// Retrieve the upload ID
|
48 |
+
$uploadId = get_transient("updraft_${hash}_uid");
|
49 |
+
if (empty($uploadId)) {
|
50 |
+
$uploadId = $s3->initiateMultipartUpload($bucket_name, $filepath);
|
51 |
+
if (empty($uploadId)) {
|
52 |
+
$updraftplus->log("S3 upload: failed: could not get uploadId for multipart upload");
|
53 |
+
continue;
|
54 |
+
} else {
|
55 |
+
$updraftplus->log("S3 chunked upload: got multipart ID: $uploadId");
|
56 |
+
set_transient("updraft_${hash}_uid", $uploadId, 3600*3);
|
57 |
+
}
|
58 |
} else {
|
59 |
+
$updraftplus->log("S3 chunked upload: retrieved previously obtained multipart ID: $uploadId");
|
60 |
+
}
|
61 |
+
|
62 |
+
$successes = 0;
|
63 |
+
$etags = array();
|
64 |
+
for ($i = 1 ; $i <= $chunks; $i++) {
|
65 |
+
# Shorted to upd here to avoid hitting the 45-character limit
|
66 |
+
$etag = get_transient("upd_${hash}_e$i");
|
67 |
+
if (strlen($etag) > 0) {
|
68 |
+
$updraftplus->log("S3 chunk $i: was already completed (etag: $etag)");
|
69 |
$successes++;
|
70 |
+
array_push($etags, $etag);
|
71 |
} else {
|
72 |
+
$etag = $s3->uploadPart($bucket_name, $filepath, $uploadId, $fullpath, $i);
|
73 |
+
if (is_string($etag)) {
|
74 |
+
$updraftplus->log("S3 chunk $i: uploaded (etag: $etag)");
|
75 |
+
array_push($etags, $etag);
|
76 |
+
set_transient("upd_${hash}_e$i", $etag, 3600*3);
|
77 |
+
$successes++;
|
78 |
+
} else {
|
79 |
+
$updraftplus->error("S3 chunk $i: upload failed");
|
80 |
+
$updraftplus->log("S3 chunk $i: upload failed");
|
81 |
+
}
|
82 |
}
|
83 |
}
|
84 |
+
if ($successes >= $chunks) {
|
85 |
+
$updraftplus->log("S3 upload: all chunks uploaded; will now instruct S3 to re-assemble");
|
86 |
+
if ($s3->completeMultipartUpload ($bucket_name, $filepath, $uploadId, $etags)) {
|
87 |
+
$updraftplus->log("S3 upload: re-assembly succeeded");
|
88 |
+
$updraftplus->uploaded_file($file);
|
89 |
+
} else {
|
90 |
+
$updraftplus->log("S3 upload: re-assembly failed");
|
91 |
+
$updraftplus->error("S3 upload: re-assembly failed");
|
92 |
+
}
|
93 |
} else {
|
94 |
+
$updraftplus->log("S3 upload: upload was not completely successful on this run");
|
|
|
95 |
}
|
|
|
|
|
96 |
}
|
97 |
}
|
98 |
+
$updraftplus->prune_retained_backups('s3', $this, array('s3_object' => $s3, 's3_orig_bucket_name' => $orig_bucket_name));
|
99 |
+
} else {
|
100 |
+
$updraftplus->log("S3 Error: Failed to create bucket $bucket_name.");
|
101 |
+
$updraftplus->error("S3 Error: Failed to create bucket $bucket_name. Check your permissions and credentials.");
|
102 |
}
|
|
|
|
|
|
|
|
|
103 |
}
|
|
|
104 |
|
105 |
+
function delete($file, $s3arr) {
|
106 |
|
107 |
+
global $updraftplus;
|
|
|
108 |
|
109 |
+
$s3 = $s3arr['s3_object'];
|
110 |
+
$orig_bucket_name = $s3arr['s3_orig_bucket_name'];
|
111 |
+
|
112 |
+
if (preg_match("#^([^/]+)/(.*)$#", $orig_bucket_name, $bmatches)) {
|
113 |
+
$s3_bucket=$bmatches[1];
|
114 |
+
$s3_uri = $bmatches[2]."/".$file;
|
115 |
+
} else {
|
116 |
+
$s3_bucket = $remote_path;
|
117 |
+
$s3_uri = $file;
|
118 |
+
}
|
119 |
+
$updraftplus->log("S3: Delete remote: bucket=$s3_bucket, URI=$s3_uri");
|
120 |
+
|
121 |
+
# Here we brought in the contents of the S3.php function deleteObject in order to get more direct access to any error
|
122 |
+
$rest = new S3Request('DELETE', $s3_bucket, $s3_uri);
|
123 |
+
$rest = $rest->getResponse();
|
124 |
+
if ($rest->error === false && $rest->code !== 204) {
|
125 |
+
$updraftplus->log("S3 Error: Expected HTTP response 204; got: ".$rest->code);
|
126 |
+
$updraftplus->error("S3 Error: Unexpected HTTP response code ".$rest->code." (expected 204)");
|
127 |
+
} elseif ($rest->error !== false) {
|
128 |
+
$updraftplus->log("S3 Error: ".$rest->error['code'].": ".$rest->error['message']);
|
129 |
+
$updraftplus->error("S3 delete error: ".$rest->error['code'].": ".$rest->error['message']);
|
130 |
+
}
|
131 |
|
|
|
|
|
|
|
132 |
}
|
133 |
|
134 |
+
function download($file) {
|
135 |
+
|
136 |
+
global $updraftplus;
|
137 |
+
if(!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
|
138 |
+
|
139 |
+
$s3 = new S3(get_option('updraft_s3_login'), get_option('updraft_s3_pass'));
|
140 |
+
$bucket_name = untrailingslashit(get_option('updraft_s3_remote_path'));
|
141 |
+
$bucket_path = "";
|
142 |
+
|
143 |
+
if (preg_match("#^([^/]+)/(.*)$#",$bucket_name,$bmatches)) {
|
144 |
+
$bucket_name = $bmatches[1];
|
145 |
+
$bucket_path = $bmatches[2]."/";
|
146 |
}
|
147 |
+
|
148 |
+
if (@$s3->getBucketLocation($bucket_name)) {
|
149 |
+
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
150 |
+
if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
|
151 |
+
$updraftplus->error("S3 Error: Failed to download $fullpath. Check your permissions and credentials.");
|
152 |
+
}
|
153 |
+
} else {
|
154 |
+
$updraftplus->error("S3 Error: Failed to access bucket $bucket_name. Check your permissions and credentials.");
|
155 |
+
}
|
156 |
+
|
157 |
}
|
158 |
|
159 |
+
function config_print() {
|
160 |
+
|
161 |
+
?>
|
162 |
+
<tr class="updraftplusmethod s3">
|
163 |
+
<td></td>
|
164 |
+
<td><em>Amazon S3 is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your blog is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.</em></td>
|
165 |
+
</tr>
|
166 |
+
<tr class="updraftplusmethod s3">
|
167 |
+
<th>S3 access key:</th>
|
168 |
+
<td><input type="text" autocomplete="off" style="width: 292px" name="updraft_s3_login" value="<?php echo htmlspecialchars(get_option('updraft_s3_login')) ?>" /></td>
|
169 |
+
</tr>
|
170 |
+
<tr class="updraftplusmethod s3">
|
171 |
+
<th>S3 secret key:</th>
|
172 |
+
<td><input type="text" autocomplete="off" style="width: 292px" name="updraft_s3_pass" value="<?php echo htmlspecialchars(get_option('updraft_s3_pass')); ?>" /></td>
|
173 |
+
</tr>
|
174 |
+
<tr class="updraftplusmethod s3">
|
175 |
+
<th>S3 location:</th>
|
176 |
+
<td>s3://<input type="text" style="width: 292px" name="updraft_s3_remote_path" value="<?php echo htmlspecialchars(get_option('updraft_s3_remote_path')); ?>" /></td>
|
177 |
+
</tr>
|
178 |
+
<tr class="updraftplusmethod s3">
|
179 |
+
<th></th>
|
180 |
+
<td><p>Get your access key and secret key from your AWS page, then pick a (globally unique) bucket name (letters and numbers) (and optionally a path) to use for storage. This bucket will be created for you if it does not already exist.</p></td>
|
181 |
+
</tr>
|
182 |
+
<?php
|
183 |
+
}
|
184 |
|
185 |
+
}
|
186 |
?>
|
readme.txt
CHANGED
@@ -87,8 +87,8 @@ No, there's no warranty or guarantee, etc. It's completely up to you to verify t
|
|
87 |
|
88 |
== Changelog ==
|
89 |
|
90 |
-
= 1.0.
|
91 |
-
*
|
92 |
|
93 |
= 1.0.16 - 12/24/2012 =
|
94 |
* Improve race detection and clean up already-created files when detected
|
87 |
|
88 |
== Changelog ==
|
89 |
|
90 |
+
= 1.0.20 - 12/29/2012 =
|
91 |
+
* Big code re-factoring; moving towards modularising cloud access methods
|
92 |
|
93 |
= 1.0.16 - 12/24/2012 =
|
94 |
* Improve race detection and clean up already-created files when detected
|
updraftplus.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: UpdraftPlus - Backup/Restore
|
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/updraftplus
|
5 |
Description: Uploads, themes, plugins, and your DB can be automatically backed up to Amazon S3, Google Drive, FTP, or emailed, on separate schedules.
|
6 |
Author: David Anderson.
|
7 |
-
Version: 1.0.
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
Author URI: http://wordshell.net
|
@@ -56,7 +56,15 @@ define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
|
|
56 |
|
57 |
class UpdraftPlus {
|
58 |
|
59 |
-
var $version = '1.0.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
var $dbhandle;
|
62 |
var $errors = array();
|
@@ -64,11 +72,9 @@ class UpdraftPlus {
|
|
64 |
var $logfile_name = "";
|
65 |
var $logfile_handle = false;
|
66 |
var $backup_time;
|
67 |
-
var $gdocs;
|
68 |
-
var $gdocs_access_token;
|
69 |
|
70 |
function __construct() {
|
71 |
-
// Initialisation actions
|
72 |
# Create admin page
|
73 |
add_action('admin_menu', array($this,'add_admin_pages'));
|
74 |
add_action('admin_init', array($this,'admin_init'));
|
@@ -85,20 +91,17 @@ class UpdraftPlus {
|
|
85 |
add_action('init', array($this, 'handle_url_actions'));
|
86 |
}
|
87 |
|
88 |
-
// Handle Google OAuth 2.0 - ?page=updraftplus&action=auth
|
89 |
// Also handle action=downloadlog
|
90 |
function handle_url_actions() {
|
91 |
// First, basic security check: must be an admin page, with ability to manage options, with the right parameters
|
92 |
if ( is_admin() && current_user_can('manage_options') && isset( $_GET['page'] ) && $_GET['page'] == 'updraftplus' && isset($_GET['action']) ) {
|
93 |
-
if ($_GET['action']
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
} elseif (isset($_GET['updraftplus_googleauth'])) {
|
100 |
-
$this->gdrive_auth_request();
|
101 |
-
}
|
102 |
} elseif ($_GET['action'] == 'downloadlog' && isset($_GET['updraftplus_backup_nonce']) && preg_match("/^[0-9a-f]{12}$/",$_GET['updraftplus_backup_nonce'])) {
|
103 |
$updraft_dir = $this->backups_dir_location();
|
104 |
$log_file = $updraft_dir.'/log.'.$_GET['updraftplus_backup_nonce'].'.txt';
|
@@ -113,101 +116,6 @@ class UpdraftPlus {
|
|
113 |
}
|
114 |
}
|
115 |
|
116 |
-
// Acquire single-use authorization code from Google OAuth 2.0
|
117 |
-
function gdrive_auth_request() {
|
118 |
-
$params = array(
|
119 |
-
'response_type' => 'code',
|
120 |
-
'client_id' => get_option('updraft_googledrive_clientid'),
|
121 |
-
'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=auth'),
|
122 |
-
'scope' => 'https://www.googleapis.com/auth/drive.file https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/',
|
123 |
-
'state' => 'token',
|
124 |
-
'access_type' => 'offline',
|
125 |
-
'approval_prompt' => 'auto'
|
126 |
-
);
|
127 |
-
header('Location: https://accounts.google.com/o/oauth2/auth?'.http_build_query($params));
|
128 |
-
}
|
129 |
-
|
130 |
-
// Get a Google account access token using the refresh token
|
131 |
-
function access_token( $token, $client_id, $client_secret ) {
|
132 |
-
$this->log("Google Drive: requesting access token: client_id=$client_id");
|
133 |
-
|
134 |
-
$query_body = array( 'refresh_token' => $token, 'client_id' => $client_id, 'client_secret' => $client_secret, 'grant_type' => 'refresh_token' );
|
135 |
-
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => '15', 'method' => 'POST', 'body' => $query_body) );
|
136 |
-
|
137 |
-
if (is_wp_error($result)) {
|
138 |
-
$this->log("Google Drive error when requesting access token");
|
139 |
-
foreach ($result->get_error_messages() as $msg) { $this->log("Error message: $msg"); }
|
140 |
-
return false;
|
141 |
-
} else {
|
142 |
-
$json_values = json_decode( $result['body'], true );
|
143 |
-
if ( isset( $json_values['access_token'] ) ) {
|
144 |
-
$this->log("Google Drive: successfully obtained access token");
|
145 |
-
return $json_values['access_token'];
|
146 |
-
} else {
|
147 |
-
$this->log("Google Drive error when requesting access token: response does not contain access_token");
|
148 |
-
return false;
|
149 |
-
}
|
150 |
-
}
|
151 |
-
}
|
152 |
-
|
153 |
-
function googledrive_delete_file( $file, $token) {
|
154 |
-
$ids = get_option('updraft_file_ids', array());
|
155 |
-
if (!isset($ids[$file])) {
|
156 |
-
$this->log("Could not delete: could not find a record of the Google Drive file ID for this file");
|
157 |
-
return;
|
158 |
-
} else {
|
159 |
-
$del == $this->gdocs->delete_resource($ids[$file]);
|
160 |
-
if (is_wp_error($del)) {
|
161 |
-
foreach ($del->get_error_messages() as $msg) {
|
162 |
-
$this->log("Deletion failed: $msg");
|
163 |
-
}
|
164 |
-
} else {
|
165 |
-
$this->log("Deletion successful");
|
166 |
-
unset($ids[$file]);
|
167 |
-
update_option('updraft_file_ids', $ids);
|
168 |
-
}
|
169 |
-
}
|
170 |
-
return;
|
171 |
-
}
|
172 |
-
|
173 |
-
// Get a Google account refresh token using the code received from gdrive_auth_request
|
174 |
-
function gdrive_auth_token() {
|
175 |
-
if( isset( $_GET['code'] ) ) {
|
176 |
-
$post_vars = array(
|
177 |
-
'code' => $_GET['code'],
|
178 |
-
'client_id' => get_option('updraft_googledrive_clientid'),
|
179 |
-
'client_secret' => get_option('updraft_googledrive_secret'),
|
180 |
-
'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=auth'),
|
181 |
-
'grant_type' => 'authorization_code'
|
182 |
-
);
|
183 |
-
|
184 |
-
$result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => 30, 'method' => 'POST', 'body' => $post_vars) );
|
185 |
-
|
186 |
-
if (is_wp_error($result)) {
|
187 |
-
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'Bad response!', 'backup' ) ) );
|
188 |
-
} else {
|
189 |
-
$json_values = json_decode( $result['body'], true );
|
190 |
-
if ( isset( $json_values['refresh_token'] ) ) {
|
191 |
-
update_option('updraft_googledrive_token',$json_values['refresh_token']); // Save token
|
192 |
-
header('Location: '.admin_url('options-general.php?page=updraftplus&message=' . __( 'Google Drive authorization was successful.', 'updraftplus' ) ) );
|
193 |
-
}
|
194 |
-
else {
|
195 |
-
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'No refresh token was received!', 'updraftplus' ) ) );
|
196 |
-
}
|
197 |
-
}
|
198 |
-
}
|
199 |
-
else {
|
200 |
-
header('Location: '.admin_url('options-general.php?page=updraftplus&error=' . __( 'Authorization failed!', 'updraftplus' ) ) );
|
201 |
-
}
|
202 |
-
}
|
203 |
-
|
204 |
-
// Revoke a Google account refresh token
|
205 |
-
function gdrive_auth_revoke() {
|
206 |
-
$ignore = wp_remote_get('https://accounts.google.com/o/oauth2/revoke?token='.get_option('updraft_googledrive_token'));
|
207 |
-
update_option('updraft_googledrive_token','');
|
208 |
-
header('Location: '.admin_url( 'options-general.php?page=updraftplus&message=Authorisation revoked'));
|
209 |
-
}
|
210 |
-
|
211 |
# Adds the settings link under the plugin on the plugin screen.
|
212 |
function plugin_action_links($links, $file) {
|
213 |
if ($file == plugin_basename(__FILE__)){
|
@@ -483,7 +391,6 @@ class UpdraftPlus {
|
|
483 |
|
484 |
// Dispatch to the relevant function
|
485 |
function cloud_backup($backup_array) {
|
486 |
-
|
487 |
$service = get_option('updraft_service');
|
488 |
$this->log("Cloud backup selection: ".$service);
|
489 |
@set_time_limit(900);
|
@@ -491,67 +398,57 @@ class UpdraftPlus {
|
|
491 |
$method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
|
492 |
if (file_exists($method_include)) require_once($method_include);
|
493 |
|
494 |
-
|
|
|
495 |
// New style - external, allowing more plugability
|
496 |
-
|
|
|
497 |
} else {
|
498 |
$this->prune_retained_backups("local");
|
499 |
}
|
500 |
}
|
501 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
// Carries out retain behaviour. Pass in a valid S3 or FTP object and path if relevant.
|
503 |
-
function prune_retained_backups($updraft_service
|
|
|
504 |
$this->log("Retain: beginning examination of existing backup sets");
|
505 |
-
|
506 |
// Number of backups to retain
|
507 |
-
$
|
|
|
508 |
$this->log("Retain: user setting: number to retain = $retain");
|
|
|
509 |
// Returns an array, most recent first, of backup sets
|
510 |
$backup_history = $this->get_backup_history();
|
511 |
$db_backups_found = 0;
|
512 |
$file_backups_found = 0;
|
513 |
$this->log("Number of backup sets in history: ".count($backup_history));
|
|
|
514 |
foreach ($backup_history as $backup_datestamp => $backup_to_examine) {
|
515 |
// $backup_to_examine is an array of file names, keyed on db/plugins/themes/uploads
|
516 |
// The new backup_history array is saved afterwards, so remember to unset the ones that are to be deleted
|
517 |
$this->log("Examining backup set with datestamp: $backup_datestamp");
|
|
|
518 |
if (isset($backup_to_examine['db'])) {
|
519 |
$db_backups_found++;
|
520 |
$this->log("$backup_datestamp: this set includes a database (".$backup_to_examine['db']."); db count is now $db_backups_found");
|
521 |
if ($db_backups_found > $retain) {
|
522 |
$this->log("$backup_datestamp: over retain limit; will delete this database");
|
523 |
-
$
|
524 |
-
$this->
|
525 |
-
if ($file != '') {
|
526 |
-
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
527 |
-
@unlink($fullpath); //delete it if it's locally available
|
528 |
-
if ($updraft_service == "s3") {
|
529 |
-
if (preg_match("#^([^/]+)/(.*)$#",$remote_path,$bmatches)) {
|
530 |
-
$s3_bucket=$bmatches[1];
|
531 |
-
$s3_uri = $bmatches[2]."/".$file;
|
532 |
-
} else {
|
533 |
-
$s3_bucket = $remote_path;
|
534 |
-
$s3_uri = $file;
|
535 |
-
}
|
536 |
-
$this->log("$backup_datestamp: Delete remote: bucket=$s3_bucket, URI=$s3_uri");
|
537 |
-
# Here we brought in the function deleteObject in order to get more direct access to any error
|
538 |
-
$rest = new S3Request('DELETE', $s3_bucket, $s3_uri);
|
539 |
-
$rest = $rest->getResponse();
|
540 |
-
if ($rest->error === false && $rest->code !== 204) {
|
541 |
-
$this->log("S3 Error: Expected HTTP response 204; got: ".$rest->code);
|
542 |
-
$this->error("S3 Error: Unexpected HTTP response code ".$rest->code." (expected 204)");
|
543 |
-
} elseif ($rest->error !== false) {
|
544 |
-
$this->log("S3 Error: ".$rest->error['code'].": ".$rest->error['message']);
|
545 |
-
$this->error("S3 delete error: ".$rest->error['code'].": ".$rest->error['message']);
|
546 |
-
}
|
547 |
-
} elseif ($updraft_service == "ftp") {
|
548 |
-
$this->log("$backup_datestamp: Delete remote ftp: $remote_path/$file");
|
549 |
-
@$remote_object->delete($remote_path.$file);
|
550 |
-
} elseif ($updraft_service == "googledrive") {
|
551 |
-
$this->log("$backup_datestamp: Delete remote file from Google Drive: $file");
|
552 |
-
$this->googledrive_delete_file($file,$remote_object);
|
553 |
-
}
|
554 |
-
}
|
555 |
unset($backup_to_examine['db']);
|
556 |
}
|
557 |
}
|
@@ -564,38 +461,8 @@ class UpdraftPlus {
|
|
564 |
$file2 = isset($backup_to_examine['themes']) ? $backup_to_examine['themes'] : "";
|
565 |
$file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
|
566 |
$file4 = isset($backup_to_examine['others']) ? $backup_to_examine['others'] : "";
|
567 |
-
foreach (array($file
|
568 |
-
if ($dofile)
|
569 |
-
$this->log("$backup_datestamp: Delete this file: $dofile");
|
570 |
-
$fullpath = trailingslashit(get_option('updraft_dir')).$dofile;
|
571 |
-
@unlink($fullpath); //delete it if it's locally available
|
572 |
-
if ($updraft_service == "s3") {
|
573 |
-
if (preg_match("#^([^/]+)/(.*)$#",$remote_path,$bmatches)) {
|
574 |
-
$s3_bucket=$bmatches[1];
|
575 |
-
$s3_uri = $bmatches[2]."/".$dofile;
|
576 |
-
} else {
|
577 |
-
$s3_bucket = $remote_path;
|
578 |
-
$s3_uri = $dofile;
|
579 |
-
}
|
580 |
-
$this->log("$backup_datestamp: Delete remote: bucket=$s3_bucket, URI=$s3_uri");
|
581 |
-
# Here we brought in the function deleteObject in order to get more direct access to any error
|
582 |
-
$rest = new S3Request('DELETE', $s3_bucket, $s3_uri);
|
583 |
-
$rest = $rest->getResponse();
|
584 |
-
if ($rest->error === false && $rest->code !== 204) {
|
585 |
-
$this->log("S3 Error: Expected HTTP response 204; got: ".$rest->code);
|
586 |
-
$this->error("S3 Error: Unexpected HTTP response code ".$rest->code." (expected 204)");
|
587 |
-
} elseif ($rest->error !== false) {
|
588 |
-
$this->log("S3 Error: ".$rest->error['code'].": ".$rest->error['message']);
|
589 |
-
$this->error("S3 delete error: ".$rest->error['code'].": ".$rest->error['message']);
|
590 |
-
}
|
591 |
-
} elseif ($updraft_service == "ftp") {
|
592 |
-
$this->log("$backup_datestamp: Delete remote ftp: $remote_path/$dofile");
|
593 |
-
@$remote_object->delete($remote_path.$dofile);
|
594 |
-
} elseif ($updraft_service == "googledrive") {
|
595 |
-
$this->log("$backup_datestamp: Delete remote file from Google Drive: $dofile");
|
596 |
-
$this->googledrive_delete_file($dofile,$remote_object);
|
597 |
-
}
|
598 |
-
}
|
599 |
}
|
600 |
unset($backup_to_examine['plugins']);
|
601 |
unset($backup_to_examine['themes']);
|
@@ -1221,8 +1088,10 @@ class UpdraftPlus {
|
|
1221 |
$method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
|
1222 |
if (file_exists($method_include)) require_once($method_include);
|
1223 |
|
1224 |
-
|
1225 |
-
|
|
|
|
|
1226 |
} else {
|
1227 |
$this->error('Automatic backup restoration is not available with the method: $service.');
|
1228 |
}
|
@@ -1259,7 +1128,7 @@ class UpdraftPlus {
|
|
1259 |
if(!class_exists('WP_Upgrader')) {
|
1260 |
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
1261 |
}
|
1262 |
-
require_once('includes/updraft-restorer.php');
|
1263 |
$restorer = new Updraft_Restorer();
|
1264 |
$val = $restorer->restore_backup($fullpath,$type);
|
1265 |
if(is_wp_error($val)) {
|
@@ -1380,6 +1249,7 @@ class UpdraftPlus {
|
|
1380 |
register_setting( 'updraft-options-group', 'updraft_retain', array($this,'retain_range') );
|
1381 |
register_setting( 'updraft-options-group', 'updraft_encryptionphrase', 'wp_filter_nohtml_kses' );
|
1382 |
register_setting( 'updraft-options-group', 'updraft_service', 'wp_filter_nohtml_kses' );
|
|
|
1383 |
register_setting( 'updraft-options-group', 'updraft_s3_login', 'wp_filter_nohtml_kses' );
|
1384 |
register_setting( 'updraft-options-group', 'updraft_s3_pass', 'wp_filter_nohtml_kses' );
|
1385 |
register_setting( 'updraft-options-group', 'updraft_s3_remote_path', 'wp_filter_nohtml_kses' );
|
@@ -1388,10 +1258,10 @@ class UpdraftPlus {
|
|
1388 |
register_setting( 'updraft-options-group', 'updraft_googledrive_remotepath', 'wp_filter_nohtml_kses' );
|
1389 |
register_setting( 'updraft-options-group', 'updraft_ftp_login', 'wp_filter_nohtml_kses' );
|
1390 |
register_setting( 'updraft-options-group', 'updraft_ftp_pass', 'wp_filter_nohtml_kses' );
|
1391 |
-
register_setting( 'updraft-options-group', 'updraft_dir', 'wp_filter_nohtml_kses' );
|
1392 |
-
register_setting( 'updraft-options-group', 'updraft_email', 'wp_filter_nohtml_kses' );
|
1393 |
register_setting( 'updraft-options-group', 'updraft_ftp_remote_path', 'wp_filter_nohtml_kses' );
|
1394 |
register_setting( 'updraft-options-group', 'updraft_server_address', 'wp_filter_nohtml_kses' );
|
|
|
|
|
1395 |
register_setting( 'updraft-options-group', 'updraft_delete_local', 'absint' );
|
1396 |
register_setting( 'updraft-options-group', 'updraft_debug_mode', 'absint' );
|
1397 |
register_setting( 'updraft-options-group', 'updraft_include_plugins', 'absint' );
|
@@ -1399,7 +1269,7 @@ class UpdraftPlus {
|
|
1399 |
register_setting( 'updraft-options-group', 'updraft_include_uploads', 'absint' );
|
1400 |
register_setting( 'updraft-options-group', 'updraft_include_others', 'absint' );
|
1401 |
register_setting( 'updraft-options-group', 'updraft_include_others_exclude', 'wp_filter_nohtml_kses' );
|
1402 |
-
|
1403 |
if (current_user_can('manage_options') && get_option('updraft_service') == "googledrive" && get_option('updraft_googledrive_clientid') != "" && get_option('updraft_googledrive_token','xyz') == 'xyz') {
|
1404 |
add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
|
1405 |
}
|
@@ -1758,19 +1628,19 @@ ENDHERE;
|
|
1758 |
?>
|
1759 |
<td><input type="text" name="updraft_retain" value="<?php echo $retain ?>" style="width:50px" /></td>
|
1760 |
</tr>
|
1761 |
-
<tr class="
|
|
|
|
|
|
|
1762 |
<th>Email:</th>
|
1763 |
<td><input type="text" style="width:260px" name="updraft_email" value="<?php echo get_option('updraft_email'); ?>" /> <br>Enter an address here to have a report sent (and the whole backup, if you choose) to it.</td>
|
1764 |
</tr>
|
1765 |
-
<tr class="deletelocal
|
1766 |
<th>Delete local backup:</th>
|
1767 |
<td><input type="checkbox" name="updraft_delete_local" value="1" <?php $delete_local = (get_option('updraft_delete_local')) ? 'checked="checked"' : "";
|
1768 |
echo $delete_local; ?> /> <br>Check this to delete the local backup file (only sensible if you have enabled a remote backup (below), otherwise you will have no backup remaining).</td>
|
1769 |
</tr>
|
1770 |
|
1771 |
-
<tr class="backup-retain-description">
|
1772 |
-
<td></td><td>By default only the most recent backup is retained. If you'd like to preserve more, specify the number here. (This many of <strong>both</strong> files and database backups will be retained.)</td>
|
1773 |
-
</tr>
|
1774 |
<tr>
|
1775 |
<th>Database encryption phrase:</th>
|
1776 |
<?php
|
@@ -1792,137 +1662,53 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
|
|
1792 |
<?php
|
1793 |
$debug_mode = (get_option('updraft_debug_mode')) ? 'checked="checked"' : "";
|
1794 |
|
1795 |
-
$display_none = 'style="display:none"';
|
1796 |
-
$s3 = ""; $ftp = ""; $email = ""; $googledrive="";
|
1797 |
-
$email_display="";
|
1798 |
-
$display_email_complete = "";
|
1799 |
$set = 'selected="selected"';
|
1800 |
-
|
1801 |
-
|
1802 |
-
|
1803 |
-
|
1804 |
-
|
1805 |
-
|
1806 |
-
|
1807 |
-
|
1808 |
-
|
1809 |
-
|
1810 |
-
|
1811 |
-
|
1812 |
-
|
1813 |
-
$googledrive_display = $display_none;
|
1814 |
-
$s3_display = $display_none;
|
1815 |
-
break;
|
1816 |
-
case 'email':
|
1817 |
-
$email = $set;
|
1818 |
-
$ftp_display = $display_none;
|
1819 |
-
$s3_display = $display_none;
|
1820 |
-
$googledrive_display = $display_none;
|
1821 |
-
$display_email_complete = $display_none;
|
1822 |
-
break;
|
1823 |
-
default:
|
1824 |
-
$none = $set;
|
1825 |
-
$ftp_display = $display_none;
|
1826 |
-
$googledrive_display = $display_none;
|
1827 |
-
$s3_display = $display_none;
|
1828 |
-
$display_delete_local = $display_none;
|
1829 |
-
break;
|
1830 |
}
|
1831 |
?>
|
1832 |
-
<option value="none" <?php echo $none?>>None</option>
|
1833 |
-
<option value="s3" <?php echo $s3?>>Amazon S3</option>
|
1834 |
-
<option value="googledrive" <?php echo $googledrive?>>Google Drive</option>
|
1835 |
-
<option value="ftp" <?php echo $ftp?>>FTP</option>
|
1836 |
-
<option value="email" <?php echo $email?>>E-mail</option>
|
1837 |
</select></td>
|
1838 |
</tr>
|
1839 |
<tr class="backup-service-description">
|
1840 |
<td></td><td>Choose your backup method. If choosing "E-Mail", then be aware that mail servers tend to have size limits; typically around 10-20Mb; backups larger than any limits will not arrive.</td>
|
1841 |
|
1842 |
</tr>
|
1843 |
-
|
1844 |
-
<!-- Amazon S3 -->
|
1845 |
-
<tr class="s3" <?php echo $s3_display?>>
|
1846 |
-
<td></td>
|
1847 |
-
<td><em>Amazon S3 is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your blog is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.</em></td>
|
1848 |
-
</tr>
|
1849 |
-
<tr class="s3" <?php echo $s3_display?>>
|
1850 |
-
<th>S3 access key:</th>
|
1851 |
-
<td><input type="text" autocomplete="off" style="width:292px" name="updraft_s3_login" value="<?php echo get_option('updraft_s3_login') ?>" /></td>
|
1852 |
-
</tr>
|
1853 |
-
<tr class="s3" <?php echo $s3_display?>>
|
1854 |
-
<th>S3 secret key:</th>
|
1855 |
-
<td><input type="text" autocomplete="off" style="width:292px" name="updraft_s3_pass" value="<?php echo get_option('updraft_s3_pass'); ?>" /></td>
|
1856 |
-
</tr>
|
1857 |
-
<tr class="s3" <?php echo $s3_display?>>
|
1858 |
-
<th>S3 location:</th>
|
1859 |
-
<td>s3://<input type="text" style="width:292px" name="updraft_s3_remote_path" value="<?php echo get_option('updraft_s3_remote_path'); ?>" /></td>
|
1860 |
-
</tr>
|
1861 |
-
<tr class="s3" <?php echo $s3_display?>>
|
1862 |
-
<th></th>
|
1863 |
-
<td><p>Get your access key and secret key from your AWS page, then pick a (globally unique) bucket name (letters and numbers) (and optionally a path) to use for storage. This bucket will be created for you if it does not already exist.</p></td>
|
1864 |
-
</tr>
|
1865 |
-
|
1866 |
-
<!-- Google Drive -->
|
1867 |
-
|
1868 |
-
<tr class="googledrive" <?php echo $googledrive_display?>>
|
1869 |
-
<th>Google Drive:</th>
|
1870 |
-
<td>
|
1871 |
-
<p><a href="http://david.dw-perspective.org.uk/da/index.php/computer-resources/updraftplus-googledrive-authorisation/"><strong>For longer help, including screenshots, follow this link. The description below is sufficient for more expert users.</strong></a></p>
|
1872 |
-
<p><a href="https://code.google.com/apis/console/">Follow this link to your Google API Console</a>, and there create a Client ID in the API Access section. Select 'Web Application' as the application type.</p><p>You must add <kbd><?php echo admin_url('options-general.php?page=updraftplus&action=auth'); ?></kbd> as the authorised redirect URI when asked.
|
1873 |
-
|
1874 |
<?php
|
1875 |
-
|
|
|
|
|
|
|
|
|
1876 |
?>
|
1877 |
-
</p>
|
1878 |
-
</td>
|
1879 |
-
</tr>
|
1880 |
-
|
1881 |
-
<tr class="googledrive" <?php echo $googledrive_display?>>
|
1882 |
-
<th>Google Drive Client ID:</th>
|
1883 |
-
<td><input type="text" autocomplete="off" style="width:332px" name="updraft_googledrive_clientid" value="<?php echo get_option('updraft_googledrive_clientid') ?>" /></td>
|
1884 |
-
</tr>
|
1885 |
-
<tr class="googledrive" <?php echo $googledrive_display?>>
|
1886 |
-
<th>Google Drive Client Secret:</th>
|
1887 |
-
<td><input type="text" style="width:332px" name="updraft_googledrive_secret" value="<?php echo get_option('updraft_googledrive_secret'); ?>" /></td>
|
1888 |
-
</tr>
|
1889 |
-
<tr class="googledrive" <?php echo $googledrive_display?>>
|
1890 |
-
<th>Google Drive Folder ID:</th>
|
1891 |
-
<td><input type="text" style="width:332px" name="updraft_googledrive_remotepath" value="<?php echo get_option('updraft_googledrive_remotepath'); ?>" /> <em>(To get a folder's ID navigate to that folder in Google Drive in your web browser and copy the ID from your browser's address bar. It is the part that comes after <kbd>#folders/.</kbd> Leave empty to use your root folder)</em></td>
|
1892 |
-
</tr>
|
1893 |
-
<tr class="googledrive" <?php echo $googledrive_display?>>
|
1894 |
-
<th>Authenticate with Google:</th>
|
1895 |
-
<td><p><?php if (get_option('updraft_googledrive_token','xyz') != 'xyz') echo "<strong>(You appear to be already authenticated).</strong>"; ?> <a href="?page=updraftplus&action=auth&updraftplus_googleauth=doit"><strong>After</strong> you have saved your settings (by clicking "Save Changes" below), then come back here once and click this link to complete authentication with Google.</a>
|
1896 |
-
|
1897 |
-
</p>
|
1898 |
-
</td>
|
1899 |
-
</tr>
|
1900 |
-
|
1901 |
-
<tr class="ftp" <?php echo $ftp_display?>>
|
1902 |
-
<th><a href="#" title="Click for help!" onclick="jQuery('.ftp-description').toggle();return false;">FTP Server:</a></th>
|
1903 |
-
<td><input type="text" style="width:260px" name="updraft_server_address" value="<?php echo get_option('updraft_server_address'); ?>" /></td>
|
1904 |
-
</tr>
|
1905 |
-
<tr class="ftp" <?php echo $ftp_display?>>
|
1906 |
-
<th><a href="#" title="Click for help!" onclick="jQuery('.ftp-description').toggle();return false;">FTP Login:</a></th>
|
1907 |
-
<td><input type="text" autocomplete="off" name="updraft_ftp_login" value="<?php echo get_option('updraft_ftp_login') ?>" /></td>
|
1908 |
-
</tr>
|
1909 |
-
<tr class="ftp" <?php echo $ftp_display?>>
|
1910 |
-
<th><a href="#" title="Click for help!" onclick="jQuery('.ftp-description').toggle();return false;">FTP Password:</a></th>
|
1911 |
-
<td><input type="text" autocomplete="off" style="width:260px" name="updraft_ftp_pass" value="<?php echo get_option('updraft_ftp_pass'); ?>" /></td>
|
1912 |
-
</tr>
|
1913 |
-
<tr class="ftp" <?php echo $ftp_display?>>
|
1914 |
-
<th><a href="#" title="Click for help!" onclick="jQuery('.ftp-description').toggle();return false;">Remote Path:</a></th>
|
1915 |
-
<td><input type="text" style="width:260px" name="updraft_ftp_remote_path" value="<?php echo get_option('updraft_ftp_remote_path'); ?>" /></td>
|
1916 |
-
</tr>
|
1917 |
-
<tr class="ftp-description" style="display:none">
|
1918 |
-
<td colspan="2">An FTP remote path will look like '/home/backup/some/folder'</td>
|
1919 |
-
</tr>
|
1920 |
</table>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1921 |
<table class="form-table" style="width:850px;">
|
1922 |
-
|
|
|
|
|
1923 |
<tr>
|
1924 |
<th>Backup Directory:</th>
|
1925 |
-
<td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo $updraft_dir ?>" /></td>
|
1926 |
</tr>
|
1927 |
<tr>
|
1928 |
<td></td><td><?php echo $dir_info ?> This is where Updraft Backup/Restore will write the zip files it creates initially. This directory must be writable by your web server. Typically you'll want to have it inside your wp-content folder (this is the default). <b>Do not</b> place it inside your uploads dir, as that will cause recursion issues (backups of backups of backups of...).</td>
|
@@ -1967,30 +1753,12 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
|
|
1967 |
|
1968 |
|
1969 |
<script type="text/javascript">
|
|
|
1970 |
jQuery(document).ready(function() {
|
1971 |
jQuery('#updraft-service').change(function() {
|
1972 |
-
|
1973 |
-
|
1974 |
-
|
1975 |
-
jQuery('.email,.email-complete').fadeIn()
|
1976 |
-
break;
|
1977 |
-
case 's3':
|
1978 |
-
jQuery('.ftp,.ftp-description,.googledrive').fadeOut()
|
1979 |
-
jQuery('.s3,.deletelocal,.email,.email-complete').fadeIn()
|
1980 |
-
break;
|
1981 |
-
case 'googledrive':
|
1982 |
-
jQuery('.ftp,.ftp-description,.s3').fadeOut()
|
1983 |
-
jQuery('.googledrive,.deletelocal,.googledrive,.email,.email-complete').fadeIn()
|
1984 |
-
break;
|
1985 |
-
case 'ftp':
|
1986 |
-
jQuery('.googledrive,.s3,.s3-description').fadeOut()
|
1987 |
-
jQuery('.ftp,.deletelocal,.email,.email-complete').fadeIn()
|
1988 |
-
break;
|
1989 |
-
case 'email':
|
1990 |
-
jQuery('.s3,.ftp,.s3-description,.googledrive,.ftp-description,.email-complete').fadeOut()
|
1991 |
-
jQuery('.email,.deletelocal').fadeIn()
|
1992 |
-
break;
|
1993 |
-
}
|
1994 |
})
|
1995 |
})
|
1996 |
jQuery(window).load(function() {
|
@@ -2000,13 +1768,14 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
|
|
2000 |
jQuery('#updraft-restore-progress').toggle(500)
|
2001 |
})
|
2002 |
})
|
|
|
2003 |
</script>
|
2004 |
<?php
|
2005 |
}
|
2006 |
|
2007 |
/*array2json provided by bin-co.com under BSD license*/
|
2008 |
function array2json($arr) {
|
2009 |
-
if(function_exists('json_encode')) return stripslashes(json_encode($arr)); //
|
2010 |
$parts = array();
|
2011 |
$is_list = false;
|
2012 |
|
@@ -2051,14 +1820,14 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
|
|
2051 |
echo '<div id="updraftmessage" class="updated fade">'."<p>$message</p></div>";
|
2052 |
}
|
2053 |
|
2054 |
-
function show_admin_warning_googledrive() {
|
2055 |
-
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=auth&updraftplus_googleauth=doit">Click here to authenticate your Google Drive account (you will not be able to back up to Google Drive without it).</a>');
|
2056 |
-
}
|
2057 |
-
|
2058 |
function show_admin_warning_unreadablelog() {
|
2059 |
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> The log file could not be read.</a>');
|
2060 |
}
|
2061 |
|
|
|
|
|
|
|
|
|
2062 |
|
2063 |
}
|
2064 |
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/updraftplus
|
5 |
Description: Uploads, themes, plugins, and your DB can be automatically backed up to Amazon S3, Google Drive, FTP, or emailed, on separate schedules.
|
6 |
Author: David Anderson.
|
7 |
+
Version: 1.0.20
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
Author URI: http://wordshell.net
|
56 |
|
57 |
class UpdraftPlus {
|
58 |
|
59 |
+
var $version = '1.0.20';
|
60 |
+
|
61 |
+
// Choices will be shown in the admin menu in the order used here
|
62 |
+
var $backup_methods = array (
|
63 |
+
"s3" => "Amazon S3",
|
64 |
+
"googledrive" => "Google Drive",
|
65 |
+
"ftp" => "FTP",
|
66 |
+
"email" => "Email"
|
67 |
+
);
|
68 |
|
69 |
var $dbhandle;
|
70 |
var $errors = array();
|
72 |
var $logfile_name = "";
|
73 |
var $logfile_handle = false;
|
74 |
var $backup_time;
|
|
|
|
|
75 |
|
76 |
function __construct() {
|
77 |
+
// Initialisation actions - takes place on plugin load
|
78 |
# Create admin page
|
79 |
add_action('admin_menu', array($this,'add_admin_pages'));
|
80 |
add_action('admin_init', array($this,'admin_init'));
|
91 |
add_action('init', array($this, 'handle_url_actions'));
|
92 |
}
|
93 |
|
94 |
+
// Handle actions passed on to method plugins; e.g. Google OAuth 2.0 - ?page=updraftplus&action=updraftmethod-googledrive-auth
|
95 |
// Also handle action=downloadlog
|
96 |
function handle_url_actions() {
|
97 |
// First, basic security check: must be an admin page, with ability to manage options, with the right parameters
|
98 |
if ( is_admin() && current_user_can('manage_options') && isset( $_GET['page'] ) && $_GET['page'] == 'updraftplus' && isset($_GET['action']) ) {
|
99 |
+
if (preg_match("/^updraftmethod-([a-z]+)-([a-z]+)$/", $_GET['action'], $matches) && file_exists(UPDRAFTPLUS_DIR.'/methods/'.$matches[1].'.php')) {
|
100 |
+
$method = $matches[1];
|
101 |
+
require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
|
102 |
+
$call_class = "UpdraftPlus_BackupModule_".$method;
|
103 |
+
$call_method = "action_".$matches[2];
|
104 |
+
if (method_exists($call_class, $call_method)) call_user_func(array($call_class,$call_method));
|
|
|
|
|
|
|
105 |
} elseif ($_GET['action'] == 'downloadlog' && isset($_GET['updraftplus_backup_nonce']) && preg_match("/^[0-9a-f]{12}$/",$_GET['updraftplus_backup_nonce'])) {
|
106 |
$updraft_dir = $this->backups_dir_location();
|
107 |
$log_file = $updraft_dir.'/log.'.$_GET['updraftplus_backup_nonce'].'.txt';
|
116 |
}
|
117 |
}
|
118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
# Adds the settings link under the plugin on the plugin screen.
|
120 |
function plugin_action_links($links, $file) {
|
121 |
if ($file == plugin_basename(__FILE__)){
|
391 |
|
392 |
// Dispatch to the relevant function
|
393 |
function cloud_backup($backup_array) {
|
|
|
394 |
$service = get_option('updraft_service');
|
395 |
$this->log("Cloud backup selection: ".$service);
|
396 |
@set_time_limit(900);
|
398 |
$method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
|
399 |
if (file_exists($method_include)) require_once($method_include);
|
400 |
|
401 |
+
$objname = "UpdraftPlus_BackupModule_${service}";
|
402 |
+
if (method_exists($objname, "backup")) {
|
403 |
// New style - external, allowing more plugability
|
404 |
+
$remote_obj = new $objname;
|
405 |
+
$remote_obj->backup($backup_array);
|
406 |
} else {
|
407 |
$this->prune_retained_backups("local");
|
408 |
}
|
409 |
}
|
410 |
|
411 |
+
function prune_file($updraft_service, $dofile, $method_object = null, $object_passback = null ) {
|
412 |
+
$this->log("Delete this file: $dofile, service=$updraft_service");
|
413 |
+
$fullpath = trailingslashit(get_option('updraft_dir')).$dofile;
|
414 |
+
// delete it if it's locally available
|
415 |
+
if (file_exists($fullpath)) {
|
416 |
+
$this->log("Deleting local copy ($fullpath)");
|
417 |
+
@unlink($fullpath);
|
418 |
+
}
|
419 |
+
|
420 |
+
// Despatch to the particular method's deletion routine
|
421 |
+
if (!is_null($method_object)) $method_object->delete($dofile, $object_passback);
|
422 |
+
}
|
423 |
+
|
424 |
// Carries out retain behaviour. Pass in a valid S3 or FTP object and path if relevant.
|
425 |
+
function prune_retained_backups($updraft_service, $backup_method_object = null, $backup_passback = null) {
|
426 |
+
|
427 |
$this->log("Retain: beginning examination of existing backup sets");
|
428 |
+
|
429 |
// Number of backups to retain
|
430 |
+
$updraft_retain = get_option('updraft_retain', 1);
|
431 |
+
$retain = (is_numeric($updraft_retain)) ? $updraft_retain : 1;
|
432 |
$this->log("Retain: user setting: number to retain = $retain");
|
433 |
+
|
434 |
// Returns an array, most recent first, of backup sets
|
435 |
$backup_history = $this->get_backup_history();
|
436 |
$db_backups_found = 0;
|
437 |
$file_backups_found = 0;
|
438 |
$this->log("Number of backup sets in history: ".count($backup_history));
|
439 |
+
|
440 |
foreach ($backup_history as $backup_datestamp => $backup_to_examine) {
|
441 |
// $backup_to_examine is an array of file names, keyed on db/plugins/themes/uploads
|
442 |
// The new backup_history array is saved afterwards, so remember to unset the ones that are to be deleted
|
443 |
$this->log("Examining backup set with datestamp: $backup_datestamp");
|
444 |
+
|
445 |
if (isset($backup_to_examine['db'])) {
|
446 |
$db_backups_found++;
|
447 |
$this->log("$backup_datestamp: this set includes a database (".$backup_to_examine['db']."); db count is now $db_backups_found");
|
448 |
if ($db_backups_found > $retain) {
|
449 |
$this->log("$backup_datestamp: over retain limit; will delete this database");
|
450 |
+
$dofile = $backup_to_examine['db'];
|
451 |
+
if (!empty($dofile)) $this->prune_file($updraft_service, $dofile, $backup_method_object, $backup_passback);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
unset($backup_to_examine['db']);
|
453 |
}
|
454 |
}
|
461 |
$file2 = isset($backup_to_examine['themes']) ? $backup_to_examine['themes'] : "";
|
462 |
$file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
|
463 |
$file4 = isset($backup_to_examine['others']) ? $backup_to_examine['others'] : "";
|
464 |
+
foreach (array($file, $file2, $file3, $file4) as $dofile) {
|
465 |
+
if (!empty($dofile)) $this->prune_file($updraft_service, $dofile, $backup_method_object, $backup_passback);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
466 |
}
|
467 |
unset($backup_to_examine['plugins']);
|
468 |
unset($backup_to_examine['themes']);
|
1088 |
$method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
|
1089 |
if (file_exists($method_include)) require_once($method_include);
|
1090 |
|
1091 |
+
$objname = "UpdraftPlus_BackupModule_${service}";
|
1092 |
+
if (method_exists($objname, "download")) {
|
1093 |
+
$remote_obj = new $objname;
|
1094 |
+
$remote_obj->download($file);
|
1095 |
} else {
|
1096 |
$this->error('Automatic backup restoration is not available with the method: $service.');
|
1097 |
}
|
1128 |
if(!class_exists('WP_Upgrader')) {
|
1129 |
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
1130 |
}
|
1131 |
+
require_once(UPDRAFTPLUS_DIR.'/includes/updraft-restorer.php');
|
1132 |
$restorer = new Updraft_Restorer();
|
1133 |
$val = $restorer->restore_backup($fullpath,$type);
|
1134 |
if(is_wp_error($val)) {
|
1249 |
register_setting( 'updraft-options-group', 'updraft_retain', array($this,'retain_range') );
|
1250 |
register_setting( 'updraft-options-group', 'updraft_encryptionphrase', 'wp_filter_nohtml_kses' );
|
1251 |
register_setting( 'updraft-options-group', 'updraft_service', 'wp_filter_nohtml_kses' );
|
1252 |
+
|
1253 |
register_setting( 'updraft-options-group', 'updraft_s3_login', 'wp_filter_nohtml_kses' );
|
1254 |
register_setting( 'updraft-options-group', 'updraft_s3_pass', 'wp_filter_nohtml_kses' );
|
1255 |
register_setting( 'updraft-options-group', 'updraft_s3_remote_path', 'wp_filter_nohtml_kses' );
|
1258 |
register_setting( 'updraft-options-group', 'updraft_googledrive_remotepath', 'wp_filter_nohtml_kses' );
|
1259 |
register_setting( 'updraft-options-group', 'updraft_ftp_login', 'wp_filter_nohtml_kses' );
|
1260 |
register_setting( 'updraft-options-group', 'updraft_ftp_pass', 'wp_filter_nohtml_kses' );
|
|
|
|
|
1261 |
register_setting( 'updraft-options-group', 'updraft_ftp_remote_path', 'wp_filter_nohtml_kses' );
|
1262 |
register_setting( 'updraft-options-group', 'updraft_server_address', 'wp_filter_nohtml_kses' );
|
1263 |
+
register_setting( 'updraft-options-group', 'updraft_dir', 'wp_filter_nohtml_kses' );
|
1264 |
+
register_setting( 'updraft-options-group', 'updraft_email', 'wp_filter_nohtml_kses' );
|
1265 |
register_setting( 'updraft-options-group', 'updraft_delete_local', 'absint' );
|
1266 |
register_setting( 'updraft-options-group', 'updraft_debug_mode', 'absint' );
|
1267 |
register_setting( 'updraft-options-group', 'updraft_include_plugins', 'absint' );
|
1269 |
register_setting( 'updraft-options-group', 'updraft_include_uploads', 'absint' );
|
1270 |
register_setting( 'updraft-options-group', 'updraft_include_others', 'absint' );
|
1271 |
register_setting( 'updraft-options-group', 'updraft_include_others_exclude', 'wp_filter_nohtml_kses' );
|
1272 |
+
|
1273 |
if (current_user_can('manage_options') && get_option('updraft_service') == "googledrive" && get_option('updraft_googledrive_clientid') != "" && get_option('updraft_googledrive_token','xyz') == 'xyz') {
|
1274 |
add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
|
1275 |
}
|
1628 |
?>
|
1629 |
<td><input type="text" name="updraft_retain" value="<?php echo $retain ?>" style="width:50px" /></td>
|
1630 |
</tr>
|
1631 |
+
<tr class="backup-retain-description">
|
1632 |
+
<td></td><td>By default only the most recent backup is retained. If you'd like to preserve more, specify the number here. (This many of <strong>both</strong> files and database backups will be retained.)</td>
|
1633 |
+
</tr>
|
1634 |
+
<tr>
|
1635 |
<th>Email:</th>
|
1636 |
<td><input type="text" style="width:260px" name="updraft_email" value="<?php echo get_option('updraft_email'); ?>" /> <br>Enter an address here to have a report sent (and the whole backup, if you choose) to it.</td>
|
1637 |
</tr>
|
1638 |
+
<tr class="deletelocal">
|
1639 |
<th>Delete local backup:</th>
|
1640 |
<td><input type="checkbox" name="updraft_delete_local" value="1" <?php $delete_local = (get_option('updraft_delete_local')) ? 'checked="checked"' : "";
|
1641 |
echo $delete_local; ?> /> <br>Check this to delete the local backup file (only sensible if you have enabled a remote backup (below), otherwise you will have no backup remaining).</td>
|
1642 |
</tr>
|
1643 |
|
|
|
|
|
|
|
1644 |
<tr>
|
1645 |
<th>Database encryption phrase:</th>
|
1646 |
<?php
|
1662 |
<?php
|
1663 |
$debug_mode = (get_option('updraft_debug_mode')) ? 'checked="checked"' : "";
|
1664 |
|
|
|
|
|
|
|
|
|
1665 |
$set = 'selected="selected"';
|
1666 |
+
|
1667 |
+
// Should be one of s3, ftp, googledrive, email, or whatever else is added
|
1668 |
+
$active_service = get_option('updraft_service');
|
1669 |
+
|
1670 |
+
?>
|
1671 |
+
<option value="none" <?php
|
1672 |
+
if ($active_service == "none") echo $set; ?>>None</option>
|
1673 |
+
<?php
|
1674 |
+
foreach ($this->backup_methods as $method => $description) {
|
1675 |
+
echo "<option value=\"$method\"";
|
1676 |
+
if ($active_service == $method) echo ' '.$set;
|
1677 |
+
echo '>'.$description;
|
1678 |
+
echo "</option>\n";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1679 |
}
|
1680 |
?>
|
|
|
|
|
|
|
|
|
|
|
1681 |
</select></td>
|
1682 |
</tr>
|
1683 |
<tr class="backup-service-description">
|
1684 |
<td></td><td>Choose your backup method. If choosing "E-Mail", then be aware that mail servers tend to have size limits; typically around 10-20Mb; backups larger than any limits will not arrive.</td>
|
1685 |
|
1686 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1687 |
<?php
|
1688 |
+
foreach ($this->backup_methods as $method => $description) {
|
1689 |
+
require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
|
1690 |
+
$call_method = "UpdraftPlus_BackupModule_$method";
|
1691 |
+
$call_method::config_print();
|
1692 |
+
}
|
1693 |
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1694 |
</table>
|
1695 |
+
<script type="text/javascript">
|
1696 |
+
/* <![CDATA[ */
|
1697 |
+
jQuery(document).ready(function() {
|
1698 |
+
jQuery('.updraftplusmethod').hide();
|
1699 |
+
<?php
|
1700 |
+
if ($active_service) { echo "jQuery('.<?php echo $active_service ?>').show();"; }
|
1701 |
+
?>
|
1702 |
+
});
|
1703 |
+
/* ]]> */
|
1704 |
+
</script>
|
1705 |
<table class="form-table" style="width:850px;">
|
1706 |
+
<tr>
|
1707 |
+
<td colspan="2"><h2>Advanced / Debugging Settings</h2></td>
|
1708 |
+
</tr>
|
1709 |
<tr>
|
1710 |
<th>Backup Directory:</th>
|
1711 |
+
<td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo htmlspecialchars($updraft_dir); ?>" /></td>
|
1712 |
</tr>
|
1713 |
<tr>
|
1714 |
<td></td><td><?php echo $dir_info ?> This is where Updraft Backup/Restore will write the zip files it creates initially. This directory must be writable by your web server. Typically you'll want to have it inside your wp-content folder (this is the default). <b>Do not</b> place it inside your uploads dir, as that will cause recursion issues (backups of backups of backups of...).</td>
|
1753 |
|
1754 |
|
1755 |
<script type="text/javascript">
|
1756 |
+
/* <![CDATA[ */
|
1757 |
jQuery(document).ready(function() {
|
1758 |
jQuery('#updraft-service').change(function() {
|
1759 |
+
jQuery('.updraftplusmethod').hide();
|
1760 |
+
var active_class = jQuery(this).val();
|
1761 |
+
jQuery('.'+active_class).show();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1762 |
})
|
1763 |
})
|
1764 |
jQuery(window).load(function() {
|
1768 |
jQuery('#updraft-restore-progress').toggle(500)
|
1769 |
})
|
1770 |
})
|
1771 |
+
/* ]]> */
|
1772 |
</script>
|
1773 |
<?php
|
1774 |
}
|
1775 |
|
1776 |
/*array2json provided by bin-co.com under BSD license*/
|
1777 |
function array2json($arr) {
|
1778 |
+
if(function_exists('json_encode')) return stripslashes(json_encode($arr)); // PHP >= 5.2 already has this functionality.
|
1779 |
$parts = array();
|
1780 |
$is_list = false;
|
1781 |
|
1820 |
echo '<div id="updraftmessage" class="updated fade">'."<p>$message</p></div>";
|
1821 |
}
|
1822 |
|
|
|
|
|
|
|
|
|
1823 |
function show_admin_warning_unreadablelog() {
|
1824 |
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> The log file could not be read.</a>');
|
1825 |
}
|
1826 |
|
1827 |
+
function show_admin_warning_googledrive() {
|
1828 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit">Click here to authenticate your Google Drive account (you will not be able to back up to Google Drive without it).</a>');
|
1829 |
+
}
|
1830 |
+
|
1831 |
|
1832 |
}
|
1833 |
|