UpdraftPlus WordPress Backup Plugin - Version 1.2.28

Version Description

  • 01/15/2013 =
  • Fixed bug with DropBox deletions
  • Fixed cases where DropBox failed to resume chunked uploading
  • Can now create uncreated zip files on a resumption attempt
  • FTP method now supports SSL (automatically detected)
  • New "Test FTP settings" button
  • Less noise when debugging is turned off
Download this release

Release Info

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

Code changes from version 1.2.27 to 1.2.28

methods/dropbox.php CHANGED
@@ -222,7 +222,7 @@ class UpdraftPlus_BackupModule_dropbox {
222
  </tr>
223
  <tr class="updraftplusmethod dropbox">
224
  <th>DropBox Folder:</th>
225
- <td><input type="text" style="width:332px" id="updraft_dropbox_folder" name="updraft_dropbox_folder" value="<?php echo htmlspecialchars(get_option('updraft_dropbox_folder')); ?>" /></td>
226
  </tr>
227
 
228
  <tr class="updraftplusmethod dropbox">
222
  </tr>
223
  <tr class="updraftplusmethod dropbox">
224
  <th>DropBox Folder:</th>
225
+ <td><input type="text" style="width:332px" id="updraft_dropbox_folder" name="updraft_dropbox_folder" value="<?php echo htmlspecialchars(get_option('updraft_dropbox_folder')); ?>" /> <em>N.B. This is inside your &quot;apps&quot; folder</em></td>
226
  </tr>
227
 
228
  <tr class="updraftplusmethod dropbox">
methods/ftp.php CHANGED
@@ -33,8 +33,8 @@ class UpdraftPlus_BackupModule_ftp {
33
  $updraftplus->log("FTP upload attempt successful (".$size_k."Kb in ".(round(microtime(true)-$timer_start,2)).'s)');
34
  $updraftplus->uploaded_file($file);
35
  } else {
36
- $updraftplus->error("FTP upload failed" );
37
  $updraftplus->log("ERROR: FTP upload failed" );
 
38
  }
39
  }
40
 
33
  $updraftplus->log("FTP upload attempt successful (".$size_k."Kb in ".(round(microtime(true)-$timer_start,2)).'s)');
34
  $updraftplus->uploaded_file($file);
35
  } else {
 
36
  $updraftplus->log("ERROR: FTP upload failed" );
37
+ $updraftplus->error("FTP upload failed" );
38
  }
39
  }
40
 
methods/googledrive.php CHANGED
@@ -117,8 +117,8 @@ class UpdraftPlus_BackupModule_googledrive {
117
  $updraftplus->log('OK: Archive ' . $file_name . ' uploaded to Google Drive in ' . ( round(microtime( true ) - $timer_start,2) ) . ' seconds (id: '.$id.')' );
118
  $updraftplus->uploaded_file($file, $id);
119
  } else {
120
- $updraftplus->error("$file_name: Failed to upload to Google Drive" );
121
  $updraftplus->log("ERROR: $file_name: Failed to upload to Google Drive" );
 
122
  }
123
  }
124
  $updraftplus->prune_retained_backups("googledrive", $this, null);
@@ -171,8 +171,8 @@ class UpdraftPlus_BackupModule_googledrive {
171
  if ( is_wp_error( $location ) ) {
172
  $updraftplus->log("GoogleDrive upload: an error occurred");
173
  foreach ($location->get_error_messages() as $msg) {
174
- $updraftplus->error($msg);
175
  $updraftplus->log("Error details: ".$msg);
 
176
  }
177
  return false;
178
  }
117
  $updraftplus->log('OK: Archive ' . $file_name . ' uploaded to Google Drive in ' . ( round(microtime( true ) - $timer_start,2) ) . ' seconds (id: '.$id.')' );
118
  $updraftplus->uploaded_file($file, $id);
119
  } else {
 
120
  $updraftplus->log("ERROR: $file_name: Failed to upload to Google Drive" );
121
+ $updraftplus->error("$file_name: Failed to upload to Google Drive" );
122
  }
123
  }
124
  $updraftplus->prune_retained_backups("googledrive", $this, null);
