UpdraftPlus WordPress Backup Plugin - Version 1.7.3

Version Description

  • 2013/08/26 =
  • FIX: Some Dropbox connect errors were being lost
  • FIX: Fix detection of availability of binary zip method on PHP installs where popen() is available put proc_open() is disabled
  • FIX: (Premium): WP Core and More Files remaining locally/not being despatched to cloud storage
  • TWEAK: More logging of the success (or not) of backups sent via email
  • TWEAK: Remember hint from previous job if PHP is allowed to run for more than 300 seconds at a time
Download this release

Release Info

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

Code changes from version 1.7.1 to 1.7.3

admin.php CHANGED
@@ -257,7 +257,7 @@ class UpdraftPlus_Admin {
257
  $dismissed = get_transient('updraftplus_dismissedautobackup');
258
  if (true == $dismissed) return;
259
 
260
- if ( 'upgrade-plugin' == $action ) {
261
  $title = __('Update Plugin');
262
  $parent_file = 'plugins.php';
263
  $submenu_file = 'plugins.php';
@@ -1245,9 +1245,9 @@ CREATE TABLE $wpdb->signups (
1245
  } elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
1246
  $settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', '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_wpcore', 'updraft_include_wpcore_exclude', 'updraft_include_more',
1247
  'updraft_include_blogs', 'updraft_include_mu-plugins', 'updraft_include_others_exclude', 'updraft_lastmessage', 'updraft_googledrive_clientid', 'updraft_googledrive_token', 'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder', 'updraft_last_backup', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_db', 'updraft_startday_files', 'updraft_sftp_settings', 'updraft_s3generic_login', 'updraft_s3generic_pass', 'updraft_s3generic_remote_path', 'updraft_s3generic_endpoint', 'updraft_webdav_settings', 'updraft_disable_ping', 'updraft_cloudfiles_user', 'updraft_cloudfiles_apikey', 'updraft_cloudfiles_path', 'updraft_cloudfiles_authurl', 'updraft_ssl_useservercerts', 'updraft_ssl_disableverify', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dreamobjects_login', 'updraft_dreamobjects_pass', 'updraft_dreamobjects_remote_path');
1248
- foreach ($settings as $s) {
1249
- UpdraftPlus_Options::delete_updraft_option($s);
1250
- }
1251
  $this->show_admin_warning(__("Your settings have been wiped.",'updraftplus'));
1252
  }
1253
 
@@ -2334,7 +2334,7 @@ ENDHERE;
2334
  // Record which set this file is found in
2335
  if (!is_array($values)) $values=array($values);
