Version Description
- 01/14/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
Download this release
Release Info
Developer | DavidAnderson |
Plugin | UpdraftPlus WordPress Backup Plugin |
Version | 1.2.26 |
Comparing to | |
See all releases |
Code changes from version 1.2.25 to 1.2.26
- methods/dropbox.php +1 -1
- readme.txt +4 -3
- updraftplus.php +75 -25
methods/dropbox.php
CHANGED
@@ -153,7 +153,7 @@ class UpdraftPlus_BackupModule_dropbox {
|
|
153 |
$dropbox->delete($dropbox_folder.'/'.$file);
|
154 |
} catch (Exception $e) {
|
155 |
$updraftplus->log('DropBox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
156 |
-
$file_success =
|
157 |
}
|
158 |
if ($file_success) $updraftplus->log('DropBox: delete succeeded (alternative path)');
|
159 |
}
|
153 |
$dropbox->delete($dropbox_folder.'/'.$file);
|
154 |
} catch (Exception $e) {
|
155 |
$updraftplus->log('DropBox error: '.$e->getMessage().' (line: '.$e->getLine().', file: '.$e->getFile().')');
|
156 |
+
$file_success = 0;
|
157 |
}
|
158 |
if ($file_success) $updraftplus->log('DropBox: delete succeeded (alternative path)');
|
159 |
}
|
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.
|
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.
|
12 |
|
13 |
== Description ==
|
14 |
|
@@ -112,9 +112,10 @@ Thanks for asking - yes, I have. Check out my profile page - http://profiles.wor
|
|
112 |
|
113 |
== Changelog ==
|
114 |
|
115 |
-
= 1.2.
|
116 |
* Fixed bug with DropBox deletions
|
117 |
* Fixed cases where DropBox failed to resume chunked uploading
|
|
|
118 |
|
119 |
= 1.2.20 - 01/12/2013 =
|
120 |
* 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.26
|
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.
|
12 |
|
13 |
== Description ==
|
14 |
|
112 |
|
113 |
== Changelog ==
|
114 |
|
115 |
+
= 1.2.26 - 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 |
|
120 |
= 1.2.20 - 01/12/2013 =
|
121 |
* 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.
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
Author URI: http://wordshell.net
|
@@ -19,6 +19,7 @@ TODO
|
|
19 |
//Eventually, when everything can be resumed, we will no longer need the backup() routine; it can be replaced with the resume() routine
|
20 |
//Remind user to look inside their 'apps' folder in DropBox
|
21 |
// Should we resume if the only errors were upon deletion (i.e. the backup itself was fine?) Presently we do, but it displays errors for the user to confuse them.
|
|
|
22 |
// Separate 'retain' settings for db + files (since they are on separate schedules)
|
23 |
// Warn the user if their zip-file creation is slooowww...
|
24 |
// Create a "Want Support?" button/console, that leads them through what is needed, and performs some basic tests...
|
@@ -65,7 +66,7 @@ define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
|
|
65 |
|
66 |
class UpdraftPlus {
|
67 |
|
68 |
-
var $version = '1.2.
|
69 |
|
70 |
// Choices will be shown in the admin menu in the order used here
|
71 |
var $backup_methods = array (
|
@@ -153,7 +154,7 @@ class UpdraftPlus {
|
|
153 |
function log($line) {
|
154 |
if ($this->logfile_handle) fwrite($this->logfile_handle,date('r')." ".$line."\n");
|
155 |
}
|
156 |
-
|
157 |
function backup_resume($resumption_no) {
|
158 |
@ignore_user_abort(true);
|
159 |
// This is scheduled for 5 minutes after a backup job starts
|
@@ -179,9 +180,13 @@ class UpdraftPlus {
|
|
179 |
}
|
180 |
$this->backup_time = $btime;
|
181 |
|
|
|
|
|
|
|
|
|
182 |
// Returns an array, most recent first, of backup sets
|
183 |
$backup_history = $this->get_backup_history();
|
184 |
-
if (!isset($backup_history[$btime])) $this->log("
|
185 |
|
186 |
$our_files=$backup_history[$btime];
|
187 |
$undone_files = array();
|
@@ -215,7 +220,8 @@ class UpdraftPlus {
|
|
215 |
|
216 |
foreach ($our_files as $key => $file) {
|
217 |
|
218 |
-
if ($key == 'nonce')
|
|
|
219 |
$hash = md5($file);
|
220 |
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
221 |
if (get_transient('updraft_'.$hash) === "yes") {
|
@@ -294,6 +300,32 @@ class UpdraftPlus {
|
|
294 |
}
|
295 |
}
|
296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
function backup($backup_files, $backup_database) {
|
298 |
|
299 |
@ignore_user_abort(true);
|
@@ -324,8 +356,8 @@ class UpdraftPlus {
|
|
324 |
// 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).
|
325 |
// If we don't finish in 3 hours, then we won't finish
|
326 |
// This transient indicates the identity of the current backup job (which can be used to find the files and logfile)
|
327 |
-
set_transient("updraftplus_backup_job_nonce", $this->nonce,3600*3);
|
328 |
-
set_transient("updraftplus_backup_job_time", $this->backup_time,3600*3);
|
329 |
|
330 |
// Schedule the event to run later, which checks on success and can resume the backup
|
331 |
// We save the time to a variable because it is needed for un-scheduling
|
@@ -340,17 +372,16 @@ class UpdraftPlus {
|
|
340 |
|
341 |
$this->check_backup_race();
|
342 |
|
343 |
-
//
|
|
|
|
|
|
|
|
|
344 |
if ($backup_files) {
|
345 |
-
|
346 |
-
$backup_array = $this->
|
347 |
-
$backup_contains = "Files only (no database)";
|
348 |
-
// This can get over-written later
|
349 |
-
set_transient("updraft_backupcontains_".$this->nonce, $backup_contains, 3600*3);
|
350 |
}
|
351 |
|
352 |
-
// Save what *should* be done, to make it resumable from this point on
|
353 |
-
set_transient("updraft_backdb_".$this->nonce, "begun", 3600*3);
|
354 |
// Save this to our history so we can track backups for the retain feature
|
355 |
$this->log("Saving backup history");
|
356 |
$this->save_backup_history($backup_array);
|
@@ -617,14 +648,21 @@ class UpdraftPlus {
|
|
617 |
return true;
|
618 |
}
|
619 |
|
620 |
-
function create_zip($whichone, $
|
621 |
// Note: $create_from_dir can be an array or a string
|
622 |
@set_time_limit(900);
|
623 |
|
624 |
-
if ($whichone != "others") $this->log("Beginning
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
625 |
|
626 |
-
|
627 |
-
$zip_object = new PclZip($full_path);
|
628 |
|
629 |
$microtime_start = microtime(true);
|
630 |
# The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
|
@@ -633,6 +671,7 @@ class UpdraftPlus {
|
|
633 |
$this->log("ERROR: PclZip failure: Could not create $whichone zip");
|
634 |
return false;
|
635 |
} else {
|
|
|
636 |
$timetaken = max(microtime(true)-$microtime_start, 0.000001);
|
637 |
$kbsize = filesize($full_path)/1024;
|
638 |
$rate = round($kbsize/$timetaken, 1);
|
@@ -642,7 +681,8 @@ class UpdraftPlus {
|
|
642 |
return basename($full_path);
|
643 |
}
|
644 |
|
645 |
-
function
|
|
|
646 |
|
647 |
if(!$this->backup_time) $this->backup_time_nonce();
|
648 |
|
@@ -660,7 +700,7 @@ class UpdraftPlus {
|
|
660 |
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
661 |
if(!$blog_name) $blog_name = 'non_alpha_name';
|
662 |
|
663 |
-
$
|
664 |
|
665 |
$backup_array = array();
|
666 |
|
@@ -674,8 +714,12 @@ class UpdraftPlus {
|
|
674 |
# Plugins, themes, uploads
|
675 |
foreach ($possible_backups as $youwhat => $whichdir) {
|
676 |
if (get_option("updraft_include_$youwhat", true)) {
|
677 |
-
|
678 |
-
|
|
|
|
|
|
|
|
|
679 |
} else {
|
680 |
$this->log("No backup of $youwhat: excluded by user's options");
|
681 |
}
|
@@ -685,6 +729,10 @@ class UpdraftPlus {
|
|
685 |
if (get_option('updraft_include_others', true)) {
|
686 |
$this->log("Beginning backup of other directories found in the content directory");
|
687 |
|
|
|
|
|
|
|
|
|
688 |
// http://www.phpconcept.net/pclzip/user-guide/53
|
689 |
/* First parameter to create is:
|
690 |
An array of filenames or dirnames,
|
@@ -719,11 +767,13 @@ class UpdraftPlus {
|
|
719 |
}
|
720 |
|
721 |
if (count($other_dirlist)>0) {
|
722 |
-
$created = $this->create_zip('others', $
|
723 |
if ($created) $backup_array['others'] = $created;
|
724 |
} else {
|
725 |
$this->log("No backup of other directories: there was nothing found to back up");
|
726 |
}
|
|
|
|
|
727 |
} else {
|
728 |
$this->log("No backup of other directories: excluded by user's options");
|
729 |
}
|
@@ -1604,7 +1654,7 @@ ENDHERE;
|
|
1604 |
<div style="float:left; width:200px; padding-top: 100px;">
|
1605 |
<form method="post" action="">
|
1606 |
<input type="hidden" name="action" value="updraft_backup" />
|
1607 |
-
<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.
|
1608 |
</form>
|
1609 |
<div style="position:relative">
|
1610 |
<div style="position:absolute;top:0;left:0">
|
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.26
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
Author URI: http://wordshell.net
|
19 |
//Eventually, when everything can be resumed, we will no longer need the backup() routine; it can be replaced with the resume() routine
|
20 |
//Remind user to look inside their 'apps' folder in DropBox
|
21 |
// Should we resume if the only errors were upon deletion (i.e. the backup itself was fine?) Presently we do, but it displays errors for the user to confuse them.
|
22 |
+
// Make jobs *individually* resumable (i.e. all the state info must be keyed on the nonce; then call the resume event *specifying the nonce*)
|
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...
|
66 |
|
67 |
class UpdraftPlus {
|
68 |
|
69 |
+
var $version = '1.2.26';
|
70 |
|
71 |
// Choices will be shown in the admin menu in the order used here
|
72 |
var $backup_methods = array (
|
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) {
|
159 |
@ignore_user_abort(true);
|
160 |
// This is scheduled for 5 minutes after a backup job starts
|
180 |
}
|
181 |
$this->backup_time = $btime;
|
182 |
|
183 |
+
$backup_array = $this->resumable_backup_of_files(false);
|
184 |
+
// This save, if there was something, is then immediately picked up again
|
185 |
+
if (is_array($backup_array)) $this->save_backup_history($backup_array);
|
186 |
+
|
187 |
// Returns an array, most recent first, of backup sets
|
188 |
$backup_history = $this->get_backup_history();
|
189 |
+
if (!isset($backup_history[$btime])) $this->log("Could not find a record in the database of a backup with this timestamp");
|
190 |
|
191 |
$our_files=$backup_history[$btime];
|
192 |
$undone_files = array();
|
220 |
|
221 |
foreach ($our_files as $key => $file) {
|
222 |
|
223 |
+
if ($key == 'nonce') continue;
|
224 |
+
|
225 |
$hash = md5($file);
|
226 |
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
227 |
if (get_transient('updraft_'.$hash) === "yes") {
|
300 |
}
|
301 |
}
|
302 |
|
303 |
+
// This uses a transient; its only purpose is to indicate *total* completion; there is no actual danger, just wasted time, in resuming when it was not needed. So the transient just helps save resources.
|
304 |
+
function resumable_backup_of_files($resumptionrun) {
|
305 |
+
//backup directories and return a numerically indexed array of file paths to the backup files
|
306 |
+
$transient_status = get_transient("updraft_backf_".$this->nonce);
|
307 |
+
if ($transient_status == "finished") {
|
308 |
+
$this->log("Creation of backups of directories: already finished");
|
309 |
+
} elseif ($transient_status == "begun") {
|
310 |
+
if ($resumptionrun) {
|
311 |
+
$this->log("Creation of backups of directories: had begun; will resume");
|
312 |
+
} else {
|
313 |
+
$this->log("Creation of backups of directories: beginning");
|
314 |
+
}
|
315 |
+
} else {
|
316 |
+
# This is not necessarily a backup run which is meant to contain files at all
|
317 |
+
$this->log("This backup run is not intended for files - skipping");
|
318 |
+
return null;
|
319 |
+
}
|
320 |
+
// We want this array, even if already finished
|
321 |
+
$backup_array = $this->backup_dirs($transient_status);
|
322 |
+
$backup_contains = "Files only (no database)";
|
323 |
+
// This can get over-written later
|
324 |
+
set_transient("updraft_backupcontains_".$this->nonce, $backup_contains, 3600*3);
|
325 |
+
set_transient("updraft_backf_".$this->nonce, "finished", 3600*3);
|
326 |
+
return $backup_array;
|
327 |
+
}
|
328 |
+
|
329 |
function backup($backup_files, $backup_database) {
|
330 |
|
331 |
@ignore_user_abort(true);
|
356 |
// 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).
|
357 |
// If we don't finish in 3 hours, then we won't finish
|
358 |
// This transient indicates the identity of the current backup job (which can be used to find the files and logfile)
|
359 |
+
set_transient("updraftplus_backup_job_nonce", $this->nonce, 3600*3);
|
360 |
+
set_transient("updraftplus_backup_job_time", $this->backup_time, 3600*3);
|
361 |
|
362 |
// Schedule the event to run later, which checks on success and can resume the backup
|
363 |
// We save the time to a variable because it is needed for un-scheduling
|
372 |
|
373 |
$this->check_backup_race();
|
374 |
|
375 |
+
// Save what *should* be done, to make it resumable from this point on
|
376 |
+
set_transient("updraft_backdb_".$this->nonce, "begun", 3600*3);
|
377 |
+
|
378 |
+
// The function itself will set to 'finished' if relevant
|
379 |
+
// The presence of the transient indicates that files are supposed to be in this set
|
380 |
if ($backup_files) {
|
381 |
+
set_transient("updraft_backf_".$this->nonce, "begun", 3600*3);
|
382 |
+
$backup_array = $this->resumable_backup_of_files(false);
|
|
|
|
|
|
|
383 |
}
|
384 |
|
|
|
|
|
385 |
// Save this to our history so we can track backups for the retain feature
|
386 |
$this->log("Saving backup history");
|
387 |
$this->save_backup_history($backup_array);
|
648 |
return true;
|
649 |
}
|
650 |
|
651 |
+
function create_zip($create_from_dir, $whichone, $create_in_dir, $backup_file_basename) {
|
652 |
// Note: $create_from_dir can be an array or a string
|
653 |
@set_time_limit(900);
|
654 |
|
655 |
+
if ($whichone != "others") $this->log("Beginning creation of dump of $whichone");
|
656 |
+
|
657 |
+
$full_path = $create_in_dir.'/'.$backup_file_basename.'-'.$whichone.'.zip';
|
658 |
+
|
659 |
+
if (file_exists($full_path)) {
|
660 |
+
$this->log("$backup_file_basename-$whichone.zip: this file has already been created");
|
661 |
+
return basename($full_path);
|
662 |
+
}
|
663 |
|
664 |
+
// Temporary file, to be able to detect actual completion (upon which, it is renamed)
|
665 |
+
$zip_object = new PclZip($full_path.'.tmp');
|
666 |
|
667 |
$microtime_start = microtime(true);
|
668 |
# The paths in the zip should then begin with '$whichone', having removed WP_CONTENT_DIR from the front
|
671 |
$this->log("ERROR: PclZip failure: Could not create $whichone zip");
|
672 |
return false;
|
673 |
} else {
|
674 |
+
rename($full_path.'.tmp', $full_path);
|
675 |
$timetaken = max(microtime(true)-$microtime_start, 0.000001);
|
676 |
$kbsize = filesize($full_path)/1024;
|
677 |
$rate = round($kbsize/$timetaken, 1);
|
681 |
return basename($full_path);
|
682 |
}
|
683 |
|
684 |
+
// This function is resumable
|
685 |
+
function backup_dirs($transient_status) {
|
686 |
|
687 |
if(!$this->backup_time) $this->backup_time_nonce();
|
688 |
|
700 |
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
701 |
if(!$blog_name) $blog_name = 'non_alpha_name';
|
702 |
|
703 |
+
$backup_file_basename = 'backup_'.date('Y-m-d-Hi', $this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
704 |
|
705 |
$backup_array = array();
|
706 |
|
714 |
# Plugins, themes, uploads
|
715 |
foreach ($possible_backups as $youwhat => $whichdir) {
|
716 |
if (get_option("updraft_include_$youwhat", true)) {
|
717 |
+
if ($transient_status == 'finished') {
|
718 |
+
$backup_array[$youwhat] = $backup_file_basename.'-'.$youwhat.'.zip';
|
719 |
+
} else {
|
720 |
+
$created = $this->create_zip($whichdir, $youwhat, $updraft_dir, $backup_file_basename);
|
721 |
+
if ($created) $backup_array[$youwhat] = $created;
|
722 |
+
}
|
723 |
} else {
|
724 |
$this->log("No backup of $youwhat: excluded by user's options");
|
725 |
}
|
729 |
if (get_option('updraft_include_others', true)) {
|
730 |
$this->log("Beginning backup of other directories found in the content directory");
|
731 |
|
732 |
+
if ($transient_status == 'finished') {
|
733 |
+
$backup_array['others'] = $backup_file_basename.'-others.zip';
|
734 |
+
} else {
|
735 |
+
|
736 |
// http://www.phpconcept.net/pclzip/user-guide/53
|
737 |
/* First parameter to create is:
|
738 |
An array of filenames or dirnames,
|
767 |
}
|
768 |
|
769 |
if (count($other_dirlist)>0) {
|
770 |
+
$created = $this->create_zip('others', $other_dirlist, $updraft_dir, $backup_file_basename);
|
771 |
if ($created) $backup_array['others'] = $created;
|
772 |
} else {
|
773 |
$this->log("No backup of other directories: there was nothing found to back up");
|
774 |
}
|
775 |
+
# If we are not already finished
|
776 |
+
}
|
777 |
} else {
|
778 |
$this->log("No backup of other directories: excluded by user's options");
|
779 |
}
|
1654 |
<div style="float:left; width:200px; padding-top: 100px;">
|
1655 |
<form method="post" action="">
|
1656 |
<input type="hidden" name="action" value="updraft_backup" />
|
1657 |
+
<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 load a page on your site. WordPress should then start the backup running in the background.'))" /></p>
|
1658 |
</form>
|
1659 |
<div style="position:relative">
|
1660 |
<div style="position:absolute;top:0;left:0">
|