171
  if ( is_wp_error( $location ) ) {
172
  $updraftplus->log("GoogleDrive upload: an error occurred");
173
  foreach ($location->get_error_messages() as $msg) {
 
174
  $updraftplus->log("Error details: ".$msg);
175
+ $updraftplus->error($msg);
176
  }
177
  return false;
178
  }
methods/s3.php CHANGED
@@ -76,8 +76,8 @@ class UpdraftPlus_BackupModule_s3 {
76
  set_transient("upd_${hash}_e$i", $etag, 3600*3);
77
  $successes++;
78
  } else {
79
- $updraftplus->error("S3 chunk $i: upload failed");
80
  $updraftplus->log("S3 chunk $i: upload failed");
 
81
  }
82
  }
83
  }
76
  set_transient("upd_${hash}_e$i", $etag, 3600*3);
77
  $successes++;
78
  } else {
 
79
  $updraftplus->log("S3 chunk $i: upload failed");
80
+ $updraftplus->error("S3 chunk $i: upload failed");
81
  }
82
  }
83
  }
readme.txt CHANGED
@@ -3,12 +3,12 @@ Contributors: David Anderson
3
  Tags: backup, restore, database, cloud, amazon, s3, Amazon S3, DropBox, DropBox backup, google drive, google, gdrive, ftp, cloud, updraft, back up
4
  Requires at least: 3.2
5
  Tested up to: 3.5
6
- Stable tag: 1.2.27
7
  Donate link: http://david.dw-perspective.org.uk/donate
8
  License: GPLv3 or later
9
 
10
  == Upgrade Notice ==
11
- DropBox can now support larger, resumable uploads. Also improved DropBox help text. Made file downloads resumable. FTP supports SSL.
12
 
13
  == Description ==
14
 
@@ -112,12 +112,13 @@ Thanks for asking - yes, I have. Check out my profile page - http://profiles.wor
112
 
113
  == Changelog ==
114
 
115
- = 1.2.27 - 01/14/2013 =
116
  * Fixed bug with DropBox deletions
117
  * Fixed cases where DropBox failed to resume chunked uploading
118
  * Can now create uncreated zip files on a resumption attempt
119
  * FTP method now supports SSL (automatically detected)
120
  * New "Test FTP settings" button
 
121
 
122
  = 1.2.20 - 01/12/2013 =
123
  * DropBox no longer limited to 150Mb uploads
3
  Tags: backup, restore, database, cloud, amazon, s3, Amazon S3, DropBox, DropBox backup, google drive, google, gdrive, ftp, cloud, updraft, back up
4
  Requires at least: 3.2
5
  Tested up to: 3.5
6
+ Stable tag: 1.2.28
7
  Donate link: http://david.dw-perspective.org.uk/donate
8
  License: GPLv3 or later
9
 
10
  == Upgrade Notice ==
11
+ Complete DropBox support. FTP over SSL. Less noise.
12
 
13
  == Description ==
14
 
112
 
113
  == Changelog ==
114
 
115
+ = 1.2.28 - 01/15/2013 =
116
  * Fixed bug with DropBox deletions
117
  * Fixed cases where DropBox failed to resume chunked uploading
118
  * Can now create uncreated zip files on a resumption attempt
119
  * FTP method now supports SSL (automatically detected)
120
  * New "Test FTP settings" button
121
+ * Less noise when debugging is turned off
122
 
123
  = 1.2.20 - 01/12/2013 =
124
  * DropBox no longer limited to 150Mb uploads
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: All your content and your DB can be automatically backed up to Amazon S3, DropBox, Google Drive, FTP, or emailed, on separate schedules.
6
  Author: David Anderson.
7
- Version: 1.2.27
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
10
  Author URI: http://wordshell.net
@@ -12,7 +12,7 @@ Author URI: http://wordshell.net
12
 