2336
  foreach ($values as $val) {
2337
- if (preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]([0-9]+(of[0-9]+)?)?+\.(zip|gz|gz\.crypt)$/i', $val, $matches)) {
2338
  $nonce = $matches[2];
2339
  if (isset($bdata['service']) && $bdata['service'] == 'none' && !is_file($updraft_dir.'/'.$val)) {
2340
  # File no longer present
257
  $dismissed = get_transient('updraftplus_dismissedautobackup');
258
  if (true == $dismissed) return;
259
 
260
+ if ( 'upgrade-plugin' == $_GET['action'] ) {
261
  $title = __('Update Plugin');
262
  $parent_file = 'plugins.php';
263
  $submenu_file = 'plugins.php';
1245
  } elseif (isset($_POST['action']) && $_POST['action'] == 'updraft_wipesettings') {
1246
  $settings = array('updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', '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_wpcore', 'updraft_include_wpcore_exclude', 'updraft_include_more',
1247
  'updraft_include_blogs', 'updraft_include_mu-plugins', 'updraft_include_others_exclude', 'updraft_lastmessage', 'updraft_googledrive_clientid', 'updraft_googledrive_token', 'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder', 'updraft_last_backup', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_db', 'updraft_startday_files', 'updraft_sftp_settings', 'updraft_s3generic_login', 'updraft_s3generic_pass', 'updraft_s3generic_remote_path', 'updraft_s3generic_endpoint', 'updraft_webdav_settings', 'updraft_disable_ping', 'updraft_cloudfiles_user', 'updraft_cloudfiles_apikey', 'updraft_cloudfiles_path', 'updraft_cloudfiles_authurl', 'updraft_ssl_useservercerts', 'updraft_ssl_disableverify', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dreamobjects_login', 'updraft_dreamobjects_pass', 'updraft_dreamobjects_remote_path');
1248
+
1249
+ foreach ($settings as $s) UpdraftPlus_Options::delete_updraft_option($s);
1250
+
1251
  $this->show_admin_warning(__("Your settings have been wiped.",'updraftplus'));
1252
  }
1253
 
2334
  // Record which set this file is found in
2335
  if (!is_array($values)) $values=array($values);
2336
  foreach ($values as $val) {
2337
+ if (preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+([0-9]+(of[0-9]+)?)?+\.(zip|gz|gz\.crypt)$/i', $val, $matches)) {
2338
  $nonce = $matches[2];
2339
  if (isset($bdata['service']) && $bdata['service'] == 'none' && !is_file($updraft_dir.'/'.$val)) {
2340
  # File no longer present
backup.php CHANGED
@@ -508,21 +508,20 @@ class UpdraftPlus_Backup {
508
  if (count($dirlist)>0) {
509
  $created = $this->create_zip($dirlist, $youwhat, $backup_file_basename, $index);
510
  # Now, store the results
511
- if (is_string($created) || is_array($created)) {
512
- if (is_string($created)) $created=array($created);
513
- foreach ($created as $findex => $fname) {
514
- $backup_array[$youwhat][$index] = $fname;
515
- $itext = ($index == 0) ? '' : $index;
516
- $index++;
517
- $backup_array[$youwhat.$itext.'-size'] = filesize($updraft_dir.'/'.$fname);
518
- }
519
- } else {
520
- $updraftplus->log("$youwhat: create_zip returned an error");
521
- }
522
  } else {
523
  $updraftplus->log("No backup of $youwhat: there was nothing found to back up");
524
  }
 
525
 
 
 
 
 
 
 
 
 
526
  }
527
 
528
  $job_file_entities[$youwhat]['index'] = $this->index;
@@ -616,7 +615,7 @@ class UpdraftPlus_Backup {
616
  if (!$updraftplus->opened_log_time) $updraftplus->logfile_open($updraftplus->nonce);
617
 
618
  // Get the blog name and rip out all non-alphanumeric chars other than _
619
- $blog_name = preg_replace('/[^A-Za-z0-9_]/','', str_replace(' ','_', substr(get_bloginfo(), 0, 96)));
620
  if (!$blog_name) $blog_name = 'non_alpha_name';
621
  $blog_name = apply_filters('updraftplus_blog_name', $blog_name);
622
 
@@ -808,7 +807,6 @@ class UpdraftPlus_Backup {
808
  }
809
 
810
  $this->stow("#\n\n");
811
-
812
  }
813
 
814
  // In UpdraftPlus, segment is always 'none'
@@ -823,7 +821,7 @@ class UpdraftPlus_Backup {
823
  $integer_fields[strtolower($struct->Field)] = "1";
824
  }
825
  }
826
-
827
  // Experimentation here shows that on large tables (we tested with 180,000 rows) on MyISAM, 1000 makes the table dump out 3x faster than the previous value of 100. After that, the benefit diminishes (increasing to 4000 only saved another 12%)
828
  if($segment == 'none') {
829
  $row_start = 0;
@@ -1024,7 +1022,7 @@ class UpdraftPlus_Backup {
1024
  $updraftplus->log(sprintf(__("Failed to open directory (check the file permissions): %s",'updraftplus'), $fullpath), 'error');
1025
  return false;
1026
  }
1027
- while ($e = readdir($dir_handle)) {
1028
  if ($e != '.' && $e != '..') {
1029
  if (is_link($fullpath.'/'.$e)) {
1030
  $deref = realpath($fullpath.'/'.$e);
@@ -1081,6 +1079,9 @@ class UpdraftPlus_Backup {
1081
  global $updraftplus;
1082
  $updraft_dir = $updraftplus->backups_dir_location();
1083
 
 
 
 
1084
  $original_index = $this->index;
1085
 
1086
  $itext = (empty($this->index)) ? '' : ($this->index+1);
@@ -1226,18 +1227,18 @@ class UpdraftPlus_Backup {
1226
  // Remove prefixes
1227
  $backupable_entities = $updraftplus->get_backupable_file_entities(true);
1228
  if (isset($backupable_entities[$this->whichone])) {
1229
- if ('plugins' == $whichone || 'themes' == $whichone || 'uploads' == $whichone) {
1230
- $remove_path = dirname($backupable_entities[$whichone]);
1231
  # To normalise instead of removing (which binzip doesn't support, so we don't do it), you'd remove the dirname() in the above line, and uncomment the below one.
1232
- #$add_path = $whichone;
1233
  } else {
1234
- $remove_path = $backupable_entities[$whichone];
1235
  }
1236
  }
1237
  if ($add_path) {
1238
  $zipcode = $zip->create($this->source, PCLZIP_OPT_REMOVE_PATH, $remove_path, PCLZIP_OPT_ADD_PATH, $add_path);
1239
  } else {
1240
- $zipcode = $zip->create($this->source, PCLZIP_OPT_REMOVE_PATH, $remove_path);
1241
  }
1242
  if ($zipcode == 0 ) {
1243
  $updraftplus->log("PclZip Error: ".$zip->errorInfo(true), 'warning');
@@ -1555,4 +1556,4 @@ class UpdraftPlus_Backup {
1555
  $updraftplus->jobdata_set('job_file_entities', $job_file_entities);
1556
  }
1557
 
1558
- }
508
  if (count($dirlist)>0) {
509
  $created = $this->create_zip($dirlist, $youwhat, $backup_file_basename, $index);
510
  # Now, store the results
511
+ if (!is_string($created) && !is_array($created)) $updraftplus->log("$youwhat: create_zip returned an error");
 
 
 
 
 
 
 
 
 
 
512
  } else {
513
  $updraftplus->log("No backup of $youwhat: there was nothing found to back up");
514
  }
515
+ }
516
 
517
+ if ( $created != $whichdir && (is_string($created) || is_array($created))) {
518
+ if (is_string($created)) $created=array($created);
519
+ foreach ($created as $findex => $fname) {
520
+ $backup_array[$youwhat][$index] = $fname;
521
+ $itext = ($index == 0) ? '' : $index;
522
+ $index++;
523
+ $backup_array[$youwhat.$itext.'-size'] = filesize($updraft_dir.'/'.$fname);
524
+ }
525
  }
526
 
527
  $job_file_entities[$youwhat]['index'] = $this->index;
615
  if (!$updraftplus->opened_log_time) $updraftplus->logfile_open($updraftplus->nonce);
616
 
617
  // Get the blog name and rip out all non-alphanumeric chars other than _
618
+ $blog_name = preg_replace('/[^A-Za-z0-9_]/','', str_replace(' ','_', substr(get_bloginfo(), 0, 32)));
619
  if (!$blog_name) $blog_name = 'non_alpha_name';
620
  $blog_name = apply_filters('updraftplus_blog_name', $blog_name);
621
 
807
  }
808
 
809
  $this->stow("#\n\n");
 
810
  }
811
 
812
  // In UpdraftPlus, segment is always 'none'
821
  $integer_fields[strtolower($struct->Field)] = "1";
822
  }
823
  }
824
+
825
  // Experimentation here shows that on large tables (we tested with 180,000 rows) on MyISAM, 1000 makes the table dump out 3x faster than the previous value of 100. After that, the benefit diminishes (increasing to 4000 only saved another 12%)
826
  if($segment == 'none') {
827
  $row_start = 0;
1022
  $updraftplus->log(sprintf(__("Failed to open directory (check the file permissions): %s",'updraftplus'), $fullpath), 'error');
1023
  return false;
1024
  }
1025
+ while (false !== ($e = readdir($dir_handle))) {
1026
  if ($e != '.' && $e != '..') {
1027
  if (is_link($fullpath.'/'.$e)) {
1028
  $deref = realpath($fullpath.'/'.$e);
1079
  global $updraftplus;
1080
  $updraft_dir = $updraftplus->backups_dir_location();
1081
 
1082
+ # This is only used by one corner-case in BinZip
1083
+ $this->make_zipfile_source = $source;
1084
+
1085
  $original_index = $this->index;
1086
 
1087
  $itext = (empty($this->index)) ? '' : ($this->index+1);
1227
  // Remove prefixes
1228
  $backupable_entities = $updraftplus->get_backupable_file_entities(true);
1229
  if (isset($backupable_entities[$this->whichone])) {
1230
+ if ('plugins' == $this->whichone || 'themes' == $this->whichone || 'uploads' == $this->whichone) {
1231
+ $remove_path = dirname($backupable_entities[$this->whichone]);
1232
  # To normalise instead of removing (which binzip doesn't support, so we don't do it), you'd remove the dirname() in the above line, and uncomment the below one.
1233
+ #$add_path = $this->whichone;
1234
  } else {
1235
+ $remove_path = $backupable_entities[$this->whichone];
1236
  }
1237
  }
1238
  if ($add_path) {
1239
  $zipcode = $zip->create($this->source, PCLZIP_OPT_REMOVE_PATH, $remove_path, PCLZIP_OPT_ADD_PATH, $add_path);
1240
  } else {
1241
+ $zipcode = $zip->create($this->source, PCLZIP_OPT_REMOVE_PATH, $remove_path);
1242
  }
1243
  if ($zipcode == 0 ) {
1244
  $updraftplus->log("PclZip Error: ".$zip->errorInfo(true), 'warning');
1556
  $updraftplus->jobdata_set('job_file_entities', $job_file_entities);
1557
  }
1558
 
1559
+ }
class-zip.php CHANGED
@@ -27,6 +27,7 @@ class UpdraftPlus_BinZip extends UpdraftPlus_PclZip {
27
  public function addFile($file, $add_as) {
28
 
29
  global $updraftplus;
 
30
  $base = $updraftplus->str_lreplace($add_as, '', $file);
31
 
32
  if ($file == $base) {
@@ -70,13 +71,21 @@ class UpdraftPlus_BinZip extends UpdraftPlus_PclZip {
70
 
71
  $added_dirs_yet = false;
72
 
 
 
 
 
 
 
 
73
  // Loop over each destination directory name
74
  foreach ($this->addfiles as $rdirname => $files) {
75
 
76
  $process = proc_open($exec, $descriptorspec, $pipes, $rdirname);
77
 
78
  if (!is_resource($process)) {
79
- $this->last_error = $updraftplus->log("BinZip error: popen failed");
 
80
  return false;
81
  }
82
 
@@ -88,9 +97,11 @@ class UpdraftPlus_BinZip extends UpdraftPlus_PclZip {
88
  $added_dirs_yet=true;
89
  }
90
 
91
- foreach ($files as $file) {
92
- // Send the list of files on stdin
93
- fwrite($pipes[0], $file."\n");
 
 
94
  }
95
  fclose($pipes[0]);
96
 
@@ -121,7 +132,7 @@ class UpdraftPlus_BinZip extends UpdraftPlus_PclZip {
121
 
122
  while (!feof($pipes[2])) {
123
  $last_error = fgets($pipes[2]);
124
- if (!empty($last_error)) $this->last_error = $last_error;
125
  }
126
  fclose($pipes[2]);
127
 
27
  public function addFile($file, $add_as) {
28
 
29
  global $updraftplus;
30
+ # Get the directory that $add_as is relative to
31
  $base = $updraftplus->str_lreplace($add_as, '', $file);
32
 
33
  if ($file == $base) {
71
 
72
  $added_dirs_yet = false;
73
 
74
+ # If there are no files to add, but there are empty directories, then we need to make sure the directories actually get added
75
+ if (0 == count($this->addfiles) && 0 < count($this->adddirs)) {
76
+ global $updraftplus_backup;
77
+ $dir = dirname(realpath($updraftplus_backup->make_zipfile_source));
78
+ $this->addfiles[$dir] = '././.';
79
+ }
80
+
81
  // Loop over each destination directory name
82
  foreach ($this->addfiles as $rdirname => $files) {
83
 
84
  $process = proc_open($exec, $descriptorspec, $pipes, $rdirname);
85
 
86
  if (!is_resource($process)) {
87
+ $updraftplus->log('BinZip error: proc_open failed');
88
+ $this->last_error = 'BinZip error: proc_open failed';
89
  return false;
90
  }
91
 
97
  $added_dirs_yet=true;
98
  }
99
 
100
+ if (is_array($files)) {
101
+ foreach ($files as $file) {
102
+ // Send the list of files on stdin
103
+ fwrite($pipes[0], $file."\n");
104
+ }
105
  }
106
  fclose($pipes[0]);
107
 
132
 
133
  while (!feof($pipes[2])) {
134
  $last_error = fgets($pipes[2]);
135
+ if (!empty($last_error)) $this->last_error = rtrim($last_error);
136
  }
137
  fclose($pipes[2]);
138
 
includes/updraft-admin-ui.js CHANGED
@@ -606,7 +606,7 @@ jQuery(document).ready(function($){
606
  // $('#' + file.id + " span").append('<button type="button" onclick="updraftplus_downloadstage2(\'db\', \'db\'">Download to your computer</button>');
607
  // $('#' + file.id + " span").append('<form action="admin-ajax.php" onsubmit="return updraft_downloader(\'+bkey+''\', \'db\')" method="post"><input type="hidden" name="_wpnonce" value="'+updraft_downloader_nonce+'"><input type="hidden" name="action" value="updraft_download_backup" /><input type="hidden" name="type" value="db" /><input type="hidden" name="timestamp" value="'+bkey+'" /><input type="submit" value="Download" /></form>');
608
  $('#' + file.id + " .fileprogress").hide();
609
- $('#' + file.id).append(updraftlion.uploaded+' <a href="?page=updraftplus&action=downloadfile&updraftplus_file='+bkey+'&decrypt_key='+$('#updraftplus_db_decrypt').val()+'">'+updraftlion.folowlink+'</a> '+updraftlion.thiskey+' '+$('#updraftplus_db_decrypt').val().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"));
610
  } else {
611
  alert(updraftlion.unknownresp+' '+response.response);
612
  }
606
  // $('#' + file.id + " span").append('<button type="button" onclick="updraftplus_downloadstage2(\'db\', \'db\'">Download to your computer</button>');
607
  // $('#' + file.id + " span").append('<form action="admin-ajax.php" onsubmit="return updraft_downloader(\'+bkey+''\', \'db\')" method="post"><input type="hidden" name="_wpnonce" value="'+updraft_downloader_nonce+'"><input type="hidden" name="action" value="updraft_download_backup" /><input type="hidden" name="type" value="db" /><input type="hidden" name="timestamp" value="'+bkey+'" /><input type="submit" value="Download" /></form>');
608
  $('#' + file.id + " .fileprogress").hide();
609
+ $('#' + file.id).append(updraftlion.uploaded+' <a href="?page=updraftplus&action=downloadfile&updraftplus_file='+bkey+'&decrypt_key='+$('#updraftplus_db_decrypt').val()+'">'+updraftlion.followlink+'</a> '+updraftlion.thiskey+' '+$('#updraftplus_db_decrypt').val().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"));
610
  } else {
611
  alert(updraftlion.unknownresp+' '+response.response);
612
  }
methods/dropbox.php CHANGED
@@ -124,7 +124,7 @@ class UpdraftPlus_BackupModule_dropbox {
124
  try {
125
  $dropbox->chunkedUpload($updraft_dir.'/'.$file, '', $ufile, true, $offset, $upload_id, array($ourself, 'chunked_callback'));
126
  } catch (Exception $e) {
127
- $updraftplus->log("Exception: ".$e->getMessage());
128
  if (preg_match("/Submitted input out of alignment: got \[(\d+)\] expected \[(\d+)\]/i", $e->getMessage(), $matches)) {
129
  // Try the indicated offset
130
  $we_tried = $matches[1];
@@ -134,7 +134,7 @@ class UpdraftPlus_BackupModule_dropbox {
134
  $dropbox->chunkedUpload($updraft_dir.'/'.$file, '', $ufile, true, $dropbox_wanted, $upload_id, array($ourself, 'chunked_callback'));
135
  } catch (Exception $e) {
136
  $updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
137
- $updraftplus->log('Dropbox ',sprintf(__('error: failed to upload file to %s (see log file for more)','updraftplus'), $ufile), 'error');
138
  $file_success = 0;
139
  }
140
  } else {
124
  try {
125
  $dropbox->chunkedUpload($updraft_dir.'/'.$file, '', $ufile, true, $offset, $upload_id, array($ourself, 'chunked_callback'));
126
  } catch (Exception $e) {
127
+ $updraftplus->log("Dropbox chunked upload exception: ".$e->getMessage());
128
  if (preg_match("/Submitted input out of alignment: got \[(\d+)\] expected \[(\d+)\]/i", $e->getMessage(), $matches)) {
129
  // Try the indicated offset
130
  $we_tried = $matches[1];
134
  $dropbox->chunkedUpload($updraft_dir.'/'.$file, '', $ufile, true, $dropbox_wanted, $upload_id, array($ourself, 'chunked_callback'));
135
  } catch (Exception $e) {
136
  $updraftplus->log('Dropbox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
137
+ $updraftplus->log('Dropbox '.sprintf(__('error: failed to upload file to %s (see log file for more)','updraftplus'), $ufile), 'error');
138
  $file_success = 0;
139
  }
140
  } else {
methods/email.php CHANGED
@@ -4,18 +4,28 @@
4
 
5
  class UpdraftPlus_BackupModule_email {
6
 
7
- function backup($backup_array) {
8
 
9
  global $updraftplus, $updraftplus_backup;
10
 
11
- $updraft_dir = $updraftplus->backups_dir_location().'/';
12
 
13
  foreach ($backup_array as $type => $file) {
14
  $fullpath = $updraft_dir.$file;
 
 
15
  foreach (explode(',', UpdraftPlus_Options::get_updraft_option('updraft_email')) as $sendmail_addr) {
16
- wp_mail(trim($sendmail_addr), __("WordPress Backup",'updraftplus')." ".date('Y-m-d H:i',$updraftplus->backup_time), __("Backup is of:",'updraftplus')." ".$type.". ".__('Be wary; email backups may fail because of file size limitations on mail servers.','updraftplus'), null, array($fullpath));
 
 
 
 
 
 
 
 
 
17
  }
18
- $updraftplus->uploaded_file($file);
19
  }
20
  $updraftplus_backup->prune_retained_backups("email", null, null);
21
  }
@@ -30,5 +40,3 @@ class UpdraftPlus_BackupModule_email {
30
  }
31
 
32
  }
33
-
34
- ?>
4
 
5
  class UpdraftPlus_BackupModule_email {
6
 
7
+ public function backup($backup_array) {
8
 
9
  global $updraftplus, $updraftplus_backup;
10
 
11
+ $updraft_dir = trailingslashit($updraftplus->backups_dir_location());
12
 
13
  foreach ($backup_array as $type => $file) {
14
  $fullpath = $updraft_dir.$file;
15
+ #if (file_exists($fullpath) && filesize($fullpath) > ...
16
+ $any_sent = false;
17
  foreach (explode(',', UpdraftPlus_Options::get_updraft_option('updraft_email')) as $sendmail_addr) {
18
+ $send_short = (strlen($sendmail_addr)>5) ? substr($sendmail_addr, 0, 5).'...' : $sendmail_addr;
19
+ $updraftplus->log("$file: email to: $send_short");
20
+ $sent = wp_mail(trim($sendmail_addr), __("WordPress Backup",'updraftplus')." ".date('Y-m-d H:i',$updraftplus->backup_time), sprintf(__("Backup is of: %s.",'updraftplus'), $type).' '.__('Be wary; email backups may fail because of file size limitations on mail servers.','updraftplus'), null, array($fullpath));
21
+ if ($sent) $any_sent = true;
22
+ }
23
+ if ($any_sent) {
24
+ $updraftplus->uploaded_file($file);
25
+ } else {
26
+ $updraftplus->log('Mails were not sent successfully');
27
+ $updraftplus->log(__('The attempt to send the backup via email failed (probably the backup was too large for this method)', 'updraftplus'), 'error');
28
  }
 
29
  }
30
  $updraftplus_backup->prune_retained_backups("email", null, null);
31
  }
40
  }
41
 
42
  }
 
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: DavidAnderson
3
  Tags: backup, backups, restore, database, rackspace, amazon, s3, amazon s3, s3 compatible, dropbox, google drive, rackspace cloud files, rackspace, cloud files, dreamhost, dreamobjects, ftp, webdav, google cloud storage, cloudian, cloudn, connectria, constant cloud, eucalyptus, nifty, nimbula, back up, multisite, restoration, sftp, ftps, migrate, duplicate, copy, updraft, schedule, database backup
4
  Requires at least: 3.1
5
- Tested up to: 3.6
6
- Stable tag: 1.7.1
7
  Author URI: http://updraftplus.com
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
@@ -126,6 +126,13 @@ Thanks for asking - yes, I have. Check out my profile page - http://profiles.wor
126
 
127
  == Changelog ==
128
 
 
 
 
 
 
 
 
129
  = 1.7.1 - 2013/08/20 =
130
  * FIX: Fix error preventing file backups in 1.7.0 for PHP installs without the ZipArchive class.
131
  * TWEAK: Only include phpseclib in the path when required
@@ -558,4 +565,4 @@ We recognise and thank the following for code and/or libraries used and/or modif
558
  Furthermore, reliance upon any non-English translation is at your own risk. UpdraftPlus can give no guarantees that translations from the original English are accurate.
559
 
560
  == Upgrade Notice ==
561
- * 1.7.1: Fix error preventing file backups in 1.7.0 for PHP installs without the ZipArchive class.
2
  Contributors: DavidAnderson
3
  Tags: backup, backups, restore, database, rackspace, amazon, s3, amazon s3, s3 compatible, dropbox, google drive, rackspace cloud files, rackspace, cloud files, dreamhost, dreamobjects, ftp, webdav, google cloud storage, cloudian, cloudn, connectria, constant cloud, eucalyptus, nifty, nimbula, back up, multisite, restoration, sftp, ftps, migrate, duplicate, copy, updraft, schedule, database backup
4
  Requires at least: 3.1
5
+ Tested up to: 3.6.1
6
+ Stable tag: 1.7.3
7
  Author URI: http://updraftplus.com
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
126
 
127
  == Changelog ==
128
 
129
+ = 1.7.3 - 2013/08/26 =
130
+ * FIX: Some Dropbox connect errors were being lost
131
+ * FIX: Fix detection of availability of binary zip method on PHP installs where popen() is available put proc_open() is disabled
132
+ * FIX: (Premium): WP Core and More Files remaining locally/not being despatched to cloud storage
133
+ * TWEAK: More logging of the success (or not) of backups sent via email
134
+ * TWEAK: Remember hint from previous job if PHP is allowed to run for more than 300 seconds at a time
135
+
136
  = 1.7.1 - 2013/08/20 =
137
  * FIX: Fix error preventing file backups in 1.7.0 for PHP installs without the ZipArchive class.
138
  * TWEAK: Only include phpseclib in the path when required
565
  Furthermore, reliance upon any non-English translation is at your own risk. UpdraftPlus can give no guarantees that translations from the original English are accurate.
566
 
567
  == Upgrade Notice ==
568
+ * 1.7.3: Fix 3 bugs - recommended upgrade for all
updraftplus.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: UpdraftPlus - Backup/Restore
4
  Plugin URI: http://updraftplus.com
5
  Description: Backup and restore: take backups locally, or backup to Amazon S3, Dropbox, Google Drive, Rackspace, (S)FTP, WebDAV & email, on automatic schedules.
6
  Author: UpdraftPlus.Com, DavidAnderson
7
- Version: 1.7.1
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
10
  Text Domain: updraftplus
@@ -13,10 +13,15 @@ Author URI: http://updraftplus.com
13
 
14
  /*
15
  TODO - some of these are out of date/done, needs pruning
 
16
  // Backup notes
17
  // Raise a warning for probably-too-large email attachments
18
  // mysqldump, if available, for faster database dumps. Need then to test compatibility with max_packet_size detection in restoration
19
  // Check flow of activation on multisite
 
 
 
 
20
  // Log migrations/restores, and have an option for auto-emailing the log
21
  // Log a warning if the resumption is loonnggg after it was expected to be (usually on unvisited dev sites)
22
  # Email backup method should be able to force split limit down to something manageable - or at least, should make the option display. (Put it in email class. Tweak the storage dropdown to not hide stuff also in expert class if expert is shown).
@@ -519,8 +524,8 @@ class UpdraftPlus {
519
  # We require -@ and -u -r to work - which is the usual Linux binzip
520
  function find_working_bin_zip($logit = true) {
521
  if ($this->detect_safe_mode()) return false;
522
- // The hosting provider may have explicitly disabled the popen function
523
- if (!function_exists('popen')) return false;
524
  $updraft_dir = $this->backups_dir_location();
525
  foreach (explode(',', UPDRAFTPLUS_ZIP_EXECUTABLE) as $potzip) {
526
  if ($logit) $this->log("Testing: $potzip");
@@ -555,22 +560,46 @@ class UpdraftPlus {
555
  if (true == $all_ok) {
556
  file_put_contents($updraft_dir.'/binziptest/subdir1/subdir2/test2.html', '<html></body><a href="http://updraftplus.com">UpdraftPlus is a really great backup and restoration plugin for WordPress.</body></html>');
557
 
558
- $exec = "cd ".escapeshellarg($updraft_dir)."; echo ".escapeshellarg('binziptest/subdir1/subdir2/test2.html')." | $potzip -@ binziptest/test.zip";
559
 
560
  $all_ok=true;
561
- $handle = popen($exec, "r");
562
- if ($handle) {
563
- while (!feof($handle)) {
564
- $w = fgets($handle);
565
- if ($w && $logit) $this->log("Output: ".trim($w));
566
- }
567
- $ret = pclose($handle);
568
- if ($ret !=0) {
569
- if ($logit) $this->log("Binary zip: error (code: $ret)");
 
 
 
570
  $all_ok = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
571
  }
 
572
  } else {
573
- if ($logit) $this->log("Error: popen failed");
574
  $all_ok = false;
575
  }
576
 
@@ -626,6 +655,7 @@ class UpdraftPlus {
626
  $resume_interval = $this->jobdata_get('resume_interval');
627
  if ($time_this_run + 30 > $resume_interval) {
628
  $new_interval = ceil($time_this_run + 30);
 
629
  $this->log("The time we have been running (".round($time_this_run,1).") is approaching the resumption interval ($resume_interval) - increasing resumption interval to $new_interval");
630
  $this->jobdata_set('resume_interval', $new_interval);
631
  }
@@ -758,8 +788,7 @@ class UpdraftPlus {
758
 
759
  // Schedule again, to run in 5 minutes again, in case we again fail
760
  // The actual interval can be increased (for future resumptions) by other code, if it detects apparent overlapping
761
- $resume_interval = $this->jobdata_get('resume_interval');
762
- if (!is_numeric($resume_interval) || $resume_interval<300) $resume_interval = 300;
763
 
764
  // We just do this once, as we don't want to be in permanent conflict with the overlap detector
765
  if ($resumption_no == 8) {
@@ -1019,9 +1048,10 @@ class UpdraftPlus {
1019
  return;
1020
  }
1021
 
1022
- $resume_interval = 300;
1023
- // $max_execution_time = ini_get('max_execution_time');
1024
- // if ($max_execution_time >0 && $max_execution_time<300 && $resume_interval< $max_execution_time + 30) $resume_interval = $max_execution_time + 30;
 
1025
 
1026
  $job_file_entities = array();
1027
  if ($backup_files) {
@@ -1044,7 +1074,7 @@ class UpdraftPlus {
1044
  'backup_time', $this->backup_time,
1045
  'backup_time_ms', $this->backup_time_ms,
1046
  'service', $service,
1047
- 'split_every', max(absint(UpdraftPlus_Options::get_updraft_option('updraft_split_every', 800)), UPDRAFTPLUS_SPLIT_MIN),
1048
  'maxzipbatch', 26214400, #25Mb
1049
  'job_file_entities', $job_file_entities,
1050
  'one_shot', $one_shot
4
  Plugin URI: http://updraftplus.com
5
  Description: Backup and restore: take backups locally, or backup to Amazon S3, Dropbox, Google Drive, Rackspace, (S)FTP, WebDAV & email, on automatic schedules.
6
  Author: UpdraftPlus.Com, DavidAnderson
7
+ Version: 1.7.3
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  License: GPLv3 or later
10
  Text Domain: updraftplus
13
 
14
  /*
15
  TODO - some of these are out of date/done, needs pruning
16
+ // Remember minimum resume intervals in between runs
17
  // Backup notes
18
  // Raise a warning for probably-too-large email attachments
19
  // mysqldump, if available, for faster database dumps. Need then to test compatibility with max_packet_size detection in restoration
20
  // Check flow of activation on multisite
21
+ // Find a faster encryption method
22
+ // Provide option to make autobackup default to off
23
+ // On restore, raise a warning for ginormous zips
24
+ // Detect double-compressed files when they are uploaded (need a way to detect gz compression in general)
25
  // Log migrations/restores, and have an option for auto-emailing the log
26
  // Log a warning if the resumption is loonnggg after it was expected to be (usually on unvisited dev sites)
27
  # Email backup method should be able to force split limit down to something manageable - or at least, should make the option display. (Put it in email class. Tweak the storage dropdown to not hide stuff also in expert class if expert is shown).
524
  # We require -@ and -u -r to work - which is the usual Linux binzip
525
  function find_working_bin_zip($logit = true) {
526
  if ($this->detect_safe_mode()) return false;
527
+ // The hosting provider may have explicitly disabled the popen or proc_open functions
528
+ if (!function_exists('popen') || !function_exists('proc_open')) return false;
529
  $updraft_dir = $this->backups_dir_location();
530
  foreach (explode(',', UPDRAFTPLUS_ZIP_EXECUTABLE) as $potzip) {
531
  if ($logit) $this->log("Testing: $potzip");
560
  if (true == $all_ok) {
561
  file_put_contents($updraft_dir.'/binziptest/subdir1/subdir2/test2.html', '<html></body><a href="http://updraftplus.com">UpdraftPlus is a really great backup and restoration plugin for WordPress.</body></html>');
562
 
563
+ $exec = $potzip." -v -@ binziptest/test.zip";
564
 
565
  $all_ok=true;
566
+
567
+ $descriptorspec = array(
568
+ 0 => array('pipe', 'r'),
569
+ 1 => array('pipe', 'w'),
570
+ 2 => array('pipe', 'w')
571
+ );
572
+ $handle = proc_open($exec, $descriptorspec, $pipes, $updraft_dir);
573
+ if (is_resource($handle)) {
574
+ if (!fwrite($pipes[0], "binziptest/subdir1/subdir2/test2.html\n")) {
575
+ @fclose($pipes[0]);
576
+ @fclose($pipes[1]);
577
+ @fclose($pipes[2]);
578
  $all_ok = false;
579
+ } else {
580
+ fclose($pipes[0]);
581
+ while (!feof($pipes[1])) {
582
+ $w = fgets($pipes[1]);
583
+ if ($w && $logit) $this->log("Output: ".trim($w));
584
+ }
585
+ fclose($pipes[1]);
586
+
587
+ while (!feof($pipes[2])) {
588
+ $last_error = fgets($pipes[2]);
589
+ if (!empty($last_error) && $logit) $this->log("Error output: ".trim($w));
590
+ }
591
+ fclose($pipes[2]);
592
+
593
+ $ret = proc_close($handle);
594
+ if ($ret !=0) {
595
+ if ($logit) $this->log("Binary zip: error (code: $ret)");
596
+ $all_ok = false;
597
+ }
598
+
599
  }
600
+
601
  } else {
602
+ if ($logit) $this->log("Error: proc_open failed");
603
  $all_ok = false;
604
  }
605
 
655
  $resume_interval = $this->jobdata_get('resume_interval');
656
  if ($time_this_run + 30 > $resume_interval) {
657
  $new_interval = ceil($time_this_run + 30);
658
+ set_transient('updraft_initial_resume_interval', (int)$new_interval, 8*86400);
659
  $this->log("The time we have been running (".round($time_this_run,1).") is approaching the resumption interval ($resume_interval) - increasing resumption interval to $new_interval");
660
  $this->jobdata_set('resume_interval', $new_interval);
661
  }
788
 
789
  // Schedule again, to run in 5 minutes again, in case we again fail
790
  // The actual interval can be increased (for future resumptions) by other code, if it detects apparent overlapping
791
+ $resume_interval = max(intval($this->jobdata_get('resume_interval')), 300);
 
792
 
793
  // We just do this once, as we don't want to be in permanent conflict with the overlap detector
794
  if ($resumption_no == 8) {
1048
  return;
1049
  }
1050
 
1051
+ // Allow the resume interval to be more than 300 if last time we know we went beyond that - but never more than 600
1052
+ $resume_interval = (int)min(max(300, get_transient('updraft_initial_resume_interval')), 600);
1053
+ # We delete it because we only want to know about behaviour found during the very last backup run (so, if you move servers then old data is not retained)
1054
+ delete_transient('updraft_initial_resume_interval');
1055
 
1056
  $job_file_entities = array();
1057
  if ($backup_files) {
1074
  'backup_time', $this->backup_time,
1075
  'backup_time_ms', $this->backup_time_ms,
1076
  'service', $service,
1077
+ 'split_every', max(intval(UpdraftPlus_Options::get_updraft_option('updraft_split_every', 800)), UPDRAFTPLUS_SPLIT_MIN),
1078
  'maxzipbatch', 26214400, #25Mb
1079
  'job_file_entities', $job_file_entities,
1080
  'one_shot', $one_shot