UpdraftPlus WordPress Backup Plugin - Version 1.3.3

Version Description

  • 01/24/2013 =
  • Fixed faulty assumptions in 'resume' code, now leading to more reliable resuming
Download this release

Release Info

Developer DavidAnderson
Plugin Icon 128x128 UpdraftPlus WordPress Backup Plugin
Version 1.3.3
Comparing to
See all releases

Code changes from version 1.2.46 to 1.3.3

includes/Dropbox/OAuth/Storage/WordPress.php CHANGED
@@ -49,7 +49,7 @@ class Dropbox_WordPress implements Dropbox_StorageInterface
49
  if ($type != 'request_token' && $type != 'access_token') {
50
  throw new Dropbox_Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
51
  } else {
52
- if (false !== ($gettoken = get_option($this->option_name_prefix.$type))) {
53
  $token = $this->decrypt($gettoken);
54
  return $token;
55
  }
@@ -70,7 +70,7 @@ class Dropbox_WordPress implements Dropbox_StorageInterface
70
  throw new Dropbox_Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
71
  } else {
72
  $token = $this->encrypt($token);
73
- update_option($this->option_name_prefix.$type, $token);
74
  }
75
  }
76
 
@@ -80,8 +80,8 @@ class Dropbox_WordPress implements Dropbox_StorageInterface
80
  */
81
  public function delete()
82
  {
83
- delete_option($this->option_name_prefix.'request_token');
84
- delete_option($this->option_name_prefix.'access_token');
85
  return true;
86
  }
87
 
49
  if ($type != 'request_token' && $type != 'access_token') {
50
  throw new Dropbox_Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
51
  } else {
52
+ if (false !== ($gettoken = UpdraftPlus_Options::get_updraft_option($this->option_name_prefix.$type))) {
53
  $token = $this->decrypt($gettoken);
54
  return $token;
55
  }
70
  throw new Dropbox_Exception("Expected a type of either 'request_token' or 'access_token', got '$type'");
71
  } else {
72
  $token = $this->encrypt($token);
73
+ UpdraftPlus_Options::update_updraft_option($this->option_name_prefix.$type, $token);
74
  }
75
  }
76
 
80
  */
81
  public function delete()
82
  {
83
+ UpdraftPlus_Options::delete_updraft_option($this->option_name_prefix.'request_token');
84
+ UpdraftPlus_Options::delete_updraft_option($this->option_name_prefix.'access_token');
85
  return true;
86
  }
87
 