13
  /*
14
  TODO
15
- //Add 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
@@ -23,7 +23,6 @@ TODO
23
  // Separate 'retain' settings for db + files (since they are on separate schedules)
24
  // Warn the user if their zip-file creation is slooowww...
25
  // Create a "Want Support?" button/console, that leads them through what is needed, and performs some basic tests...
26
- // Add/test FTP-over-TLS
27
  // Resuming partial FTP uploads
28
 
29
  Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
@@ -66,7 +65,7 @@ define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
66
 
67
  class UpdraftPlus {
68
 
69
- var $version = '1.2.27';
70
 
71
  // Choices will be shown in the admin menu in the order used here
72
  var $backup_methods = array (
@@ -86,6 +85,8 @@ class UpdraftPlus {
86
  var $logfile_handle = false;
87
  var $backup_time;
88
 
 
 
89
  function __construct() {
90
  // Initialisation actions - takes place on plugin load
91
  # Create admin page
@@ -150,9 +151,19 @@ class UpdraftPlus {
150
  set_transient("updraftplus_runtype_$nonce", $this->cronrun_type, 300);
151
  }
152
 
153
- # Logs the given line, adding date stamp and newline
 
 
 
 
 
 
 
 
 
 
154
  function log($line) {
155
- if ($this->logfile_handle) fwrite($this->logfile_handle,date('r')." ".$line."\n");
156
  }
157
 
158
  function backup_resume($resumption_no) {
@@ -242,11 +253,10 @@ class UpdraftPlus {
242
 
243
  $this->log("Requesting backup of the files that were not successfully uploaded");
244
  $this->cloud_backup($undone_files);
245
- $this->cloud_backup_finish($undone_files);
246
 
247
  $this->log("Resume backup ($resumption_no): finish run");
248
 
249
- $this->backup_finish($next_resumption, true);
250
 
251
  }
252
 
@@ -266,14 +276,6 @@ class UpdraftPlus {
266
  $this->backup(false,true);
267
  }
268
 
269
- function logfile_open($nonce) {
270
- //set log file name and open log file
271
- $updraft_dir = $this->backups_dir_location();
272
- $this->logfile_name = $updraft_dir. "/log.$nonce.txt";
273
- // Use append mode in case it already exists
274
- $this->logfile_handle = fopen($this->logfile_name, 'a');
275
- }
276
-
277
  function check_backup_race( $to_delete = false ) {
278
  // Avoid caching
279
  global $wpdb;
@@ -424,13 +426,10 @@ class UpdraftPlus {
424
  $this->log("Saving last backup information into WordPress db");
425
  $this->save_last_backup($backup_array);
426
 
427
- // Send the email
428
- $this->cloud_backup_finish($backup_array, $clear_nonce_transient);
429
-
430
  }
431
 
432
  // Close log file; delete and also delete transients if not in debug mode
433
- $this->backup_finish(1, $clear_nonce_transient);
434
 
435
  }
436
 
@@ -468,7 +467,7 @@ class UpdraftPlus {
468
  }
469
  }
470
 
471
- function backup_finish($cancel_event, $clear_nonce_transient) {
472
 
473
  // In fact, leaving the hook to run (if debug is set) is harmless, as the resume job should only do tasks that were left unfinished, which at this stage is none.
474
  if (empty($this->errors)) {
@@ -482,6 +481,15 @@ class UpdraftPlus {
482
  $this->log("There were errors in the uploads, so the 'resume' event is remaining scheduled");
483
  }
484
 
 
 
 
 
 
 
 
 
 
485
  @fclose($this->logfile_handle);
486
 
487
  // Don't delete the log file now; delete it upon rotation
@@ -489,20 +497,15 @@ class UpdraftPlus {
489
 
490
  }
491
 
492
- function cloud_backup_finish($backup_array) {
493
-
494
- // Send the results email if requested
495
- if(get_option('updraft_email') != "" && get_option('updraft_service') != 'email') $this->send_results_email();
496
-
497
- }
498
-
499
  function send_results_email() {
500
 
 
 
501
  $sendmail_to = get_option('updraft_email');
502
 
503
- $this->log("Sending email report to: ".$sendmail_to);
504
 
505
- $append_log = (get_option('updraft_debug_mode') && $this->logfile_name != "") ? "\r\nLog contents:\r\n".file_get_contents($this->logfile_name) : "" ;
506
 
507
  wp_mail($sendmail_to,'Backed up: '.get_bloginfo('name').' (UpdraftPlus '.$this->version.') '.date('Y-m-d H:i',time()),'Site: '.site_url()."\r\nUpdraftPlus WordPress backup is complete.\r\nBackup contains: ".get_transient("updraft_backupcontains_".$this->nonce)."\r\n\r\n".$this->wordshell_random_advert(0)."\r\n".$append_log);
508
 
@@ -667,8 +670,8 @@ class UpdraftPlus {
667
  $microtime_start = microtime(true);
668
  # The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
669
  if (!$zip_object->create($create_from_dir, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR)) {
670
- $this->error("Could not create $whichone zip. Consult the log file for more information.");
671
  $this->log("ERROR: PclZip failure: Could not create $whichone zip");
 
672
  return false;
673
  } else {
674
  rename($full_path.'.tmp', $full_path);
@@ -690,8 +693,8 @@ class UpdraftPlus {
690
 
691
  $updraft_dir = $this->backups_dir_location();
692
  if(!is_writable($updraft_dir)) {
693
- $this->error('Backup directory is not writable, or does not exist.','fatal');
694
  $this->log('Backup directory is not writable, or does not exist');
 
695
  return array();
696
  }
697
 
@@ -788,6 +791,7 @@ class UpdraftPlus {
788
  $backup_history[$this->backup_time] = $backup_array;
789
  update_option('updraft_backup_history',$backup_history);
790
  } else {
 
791
  $this->error('Could not save backup history because we have no backup array. Backup probably failed.');
792
  }
793
  }
@@ -857,6 +861,7 @@ class UpdraftPlus {
857
  $updraft_dir = $this->backups_dir_location();
858
 
859
  if (!is_writable($updraft_dir)) {
 
860
  $this->error('The backup directory is not writable.');
861
  return false;
862
  }
@@ -1077,7 +1082,8 @@ class UpdraftPlus {
1077
  }
1078
  }
1079
 
1080
- function error($error,$severity='') {
 
1081
  $this->errors[] = $error;
1082
  return true;
1083
  }
@@ -1913,7 +1919,7 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
1913
  </tr>
1914
  <tr>
1915
  <th>Debug mode:</th>
1916
- <td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to receive more information 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>
1917
  </tr>
1918
  <tr>
1919
  <td></td>
4
  Plugin URI: http://wordpress.org/extend/plugins/updraftplus
5
  Description: Backup and restore: All your content and your DB can be automatically backed up to Amazon S3, DropBox, Google Drive, FTP, or emailed, on separate schedules.
6
  Author: David Anderson.
7
+ Version: 1.2.28
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
10
  Author URI: http://wordshell.net
12
 
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
23
  // Separate 'retain' settings for db + files (since they are on separate schedules)
24
  // Warn the user if their zip-file creation is slooowww...
25
  // Create a "Want Support?" button/console, that leads them through what is needed, and performs some basic tests...
 
26
  // Resuming partial FTP uploads
27
 
28
  Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
65
 
66
  class UpdraftPlus {
67
 
68
+ var $version = '1.2.28';
69
 
70
  // Choices will be shown in the admin menu in the order used here
71
  var $backup_methods = array (
85
  var $logfile_handle = false;
86
  var $backup_time;
87
 
88
+ var $opened_log_time;
89
+
90
  function __construct() {
91
  // Initialisation actions - takes place on plugin load
92
  # Create admin page
151
  set_transient("updraftplus_runtype_$nonce", $this->cronrun_type, 300);
152
  }
153
 
154
+ function logfile_open($nonce) {
155
+ //set log file name and open log file
156
+ $updraft_dir = $this->backups_dir_location();
157
+ $this->logfile_name = $updraft_dir. "/log.$nonce.txt";
158
+ // Use append mode in case it already exists
159
+ $this->logfile_handle = fopen($this->logfile_name, 'a');
160
+ $this->opened_log_time = microtime(true);
161
+ $this->log("Opened log file at time: ".date('r'));
162
+ }
163
+
164
+ # Logs the given line, adding (relative) time stamp and newline
165
  function log($line) {
166
+ if ($this->logfile_handle) fwrite($this->logfile_handle, sprintf("%08.03f", round(microtime(true)-$this->opened_log_time, 3))." ".$line."\n");
167
  }
168
 
169
  function backup_resume($resumption_no) {
253
 
254
  $this->log("Requesting backup of the files that were not successfully uploaded");
255
  $this->cloud_backup($undone_files);
 
256
 
257
  $this->log("Resume backup ($resumption_no): finish run");
258
 
259
+ $this->backup_finish($next_resumption, true, true, $resumption_no);
260
 
261
  }
262
 
276
  $this->backup(false,true);
277
  }
278
 
 
 
 
 
 
 
 
 
279
  function check_backup_race( $to_delete = false ) {
280
  // Avoid caching
281
  global $wpdb;
426
  $this->log("Saving last backup information into WordPress db");
427
  $this->save_last_backup($backup_array);
428
 
 
 
 
429
  }
430
 
431
  // Close log file; delete and also delete transients if not in debug mode
432
+ $this->backup_finish(1, $clear_nonce_transient, $clear_nonce_transient, 0);
433
 
434
  }
435
 
467
  }
468
  }
469
 
470
+ function backup_finish($cancel_event, $clear_nonce_transient, $allow_email, $resumption_no) {
471
 
472
  // In fact, leaving the hook to run (if debug is set) is harmless, as the resume job should only do tasks that were left unfinished, which at this stage is none.
473
  if (empty($this->errors)) {
481
  $this->log("There were errors in the uploads, so the 'resume' event is remaining scheduled");
482
  }
483
 
484
+ // Send the results email if appropriate, which means:
485
+ // - The caller allowed it (which is not the case in an 'empty' run)
486
+ // - And: An email address was set (which must be so in email mode)
487
+ // And one of:
488
+ // - Debug mode
489
+ // - There were no errors (which means we completed and so this is the final run - time for the final report)
490
+ // - It was the tenth resumption; everything failed
491
+ if ($allow_email && get_option('updraft_email') != "" && (get_option('updraft_debug_mode') || empty($this->errors) || $resumption_no >=9 )) $this->send_results_email();
492
+
493
  @fclose($this->logfile_handle);
494
 
495
  // Don't delete the log file now; delete it upon rotation
497
 
498
  }
499
 
 
 
 
 
 
 
 
500
  function send_results_email() {
501
 
502
+ $debug_mode = get_option('updraft_debug_mode');
503
+
504
  $sendmail_to = get_option('updraft_email');
505
 
506
+ $this->log("Sending email report to: ".substr($sendmail_to, 0, 5)."...");
507
 
508
+ $append_log = ($debug_mode && $this->logfile_name != "") ? "\r\nLog contents:\r\n".file_get_contents($this->logfile_name) : "" ;
509
 
510
  wp_mail($sendmail_to,'Backed up: '.get_bloginfo('name').' (UpdraftPlus '.$this->version.') '.date('Y-m-d H:i',time()),'Site: '.site_url()."\r\nUpdraftPlus WordPress backup is complete.\r\nBackup contains: ".get_transient("updraft_backupcontains_".$this->nonce)."\r\n\r\n".$this->wordshell_random_advert(0)."\r\n".$append_log);
511
 
670
  $microtime_start = microtime(true);
671
  # The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
672
  if (!$zip_object->create($create_from_dir, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR)) {
 
673
  $this->log("ERROR: PclZip failure: Could not create $whichone zip");
674
+ $this->error("Could not create $whichone zip. Consult the log file for more information.");
675
  return false;
676
  } else {
677
  rename($full_path.'.tmp', $full_path);
693
 
694
  $updraft_dir = $this->backups_dir_location();
695
  if(!is_writable($updraft_dir)) {
 
696
  $this->log('Backup directory is not writable, or does not exist');
697
+ $this->error('Backup directory is not writable, or does not exist.');
698
  return array();
699
  }
700
 
791
  $backup_history[$this->backup_time] = $backup_array;
792
  update_option('updraft_backup_history',$backup_history);
793
  } else {
794
+ $this->log('Could not save backup history because we have no backup array. Backup probably failed.');
795
  $this->error('Could not save backup history because we have no backup array. Backup probably failed.');
796
  }
797
  }
861
  $updraft_dir = $this->backups_dir_location();
862
 
863
  if (!is_writable($updraft_dir)) {
864
+ $this->log('The backup directory is not writable.');
865
  $this->error('The backup directory is not writable.');
866
  return false;
867
  }
1082
  }
1083
  }
1084
 
1085
+ function error($error) {
1086
+ if (count($this->errors) == 0) $this->log("An error condition has occurred for the first time on this run");
1087
  $this->errors[] = $error;
1088
  return true;
1089
  }
1919
  </tr>
1920
  <tr>
1921
  <th>Debug mode:</th>
1922
+ <td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this to 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>
1923
  </tr>
1924
  <tr>
1925
  <td></td>