includes/updraft-restorer.php CHANGED
@@ -14,7 +14,7 @@ class Updraft_Restorer extends WP_Upgrader {
14
 
15
  function restore_backup($backup_file, $type) {
16
 
17
- if ($type == 'nonce') return;
18
 
19
  global $wp_filesystem;
20
  $this->init();
@@ -29,7 +29,7 @@ class Updraft_Restorer extends WP_Upgrader {
29
  if ( is_wp_error($download) )
30
  return $download;
31
 
32
- $delete = (get_option('updraft_delete_local')) ? true : false;
33
 
34
  $working_dir = $this->unpack_package($download , $delete);
35
  if (is_wp_error($working_dir)) return $working_dir;
14
 
15
  function restore_backup($backup_file, $type) {
16
 
17
+ if ($type != 'plugins' && $type != 'themes' && $type != 'others' && $type != 'uploads') continue;
18
 
19
  global $wp_filesystem;
20
  $this->init();
29
  if ( is_wp_error($download) )
30
  return $download;
31
 
32
+ $delete = (UpdraftPlus_Options::get_updraft_option('updraft_delete_local')) ? true : false;
33
 
34
  $working_dir = $this->unpack_package($download , $delete);
35
  if (is_wp_error($working_dir)) return $working_dir;
methods/dropbox.php CHANGED
@@ -28,7 +28,7 @@ class UpdraftPlus_BackupModule_dropbox {
28
  global $updraftplus;
29
  $updraftplus->log("Dropbox: begin cloud upload");
30
 
31
- if (get_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
32
  $updraftplus->log('You do not appear to be authenticated with Dropbox');
33
  $updraftplus->error('You do not appear to be authenticated with Dropbox');
34
  return false;
@@ -44,7 +44,7 @@ class UpdraftPlus_BackupModule_dropbox {
44
  }
45
 
46
  $updraft_dir = $updraftplus->backups_dir_location();
47
- $dropbox_folder = trailingslashit(get_option('updraft_dropbox_folder'));
48
 
49
  foreach($backup_array as $file) {
50
  $updraftplus->log("Dropbox: Attempt to upload: $file");
@@ -121,7 +121,7 @@ class UpdraftPlus_BackupModule_dropbox {
121
  global $updraftplus;
122
  $updraftplus->log("Dropbox: request deletion: $file");
123
 
124
- if (get_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
125
  $updraftplus->log('You do not appear to be authenticated with Dropbox');
126
  //$updraftplus->error('You do not appear to be authenticated with Dropbox');
127
  return false;
@@ -135,7 +135,7 @@ class UpdraftPlus_BackupModule_dropbox {
135
  return false;
136
  }
137
 
138
- $dropbox_folder = trailingslashit(get_option('updraft_dropbox_folder'));
139
 
140
  $file_success = 1;
141
  try {
@@ -168,7 +168,7 @@ class UpdraftPlus_BackupModule_dropbox {
168
 
169
  global $updraftplus;
170
 
171
- if (get_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
172
  $updraftplus->error('You do not appear to be authenticated with Dropbox');
173
  return false;
174
  }
@@ -194,7 +194,7 @@ class UpdraftPlus_BackupModule_dropbox {
194
 
195
  // TODO: Remove this October 2013 (we stored in the wrong place for a while...)
196
  if ($try_the_other_one) {
197
- $dropbox_folder = trailingslashit(get_option('updraft_dropbox_folder'));
198
  $updraftplus->error('Dropbox error: '.$e);
199
  try {
200
  $get = $dropbox->getFile($file, $updraft_dir.'/'.$file);
@@ -219,7 +219,7 @@ class UpdraftPlus_BackupModule_dropbox {
219
 
220
  <tr class="updraftplusmethod dropbox">
221
  <th>Authenticate with Dropbox:</th>
222
- <td><p><?php if (get_option('updraft_dropboxtk_request_token','xyz') != 'xyz') echo "<strong>(You appear to be already authenticated).</strong>"; ?> <a href="?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit"><strong>After</strong> you have saved your settings (by clicking &quot;Save Changes&quot; below), then come back here once and click this link to complete authentication with Dropbox.</a>
223
  </p>
224
  </td>
225
  </tr>
@@ -252,16 +252,16 @@ class UpdraftPlus_BackupModule_dropbox {
252
 
253
  <?php
254
  // Legacy: only show this next setting to old users who had a setting stored
255
- if (get_option('updraft_dropbox_appkey')) {
256
  ?>
257
 
258
  <tr class="updraftplusmethod dropbox">
259
  <th>Your Dropbox App Key:</th>
260
- <td><input type="text" autocomplete="off" style="width:332px" id="updraft_dropbox_appkey" name="updraft_dropbox_appkey" value="<?php echo htmlspecialchars(get_option('updraft_dropbox_appkey')) ?>" /></td>
261
  </tr>
262
  <tr class="updraftplusmethod dropbox">
263
  <th>Your Dropbox App Secret:</th>
264
- <td><input type="text" style="width:332px" id="updraft_dropbox_secret" name="updraft_dropbox_secret" value="<?php echo htmlspecialchars(get_option('updraft_dropbox_secret')); ?>" /></td>
265
  </tr>
266
 
267
  <?php } ?>
@@ -318,9 +318,9 @@ class UpdraftPlus_BackupModule_dropbox {
318
  }
319
 
320
  function auth_token() {
321
- $previous_token = get_option("updraft_dropboxtk_request_token","xyz");
322
  self::bootstrap();
323
- $new_token = get_option("updraft_dropboxtk_request_token","xyz");
324
  if ($new_token && $new_token != "xyz") {
325
  add_action('admin_notices', array('UpdraftPlus_BackupModule_dropbox', 'show_authed_admin_warning') );
326
  }
@@ -347,8 +347,8 @@ class UpdraftPlus_BackupModule_dropbox {
347
  // require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Consumer/WordPress.php');
348
 
349
  // This formulation was required by Dropbox's developer programme, for what reasons you should ask them!
350
- $sec = get_option(base64_decode('dXBkcmFmdF9kcm9wYm94X2FwcGtleQ=='));
351
- $key = get_option(base64_decode('dXBkcmFmdF9kcm9wYm94X3NlY3JldA=='));
352
 
353
  // Set the callback URL
354
  $callback = admin_url('options-general.php?page=updraftplus&action=updraftmethod-dropbox-auth');
28
  global $updraftplus;
29
  $updraftplus->log("Dropbox: begin cloud upload");
30
 
31
+ if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
32
  $updraftplus->log('You do not appear to be authenticated with Dropbox');
33
  $updraftplus->error('You do not appear to be authenticated with Dropbox');
34
  return false;
44
  }
45
 
46
  $updraft_dir = $updraftplus->backups_dir_location();
47
+ $dropbox_folder = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_folder'));
48
 
49
  foreach($backup_array as $file) {
50
  $updraftplus->log("Dropbox: Attempt to upload: $file");
121
  global $updraftplus;
122
  $updraftplus->log("Dropbox: request deletion: $file");
123
 
124
+ if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
125
  $updraftplus->log('You do not appear to be authenticated with Dropbox');
126
  //$updraftplus->error('You do not appear to be authenticated with Dropbox');
127
  return false;
135
  return false;
136
  }
137
 
138
+ $dropbox_folder = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_folder'));
139
 
140
  $file_success = 1;
141
  try {
168
 
169
  global $updraftplus;
170
 
171
+ if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token', 'xyz') == 'xyz') {
172
  $updraftplus->error('You do not appear to be authenticated with Dropbox');
173
  return false;
174
  }
194
 
195
  // TODO: Remove this October 2013 (we stored in the wrong place for a while...)
196
  if ($try_the_other_one) {
197
+ $dropbox_folder = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_folder'));
198
  $updraftplus->error('Dropbox error: '.$e);
199
  try {
200
  $get = $dropbox->getFile($file, $updraft_dir.'/'.$file);
219
 
220
  <tr class="updraftplusmethod dropbox">
221
  <th>Authenticate with Dropbox:</th>
222
+ <td><p><?php if (UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','xyz') != 'xyz') echo "<strong>(You appear to be already authenticated).</strong>"; ?> <a href="?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit"><strong>After</strong> you have saved your settings (by clicking &quot;Save Changes&quot; below), then come back here once and click this link to complete authentication with Dropbox.</a>
223
  </p>
224
  </td>
225
  </tr>
252
 
253
  <?php
254
  // Legacy: only show this next setting to old users who had a setting stored
255
+ if (UpdraftPlus_Options::get_updraft_option('updraft_dropbox_appkey')) {
256
  ?>
257
 
258
  <tr class="updraftplusmethod dropbox">
259
  <th>Your Dropbox App Key:</th>
260
+ <td><input type="text" autocomplete="off" style="width:332px" id="updraft_dropbox_appkey" name="updraft_dropbox_appkey" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_appkey')) ?>" /></td>
261
  </tr>
262
  <tr class="updraftplusmethod dropbox">
263
  <th>Your Dropbox App Secret:</th>
264
+ <td><input type="text" style="width:332px" id="updraft_dropbox_secret" name="updraft_dropbox_secret" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_dropbox_secret')); ?>" /></td>
265
  </tr>
266
 
267
  <?php } ?>
318
  }
319
 
320
  function auth_token() {
321
+ $previous_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
322
  self::bootstrap();
323
+ $new_token = UpdraftPlus_Options::get_updraft_option("updraft_dropboxtk_request_token","xyz");
324
  if ($new_token && $new_token != "xyz") {
325
  add_action('admin_notices', array('UpdraftPlus_BackupModule_dropbox', 'show_authed_admin_warning') );
326
  }
347
  // require_once(UPDRAFTPLUS_DIR.'/includes/Dropbox/OAuth/Consumer/WordPress.php');
348
 
349
  // This formulation was required by Dropbox's developer programme, for what reasons you should ask them!
350
+ $sec = UpdraftPlus_Options::get_updraft_option(base64_decode('dXBkcmFmdF9kcm9wYm94X2FwcGtleQ=='));
351
+ $key = UpdraftPlus_Options::get_updraft_option(base64_decode('dXBkcmFmdF9kcm9wYm94X3NlY3JldA=='));
352
 
353
  // Set the callback URL
354
  $callback = admin_url('options-general.php?page=updraftplus&action=updraftmethod-dropbox-auth');
methods/email.php CHANGED
@@ -9,8 +9,8 @@ class UpdraftPlus_BackupModule_email {
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
  $updraftplus->prune_retained_backups("email", null, null);
9
  global $updraftplus;
10
 
11
  foreach ($backup_array as $type => $file) {
12
+ $fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
13
+ wp_mail(UpdraftPlus_Options::get_updraft_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
  $updraftplus->prune_retained_backups("email", null, null);
methods/ftp.php CHANGED
@@ -8,8 +8,8 @@ class UpdraftPlus_BackupModule_ftp {
8
 
9
  if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
10
 
11
- $server = get_option('updraft_server_address');
12
- $ftp = new ftp_wrapper($server , get_option('updraft_ftp_login'), get_option('updraft_ftp_pass'));
13
  $ftp->passive = true;
14
 
15
  if (!$ftp->connect()) {
@@ -23,9 +23,9 @@ class UpdraftPlus_BackupModule_ftp {
23
 
24
  //$ftp->make_dir(); we may need to recursively create dirs? TODO
25
 
26
- $ftp_remote_path = trailingslashit(get_option('updraft_ftp_remote_path'));
27
  foreach($backup_array as $file) {
28
- $fullpath = trailingslashit(get_option('updraft_dir')).$file;
29
  $updraftplus->log("FTP upload attempt: $file -> ftp://$server/${ftp_remote_path}${file}");
30
  $timer_start = microtime(true);
31
  $size_k = round(filesize($fullpath)/1024,1);
@@ -56,7 +56,7 @@ class UpdraftPlus_BackupModule_ftp {
56
  if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
57
 
58
  //handle errors at some point TODO
59
- $ftp = new ftp_wrapper(get_option('updraft_server_address'),get_option('updraft_ftp_login'),get_option('updraft_ftp_pass'));
60
  $ftp->passive = true;
61
 
62
  if (!$ftp->connect()) {
@@ -70,8 +70,8 @@ class UpdraftPlus_BackupModule_ftp {
70
 
71
  //$ftp->make_dir(); we may need to recursively create dirs? TODO
72
 
73
- $ftp_remote_path = trailingslashit(get_option('updraft_ftp_remote_path'));
74
- $fullpath = trailingslashit(get_option('updraft_dir')).$file;
75
  $ftp->get($fullpath, $ftp_remote_path.$file, FTP_BINARY);
76
  }
77
 
@@ -99,19 +99,19 @@ class UpdraftPlus_BackupModule_ftp {
99
  ?>
100
  <tr class="updraftplusmethod ftp">
101
  <th>FTP Server:</th>
102
- <td><input type="text" size="40" id="updraft_server_address" name="updraft_server_address" value="<?php echo htmlspecialchars(get_option('updraft_server_address')); ?>" /> <em>Both SSL and non-SSL are supported</em></td>
103
  </tr>
104
  <tr class="updraftplusmethod ftp">
105
  <th>FTP Login:</th>
106
- <td><input type="text" size="40" id="updraft_ftp_login" name="updraft_ftp_login" value="<?php echo htmlspecialchars(get_option('updraft_ftp_login')) ?>" /></td>
107
  </tr>
108
  <tr class="updraftplusmethod ftp">
109
  <th>FTP Password:</th>
110
- <td><input type="text" size="40" id="updraft_ftp_pass" name="updraft_ftp_pass" value="<?php echo htmlspecialchars(get_option('updraft_ftp_pass')); ?>" /></td>
111
  </tr>
112
  <tr class="updraftplusmethod ftp">
113
  <th>Remote Path:</th>
114
- <td><input type="text" size="64" id="updraft_ftp_remote_path" name="updraft_ftp_remote_path" value="<?php echo htmlspecialchars(get_option('updraft_ftp_remote_path')); ?>" /> <em>Needs to already exist</em></td>
115
  </tr>
116
  <tr class="updraftplusmethod ftp">
117
  <th></th>
8
 
9
  if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
10
 
11
+ $server = UpdraftPlus_Options::get_updraft_option('updraft_server_address');
12
+ $ftp = new ftp_wrapper($server , UpdraftPlus_Options::get_updraft_option('updraft_ftp_login'), UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass'));
13
  $ftp->passive = true;
14
 
15
  if (!$ftp->connect()) {
23
 
24
  //$ftp->make_dir(); we may need to recursively create dirs? TODO
25
 
26
+ $ftp_remote_path = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path'));
27
  foreach($backup_array as $file) {
28
+ $fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
29
  $updraftplus->log("FTP upload attempt: $file -> ftp://$server/${ftp_remote_path}${file}");
30
  $timer_start = microtime(true);
31
  $size_k = round(filesize($fullpath)/1024,1);
56
  if( !class_exists('ftp_wrapper')) require_once(UPDRAFTPLUS_DIR.'/includes/ftp.class.php');
57
 
58
  //handle errors at some point TODO
59
+ $ftp = new ftp_wrapper(UpdraftPlus_Options::get_updraft_option('updraft_server_address'),UpdraftPlus_Options::get_updraft_option('updraft_ftp_login'),UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass'));
60
  $ftp->passive = true;
61
 
62
  if (!$ftp->connect()) {
70
 
71
  //$ftp->make_dir(); we may need to recursively create dirs? TODO
72
 
73
+ $ftp_remote_path = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path'));
74
+ $fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
75
  $ftp->get($fullpath, $ftp_remote_path.$file, FTP_BINARY);
76
  }
77
 
99
  ?>
100
  <tr class="updraftplusmethod ftp">
101
  <th>FTP Server:</th>
102
+ <td><input type="text" size="40" id="updraft_server_address" name="updraft_server_address" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_server_address')); ?>" /> <em>Both SSL and non-SSL are supported</em></td>
103
  </tr>
104
  <tr class="updraftplusmethod ftp">
105
  <th>FTP Login:</th>
106
+ <td><input type="text" size="40" id="updraft_ftp_login" name="updraft_ftp_login" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_login')) ?>" /></td>
107
  </tr>
108
  <tr class="updraftplusmethod ftp">
109
  <th>FTP Password:</th>
110
+ <td><input type="text" size="40" id="updraft_ftp_pass" name="updraft_ftp_pass" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_pass')); ?>" /></td>
111
  </tr>
112
  <tr class="updraftplusmethod ftp">
113
  <th>Remote Path:</th>
114
+ <td><input type="text" size="64" id="updraft_ftp_remote_path" name="updraft_ftp_remote_path" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_ftp_remote_path')); ?>" /> <em>Needs to already exist</em></td>
115
  </tr>
116
  <tr class="updraftplusmethod ftp">
117
  <th></th>
methods/googledrive.php CHANGED
@@ -45,7 +45,7 @@ class UpdraftPlus_BackupModule_googledrive {
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',
@@ -57,8 +57,8 @@ class UpdraftPlus_BackupModule_googledrive {
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
 
@@ -67,8 +67,8 @@ class UpdraftPlus_BackupModule_googledrive {
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
  );
@@ -80,7 +80,7 @@ class UpdraftPlus_BackupModule_googledrive {
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 {
@@ -101,7 +101,7 @@ class UpdraftPlus_BackupModule_googledrive {
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
  }
@@ -109,11 +109,11 @@ class UpdraftPlus_BackupModule_googledrive {
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 {
@@ -126,7 +126,7 @@ class UpdraftPlus_BackupModule_googledrive {
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;
@@ -137,7 +137,7 @@ class UpdraftPlus_BackupModule_googledrive {
137
  } else {
138
  $updraftplus->log("Deletion successful");
139
  unset($ids[$file]);
140
- update_option('updraft_file_ids', $ids);
141
  }
142
  }
143
  return;
@@ -235,7 +235,7 @@ class UpdraftPlus_BackupModule_googledrive {
235
  if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
236
 
237
  // Do we have an access token?
238
- if ( !$access_token = $this->access_token( get_option('updraft_googledrive_token'), get_option('updraft_googledrive_clientid'), get_option('updraft_googledrive_secret') )) {
239
  $updraftplus->error('Have not yet obtained an access token from Google (has the user authorised?)');
240
  return false;
241
  }
@@ -246,7 +246,7 @@ class UpdraftPlus_BackupModule_googledrive {
246
  if ( is_wp_error( $e = $this->need_gdocs() ) ) return false;
247
  $gdocs_object = $this->gdocs;
248
 
249
- $ids = get_option('updraft_file_ids', array());
250
  if (!isset($ids[$file])) {
251
  $updraftplus->error("Google Drive error: $file: could not download: could not find a record of the Google Drive file ID for this file");
252
  return;
@@ -258,7 +258,7 @@ class UpdraftPlus_BackupModule_googledrive {
258
  return false;
259
  }
260
  // Actually download the thing
261
- $download_to = trailingslashit(get_option('updraft_dir')).$file;
262
  $gdocs_object->download_data($content_link, $download_to);
263
 
264
  if (filesize($download_to) >0) {
@@ -280,7 +280,7 @@ class UpdraftPlus_BackupModule_googledrive {
280
  global $updraftplus;
281
 
282
  if ( ! $this->is_gdocs($this->gdocs) ) {
283
- if ( get_option('updraft_googledrive_token') == "" || get_option('updraft_googledrive_clientid') == "" || get_option('updraft_googledrive_secret') == "" ) {
284
  $updraftplus->log("GoogleDrive: this account is not authorised");
285
  return new WP_Error( "not_authorized", "Account is not authorized." );
286
  }
@@ -327,19 +327,19 @@ class UpdraftPlus_BackupModule_googledrive {
327
 
328
  <tr class="updraftplusmethod googledrive">
329
  <th>Google Drive Client ID:</th>
330
- <td><input type="text" autocomplete="off" style="width:332px" name="updraft_googledrive_clientid" value="<?php echo htmlspecialchars(get_option('updraft_googledrive_clientid')) ?>" /></td>
331
  </tr>
332
  <tr class="updraftplusmethod googledrive">
333
  <th>Google Drive Client Secret:</th>
334
- <td><input type="text" style="width:332px" name="updraft_googledrive_secret" value="<?php echo htmlspecialchars(get_option('updraft_googledrive_secret')); ?>" /></td>
335
  </tr>
336
  <tr class="updraftplusmethod googledrive">
337
  <th>Google Drive Folder ID:</th>
338
- <td><input type="text" style="width:332px" name="updraft_googledrive_remotepath" value="<?php echo htmlspecialchars(get_option('updraft_googledrive_remotepath')); ?>" /> <em><strong>This is NOT a folder name</strong>. 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>
339
  </tr>
340
  <tr class="updraftplusmethod googledrive">
341
  <th>Authenticate with Google:</th>
342
- <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 &quot;Save Changes&quot; below), then come back here once and click this link to complete authentication with Google.</a>
343
  </p>
344
  </td>
345
  </tr>
45
  function gdrive_auth_request() {
46
  $params = array(
47
  'response_type' => 'code',
48
+ 'client_id' => UpdraftPlus_Options::get_updraft_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',
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='.UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'));
61
+ UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token','');
62
  header('Location: '.admin_url( 'options-general.php?page=updraftplus&message=Authorisation revoked'));
63
  }
64
 
67
  if( isset( $_GET['code'] ) ) {
68
  $post_vars = array(
69
  'code' => $_GET['code'],
70
+ 'client_id' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'),
71
+ 'client_secret' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret'),
72
  'redirect_uri' => admin_url('options-general.php?page=updraftplus&action=updraftmethod-googledrive-auth'),
73
  'grant_type' => 'authorization_code'
74
  );
80
  } else {
81
  $json_values = json_decode( $result['body'], true );
82
  if ( isset( $json_values['refresh_token'] ) ) {
83
+ UpdraftPlus_Options::update_updraft_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 {
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( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_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
  }
109
  $this->gdocs_access_token = $access_token;
110
 
111
  foreach ($backup_array as $file) {
112
+ $file_path = trailingslashit(UpdraftPlus_Options::get_updraft_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, UpdraftPlus_Options::get_updraft_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 {
126
 
127
  function delete($file) {
128
  global $updraftplus;
129
+ $ids = UpdraftPlus_Options::get_updraft_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;
137
  } else {
138
  $updraftplus->log("Deletion successful");
139
  unset($ids[$file]);
140
+ UpdraftPlus_Options::update_updraft_option('updraft_file_ids', $ids);
141
  }
142
  }
143
  return;
235
  if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
236
 
237
  // Do we have an access token?
238
+ if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
239
  $updraftplus->error('Have not yet obtained an access token from Google (has the user authorised?)');
240
  return false;
241
  }
246
  if ( is_wp_error( $e = $this->need_gdocs() ) ) return false;
247
  $gdocs_object = $this->gdocs;
248
 
249
+ $ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array());
250
  if (!isset($ids[$file])) {
251
  $updraftplus->error("Google Drive error: $file: could not download: could not find a record of the Google Drive file ID for this file");
252
  return;
258
  return false;
259
  }
260
  // Actually download the thing
261
+ $download_to = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
262
  $gdocs_object->download_data($content_link, $download_to);
263
 
264
  if (filesize($download_to) >0) {
280
  global $updraftplus;
281
 
282
  if ( ! $this->is_gdocs($this->gdocs) ) {
283
+ if ( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') == "" || UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid') == "" || UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') == "" ) {
284
  $updraftplus->log("GoogleDrive: this account is not authorised");
285
  return new WP_Error( "not_authorized", "Account is not authorized." );
286
  }
327
 
328
  <tr class="updraftplusmethod googledrive">
329
  <th>Google Drive Client ID:</th>
330
+ <td><input type="text" autocomplete="off" style="width:332px" name="updraft_googledrive_clientid" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid')) ?>" /></td>
331
  </tr>
332
  <tr class="updraftplusmethod googledrive">
333
  <th>Google Drive Client Secret:</th>
334
+ <td><input type="text" style="width:332px" name="updraft_googledrive_secret" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret')); ?>" /></td>
335
  </tr>
336
  <tr class="updraftplusmethod googledrive">
337
  <th>Google Drive Folder ID:</th>
338
+ <td><input type="text" style="width:332px" name="updraft_googledrive_remotepath" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_remotepath')); ?>" /> <em><strong>This is NOT a folder name</strong>. 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>
339
  </tr>
340
  <tr class="updraftplusmethod googledrive">
341
  <th>Authenticate with Google:</th>
342
+ <td><p><?php if (UpdraftPlus_Options::get_updraft_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 &quot;Save Changes&quot; below), then come back here once and click this link to complete authentication with Google.</a>
343
  </p>
344
  </td>
345
  </tr>
methods/s3.php CHANGED
@@ -8,9 +8,9 @@ class UpdraftPlus_BackupModule_s3 {
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
 
@@ -25,7 +25,7 @@ class UpdraftPlus_BackupModule_s3 {
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
 
@@ -136,8 +136,8 @@ class UpdraftPlus_BackupModule_s3 {
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)) {
@@ -146,7 +146,7 @@ class UpdraftPlus_BackupModule_s3 {
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 $file. Check your permissions and credentials.");
152
  }
@@ -189,15 +189,15 @@ class UpdraftPlus_BackupModule_s3 {
189
  </td></tr>
190
  <tr class="updraftplusmethod s3">
191
  <th>S3 access key:</th>
192
- <td><input type="text" autocomplete="off" style="width: 292px" id="updraft_s3_apikey" name="updraft_s3_login" value="<?php echo htmlspecialchars(get_option('updraft_s3_login')) ?>" /></td>
193
  </tr>
194
  <tr class="updraftplusmethod s3">
195
  <th>S3 secret key:</th>
196
- <td><input type="text" autocomplete="off" style="width: 292px" id="updraft_s3_apisecret" name="updraft_s3_pass" value="<?php echo htmlspecialchars(get_option('updraft_s3_pass')); ?>" /></td>
197
  </tr>
198
  <tr class="updraftplusmethod s3">
199
  <th>S3 location:</th>
200
- <td>s3://<input type="text" style="width: 292px" name="updraft_s3_remote_path" id="updraft_s3_path" value="<?php echo htmlspecialchars(get_option('updraft_s3_remote_path')); ?>" /></td>
201
  </tr>
202
  <tr class="updraftplusmethod s3">
203
  <th></th>
8
 
9
  if (!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
10
 
11
+ $s3 = new S3(UpdraftPlus_Options::get_updraft_option('updraft_s3_login'), UpdraftPlus_Options::get_updraft_option('updraft_s3_pass'));
12
 
13
+ $bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
14
  $bucket_path = "";
15
  $orig_bucket_name = $bucket_name;
16
 
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(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
29
  $chunks = floor(filesize($fullpath) / 5242880)+1;
30
  $hash = md5($file);
31
 
136
  global $updraftplus;
137
  if(!class_exists('S3')) require_once(UPDRAFTPLUS_DIR.'/includes/S3.php');
138
 
139
+ $s3 = new S3(UpdraftPlus_Options::get_updraft_option('updraft_s3_login'), UpdraftPlus_Options::get_updraft_option('updraft_s3_pass'));
140
+ $bucket_name = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path'));
141
  $bucket_path = "";
142
 
143
  if (preg_match("#^([^/]+)/(.*)$#",$bucket_name,$bmatches)) {
146
  }
147
 
148
  if (@$s3->getBucketLocation($bucket_name)) {
149
+ $fullpath = trailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir')).$file;
150
  if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
151
  $updraftplus->error("S3 Error: Failed to download $file. Check your permissions and credentials.");
152
  }
189
  </td></tr>
190
  <tr class="updraftplusmethod s3">
191
  <th>S3 access key:</th>
192
+ <td><input type="text" autocomplete="off" style="width: 292px" id="updraft_s3_apikey" name="updraft_s3_login" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_s3_login')) ?>" /></td>
193
  </tr>
194
  <tr class="updraftplusmethod s3">
195
  <th>S3 secret key:</th>
196
+ <td><input type="text" autocomplete="off" style="width: 292px" id="updraft_s3_apisecret" name="updraft_s3_pass" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_s3_pass')); ?>" /></td>
197
  </tr>
198
  <tr class="updraftplusmethod s3">
199
  <th>S3 location:</th>
200
+ <td>s3://<input type="text" style="width: 292px" name="updraft_s3_remote_path" id="updraft_s3_path" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_s3_remote_path')); ?>" /></td>
201
  </tr>
202
  <tr class="updraftplusmethod s3">
203
  <th></th>
options.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Options handling
4
+ if (!defined ('ABSPATH')) die ('No direct access allowed');
5
+
6
+ class UpdraftPlus_Options {
7
+
8
+ function user_can_manage() {
9
+ return current_user_can('manage_options');
10
+ }
11
+
12
+ function get_updraft_option($option, $default = null) {
13
+ return get_option($option, $default);
14
+ }
15
+
16
+ function update_updraft_option($option, $value) {
17
+ update_option($option, $value);
18
+ }
19
+
20
+ function delete_updraft_option($option) {
21
+ delete_option($option, $value);
22
+ }
23
+
24
+ function add_admin_pages() {
25
+ global $updraftplus;
26
+ add_submenu_page('options-general.php', "UpdraftPlus", "UpdraftPlus", "manage_options", "updraftplus", array($updraftplus, "settings_output"));
27
+ }
28
+
29
+ function options_form_begin() {
30
+ echo '<form method="post" action="options.php">';
31
+ settings_fields('updraft-options-group');
32
+ }
33
+
34
+ function admin_init() {
35
+
36
+ global $updraftplus;
37
+ register_setting('updraft-options-group', 'updraft_interval', array($updraftplus, 'schedule_backup') );
38
+ register_setting('updraft-options-group', 'updraft_interval_database', array($updraftplus, 'schedule_backup_database') );
39
+ register_setting('updraft-options-group', 'updraft_retain', array($updraftplus, 'retain_range') );
40
+ register_setting('updraft-options-group', 'updraft_retain_db', array($updraftplus, 'retain_range') );
41
+ register_setting('updraft-options-group', 'updraft_encryptionphrase');
42
+ register_setting('updraft-options-group', 'updraft_service' );
43
+
44
+ register_setting('updraft-options-group', 'updraft_s3_login' );
45
+ register_setting('updraft-options-group', 'updraft_s3_pass' );
46
+ register_setting('updraft-options-group', 'updraft_s3_remote_path' );
47
+
48
+ register_setting('updraft-options-group', 'updraft_dropbox_appkey' );
49
+ register_setting('updraft-options-group', 'updraft_dropbox_secret' );
50
+ register_setting('updraft-options-group', 'updraft_dropbox_folder' );
51
+
52
+ register_setting('updraft-options-group', 'updraft_googledrive_clientid' );
53
+ register_setting('updraft-options-group', 'updraft_googledrive_secret' );
54
+ register_setting('updraft-options-group', 'updraft_googledrive_remotepath' );
55
+ register_setting('updraft-options-group', 'updraft_ftp_login' );
56
+ register_setting('updraft-options-group', 'updraft_ftp_pass' );
57
+ register_setting('updraft-options-group', 'updraft_ftp_remote_path' );
58
+ register_setting('updraft-options-group', 'updraft_server_address' );
59
+ register_setting('updraft-options-group', 'updraft_dir' );
60
+ register_setting('updraft-options-group', 'updraft_email');
61
+ register_setting('updraft-options-group', 'updraft_delete_local', 'absint' );
62
+ register_setting('updraft-options-group', 'updraft_debug_mode', 'absint' );
63
+ register_setting('updraft-options-group', 'updraft_include_plugins', 'absint' );
64
+ register_setting('updraft-options-group', 'updraft_include_themes', 'absint' );
65
+ register_setting('updraft-options-group', 'updraft_include_uploads', 'absint' );
66
+ register_setting('updraft-options-group', 'updraft_include_others', 'absint' );
67
+ register_setting('updraft-options-group', 'updraft_include_others_exclude' );
68
+
69
+ if (is_multisite()) {
70
+ add_action('admin_notices', array('UpdraftPlus_Options', 'show_admin_warning_multisite') );
71
+ }
72
+
73
+ }
74
+
75
+ function show_admin_warning_multisite() {
76
+
77
+ global $updraftplus;
78
+
79
+ $updraftplus->show_admin_warning('<strong>UpdraftPlus warning:</strong> This is a WordPress multi-site (a.k.a. network) installation. <a href="http://updraftplus.com">WordPress Multisite is supported by UpdraftPlus Premium</a>. Non-premium UpdraftPlus does not support multi-site installations securely. <strong>Every</strong> blog admin can both back up (and hence access the data, including passwords, from) and restore (including with customised modifications, e.g. changed passwords) <strong>the entire network</strong>. Unless you are the only blog admin user across the entire network, you should immediately de-active UpdraftPlus. (This applies to all WordPress backup plugins unless they have been explicitly coded for multisite compatibility).', "error");
80
+
81
+ }
82
+
83
+
84
+ }
85
+
86
+ add_action('admin_init', array('UpdraftPlus_Options', 'admin_init'));
87
+ add_action('admin_menu', array('UpdraftPlus_Options', 'add_admin_pages'));
88
+
89
+ ?>
readme.txt CHANGED
@@ -1,14 +1,14 @@
1
  === UpdraftPlus Backup ===
2
  Contributors: David Anderson
3
- Tags: backup, restore, database, cloud, amazon, s3, dropbox, google drive, gdrive, ftp, cloud, updraft, back up
4
  Requires at least: 3.2
5
  Tested up to: 3.5
6
- Stable tag: 1.2.46
7
  Donate link: http://david.dw-perspective.org.uk/donate
8
  License: GPLv3 or later
9
 
10
  == Upgrade Notice ==
11
- Set retention separately for files/db. Complete Dropbox support. FTP over SSL. Less noise, more info. Option to delete all settings.
12
 
13
  == Description ==
14
 
@@ -23,6 +23,7 @@ UpdraftPlus simplifies backups (and restoration). Backup into the cloud (Amazon
23
  * Database backups can be encrypted for security
24
  * Debug mode that gives full logging of the backup
25
  * Thousands of users: widely tested and reliable
 
26
 
27
  = Best New WordPress Plugin =
28
 
@@ -32,6 +33,10 @@ That's according to WordPress big cheese, Vladimir Prelovac. Check out his weekl
32
 
33
  UpdraftPlus is written by professional WordPress developers. If your site needs guaranteed support, then we are available. Get in touch - https://www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/ - to arrange the support contract that your site needs.
34
 
 
 
 
 
35
  = Other support =
36
 
37
  We hang out in the support forum for this plugin - http://wordpress.org/support/plugin/updraftplus - however, to save our time so that we can spend it on development, please read the plugin's Frequently Asked Questions - http://wordpress.org/extend/plugins/updraftplus/faq/ - before going there, and ensure that you have updated to the latest released version of UpdraftPlus.
@@ -58,6 +63,10 @@ It does not back up WordPress core (since you can always get another copy of thi
58
 
59
  That's very good of you, thank you. You are looking for WordShell, <a href="http://wordshell.net">http://wordshell.net</a>.
60
 
 
 
 
 
61
  = I found a bug. What do I do? =
62
 
63
  Firstly, please make sure you read this FAQ through to the end - it may already have the answer you need. If it does, then please consider a donation (http://david.dw-perspective.org.uk/donate); it takes time to develop this plugin and FAQ.
@@ -132,6 +141,12 @@ Thanks for asking - yes, I have. Check out my profile page - http://profiles.wor
132
 
133
  == Changelog ==
134
 
 
 
 
 
 
 
135
  = 1.2.46 - 01/22/2013 =
136
  * Easier Dropbox setup (we are now an official production app)
137
  * New button to delete all existing settings
1
  === UpdraftPlus Backup ===
2
  Contributors: David Anderson
3
+ Tags: backup, restore, database, cloud, amazon, s3, dropbox, google drive, gdrive, ftp, cloud, updraft, back up, multisite
4
  Requires at least: 3.2
5
  Tested up to: 3.5
6
+ Stable tag: 1.3.2
7
  Donate link: http://david.dw-perspective.org.uk/donate
8
  License: GPLv3 or later
9
 
10
  == Upgrade Notice ==
11
+ Internal reorganisation, opening way for UpdraftPlus Premium
12
 
13
  == Description ==
14
 
23
  * Database backups can be encrypted for security
24
  * Debug mode that gives full logging of the backup
25
  * Thousands of users: widely tested and reliable
26
+ * Premium/multi-site version available (see below)
27
 
28
  = Best New WordPress Plugin =
29
 
33
 
34
  UpdraftPlus is written by professional WordPress developers. If your site needs guaranteed support, then we are available. Get in touch - https://www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/ - to arrange the support contract that your site needs.
35
 
36
+ = UpdraftPlus Premium =
37
+
38
+ If you need WordPress multisite compatibility (you'll know if you do), then you need UpdraftPlus Premium: http://updraftplus.com
39
+
40
  = Other support =
41
 
42
  We hang out in the support forum for this plugin - http://wordpress.org/support/plugin/updraftplus - however, to save our time so that we can spend it on development, please read the plugin's Frequently Asked Questions - http://wordpress.org/extend/plugins/updraftplus/faq/ - before going there, and ensure that you have updated to the latest released version of UpdraftPlus.
63
 
64
  That's very good of you, thank you. You are looking for WordShell, <a href="http://wordshell.net">http://wordshell.net</a>.
65
 
66
+ = Is it WordPress Multisite (a.k.a. WordPress network) compatible? =
67
+
68
+ If you have a WordPress Multisite install (and you'll know if you do), then you need <a href="http://updraftplus.com">UpdraftPlus Premium</a>.
69
+
70
  = I found a bug. What do I do? =
71
 
72
  Firstly, please make sure you read this FAQ through to the end - it may already have the answer you need. If it does, then please consider a donation (http://david.dw-perspective.org.uk/donate); it takes time to develop this plugin and FAQ.
141
 
142
  == Changelog ==
143
 
144
+ = 1.3.3 - 01/24/2013 =
145
+ * Fixed faulty assumptions in 'resume' code, now leading to more reliable resuming
146
+
147
+ = 1.3.2 - 01/23/2013 =
148
+ * Internal reorganisation, enabling UpdraftPlus Premium
149
+
150
  = 1.2.46 - 01/22/2013 =
151
  * Easier Dropbox setup (we are now an official production app)
152
  * New button to delete all existing settings
updraftplus.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: UpdraftPlus - Backup/Restore
4
  Plugin URI: http://wordpress.org/extend/plugins/updraftplus
5
  Description: Backup and restore: your content and database can be automatically backed up to Amazon S3, Dropbox, Google Drive, FTP or email, on separate schedules.
6
  Author: David Anderson.
7
- Version: 1.2.46
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
10
  Author URI: http://wordshell.net
@@ -13,6 +13,7 @@ Author URI: http://wordshell.net
13
  /*
14
  TODO
15
  //Add SFTP, Box.Net, SugarSync and Microsoft Skydrive support??
 
16
  //improve error reporting / pretty up return messages in admin area. One thing: have a "backup is now finished" flag. Otherwise with the resuming things get ambiguous/confusing. See http://wordpress.org/support/topic/backup-status - user was not aware that backup completely failed. Maybe a "backup status" field for each nonce that gets updated? (Even via AJAX?)
17
  //?? On 'backup now', open up a Lightbox, count down 5 seconds, then start examining the log file (if it can be found)
18
  //Should make clear in dashboard what is a non-fatal error (i.e. can be retried) - leads to unnecessary bug reports
@@ -25,7 +26,7 @@ TODO
25
  // Turn expert options into a jQuery toggle
26
  // Provide backup/restoration for UpdraftPlus's settings, to allow 'bootstrap' on a fresh WP install
27
  // Multiple jobs
28
- // Multi-site
29
 
30
  Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
31
  // Does not delete old custom directories upon a restore?
@@ -64,11 +65,16 @@ if (!$updraftplus->memory_check(192)) {
64
 
65
  define('UPDRAFTPLUS_DIR', dirname(__FILE__));
66
  define('UPDRAFTPLUS_URL', plugins_url('', __FILE__));
67
- define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
 
 
 
 
68
 
69
  class UpdraftPlus {
70
 
71
- var $version = '1.2.46';
 
72
 
73
  // Choices will be shown in the admin menu in the order used here
74
  var $backup_methods = array (
@@ -89,12 +95,12 @@ class UpdraftPlus {
89
  var $backup_time;
90
 
91
  var $opened_log_time;
 
92
 
93
  function __construct() {
94
  // Initialisation actions - takes place on plugin load
95
  # Create admin page
96
- add_action('admin_menu', array($this,'add_admin_pages'));
97
- add_action('admin_init', array($this,'admin_init'));
98
  add_action('updraft_backup', array($this,'backup_files'));
99
  add_action('updraft_backup_database', array($this,'backup_database'));
100
  # backup_all is used by the manual "Backup Now" button
@@ -114,7 +120,7 @@ class UpdraftPlus {
114
  // Also handle action=downloadlog
115
  function handle_url_actions() {
116
  // First, basic security check: must be an admin page, with ability to manage options, with the right parameters
117
- if ( is_admin() && current_user_can('manage_options') && isset( $_GET['page'] ) && $_GET['page'] == 'updraftplus' && isset($_GET['action']) ) {
118
  if (preg_match("/^updraftmethod-([a-z]+)-([a-z]+)$/", $_GET['action'], $matches) && file_exists(UPDRAFTPLUS_DIR.'/methods/'.$matches[1].'.php')) {
119
  $method = $matches[1];
120
  require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
@@ -168,33 +174,33 @@ class UpdraftPlus {
168
  # Logs the given line, adding (relative) time stamp and newline
169
  function log($line) {
170
  if ($this->logfile_handle) fwrite($this->logfile_handle, sprintf("%08.03f", round(microtime(true)-$this->opened_log_time, 3))." ".$line."\n");
171
- update_option("updraft_lastmessage", $line." (".date('M d H:i:s').")");
172
  }
173
 
174
- function backup_resume($resumption_no) {
 
 
 
 
175
  @ignore_user_abort(true);
176
  // This is scheduled for 5 minutes after a backup job starts
177
- $bnonce = get_transient('updraftplus_backup_job_nonce');
178
- if (!$bnonce) return;
179
  $this->nonce = $bnonce;
 
180
  $this->logfile_open($bnonce);
181
- $this->log("Resume backup ($resumption_no): begin run (will check for any remaining jobs)");
182
- $btime = get_transient('updraftplus_backup_job_time');
183
- if (!$btime) {
184
- $this->log("Did not find stored time setting - aborting");
185
- return;
186
- }
187
  $this->log("Resuming backup: resumption=$resumption_no, nonce=$bnonce, begun at=$btime");
188
  // Schedule again, to run in 5 minutes again, in case we again fail
189
  $resume_delay = 300;
190
  // A different argument than before is needed otherwise the event is ignored
191
  $next_resumption = $resumption_no+1;
192
  if ($next_resumption < 10) {
193
- wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume' ,array($next_resumption));
 
194
  } else {
195
- $this->log("The current run is our tenth attempt - will not try again");
196
  }
197
- $this->backup_time = $btime;
198
 
199
  $backup_array = $this->resumable_backup_of_files(false);
200
  // This save, if there was something, is then immediately picked up again
@@ -212,9 +218,11 @@ class UpdraftPlus {
212
  $backup_database = get_transient("updraft_backdb_".$bnonce);
213
 
214
  // The transient is read and written below (instead of using the existing variable) so that we can copy-and-paste this part as needed.
215
- if ($backup_database == "begun" || $backup_database == "finished") {
216
  if ($backup_database == "begun") {
217
  $this->log("Resuming creation of database dump");
 
 
218
  } else {
219
  $this->log("Database dump: Creation was completed already");
220
  }
@@ -223,6 +231,7 @@ class UpdraftPlus {
223
  $backup_contains = get_transient("updraft_backupcontains_".$this->nonce);
224
  $backup_contains = (substr($backup_contains,0,10) == "Files only") ? "Files and database" : "Database only (no files)";
225
  set_transient("updraft_backupcontains_".$this->nonce, $backup_contains, 3600*3);
 
226
  } else {
227
  $this->log("Unrecognised data when trying to ascertain if the database was backed up ($backup_database)");
228
  }
@@ -236,14 +245,17 @@ class UpdraftPlus {
236
  if (isset($our_files['db']) && !preg_match("/\.crypt$/", $our_files['db'])) {
237
  $our_files['db'] = $this->encrypt_file($our_files['db']);
238
  $this->save_backup_history($our_files);
 
 
239
  }
240
 
241
  foreach ($our_files as $key => $file) {
242
 
243
- if ($key == 'nonce') continue;
 
244
 
245
  $hash = md5($file);
246
- $fullpath = trailingslashit(get_option('updraft_dir')).$file;
247
  if (get_transient('updraft_'.$hash) === "yes") {
248
  $this->log("$file: $key: This file has been successfully uploaded in the last 3 hours");
249
  } elseif (is_file($fullpath)) {
@@ -257,13 +269,15 @@ class UpdraftPlus {
257
 
258
  if (count($undone_files) == 0) {
259
  $this->log("There were no more files that needed uploading; backup job is complete");
 
 
260
  return;
261
  }
262
 
263
  $this->log("Requesting backup of the files that were not successfully uploaded");
264
  $this->cloud_backup($undone_files);
265
 
266
- $this->log("Resume backup ($resumption_no): finish run");
267
 
268
  $this->backup_finish($next_resumption, true, true, $resumption_no);
269
 
@@ -287,6 +301,11 @@ class UpdraftPlus {
287
 
288
  function check_backup_race( $to_delete = false ) {
289
  // Avoid caching
 
 
 
 
 
290
  global $wpdb;
291
  $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", "_transient_updraftplus_backup_job_nonce"));
292
  $cur_trans = ( is_object( $row ) ) ? $row->option_value : "";
@@ -347,11 +366,11 @@ class UpdraftPlus {
347
 
348
  // Log some information that may be helpful
349
  global $wp_version;
350
- $this->log("Tasks: Backup files: $backup_files (schedule: ".get_option('updraft_interval','unset').") Backup DB: $backup_database (schedule: ".get_option('updraft_interval_database','unset').")");
351
 
352
  # If the files and database schedules are the same, and if this the file one, then we rope in database too.
353
  # On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
354
- if (get_option('updraft_interval') == get_option('updraft_interval_database') || get_option('updraft_interval_database','xyz') == 'xyz' ) {
355
  $backup_database = ($backup_files == true) ? true : false;
356
  }
357
 
@@ -364,16 +383,13 @@ class UpdraftPlus {
364
 
365
  $clear_nonce_transient = true;
366
 
367
- // Do not set the transient or schedule the resume event until now, when we know there is something to do - otherwise 'vacatated' runs (when the database is on the same schedule as the files, and they get combined, leading to an empty run) can over-write the resume event and prevent resumption (because it is 'successful' - there was nothing to do).
368
  // If we don't finish in 3 hours, then we won't finish
369
- // This transient indicates the identity of the current backup job (which can be used to find the files and logfile)
370
- set_transient("updraftplus_backup_job_nonce", $this->nonce, 3600*3);
371
- set_transient("updraftplus_backup_job_time", $this->backup_time, 3600*3);
372
 
373
  // Schedule the event to run later, which checks on success and can resume the backup
374
  // We save the time to a variable because it is needed for un-scheduling
375
  $resume_delay = 300;
376
- wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume', array(1));
377
  $this->log("In case we run out of time, scheduled a resumption at: $resume_delay seconds from now");
378
 
379
  $backup_contains = "";
@@ -420,6 +436,7 @@ class UpdraftPlus {
420
  // Now encrypt the database, and re-save
421
  if ($backup_database && isset($backup_array['db'])) {
422
  $backup_array['db'] = $this->encrypt_file($backup_array['db']);
 
423
  // Re-save with the possibly-altered database filename
424
  $this->save_backup_history($backup_array);
425
  }
@@ -443,7 +460,7 @@ class UpdraftPlus {
443
 
444
  // Encrypts the file if the option is set; returns the basename of the file (according to whether it was encrypted or nto)
445
  function encrypt_file($file) {
446
- $encryption = get_option('updraft_encryptionphrase');
447
  if (strlen($encryption) > 0) {
448
  $this->log("$file: applying encryption");
449
  $encryption_error = 0;
@@ -453,15 +470,7 @@ class UpdraftPlus {
453
  $rijndael->setKey($encryption);
454
  $updraft_dir = $this->backups_dir_location();
455
  $file_size = @filesize($updraft_dir.'/'.$file)/1024;
456
- $in_handle = @fopen($updraft_dir.'/'.$file,'r');
457
- $buffer = "";
458
- while (!feof ($in_handle)) {
459
- $buffer .= fread($in_handle, 16384);
460
- }
461
- fclose ($in_handle);
462
- $out_handle = @fopen($updraft_dir.'/'.$file.'.crypt','w');
463
- if (!fwrite($out_handle, $rijndael->encrypt($buffer))) {$encryption_error = 1;}
464
- fclose ($out_handle);
465
  if (0 == $encryption_error) {
466
  $time_taken = max(0.000001, microtime(true)-$microstart);
467
  $this->log("$file: encryption successful: ".round($file_size,1)."Kb in ".round($time_taken,1)."s (".round($file_size/$time_taken, 1)."Kb/s)");
@@ -484,9 +493,7 @@ class UpdraftPlus {
484
  if (empty($this->errors)) {
485
  if ($clear_nonce_transient) {
486
  $this->log("There were no errors in the uploads, so the 'resume' event is being unscheduled");
487
- wp_clear_scheduled_hook('updraft_backup_resume', array($cancel_event));
488
- delete_transient("updraftplus_backup_job_nonce");
489
- delete_transient("updraftplus_backup_job_time");
490
  }
491
  } else {
492
  $this->log("There were errors in the uploads, so the 'resume' event is remaining scheduled");
@@ -515,7 +522,7 @@ class UpdraftPlus {
515
  }
516
 
517
  // Now over-ride the decision to send an email, if needed
518
- if (get_option('updraft_debug_mode')) {
519
  $send_an_email = true;
520
  $this->log("An email has been scheduled for this job, because we are in debug mode");
521
  }
@@ -523,7 +530,7 @@ class UpdraftPlus {
523
  if (!$allow_email) {
524
  $send_an_email = false;
525
  $this->log("No email will be sent - this backup set was empty.");
526
- } elseif (get_option('updraft_email') == '') {
527
  $send_an_email = false;
528
  $this->log("No email will/can be sent - the user has not configured an email address.");
529
  }
@@ -535,15 +542,15 @@ class UpdraftPlus {
535
  @fclose($this->logfile_handle);
536
 
537
  // Don't delete the log file now; delete it upon rotation
538
- //if (!get_option('updraft_debug_mode')) @unlink($this->logfile_name);
539
 
540
  }
541
 
542
  function send_results_email() {
543
 
544
- $debug_mode = get_option('updraft_debug_mode');
545
 
546
- $sendmail_to = get_option('updraft_email');
547
 
548
  $this->log("Sending email report to: ".substr($sendmail_to, 0, 5)."...");
549
 
@@ -558,7 +565,7 @@ class UpdraftPlus {
558
 
559
  $last_backup = array('backup_time'=>$this->backup_time, 'backup_array'=>$backup_array, 'success'=>$success, 'errors'=>$this->errors, 'backup_nonce' => $this->nonce);
560
 
561
- update_option('updraft_last_backup', $last_backup);
562
  }
563
 
564
  // This should be called whenever a file is successfully uploaded
@@ -568,19 +575,19 @@ class UpdraftPlus {
568
  $this->log("Recording as successfully uploaded: $file ($hash)");
569
  set_transient("updraft_".$hash, "yes", 3600*4);
570
  if ($id) {
571
- $ids = get_option('updraft_file_ids', array() );
572
  $ids[$file] = $id;
573
- update_option('updraft_file_ids',$ids);
574
  $this->log("Stored file<->id correlation in database ($file <-> $id)");
575
  }
576
  // Delete local files immediately if the option is set
577
  // Where we are only backing up locally, only the "prune" function should do deleting
578
- if (get_option('updraft_service', 'none') != 'none') $this->delete_local($file);
579
  }
580
 
581
  // Dispatch to the relevant function
582
  function cloud_backup($backup_array) {
583
- $service = get_option('updraft_service');
584
  $this->log("Cloud backup selection: ".$service);
585
  @set_time_limit(900);
586
 
@@ -605,7 +612,7 @@ class UpdraftPlus {
605
 
606
  function prune_file($updraft_service, $dofile, $method_object = null, $object_passback = null ) {
607
  $this->log("Delete this file: $dofile, service=$updraft_service");
608
- $fullpath = trailingslashit(get_option('updraft_dir')).$dofile;
609
  // delete it if it's locally available
610
  if (file_exists($fullpath)) {
611
  $this->log("Deleting local copy ($fullpath)");
@@ -620,7 +627,7 @@ class UpdraftPlus {
620
  function prune_retained_backups($updraft_service, $backup_method_object = null, $backup_passback = null) {
621
 
622
  // If they turned off deletion on local backups, then there is nothing to do
623
- if (get_option('updraft_delete_local') == 0 && $updraft_service == 'none') {
624
  $this->log("Prune old backups from local store: nothing to do, since the user disabled local deletion and we are using local backups");
625
  return;
626
  }
@@ -628,12 +635,12 @@ class UpdraftPlus {
628
  $this->log("Retain: beginning examination of existing backup sets");
629
 
630
  // Number of backups to retain - files
631
- $updraft_retain = get_option('updraft_retain', 1);
632
  $updraft_retain = (is_numeric($updraft_retain)) ? $updraft_retain : 1;
633
  $this->log("Retain files: user setting: number to retain = $updraft_retain");
634
 
635
  // Number of backups to retain - db
636
- $updraft_retain_db = get_option('updraft_retain_db', $updraft_retain);
637
  $updraft_retain_db = (is_numeric($updraft_retain_db)) ? $updraft_retain_db : 1;
638
  $this->log("Retain db: user setting: number to retain = $updraft_retain_db");
639
 
@@ -681,7 +688,7 @@ class UpdraftPlus {
681
  $this->log("$backup_datestamp: this backup set is now empty; will remove from history");
682
  unset($backup_history[$backup_datestamp]);
683
  if (isset($backup_to_examine['nonce'])) {
684
- $fullpath = trailingslashit(get_option('updraft_dir')).'log.'.$backup_to_examine['nonce'].'.txt';
685
  if (is_file($fullpath)) {
686
  $this->log("$backup_datestamp: deleting log file (log.".$backup_to_examine['nonce'].".txt)");
687
  @unlink($fullpath);
@@ -697,14 +704,14 @@ class UpdraftPlus {
697
  }
698
  }
699
  $this->log("Retain: saving new backup history (sets now: ".count($backup_history).") and finishing retain operation");
700
- update_option('updraft_backup_history',$backup_history);
701
  }
702
 
703
  function delete_local($file) {
704
- if(get_option('updraft_delete_local')) {
705
  $this->log("Deleting local file: $file");
706
  //need error checking so we don't delete what isn't successfully uploaded?
707
- $fullpath = trailingslashit(get_option('updraft_dir')).$file;
708
  return unlink($fullpath);
709
  }
710
  return true;
@@ -783,7 +790,7 @@ class UpdraftPlus {
783
 
784
  # Plugins, themes, uploads
785
  foreach ($possible_backups as $youwhat => $whichdir) {
786
- if (get_option("updraft_include_$youwhat", true)) {
787
  if ($transient_status == 'finished') {
788
  $backup_array[$youwhat] = $backup_file_basename.'-'.$youwhat.'.zip';
789
  } else {
@@ -796,7 +803,7 @@ class UpdraftPlus {
796
  }
797
 
798
  # Others
799
- if (get_option('updraft_include_others', true)) {
800
  $this->log("Beginning backup of other directories found in the content directory");
801
 
802
  if ($transient_status == 'finished') {
@@ -815,7 +822,7 @@ class UpdraftPlus {
815
  # Initialise
816
  $other_dirlist = array();
817
 
818
- $others_skip = preg_split("/,/",get_option('updraft_include_others_exclude', UPDRAFT_DEFAULT_OTHERS_EXCLUDE));
819
  # Make the values into the keys
820
  $others_skip = array_flip($others_skip);
821
 
@@ -852,11 +859,11 @@ class UpdraftPlus {
852
 
853
  function save_backup_history($backup_array) {
854
  if(is_array($backup_array)) {
855
- $backup_history = get_option('updraft_backup_history');
856
  $backup_history = (is_array($backup_history)) ? $backup_history : array();
857
  $backup_array['nonce'] = $this->nonce;
858
  $backup_history[$this->backup_time] = $backup_array;
859
- update_option('updraft_backup_history',$backup_history);
860
  } else {
861
  $this->log('Could not save backup history because we have no backup array. Backup probably failed.');
862
  $this->error('Could not save backup history because we have no backup array. Backup probably failed.');
@@ -864,7 +871,7 @@ class UpdraftPlus {
864
  }
865
 
866
  function get_backup_history() {
867
- //$backup_history = get_option('updraft_backup_history');
868
  //by doing a raw DB query to get the most up-to-date data from this option we slightly narrow the window for the multiple-cron race condition
869
  global $wpdb;
870
  $backup_history = @unserialize($wpdb->get_var($wpdb->prepare("SELECT option_value from $wpdb->options WHERE option_name='updraft_backup_history'")));
@@ -930,6 +937,7 @@ class UpdraftPlus {
930
  $backup_file_base = $updraft_dir.'/'.$file_base;
931
 
932
  if ("finished" == $already_done) return basename($backup_file_base.'-db.gz');
 
933
 
934
  $total_tables = 0;
935
 
@@ -1234,18 +1242,20 @@ class UpdraftPlus {
1234
  $schedules['every8hours'] = array( 'interval' => 28800, 'display' => 'Every 8 hours' );
1235
  return $schedules;
1236
  }
1237
-
1238
  function backups_dir_location() {
1239
- $updraft_dir = untrailingslashit(get_option('updraft_dir'));
 
1240
  $default_backup_dir = WP_CONTENT_DIR.'/updraft';
1241
  //if the option isn't set, default it to /backups inside the upload dir
1242
  $updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
1243
  //check for the existence of the dir and an enumeration preventer.
1244
  if(!is_dir($updraft_dir) || !is_file($updraft_dir.'/index.html') || !is_file($updraft_dir.'/.htaccess')) {
1245
- @mkdir($updraft_dir,0777,true); //recursively create the dir with 0777 permissions. 0777 is default for php creation. not ideal, but I'll get back to this
1246
  @file_put_contents($updraft_dir.'/index.html','Nothing to see here.');
1247
  @file_put_contents($updraft_dir.'/.htaccess','deny from all');
1248
  }
 
1249
  return $updraft_dir;
1250
  }
1251
 
@@ -1256,7 +1266,7 @@ class UpdraftPlus {
1256
  if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
1257
 
1258
  if ('lastlog' == $_GET['subaction']) {
1259
- echo htmlspecialchars(get_option('updraft_lastmessage', '(Nothing yet logged)'));
1260
  } elseif ($_POST['subaction'] == 'credentials_test') {
1261
  $method = (preg_match("/^[a-z0-9]+$/", $_POST['method'])) ? $_POST['method'] : "";
1262
 
@@ -1276,7 +1286,7 @@ class UpdraftPlus {
1276
  $timestamp = (int)$_POST['timestamp'];
1277
  $backup_history = $this->get_backup_history();
1278
  $file = $backup_history[$timestamp][$type];
1279
- $fullpath = trailingslashit(get_option('updraft_dir')).$file;
1280
  if(!is_readable($fullpath)) {
1281
  //if the file doesn't exist and they're using one of the cloud options, fetch it down from the cloud.
1282
  $this->download_backup($file);
@@ -1303,7 +1313,7 @@ class UpdraftPlus {
1303
  }
1304
  ob_end_flush();
1305
  if ($file_ext == 'crypt') {
1306
- $encryption = get_option('updraft_encryptionphrase');
1307
  if ($encryption == "") {
1308
  $this->error('Decryption of database failed: the database file is encrypted, but you have no encryption key entered.');
1309
  } else {
@@ -1329,7 +1339,7 @@ class UpdraftPlus {
1329
  }
1330
 
1331
  function download_backup($file) {
1332
- $service = get_option('updraft_service');
1333
 
1334
  $method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
1335
  if (file_exists($method_include)) require_once($method_include);
@@ -1346,7 +1356,7 @@ class UpdraftPlus {
1346
 
1347
  function restore_backup($timestamp) {
1348
  global $wp_filesystem;
1349
- $backup_history = get_option('updraft_backup_history');
1350
  if(!is_array($backup_history[$timestamp])) {
1351
  echo '<p>This backup does not exist in the backup history - restoration aborted. Timestamp: '.$timestamp.'</p><br/>';
1352
  return false;
@@ -1363,7 +1373,7 @@ class UpdraftPlus {
1363
  //if we make it this far then WP_Filesystem has been instantiated and is functional (tested with ftpext, what about suPHP and other situations where direct may work?)
1364
  echo '<span style="font-weight:bold">Restoration Progress</span><div id="updraft-restore-progress">';
1365
 
1366
- $updraft_dir = trailingslashit(get_option('updraft_dir'));
1367
  foreach($backup_history[$timestamp] as $type => $file) {
1368
  if ($type == 'nonce') continue;
1369
  $fullpath = $updraft_dir.$file;
@@ -1444,7 +1454,7 @@ class UpdraftPlus {
1444
  exit;
1445
  }
1446
 
1447
- $updraft_dir = untrailingslashit(get_option('updraft_dir'));
1448
  $default_backup_dir = WP_CONTENT_DIR.'/updraft';
1449
  $updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
1450
 
@@ -1483,55 +1493,19 @@ class UpdraftPlus {
1483
  return ( $setting==0 || $setting >= $time) ? true : false;
1484
  }
1485
 
1486
- function register_settings() {
1487
- register_setting( 'updraft-options-group', 'updraft_interval', array($this,'schedule_backup') );
1488
- register_setting( 'updraft-options-group', 'updraft_interval_database', array($this,'schedule_backup_database') );
1489
- register_setting( 'updraft-options-group', 'updraft_retain', array($this,'retain_range') );
1490
- register_setting( 'updraft-options-group', 'updraft_retain_db', array($this,'retain_range') );
1491
- register_setting( 'updraft-options-group', 'updraft_encryptionphrase');
1492
- register_setting( 'updraft-options-group', 'updraft_service' );
1493
-
1494
- register_setting( 'updraft-options-group', 'updraft_s3_login' );
1495
- register_setting( 'updraft-options-group', 'updraft_s3_pass' );
1496
- register_setting( 'updraft-options-group', 'updraft_s3_remote_path' );
1497
-
1498
- register_setting( 'updraft-options-group', 'updraft_dropbox_appkey' );
1499
- register_setting( 'updraft-options-group', 'updraft_dropbox_secret' );
1500
- register_setting( 'updraft-options-group', 'updraft_dropbox_folder' );
1501
-
1502
- register_setting( 'updraft-options-group', 'updraft_googledrive_clientid' );
1503
- register_setting( 'updraft-options-group', 'updraft_googledrive_secret' );
1504
- register_setting( 'updraft-options-group', 'updraft_googledrive_remotepath' );
1505
- register_setting( 'updraft-options-group', 'updraft_ftp_login' );
1506
- register_setting( 'updraft-options-group', 'updraft_ftp_pass' );
1507
- register_setting( 'updraft-options-group', 'updraft_ftp_remote_path' );
1508
- register_setting( 'updraft-options-group', 'updraft_server_address' );
1509
- register_setting( 'updraft-options-group', 'updraft_dir' );
1510
- register_setting( 'updraft-options-group', 'updraft_email');
1511
- register_setting( 'updraft-options-group', 'updraft_delete_local', 'absint' );
1512
- register_setting( 'updraft-options-group', 'updraft_debug_mode', 'absint' );
1513
- register_setting( 'updraft-options-group', 'updraft_include_plugins', 'absint' );
1514
- register_setting( 'updraft-options-group', 'updraft_include_themes', 'absint' );
1515
- register_setting( 'updraft-options-group', 'updraft_include_uploads', 'absint' );
1516
- register_setting( 'updraft-options-group', 'updraft_include_others', 'absint' );
1517
- register_setting( 'updraft-options-group', 'updraft_include_others_exclude' );
1518
- }
1519
-
1520
  function admin_init() {
1521
- if(get_option('updraft_debug_mode')) {
1522
- ini_set('display_errors',1);
1523
- error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
1524
- ini_set('track_errors',1);
1525
  }
1526
  wp_enqueue_script('jquery');
1527
 
1528
- $this->register_settings();
1529
-
1530
- if (current_user_can('manage_options') && get_option('updraft_service') == "googledrive" && get_option('updraft_googledrive_clientid') != "" && get_option('updraft_googledrive_token','xyz') == 'xyz') {
1531
  add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
1532
  }
1533
 
1534
- if (current_user_can('manage_options') && get_option('updraft_service') == "dropbox" && get_option('updraft_dropboxtk_request_token','xyz') == 'xyz') {
1535
  add_action('admin_notices', array($this,'show_admin_warning_dropbox') );
1536
  }
1537
  }
@@ -1541,11 +1515,6 @@ class UpdraftPlus {
1541
  // wp_localize_script('updraftplus-ajax', 'updraft_credentials_test', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
1542
  }
1543
 
1544
- function add_admin_pages() {
1545
- add_submenu_page('options-general.php', "UpdraftPlus", "UpdraftPlus", "manage_options", "updraftplus",
1546
- array($this,"settings_output"));
1547
- }
1548
-
1549
  function url_start($urls,$url) {
1550
  return ($urls) ? '<a href="http://'.$url.'">' : "";
1551
  }
@@ -1555,7 +1524,8 @@ class UpdraftPlus {
1555
  }
1556
 
1557
  function wordshell_random_advert($urls) {
1558
- $rad = rand(0,5);
 
1559
  switch ($rad) {
1560
  case 0:
1561
  return "Like automating WordPress operations? Use the CLI? ".$this->url_start($urls,'wordshell.net')."You will love WordShell".$this->url_end($urls,'www.wordshell.net')." - saves time and money fast.";
@@ -1572,11 +1542,223 @@ class UpdraftPlus {
1572
  return $this->url_start($urls,'www.simbahosting.co.uk')."Need high-quality WordPress hosting from WordPress specialists? (Including automatic backups and 1-click installer). Get it from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk');
1573
  break;
1574
  case 5:
 
 
 
 
 
 
 
1575
  return "Need custom WordPress services from experts (including bespoke development)?".$this->url_start($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/')." Get them from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/');
1576
  break;
1577
  }
1578
  }
1579
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1580
  function settings_output() {
1581
 
1582
  /*
@@ -1650,16 +1832,16 @@ class UpdraftPlus {
1650
  elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
1651
  $settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_dropbox_folder', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_others_exclude', 'updraft_lastmessage');
1652
  foreach ($settings as $s) {
1653
- delete_option($s);
1654
  }
1655
  $this->show_admin_warning("Your settings have been wiped.");
1656
  }
1657
 
1658
  ?>
1659
  <div class="wrap">
1660
- <h1>UpdraftPlus - Backup/Restore</h1>
1661
 
1662
- Maintained by <b>David Anderson</b> (<a href="http://david.dw-perspective.org.uk">Homepage</a> | <a href="http://wordshell.net">WordShell - WordPress command line</a> | <a href="http://david.dw-perspective.org.uk/donate">Donate</a> | <a href="http://wordpress.org/extend/plugins/updraftplus/faq/">FAQs</a> | <a href="http://profiles.wordpress.org/davidanderson/">My other WordPress plugins</a>). Version: <?php echo $this->version; ?>
1663
  <br>
1664
  <?php
1665
  if(isset($_GET['updraft_restore_success'])) {
@@ -1667,13 +1849,10 @@ class UpdraftPlus {
1667
  }
1668
 
1669
  $ws_advert = $this->wordshell_random_advert(1);
1670
- echo <<<ENDHERE
1671
- <div class="updated fade" style="max-width: 800px; font-size:140%; line-height: 140%; padding:14px; clear:left;">${ws_advert}</div>
1672
- ENDHERE;
1673
 
1674
- if($deleted_old_dirs) {
1675
- echo '<div style="color:blue">Old directories successfully deleted.</div>';
1676
- }
1677
  if(!$this->memory_check(96)) {?>
1678
  <div style="color:orange">Your PHP memory limit is too low. UpdraftPlus attempted to raise it but was unsuccessful. This plugin may not work properly with a memory limit of less than 96 Mb (though on the other hand, it has been used successfully with a 32Mb limit - your mileage may vary, but don't blame us!). Current limit is: <?php echo $this->memory_check_current(); ?> Mb</div>
1679
  <?php
@@ -1707,13 +1886,13 @@ ENDHERE;
1707
  $next_scheduled_backup = wp_next_scheduled('updraft_backup');
1708
  $next_scheduled_backup = ($next_scheduled_backup) ? date('D, F j, Y H:i T',$next_scheduled_backup) : 'No backups are scheduled at this time.';
1709
  $next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
1710
- if (get_option('updraft_interval_database',get_option('updraft_interval')) == get_option('updraft_interval')) {
1711
  $next_scheduled_backup_database = "Will take place at the same time as the files backup.";
1712
  } else {
1713
  $next_scheduled_backup_database = ($next_scheduled_backup_database) ? date('D, F j, Y H:i T',$next_scheduled_backup_database) : 'No backups are scheduled at this time.';
1714
  }
1715
  $current_time = date('D, F j, Y H:i T',time());
1716
- $updraft_last_backup = get_option('updraft_last_backup');
1717
  if($updraft_last_backup) {
1718
  $last_backup = ($updraft_last_backup['success']) ? date('D, F j, Y H:i T',$updraft_last_backup['backup_time']) : implode("<br>",$updraft_last_backup['errors']);
1719
  $last_backup_color = ($updraft_last_backup['success']) ? 'green' : 'red';
@@ -1727,11 +1906,9 @@ ENDHERE;
1727
  }
1728
 
1729
  if(is_writable($updraft_dir)) {
1730
- $dir_info = '<span style="color:green">Backup directory specified is writable, which is good.</span>';
1731
  $backup_disabled = "";
1732
  } else {
1733
  $backup_disabled = 'disabled="disabled"';
1734
- $dir_info = '<span style="color:red">Backup directory specified is <b>not</b> writable, or does not exist. <span style="font-size:110%;font-weight:bold"><a href="options-general.php?page=updraftplus&action=updraft_create_backup_dir">Click here</a></span> to attempt to create the directory and set the permissions. If that is unsuccessful check the permissions on your server or change it to another directory that is writable by your web server process.</span>';
1735
  }
1736
  ?>
1737
 
@@ -1754,16 +1931,16 @@ ENDHERE;
1754
  <div style="float:left; width:200px; padding-top: 40px;">
1755
  <form method="post" action="">
1756
  <input type="hidden" name="action" value="updraft_backup" />
1757
- <p><input type="submit" <?php echo $backup_disabled ?> class="button-primary" value="Backup Now!" style="padding-top:3px;padding-bottom:3px;font-size:24px !important" onclick="return(confirm('This will schedule a one-time backup. To trigger the backup you should go ahead, then wait 10 seconds, then visit any page on your site. WordPress should then start the backup running in the background.'))" /></p>
1758
  </form>
1759
  <div style="position:relative">
1760
  <div style="position:absolute;top:0;left:0">
1761
  <?php
1762
- $backup_history = get_option('updraft_backup_history');
1763
  $backup_history = (is_array($backup_history))?$backup_history:array();
1764
  $restore_disabled = (count($backup_history) == 0) ? 'disabled="disabled"' : "";
1765
  ?>
1766
- <input type="button" class="button-primary" <?php echo $restore_disabled ?> value="Restore" style="padding-top:3px;padding-bottom:3px;font-size:24px !important" onclick="jQuery('#backup-restore').fadeIn('slow');jQuery(this).parent().fadeOut('slow')" />
1767
  </div>
1768
  <div style="display:none;position:absolute;top:0;left:0" id="backup-restore">
1769
  <form method="post" action="">
@@ -1786,7 +1963,7 @@ ENDHERE;
1786
  <table class="form-table">
1787
  <tr>
1788
  <th>Last backup log message:</th>
1789
- <td id="updraft_lastlogcontainer"><?php echo htmlspecialchars(get_option('updraft_lastmessage', '(Nothing yet logged)')); ?></td>
1790
  </tr>
1791
  <tr>
1792
  <th>Download backups</th>
@@ -1867,198 +2044,24 @@ ENDHERE;
1867
  </td>
1868
  </tr>
1869
  </table>
1870
- <form method="post" action="options.php">
1871
- <?php settings_fields('updraft-options-group'); ?>
1872
- <h2>Configure Backup Contents And Schedule</h2>
1873
- <table class="form-table" style="width:850px;">
1874
- <tr>
1875
- <th>File backup intervals:</th>
1876
- <td><select name="updraft_interval">
1877
- <?php
1878
- $intervals = array ("manual" => "Manual", 'every4hours' => "Every 4 hours", 'every8hours' => "Every 8 hours", 'twicedaily' => "Every 12 hours", 'daily' => "Daily", 'weekly' => "Weekly", 'fortnightly' => "Fortnightly", 'monthly' => "Monthly");
1879
- foreach ($intervals as $cronsched => $descrip) {
1880
- echo "<option value=\"$cronsched\" ";
1881
- if ($cronsched == get_option('updraft_interval','manual')) echo 'selected="selected"';
1882
- echo ">$descrip</option>\n";
1883
- }
1884
- ?>
1885
- </select>
1886
- and retain this many backups: <?php
1887
- $updraft_retain = get_option('updraft_retain', 1);
1888
- $updraft_retain = ((int)$updraft_retain > 0) ? (int)$updraft_retain : 1;
1889
- ?> <input type="text" name="updraft_retain" value="<?php echo $updraft_retain ?>" style="width:40px;" />
1890
- </td>
1891
- </tr>
1892
- <tr>
1893
- <th>Database backup intervals:</th>
1894
- <td><select name="updraft_interval_database">
1895
- <?php
1896
- foreach ($intervals as $cronsched => $descrip) {
1897
- echo "<option value=\"$cronsched\" ";
1898
- if ($cronsched == get_option('updraft_interval_database',get_option('updraft_interval'))) echo 'selected="selected"';
1899
- echo ">$descrip</option>\n";
1900
- }
1901
- ?>
1902
- </select>
1903
- and retain this many backups: <?php
1904
- $updraft_retain_db = get_option('updraft_retain_db', $updraft_retain);
1905
- $updraft_retain_db = ((int)$updraft_retain_db > 0) ? (int)$updraft_retain_db : 1;
1906
- ?> <input type="text" name="updraft_retain_db" value="<?php echo $updraft_retain_db ?>" style="width:40px" />
1907
- </td>
1908
- </tr>
1909
- <tr class="backup-interval-description">
1910
- <td></td><td>If you would like to automatically schedule backups, choose schedules from the dropdowns above. Backups will occur at the intervals specified starting just after the current time. If the two schedules are the same, then the two backups will take place together. If you choose &quot;manual&quot; then you must click the &quot;Backup Now!&quot; button whenever you wish a backup to occur. </td>
1911
- </tr>
1912
- <?php
1913
- # The true (default value if non-existent) here has the effect of forcing a default of on.
1914
- $include_themes = (get_option('updraft_include_themes',true)) ? 'checked="checked"' : "";
1915
- $include_plugins = (get_option('updraft_include_plugins',true)) ? 'checked="checked"' : "";
1916
- $include_uploads = (get_option('updraft_include_uploads',true)) ? 'checked="checked"' : "";
1917
- $include_others = (get_option('updraft_include_others',true)) ? 'checked="checked"' : "";
1918
- $include_others_exclude = get_option('updraft_include_others_exclude',UPDRAFT_DEFAULT_OTHERS_EXCLUDE);
1919
- ?>
1920
- <tr>
1921
- <th>Include in files backup:</th>
1922
- <td>
1923
- <input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br>
1924
- <input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br>
1925
- <input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br>
1926
- <input type="checkbox" name="updraft_include_others" value="1" <?php echo $include_others; ?> /> Any other directories found inside wp-content - but exclude these directories: <input type="text" name="updraft_include_others_exclude" size="32" value="<?php echo htmlspecialchars($include_others_exclude); ?>"/><br>
1927
- Include all of these, unless you are backing them up outside of UpdraftPlus. The above directories are usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way. (<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br></td>
1928
- </td>
1929
- </tr>
1930
- <tr>
1931
- <th>Email:</th>
1932
- <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>
1933
- </tr>
1934
-
1935
- <tr>
1936
- <th>Database encryption phrase:</th>
1937
- <?php
1938
- $updraft_encryptionphrase = get_option('updraft_encryptionphrase');
1939
- ?>
1940
- <td><input type="text" name="updraft_encryptionphrase" value="<?php echo $updraft_encryptionphrase ?>" style="width:132px" /></td>
1941
- </tr>
1942
- <tr class="backup-crypt-description">
1943
- <td></td><td>If you enter text here, it is used to encrypt backups (Rijndael). <strong>Do make a separate record of it and do not lose it, or all your backups <em>will</em> be useless.</strong> Presently, only the database file is encrypted. This is also the key used to decrypt backups from this admin interface (so if you change it, then automatic decryption will not work until you change it back). You can also use the file example-decrypt.php from inside the UpdraftPlus plugin directory to decrypt manually.</td>
1944
- </tr>
1945
- </table>
1946
-
1947
- <h2>Copying Your Backup To Remote Storage</h2>
1948
-
1949
- <table class="form-table" style="width:850px;">
1950
- <tr>
1951
- <th>Choose your remote storage:</th>
1952
- <td><select name="updraft_service" id="updraft-service">
1953
- <?php
1954
- $debug_mode = (get_option('updraft_debug_mode')) ? 'checked="checked"' : "";
1955
-
1956
- $set = 'selected="selected"';
1957
-
1958
- // Should be one of s3, dropbox, ftp, googledrive, email, or whatever else is added
1959
- $active_service = get_option('updraft_service');
1960
-
1961
- ?>
1962
- <option value="none" <?php
1963
- if ($active_service == "none") echo $set; ?>>None</option>
1964
- <?php
1965
- foreach ($this->backup_methods as $method => $description) {
1966
- echo "<option value=\"$method\"";
1967
- if ($active_service == $method) echo ' '.$set;
1968
- echo '>'.$description;
1969
- echo "</option>\n";
1970
- }
1971
- ?>
1972
- </select></td>
1973
- </tr>
1974
- <?php
1975
- foreach ($this->backup_methods as $method => $description) {
1976
- require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
1977
- $call_method = "UpdraftPlus_BackupModule_$method";
1978
- call_user_func(array($call_method, 'config_print'));
1979
- }
1980
  ?>
1981
- </table>
1982
- <script type="text/javascript">
1983
- /* <![CDATA[ */
1984
- var lastlog_lastmessage = "";
1985
- var lastlog_sdata = {
1986
- action: 'updraft_ajax',
1987
- subaction: 'lastlog',
1988
- nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
1989
- };
1990
- function updraft_showlastlog(){
1991
- jQuery.get(ajaxurl, lastlog_sdata, function(response) {
1992
- nexttimer = 1500;
1993
- if (lastlog_lastmessage == response) { nexttimer = 4500; }
1994
- window.setTimeout(function(){updraft_showlastlog()}, nexttimer);
1995
- jQuery('#updraft_lastlogcontainer').html(response);
1996
- lastlog_lastmessage = response;
1997
- });
1998
- }
1999
- jQuery(document).ready(function() {
2000
- window.setTimeout(function(){updraft_showlastlog()}, 1200);
2001
- jQuery('.updraftplusmethod').hide();
2002
- <?php
2003
- if ($active_service) echo "jQuery('.${active_service}').show();";
2004
- foreach ($this->backup_methods as $method => $description) {
2005
- // already done: require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
2006
- $call_method = "UpdraftPlus_BackupModule_$method";
2007
- if (method_exists($call_method, 'config_print_javascript_onready')) call_user_func(array($call_method, 'config_print_javascript_onready'));
2008
- }
2009
- ?>
2010
- });
2011
- /* ]]> */
2012
- </script>
2013
- <table class="form-table" style="width:850px;">
2014
- <tr>
2015
- <td colspan="2"><h2>Advanced / Debugging Settings</h2></td>
2016
- </tr>
2017
- <tr>
2018
- <th>Debug / Expert mode:</th>
2019
- <td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to enable some more options here and below (that will appear after you save), and potentially receive more information and emails on the backup process - useful if something is going wrong. You <strong>must</strong> send me this log if you are filing a bug report.</td>
2020
- </tr>
2021
- <?php
2022
- $delete_local = get_option('updraft_delete_local', 1);
2023
- if (get_option('updraft_debug_mode')) { ?>
2024
-
2025
- <tr class="deletelocal">
2026
- <th>Delete local backup:</th>
2027
- <td><input type="checkbox" name="updraft_delete_local" value="1" <?php if ($delete_local) echo 'checked="checked"'; ?>> <br>Uncheck this to prevent deletion of any superfluous backup files from your server after the backup run finishes (i.e. any files despatched remotely will also remain locally, and any files being kept locally will not be subject to the retention limits).</td>
2028
- </tr>
2029
-
2030
- <?php } else { ?>
2031
- <input type="hidden" name="updraft_delete_local" value="<?php echo ($delete_local) ? 1 : 0; ?>">
2032
- <?php } ?>
2033
-
2034
  <tr>
2035
- <th>Backup directory:</th>
2036
- <td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo htmlspecialchars($updraft_dir); ?>" /></td>
2037
- </tr>
2038
- <tr>
2039
- <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>
2040
- </tr>
2041
- <tr>
2042
- <td></td>
2043
  <td>
2044
- <p style="margin: 10px 0; padding: 10px; font-size: 140%; background-color: lightYellow; border-color: #E6DB55; border: 1px solid; border-radius: 4px;">
2045
- <?php
2046
- echo $this->wordshell_random_advert(1);
2047
- ?>
2048
- </p>
2049
- </td>
2050
- </tr>
2051
- <tr>
2052
- <td></td>
2053
- <td>
2054
- <input type="hidden" name="action" value="update" />
2055
- <input type="submit" class="button-primary" value="Save Changes" />
2056
- </td>
2057
  </tr>
2058
- </table>
 
 
 
 
2059
  </form>
2060
  <?php
2061
- if(get_option('updraft_debug_mode')) {
2062
  ?>
2063
  <div style="padding-top: 40px;">
2064
  <hr>
@@ -2112,20 +2115,20 @@ ENDHERE;
2112
  <?php
2113
  }
2114
 
2115
- function show_admin_warning($message) {
2116
- echo '<div id="updraftmessage" class="updated fade">'."<p>$message</p></div>";
2117
  }
2118
 
2119
  function show_admin_warning_unreadablelog() {
2120
- $this->show_admin_warning('<strong>UpdraftPlus notice:</strong> The log file could not be read.</a>');
2121
  }
2122
 
2123
  function show_admin_warning_dropbox() {
2124
- $this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit">Click here to authenticate your Dropbox account (you will not be able to back up to Dropbox without it).</a>');
2125
  }
2126
 
2127
  function show_admin_warning_googledrive() {
2128
- $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>');
2129
  }
2130
 
2131
  }
4
  Plugin URI: http://wordpress.org/extend/plugins/updraftplus
5
  Description: Backup and restore: your content and database can be automatically backed up to Amazon S3, Dropbox, Google Drive, FTP or email, on separate schedules.
6
  Author: David Anderson.
7
+ Version: 1.3.3
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
10
  Author URI: http://wordshell.net
13
  /*
14
  TODO
15
  //Add SFTP, Box.Net, SugarSync and Microsoft Skydrive support??
16
+ //The restorer has a hard-coded wp-content - fix
17
  //improve error reporting / pretty up return messages in admin area. One thing: have a "backup is now finished" flag. Otherwise with the resuming things get ambiguous/confusing. See http://wordpress.org/support/topic/backup-status - user was not aware that backup completely failed. Maybe a "backup status" field for each nonce that gets updated? (Even via AJAX?)
18
  //?? On 'backup now', open up a Lightbox, count down 5 seconds, then start examining the log file (if it can be found)
19
  //Should make clear in dashboard what is a non-fatal error (i.e. can be retried) - leads to unnecessary bug reports
26
  // Turn expert options into a jQuery toggle
27
  // Provide backup/restoration for UpdraftPlus's settings, to allow 'bootstrap' on a fresh WP install
28
  // Multiple jobs
29
+ // Create single zip, containing even WordPress itself
30
 
31
  Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
32
  // Does not delete old custom directories upon a restore?
65
 
66
  define('UPDRAFTPLUS_DIR', dirname(__FILE__));
67
  define('UPDRAFTPLUS_URL', plugins_url('', __FILE__));
68
+ define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php,backup');
69
+
70
+ if (is_file(UPDRAFTPLUS_DIR.'/premium.php')) require_once(UPDRAFTPLUS_DIR.'/premium.php');
71
+
72
+ if (!class_exists('UpdraftPlus_Options')) require_once(UPDRAFTPLUS_DIR.'/options.php');
73
 
74
  class UpdraftPlus {
75
 
76
+ var $version = '1.3.3';
77
+ var $plugin_title = 'UpdraftPlus Backup/Restore';
78
 
79
  // Choices will be shown in the admin menu in the order used here
80
  var $backup_methods = array (
95
  var $backup_time;
96
 
97
  var $opened_log_time;
98
+ var $backup_dir;
99
 
100
  function __construct() {
101
  // Initialisation actions - takes place on plugin load
102
  # Create admin page
103
+ add_action('admin_init', array($this, 'admin_init'));
 
104
  add_action('updraft_backup', array($this,'backup_files'));
105
  add_action('updraft_backup_database', array($this,'backup_database'));
106
  # backup_all is used by the manual "Backup Now" button
120
  // Also handle action=downloadlog
121
  function handle_url_actions() {
122
  // First, basic security check: must be an admin page, with ability to manage options, with the right parameters
123
+ if ( UpdraftPlus_Options::user_can_manage() && isset( $_GET['page'] ) && $_GET['page'] == 'updraftplus' && isset($_GET['action']) ) {
124
  if (preg_match("/^updraftmethod-([a-z]+)-([a-z]+)$/", $_GET['action'], $matches) && file_exists(UPDRAFTPLUS_DIR.'/methods/'.$matches[1].'.php')) {
125
  $method = $matches[1];
126
  require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
174
  # Logs the given line, adding (relative) time stamp and newline
175
  function log($line) {
176
  if ($this->logfile_handle) fwrite($this->logfile_handle, sprintf("%08.03f", round(microtime(true)-$this->opened_log_time, 3))." ".$line."\n");
177
+ UpdraftPlus_Options::update_updraft_option("updraft_lastmessage", $line." (".date('M d H:i:s').")");
178
  }
179
 
180
+ function backup_resume($resumption_array) {
181
+ $resumption_no = $resumption_array[0];
182
+ $bnonce = $resumption_array[1];
183
+ $btime = $resumption_array[2];
184
+
185
  @ignore_user_abort(true);
186
  // This is scheduled for 5 minutes after a backup job starts
187
+ if (!$bnonce || !$btime) return;
188
+ // Restore state
189
  $this->nonce = $bnonce;
190
+ $this->backup_time = $btime;
191
  $this->logfile_open($bnonce);
192
+
 
 
 
 
 
193
  $this->log("Resuming backup: resumption=$resumption_no, nonce=$bnonce, begun at=$btime");
194
  // Schedule again, to run in 5 minutes again, in case we again fail
195
  $resume_delay = 300;
196
  // A different argument than before is needed otherwise the event is ignored
197
  $next_resumption = $resumption_no+1;
198
  if ($next_resumption < 10) {
199
+ $this->log("Scheduling next resumption ($next_resumption) in case this run gets aborted");
200
+ wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume' ,array($next_resumption, $bnonce, $btime));
201
  } else {
202
+ $this->log("The current run is our tenth attempt - will not schedule a further attempt");
203
  }
 
204
 
205
  $backup_array = $this->resumable_backup_of_files(false);
206
  // This save, if there was something, is then immediately picked up again
218
  $backup_database = get_transient("updraft_backdb_".$bnonce);
219
 
220
  // The transient is read and written below (instead of using the existing variable) so that we can copy-and-paste this part as needed.
221
+ if ($backup_database == "begun" || $backup_database == "finished" || $backup_database == "encrypted") {
222
  if ($backup_database == "begun") {
223
  $this->log("Resuming creation of database dump");
224
+ } elseif ($backup_database == 'encrypted') {
225
+ $this->log("Database dump: Creation and encryption were completed already");
226
  } else {
227
  $this->log("Database dump: Creation was completed already");
228
  }
231
  $backup_contains = get_transient("updraft_backupcontains_".$this->nonce);
232
  $backup_contains = (substr($backup_contains,0,10) == "Files only") ? "Files and database" : "Database only (no files)";
233
  set_transient("updraft_backupcontains_".$this->nonce, $backup_contains, 3600*3);
234
+ set_transient("updraft_backdb_".$this->nonce, "finished", 3600*3);
235
  } else {
236
  $this->log("Unrecognised data when trying to ascertain if the database was backed up ($backup_database)");
237
  }
245
  if (isset($our_files['db']) && !preg_match("/\.crypt$/", $our_files['db'])) {
246
  $our_files['db'] = $this->encrypt_file($our_files['db']);
247
  $this->save_backup_history($our_files);
248
+ // TODO: This transient is redundant; the presence of the .crypt in the db key already indicates what this transient indicates
249
+ set_transient("updraft_backdb_".$this->nonce, "encrypted", 3600*3);
250
  }
251
 
252
  foreach ($our_files as $key => $file) {
253
 
254
+ // Only continue if the stored info was about a dump
255
+ if ($key != 'plugins' && $key != 'themes' && $key != 'others' && $key != 'uploads' && $key != 'db') continue;
256
 
257
  $hash = md5($file);
258
+ $fullpath = $this->backups_dir_location().'/'.$file;
259
  if (get_transient('updraft_'.$hash) === "yes") {
260
  $this->log("$file: $key: This file has been successfully uploaded in the last 3 hours");
261
  } elseif (is_file($fullpath)) {
269
 
270
  if (count($undone_files) == 0) {
271
  $this->log("There were no more files that needed uploading; backup job is complete");
272
+ // No email, as the user probably already got one if something else completed the run
273
+ backup_finish($next_resumption, true, false, $resumption_no);
274
  return;
275
  }
276
 
277
  $this->log("Requesting backup of the files that were not successfully uploaded");
278
  $this->cloud_backup($undone_files);
279
 
280
+ $this->log("Resume backup ($bnonce, $resumption_no): finish run");
281
 
282
  $this->backup_finish($next_resumption, true, true, $resumption_no);
283
 
301
 
302
  function check_backup_race( $to_delete = false ) {
303
  // Avoid caching
304
+ // Short-circuit - we believe WordPress has taken steps itself to prevent this race
305
+ // Furthermore, we now pass the nonce to the resumption job, so races should not be possible on resumptions
306
+ return true;
307
+
308
+ // We no longer even user the nonce
309
  global $wpdb;
310
  $row = $wpdb->get_row($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", "_transient_updraftplus_backup_job_nonce"));
311
  $cur_trans = ( is_object( $row ) ) ? $row->option_value : "";
366
 
367
  // Log some information that may be helpful
368
  global $wp_version;
369
+ $this->log("Tasks: Backup files: $backup_files (schedule: ".UpdraftPlus_Options::get_updraft_option('updraft_interval','unset').") Backup DB: $backup_database (schedule: ".UpdraftPlus_Options::get_updraft_option('updraft_interval_database','unset').")");
370
 
371
  # If the files and database schedules are the same, and if this the file one, then we rope in database too.
372
  # On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
373
+ if (UpdraftPlus_Options::get_updraft_option('updraft_interval') == UpdraftPlus_Options::get_updraft_option('updraft_interval_database') || UpdraftPlus_Options::get_updraft_option('updraft_interval_database','xyz') == 'xyz' ) {
374
  $backup_database = ($backup_files == true) ? true : false;
375
  }
376
 
383
 
384
  $clear_nonce_transient = true;
385
 
386
+ // Do not schedule the resume event until now, when we know there is something to do - otherwise 'vacatated' runs (when the database is on the same schedule as the files, and they get combined, leading to an empty run) can over-write the resume event and prevent resumption (because it is 'successful' - there was nothing to do).
387
  // If we don't finish in 3 hours, then we won't finish
 
 
 
388
 
389
  // Schedule the event to run later, which checks on success and can resume the backup
390
  // We save the time to a variable because it is needed for un-scheduling
391
  $resume_delay = 300;
392
+ wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume', array(1, $this->nonce, $this->backup_time));
393
  $this->log("In case we run out of time, scheduled a resumption at: $resume_delay seconds from now");
394
 
395
  $backup_contains = "";
436
  // Now encrypt the database, and re-save
437
  if ($backup_database && isset($backup_array['db'])) {
438
  $backup_array['db'] = $this->encrypt_file($backup_array['db']);
439
+ set_transient("updraft_backdb_".$this->nonce, "encrypted", 3600*3);
440
  // Re-save with the possibly-altered database filename
441
  $this->save_backup_history($backup_array);
442
  }
460
 
461
  // Encrypts the file if the option is set; returns the basename of the file (according to whether it was encrypted or nto)
462
  function encrypt_file($file) {
463
+ $encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase');
464
  if (strlen($encryption) > 0) {
465
  $this->log("$file: applying encryption");
466
  $encryption_error = 0;
470
  $rijndael->setKey($encryption);
471
  $updraft_dir = $this->backups_dir_location();
472
  $file_size = @filesize($updraft_dir.'/'.$file)/1024;
473
+ if (false === file_put_contents($updraft_dir.'/'.$file.'.crypt' , $rijndael->encrypt(file_get_contents($updraft_dir.'/'.$file)))) {$encryption_error = 1;}
 
 
 
 
 
 
 
 
474
  if (0 == $encryption_error) {
475
  $time_taken = max(0.000001, microtime(true)-$microstart);
476
  $this->log("$file: encryption successful: ".round($file_size,1)."Kb in ".round($time_taken,1)."s (".round($file_size/$time_taken, 1)."Kb/s)");
493
  if (empty($this->errors)) {
494
  if ($clear_nonce_transient) {
495
  $this->log("There were no errors in the uploads, so the 'resume' event is being unscheduled");
496
+ wp_clear_scheduled_hook('updraft_backup_resume', array($cancel_event, $this->nonce, $this->backup_time));
 
 
497
  }
498
  } else {
499
  $this->log("There were errors in the uploads, so the 'resume' event is remaining scheduled");
522
  }
523
 
524
  // Now over-ride the decision to send an email, if needed
525
+ if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
526
  $send_an_email = true;
527
  $this->log("An email has been scheduled for this job, because we are in debug mode");
528
  }
530
  if (!$allow_email) {
531
  $send_an_email = false;
532
  $this->log("No email will be sent - this backup set was empty.");
533
+ } elseif (UpdraftPlus_Options::get_updraft_option('updraft_email') == '') {
534
  $send_an_email = false;
535
  $this->log("No email will/can be sent - the user has not configured an email address.");
536
  }
542
  @fclose($this->logfile_handle);
543
 
544
  // Don't delete the log file now; delete it upon rotation
545
+ //if (!UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) @unlink($this->logfile_name);
546
 
547
  }
548
 
549
  function send_results_email() {
550
 
551
+ $debug_mode = UpdraftPlus_Options::get_updraft_option('updraft_debug_mode');
552
 
553
+ $sendmail_to = UpdraftPlus_Options::get_updraft_option('updraft_email');
554
 
555
  $this->log("Sending email report to: ".substr($sendmail_to, 0, 5)."...");
556
 
565
 
566
  $last_backup = array('backup_time'=>$this->backup_time, 'backup_array'=>$backup_array, 'success'=>$success, 'errors'=>$this->errors, 'backup_nonce' => $this->nonce);
567
 
568
+ UpdraftPlus_Options::update_updraft_option('updraft_last_backup', $last_backup);
569
  }
570
 
571
  // This should be called whenever a file is successfully uploaded
575
  $this->log("Recording as successfully uploaded: $file ($hash)");
576
  set_transient("updraft_".$hash, "yes", 3600*4);
577
  if ($id) {
578
+ $ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array() );
579
  $ids[$file] = $id;
580
+ UpdraftPlus_Options::update_updraft_option('updraft_file_ids',$ids);
581
  $this->log("Stored file<->id correlation in database ($file <-> $id)");
582
  }
583
  // Delete local files immediately if the option is set
584
  // Where we are only backing up locally, only the "prune" function should do deleting
585
+ if (UpdraftPlus_Options::get_updraft_option('updraft_service', 'none') != 'none') $this->delete_local($file);
586
  }
587
 
588
  // Dispatch to the relevant function
589
  function cloud_backup($backup_array) {
590
+ $service = UpdraftPlus_Options::get_updraft_option('updraft_service');
591
  $this->log("Cloud backup selection: ".$service);
592
  @set_time_limit(900);
593
 
612
 
613
  function prune_file($updraft_service, $dofile, $method_object = null, $object_passback = null ) {
614
  $this->log("Delete this file: $dofile, service=$updraft_service");
615
+ $fullpath = $this->backups_dir_location().'/'.$dofile;
616
  // delete it if it's locally available
617
  if (file_exists($fullpath)) {
618
  $this->log("Deleting local copy ($fullpath)");
627
  function prune_retained_backups($updraft_service, $backup_method_object = null, $backup_passback = null) {
628
 
629
  // If they turned off deletion on local backups, then there is nothing to do
630
+ if (UpdraftPlus_Options::get_updraft_option('updraft_delete_local') == 0 && $updraft_service == 'none') {
631
  $this->log("Prune old backups from local store: nothing to do, since the user disabled local deletion and we are using local backups");
632
  return;
633
  }
635
  $this->log("Retain: beginning examination of existing backup sets");
636
 
637
  // Number of backups to retain - files
638
+ $updraft_retain = UpdraftPlus_Options::get_updraft_option('updraft_retain', 1);
639
  $updraft_retain = (is_numeric($updraft_retain)) ? $updraft_retain : 1;
640
  $this->log("Retain files: user setting: number to retain = $updraft_retain");
641
 
642
  // Number of backups to retain - db
643
+ $updraft_retain_db = UpdraftPlus_Options::get_updraft_option('updraft_retain_db', $updraft_retain);
644
  $updraft_retain_db = (is_numeric($updraft_retain_db)) ? $updraft_retain_db : 1;
645
  $this->log("Retain db: user setting: number to retain = $updraft_retain_db");
646
 
688
  $this->log("$backup_datestamp: this backup set is now empty; will remove from history");
689
  unset($backup_history[$backup_datestamp]);
690
  if (isset($backup_to_examine['nonce'])) {
691
+ $fullpath = $this->backups_dir_location().'/log.'.$backup_to_examine['nonce'].'.txt';
692
  if (is_file($fullpath)) {
693
  $this->log("$backup_datestamp: deleting log file (log.".$backup_to_examine['nonce'].".txt)");
694
  @unlink($fullpath);
704
  }
705
  }
706
  $this->log("Retain: saving new backup history (sets now: ".count($backup_history).") and finishing retain operation");
707
+ UpdraftPlus_Options::update_updraft_option('updraft_backup_history',$backup_history);
708
  }
709
 
710
  function delete_local($file) {
711
+ if(UpdraftPlus_Options::get_updraft_option('updraft_delete_local')) {
712
  $this->log("Deleting local file: $file");
713
  //need error checking so we don't delete what isn't successfully uploaded?
714
+ $fullpath = $this->backups_dir_location().'/'.$file;
715
  return unlink($fullpath);
716
  }
717
  return true;
790
 
791
  # Plugins, themes, uploads
792
  foreach ($possible_backups as $youwhat => $whichdir) {
793
+ if (UpdraftPlus_Options::get_updraft_option("updraft_include_$youwhat", true)) {
794
  if ($transient_status == 'finished') {
795
  $backup_array[$youwhat] = $backup_file_basename.'-'.$youwhat.'.zip';
796
  } else {
803
  }
804
 
805
  # Others
806
+ if (UpdraftPlus_Options::get_updraft_option('updraft_include_others', true)) {
807
  $this->log("Beginning backup of other directories found in the content directory");
808
 
809
  if ($transient_status == 'finished') {
822
  # Initialise
823
  $other_dirlist = array();
824
 
825
+ $others_skip = preg_split("/,/",UpdraftPlus_Options::get_updraft_option('updraft_include_others_exclude', UPDRAFT_DEFAULT_OTHERS_EXCLUDE));
826
  # Make the values into the keys
827
  $others_skip = array_flip($others_skip);
828
 
859
 
860
  function save_backup_history($backup_array) {
861
  if(is_array($backup_array)) {
862
+ $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
863
  $backup_history = (is_array($backup_history)) ? $backup_history : array();
864
  $backup_array['nonce'] = $this->nonce;
865
  $backup_history[$this->backup_time] = $backup_array;
866
+ UpdraftPlus_Options::update_updraft_option('updraft_backup_history',$backup_history);
867
  } else {
868
  $this->log('Could not save backup history because we have no backup array. Backup probably failed.');
869
  $this->error('Could not save backup history because we have no backup array. Backup probably failed.');
871
  }
872
 
873
  function get_backup_history() {
874
+ //$backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
875
  //by doing a raw DB query to get the most up-to-date data from this option we slightly narrow the window for the multiple-cron race condition
876
  global $wpdb;
877
  $backup_history = @unserialize($wpdb->get_var($wpdb->prepare("SELECT option_value from $wpdb->options WHERE option_name='updraft_backup_history'")));
937
  $backup_file_base = $updraft_dir.'/'.$file_base;
938
 
939
  if ("finished" == $already_done) return basename($backup_file_base.'-db.gz');
940
+ if ("encrypted" == $already_done) return basename($backup_file_base.'-db.gz.crypt');
941
 
942
  $total_tables = 0;
943
 
1242
  $schedules['every8hours'] = array( 'interval' => 28800, 'display' => 'Every 8 hours' );
1243
  return $schedules;
1244
  }
1245
+
1246
  function backups_dir_location() {
1247
+ if (isset($this->backup_dir)) return $this->backup_dir;
1248
+ $updraft_dir = untrailingslashit(UpdraftPlus_Options::get_updraft_option('updraft_dir'));
1249
  $default_backup_dir = WP_CONTENT_DIR.'/updraft';
1250
  //if the option isn't set, default it to /backups inside the upload dir
1251
  $updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
1252
  //check for the existence of the dir and an enumeration preventer.
1253
  if(!is_dir($updraft_dir) || !is_file($updraft_dir.'/index.html') || !is_file($updraft_dir.'/.htaccess')) {
1254
+ @mkdir($updraft_dir, 0775, true);
1255
  @file_put_contents($updraft_dir.'/index.html','Nothing to see here.');
1256
  @file_put_contents($updraft_dir.'/.htaccess','deny from all');
1257
  }
1258
+ $this->backup_dir = $updraft_dir;
1259
  return $updraft_dir;
1260
  }
1261
 
1266
  if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
1267
 
1268
  if ('lastlog' == $_GET['subaction']) {
1269
+ echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '(Nothing yet logged)'));
1270
  } elseif ($_POST['subaction'] == 'credentials_test') {
1271
  $method = (preg_match("/^[a-z0-9]+$/", $_POST['method'])) ? $_POST['method'] : "";
1272
 
1286
  $timestamp = (int)$_POST['timestamp'];
1287
  $backup_history = $this->get_backup_history();
1288
  $file = $backup_history[$timestamp][$type];
1289
+ $fullpath = $this->backups_dir_location().'/'.$file;
1290
  if(!is_readable($fullpath)) {
1291
  //if the file doesn't exist and they're using one of the cloud options, fetch it down from the cloud.
1292
  $this->download_backup($file);
1313
  }
1314
  ob_end_flush();
1315
  if ($file_ext == 'crypt') {
1316
+ $encryption = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase');
1317
  if ($encryption == "") {
1318
  $this->error('Decryption of database failed: the database file is encrypted, but you have no encryption key entered.');
1319
  } else {
1339
  }
1340
 
1341
  function download_backup($file) {
1342
+ $service = UpdraftPlus_Options::get_updraft_option('updraft_service');
1343
 
1344
  $method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
1345
  if (file_exists($method_include)) require_once($method_include);
1356
 
1357
  function restore_backup($timestamp) {
1358
  global $wp_filesystem;
1359
+ $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
1360
  if(!is_array($backup_history[$timestamp])) {
1361
  echo '<p>This backup does not exist in the backup history - restoration aborted. Timestamp: '.$timestamp.'</p><br/>';
1362
  return false;
1373
  //if we make it this far then WP_Filesystem has been instantiated and is functional (tested with ftpext, what about suPHP and other situations where direct may work?)
1374
  echo '<span style="font-weight:bold">Restoration Progress</span><div id="updraft-restore-progress">';
1375
 
1376
+ $updraft_dir = $this->backups_dir_location().'/';
1377
  foreach($backup_history[$timestamp] as $type => $file) {
1378
  if ($type == 'nonce') continue;
1379
  $fullpath = $updraft_dir.$file;
1454
  exit;
1455
  }
1456
 
1457
+ $updraft_dir = $this->backups_dir_location();
1458
  $default_backup_dir = WP_CONTENT_DIR.'/updraft';
1459
  $updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
1460
 
1493
  return ( $setting==0 || $setting >= $time) ? true : false;
1494
  }
1495
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1496
  function admin_init() {
1497
+ if(UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
1498
+ @ini_set('display_errors',1);
1499
+ @error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
1500
+ @ini_set('track_errors',1);
1501
  }
1502
  wp_enqueue_script('jquery');
1503
 
1504
+ if (UpdraftPlus_Options::user_can_manage() && UpdraftPlus_Options::get_updraft_option('updraft_service') == "googledrive" && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid') != "" && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token','xyz') == 'xyz') {
 
 
1505
  add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
1506
  }
1507
 
1508
+ if (UpdraftPlus_Options::user_can_manage() && UpdraftPlus_Options::get_updraft_option('updraft_service') == "dropbox" && UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','xyz') == 'xyz') {
1509
  add_action('admin_notices', array($this,'show_admin_warning_dropbox') );
1510
  }
1511
  }
1515
  // wp_localize_script('updraftplus-ajax', 'updraft_credentials_test', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
1516
  }
1517
 
 
 
 
 
 
1518
  function url_start($urls,$url) {
1519
  return ($urls) ? '<a href="http://'.$url.'">' : "";
1520
  }
1524
  }
1525
 
1526
  function wordshell_random_advert($urls) {
1527
+ if (defined('UPDRAFTPLUS_PREMIUM')) return "";
1528
+ $rad = rand(0,6);
1529
  switch ($rad) {
1530
  case 0:
1531
  return "Like automating WordPress operations? Use the CLI? ".$this->url_start($urls,'wordshell.net')."You will love WordShell".$this->url_end($urls,'www.wordshell.net')." - saves time and money fast.";
1542
  return $this->url_start($urls,'www.simbahosting.co.uk')."Need high-quality WordPress hosting from WordPress specialists? (Including automatic backups and 1-click installer). Get it from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk');
1543
  break;
1544
  case 5:
1545
+ if (!defined('UPDRAFTPLUS_PREMIUM')) {
1546
+ return $this->url_start($urls,'www.updraftplus.com')."Need even more features and support? Check out UpdraftPlus Premium".$this->url_end($urls,'www.updraftplus.com');
1547
+ } else {
1548
+ return "Thanks for being an UpdraftPlus premium user. Keep visiting ".$this->url_start($urls,'www.updraftplus.com')."updraftplus.com".$this->url_end($urls,'www.updraftplus.com')." to see what's going on.";
1549
+ }
1550
+ break;
1551
+ case 6:
1552
  return "Need custom WordPress services from experts (including bespoke development)?".$this->url_start($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/')." Get them from the creators of UpdraftPlus.".$this->url_end($urls,'www.simbahosting.co.uk/s3/products-and-services/wordpress-experts/');
1553
  break;
1554
  }
1555
  }
1556
 
1557
+ function settings_formcontents() {
1558
+ $updraft_dir = $this->backups_dir_location();
1559
+ ?>
1560
+ <table class="form-table" style="width:850px;">
1561
+ <tr>
1562
+ <th>File backup intervals:</th>
1563
+ <td><select name="updraft_interval">
1564
+ <?php
1565
+ $intervals = array ("manual" => "Manual", 'every4hours' => "Every 4 hours", 'every8hours' => "Every 8 hours", 'twicedaily' => "Every 12 hours", 'daily' => "Daily", 'weekly' => "Weekly", 'fortnightly' => "Fortnightly", 'monthly' => "Monthly");
1566
+ foreach ($intervals as $cronsched => $descrip) {
1567
+ echo "<option value=\"$cronsched\" ";
1568
+ if ($cronsched == UpdraftPlus_Options::get_updraft_option('updraft_interval','manual')) echo 'selected="selected"';
1569
+ echo ">$descrip</option>\n";
1570
+ }
1571
+ ?>
1572
+ </select>
1573
+ and retain this many backups: <?php
1574
+ $updraft_retain = UpdraftPlus_Options::get_updraft_option('updraft_retain', 1);
1575
+ $updraft_retain = ((int)$updraft_retain > 0) ? (int)$updraft_retain : 1;
1576
+ ?> <input type="text" name="updraft_retain" value="<?php echo $updraft_retain ?>" style="width:40px;" />
1577
+ </td>
1578
+ </tr>
1579
+ <tr>
1580
+ <th>Database backup intervals:</th>
1581
+ <td><select name="updraft_interval_database">
1582
+ <?php
1583
+ foreach ($intervals as $cronsched => $descrip) {
1584
+ echo "<option value=\"$cronsched\" ";
1585
+ if ($cronsched == UpdraftPlus_Options::get_updraft_option('updraft_interval_database', UpdraftPlus_Options::get_updraft_option('updraft_interval'))) echo 'selected="selected"';
1586
+ echo ">$descrip</option>\n";
1587
+ }
1588
+ ?>
1589
+ </select>
1590
+ and retain this many backups: <?php
1591
+ $updraft_retain_db = UpdraftPlus_Options::get_updraft_option('updraft_retain_db', $updraft_retain);
1592
+ $updraft_retain_db = ((int)$updraft_retain_db > 0) ? (int)$updraft_retain_db : 1;
1593
+ ?> <input type="text" name="updraft_retain_db" value="<?php echo $updraft_retain_db ?>" style="width:40px" />
1594
+ </td>
1595
+ </tr>
1596
+ <tr class="backup-interval-description">
1597
+ <td></td><td>If you would like to automatically schedule backups, choose schedules from the dropdowns above. Backups will occur at the intervals specified starting just after the current time. If the two schedules are the same, then the two backups will take place together. If you choose &quot;manual&quot; then you must click the &quot;Backup Now!&quot; button whenever you wish a backup to occur. </td>
1598
+ </tr>
1599
+ <?php
1600
+ # The true (default value if non-existent) here has the effect of forcing a default of on.
1601
+ $include_themes = (UpdraftPlus_Options::get_updraft_option('updraft_include_themes',true)) ? 'checked="checked"' : "";
1602
+ $include_plugins = (UpdraftPlus_Options::get_updraft_option('updraft_include_plugins',true)) ? 'checked="checked"' : "";
1603
+ $include_uploads = (UpdraftPlus_Options::get_updraft_option('updraft_include_uploads',true)) ? 'checked="checked"' : "";
1604
+ $include_others = (UpdraftPlus_Options::get_updraft_option('updraft_include_others',true)) ? 'checked="checked"' : "";
1605
+ $include_others_exclude = UpdraftPlus_Options::get_updraft_option('updraft_include_others_exclude',UPDRAFT_DEFAULT_OTHERS_EXCLUDE);
1606
+ ?>
1607
+ <tr>
1608
+ <th>Include in files backup:</th>
1609
+ <td>
1610
+ <input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br>
1611
+ <input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br>
1612
+ <input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br>
1613
+ <input type="checkbox" name="updraft_include_others" value="1" <?php echo $include_others; ?> /> Any other directories found inside wp-content <?php if (is_multisite()) echo "(which on a multisite install includes users' blog contents) "; ?>- but exclude these directories: <input type="text" name="updraft_include_others_exclude" size="32" value="<?php echo htmlspecialchars($include_others_exclude); ?>"/><br>
1614
+ Include all of these, unless you are backing them up outside of UpdraftPlus. The above directories are usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way. (<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br></td>
1615
+ </td>
1616
+ </tr>
1617
+ <tr>
1618
+ <th>Email:</th>
1619
+ <td><input type="text" style="width:260px" name="updraft_email" value="<?php echo UpdraftPlus_Options::get_updraft_option('updraft_email'); ?>" /> <br>Enter an address here to have a report sent (and the whole backup, if you choose) to it.</td>
1620
+ </tr>
1621
+
1622
+ <tr>
1623
+ <th>Database encryption phrase:</th>
1624
+ <?php
1625
+ $updraft_encryptionphrase = UpdraftPlus_Options::get_updraft_option('updraft_encryptionphrase');
1626
+ ?>
1627
+ <td><input type="text" name="updraft_encryptionphrase" value="<?php echo $updraft_encryptionphrase ?>" style="width:132px" /></td>
1628
+ </tr>
1629
+ <tr class="backup-crypt-description">
1630
+ <td></td><td>If you enter text here, it is used to encrypt backups (Rijndael). <strong>Do make a separate record of it and do not lose it, or all your backups <em>will</em> be useless.</strong> Presently, only the database file is encrypted. This is also the key used to decrypt backups from this admin interface (so if you change it, then automatic decryption will not work until you change it back). You can also use the file example-decrypt.php from inside the UpdraftPlus plugin directory to decrypt manually.</td>
1631
+ </tr>
1632
+ </table>
1633
+
1634
+ <h2>Copying Your Backup To Remote Storage</h2>
1635
+
1636
+ <table class="form-table" style="width:850px;">
1637
+ <tr>
1638
+ <th>Choose your remote storage:</th>
1639
+ <td><select name="updraft_service" id="updraft-service">
1640
+ <?php
1641
+ $debug_mode = (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) ? 'checked="checked"' : "";
1642
+
1643
+ $set = 'selected="selected"';
1644
+
1645
+ // Should be one of s3, dropbox, ftp, googledrive, email, or whatever else is added
1646
+ $active_service = UpdraftPlus_Options::get_updraft_option('updraft_service');
1647
+
1648
+ ?>
1649
+ <option value="none" <?php
1650
+ if ($active_service == "none") echo $set; ?>>None</option>
1651
+ <?php
1652
+ foreach ($this->backup_methods as $method => $description) {
1653
+ echo "<option value=\"$method\"";
1654
+ if ($active_service == $method) echo ' '.$set;
1655
+ echo '>'.$description;
1656
+ echo "</option>\n";
1657
+ }
1658
+ ?>
1659
+ </select></td>
1660
+ </tr>
1661
+ <?php
1662
+ foreach ($this->backup_methods as $method => $description) {
1663
+ require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
1664
+ $call_method = "UpdraftPlus_BackupModule_$method";
1665
+ call_user_func(array($call_method, 'config_print'));
1666
+ }
1667
+ ?>
1668
+ </table>
1669
+ <script type="text/javascript">
1670
+ /* <![CDATA[ */
1671
+ var lastlog_lastmessage = "";
1672
+ var lastlog_sdata = {
1673
+ action: 'updraft_ajax',
1674
+ subaction: 'lastlog',
1675
+ nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
1676
+ };
1677
+ function updraft_showlastlog(){
1678
+ jQuery.get(ajaxurl, lastlog_sdata, function(response) {
1679
+ nexttimer = 1500;
1680
+ if (lastlog_lastmessage == response) { nexttimer = 4500; }
1681
+ window.setTimeout(function(){updraft_showlastlog()}, nexttimer);
1682
+ jQuery('#updraft_lastlogcontainer').html(response);
1683
+ lastlog_lastmessage = response;
1684
+ });
1685
+ }
1686
+ jQuery(document).ready(function() {
1687
+ window.setTimeout(function(){updraft_showlastlog()}, 1200);
1688
+ jQuery('.updraftplusmethod').hide();
1689
+ <?php
1690
+ if ($active_service) echo "jQuery('.${active_service}').show();";
1691
+ foreach ($this->backup_methods as $method => $description) {
1692
+ // already done: require_once(UPDRAFTPLUS_DIR.'/methods/'.$method.'.php');
1693
+ $call_method = "UpdraftPlus_BackupModule_$method";
1694
+ if (method_exists($call_method, 'config_print_javascript_onready')) call_user_func(array($call_method, 'config_print_javascript_onready'));
1695
+ }
1696
+ ?>
1697
+ });
1698
+ /* ]]> */
1699
+ </script>
1700
+ <table class="form-table" style="width:850px;">
1701
+ <tr>
1702
+ <td colspan="2"><h2>Advanced / Debugging Settings</h2></td>
1703
+ </tr>
1704
+ <tr>
1705
+ <th>Debug / Expert mode:</th>
1706
+ <td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to enable some more options here and below (that will appear after you save), and potentially receive more information and emails on the backup process - useful if something is going wrong. You <strong>must</strong> send me this log if you are filing a bug report.</td>
1707
+ </tr>
1708
+ <?php
1709
+ $delete_local = UpdraftPlus_Options::get_updraft_option('updraft_delete_local', 1);
1710
+ if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) { ?>
1711
+
1712
+ <tr class="deletelocal">
1713
+ <th>Delete local backup:</th>
1714
+ <td><input type="checkbox" name="updraft_delete_local" value="1" <?php if ($delete_local) echo 'checked="checked"'; ?>> <br>Uncheck this to prevent deletion of any superfluous backup files from your server after the backup run finishes (i.e. any files despatched remotely will also remain locally, and any files being kept locally will not be subject to the retention limits).</td>
1715
+ </tr>
1716
+
1717
+ <?php } else { ?>
1718
+ <input type="hidden" name="updraft_delete_local" value="<?php echo ($delete_local) ? 1 : 0; ?>">
1719
+ <?php } ?>
1720
+
1721
+ <tr>
1722
+ <th>Backup directory:</th>
1723
+ <td><input type="text" name="updraft_dir" style="width:525px" value="<?php echo htmlspecialchars($updraft_dir); ?>" /></td>
1724
+ </tr>
1725
+ <tr>
1726
+ <td></td><td><?php
1727
+
1728
+ if(is_writable($updraft_dir)) {
1729
+ $dir_info = '<span style="color:green">Backup directory specified is writable, which is good.</span>';
1730
+ } else {
1731
+ $dir_info = '<span style="color:red">Backup directory specified is <b>not</b> writable, or does not exist. <span style="font-size:110%;font-weight:bold"><a href="options-general.php?page=updraftplus&action=updraft_create_backup_dir">Click here</a></span> to attempt to create the directory and set the permissions. If that is unsuccessful check the permissions on your server or change it to another directory that is writable by your web server process.</span>';
1732
+ }
1733
+
1734
+ 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>
1735
+ </tr>
1736
+ <tr>
1737
+ <td></td>
1738
+ <td>
1739
+ <?php
1740
+ $ws_ad = $this->wordshell_random_advert(1);
1741
+ if ($ws_ad) {
1742
+ ?>
1743
+ <p style="margin: 10px 0; padding: 10px; font-size: 140%; background-color: lightYellow; border-color: #E6DB55; border: 1px solid; border-radius: 4px;">
1744
+ <?php echo $ws_ad; ?>
1745
+ </p>
1746
+ <?php
1747
+ }
1748
+ ?>
1749
+ </td>
1750
+ </tr>
1751
+ <tr>
1752
+ <td></td>
1753
+ <td>
1754
+ <input type="hidden" name="action" value="update" />
1755
+ <input type="submit" class="button-primary" value="Save Changes" />
1756
+ </td>
1757
+ </tr>
1758
+ </table>
1759
+ <?php
1760
+ }
1761
+
1762
  function settings_output() {
1763
 
1764
  /*
1832
  elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
1833
  $settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_dropbox_folder', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_others_exclude', 'updraft_lastmessage');
1834
  foreach ($settings as $s) {
1835
+ UpdraftPlus_Options::delete_updraft_option($s);
1836
  }
1837
  $this->show_admin_warning("Your settings have been wiped.");
1838
  }
1839
 
1840
  ?>
1841
  <div class="wrap">
1842
+ <h1><?php echo $this->plugin_title; ?></h1>
1843
 
1844
+ Maintained by <b>David Anderson</b> (<a href="http://david.dw-perspective.org.uk">Homepage</a><?php if (!defined('UPDRAFTPLUS_PREMIUM')) { ?> | <a href="http://updraftplus.com">Premium</a> | <a href="http://wordshell.net">WordShell - WordPress command line</a> | <a href="http://david.dw-perspective.org.uk/donate">Donate</a><?php } ?> | <a href="http://wordpress.org/extend/plugins/updraftplus/faq/">FAQs</a> | <a href="http://profiles.wordpress.org/davidanderson/">My other WordPress plugins</a>). Version: <?php echo $this->version; ?>
1845
  <br>
1846
  <?php
1847
  if(isset($_GET['updraft_restore_success'])) {
1849
  }
1850
 
1851
  $ws_advert = $this->wordshell_random_advert(1);
1852
+ if ($ws_advert) { echo '<div class="updated fade" style="max-width: 800px; font-size:140%; line-height: 140%; padding:14px; clear:left;">'.$ws_advert.'</div>'; }
1853
+
1854
+ if($deleted_old_dirs) echo '<div style="color:blue">Old directories successfully deleted.</div>';
1855
 
 
 
 
1856
  if(!$this->memory_check(96)) {?>
1857
  <div style="color:orange">Your PHP memory limit is too low. UpdraftPlus attempted to raise it but was unsuccessful. This plugin may not work properly with a memory limit of less than 96 Mb (though on the other hand, it has been used successfully with a 32Mb limit - your mileage may vary, but don't blame us!). Current limit is: <?php echo $this->memory_check_current(); ?> Mb</div>
1858
  <?php
1886
  $next_scheduled_backup = wp_next_scheduled('updraft_backup');
1887
  $next_scheduled_backup = ($next_scheduled_backup) ? date('D, F j, Y H:i T',$next_scheduled_backup) : 'No backups are scheduled at this time.';
1888
  $next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
1889
+ if (UpdraftPlus_Options::get_updraft_option('updraft_interval_database',UpdraftPlus_Options::get_updraft_option('updraft_interval')) == UpdraftPlus_Options::get_updraft_option('updraft_interval')) {
1890
  $next_scheduled_backup_database = "Will take place at the same time as the files backup.";
1891
  } else {
1892
  $next_scheduled_backup_database = ($next_scheduled_backup_database) ? date('D, F j, Y H:i T',$next_scheduled_backup_database) : 'No backups are scheduled at this time.';
1893
  }
1894
  $current_time = date('D, F j, Y H:i T',time());
1895
+ $updraft_last_backup = UpdraftPlus_Options::get_updraft_option('updraft_last_backup');
1896
  if($updraft_last_backup) {
1897
  $last_backup = ($updraft_last_backup['success']) ? date('D, F j, Y H:i T',$updraft_last_backup['backup_time']) : implode("<br>",$updraft_last_backup['errors']);
1898
  $last_backup_color = ($updraft_last_backup['success']) ? 'green' : 'red';
1906
  }
1907
 
1908
  if(is_writable($updraft_dir)) {
 
1909
  $backup_disabled = "";
1910
  } else {
1911
  $backup_disabled = 'disabled="disabled"';
 
1912
  }
1913
  ?>
1914
 
1931
  <div style="float:left; width:200px; padding-top: 40px;">
1932
  <form method="post" action="">
1933
  <input type="hidden" name="action" value="updraft_backup" />
1934
+ <p><input type="submit" <?php echo $backup_disabled ?> class="button-primary" value="Backup Now!" style="padding-top:3px;padding-bottom:3px;font-size:24px !important" onclick="return(confirm('This will schedule a one-time backup. To trigger the backup you should go ahead, then wait 10 seconds, then visit any page on your site. WordPress should then start the backup running in the background.'))"></p>
1935
  </form>
1936
  <div style="position:relative">
1937
  <div style="position:absolute;top:0;left:0">
1938
  <?php
1939
+ $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
1940
  $backup_history = (is_array($backup_history))?$backup_history:array();
1941
  $restore_disabled = (count($backup_history) == 0) ? 'disabled="disabled"' : "";
1942
  ?>
1943
+ <input type="button" class="button-primary" <?php echo $restore_disabled ?> value="Restore" style="padding-top:3px;padding-bottom:3px;font-size:24px !important" onclick="jQuery('#backup-restore').fadeIn('slow');jQuery(this).parent().fadeOut('slow')">
1944
  </div>
1945
  <div style="display:none;position:absolute;top:0;left:0" id="backup-restore">
1946
  <form method="post" action="">
1963
  <table class="form-table">
1964
  <tr>
1965
  <th>Last backup log message:</th>
1966
+ <td id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '(Nothing yet logged)')); ?></td>
1967
  </tr>
1968
  <tr>
1969
  <th>Download backups</th>
2044
  </td>
2045
  </tr>
2046
  </table>
2047
+ <?php
2048
+ if (!defined('UPDRAFTPLUS_PREMIUM') && is_multisite()) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2049
  ?>
2050
+ <h2>UpdraftPlus Premium</h2>
2051
+ <table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2052
  <tr>
 
 
 
 
 
 
 
 
2053
  <td>
2054
+ <p style="max-width:800px;">Do you need WordPress Multisite support? Please check out <a href="http://updraftplus.com">UpdraftPlus Premium</a> - and in coming weeks, it will add even more premium features. Why not support UpdraftPlus development?</p>
2055
+ </td>
 
 
 
 
 
 
 
 
 
 
 
2056
  </tr>
2057
+ </table>
2058
+ <?php } ?>
2059
+ <h2>Configure Backup Contents And Schedule</h2>
2060
+ <?php UpdraftPlus_Options::options_form_begin(); ?>
2061
+ <?php $this->settings_formcontents(); ?>
2062
  </form>
2063
  <?php
2064
+ if (UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
2065
  ?>
2066
  <div style="padding-top: 40px;">
2067
  <hr>
2115
  <?php
2116
  }
2117
 
2118
+ function show_admin_warning($message, $class = "updated") {
2119
+ echo '<div id="updraftmessage" class="'.$class.' fade">'."<p>$message</p></div>";
2120
  }
2121
 
2122
  function show_admin_warning_unreadablelog() {
2123
+ $this->show_admin_warning('<strong>UpdraftPlus notice:</strong> The log file could not be read.');
2124
  }
2125
 
2126
  function show_admin_warning_dropbox() {
2127
+ $this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit">Click here to authenticate your Dropbox account (you will not be able to back up to Dropbox without it).');
2128
  }
2129
 
2130
  function show_admin_warning_googledrive() {
2131
+ $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).');
2132
  }
2133
 
2134
  }