Version Description
- 12/22/2012 =
- Fixed bug that set 1Tb (instead of 1Mb) chunk sizes for Google Drive uploads
- Added link to some screenshots to help with Google Drive setup
- Allowed use of existing Amazon S3 buckets with restrictive policies (previously, we tested for the bucket's existence by running a create operation on it, which may not be permitted)
- Use WordPress's native HTTP functions for greater reliability when performing Google Drive authorisation
- Deal with WP-Cron racey double events (abort superceeded backups)
- Allow user to download logs from admin interface
Download this release
Release Info
Developer | DavidAnderson |
Plugin | UpdraftPlus WordPress Backup Plugin |
Version | 1.0.15 |
Comparing to | |
See all releases |
Code changes from version 1.0.12 to 1.0.15
- readme.txt +4 -2
- updraftplus.php +100 -109
readme.txt
CHANGED
@@ -45,7 +45,7 @@ That's very good of you, thank you. You are looking for WordShell, <a href="http
|
|
45 |
|
46 |
Contact me! This is a complex plugin and the only way I can ensure it's robust is to get bug reports and fix the problems that crop up. Please make sure you are using the latest version of the plugin, and that you include the version in your bug report - if you are not using the latest, then the first thing you will be asked to do is upgrade.
|
47 |
|
48 |
-
Please turn on debugging mode (in the UpdraftPlus options page) and then try again, and after that send me the log if you can find it (it is in the directory wp-content/updraft, so FTP in and look for it there). If you cannot find the log, then I may not be able to help, but you can try - include as much information as you can when reporting (PHP version, your blog's site, the error you saw and how you got to the page that caused it, etcetera).
|
49 |
|
50 |
If you can send a patch, that's even better.
|
51 |
|
@@ -87,11 +87,13 @@ No, there's no warranty or guarantee, etc. It's completely up to you to verify t
|
|
87 |
|
88 |
== Changelog ==
|
89 |
|
90 |
-
= 1.0.
|
91 |
* Fixed bug that set 1Tb (instead of 1Mb) chunk sizes for Google Drive uploads
|
92 |
* Added link to some screenshots to help with Google Drive setup
|
93 |
* Allowed use of existing Amazon S3 buckets with restrictive policies (previously, we tested for the bucket's existence by running a create operation on it, which may not be permitted)
|
94 |
* Use WordPress's native HTTP functions for greater reliability when performing Google Drive authorisation
|
|
|
|
|
95 |
|
96 |
= 1.0.5 - 12/13/2012 =
|
97 |
* Tweaked default Google Drive options
|
45 |
|
46 |
Contact me! This is a complex plugin and the only way I can ensure it's robust is to get bug reports and fix the problems that crop up. Please make sure you are using the latest version of the plugin, and that you include the version in your bug report - if you are not using the latest, then the first thing you will be asked to do is upgrade.
|
47 |
|
48 |
+
Please turn on debugging mode (in the UpdraftPlus options page) and then try again, and after that send me the log if you can find it (there are links to download logs on the UpdraftPlus settings page; failing that, it is in the directory wp-content/updraft, so FTP in and look for it there). If you cannot find the log, then I may not be able to help, but you can try - include as much information as you can when reporting (PHP version, your blog's site, the error you saw and how you got to the page that caused it, etcetera).
|
49 |
|
50 |
If you can send a patch, that's even better.
|
51 |
|
87 |
|
88 |
== Changelog ==
|
89 |
|
90 |
+
= 1.0.15 - 12/22/2012 =
|
91 |
* Fixed bug that set 1Tb (instead of 1Mb) chunk sizes for Google Drive uploads
|
92 |
* Added link to some screenshots to help with Google Drive setup
|
93 |
* Allowed use of existing Amazon S3 buckets with restrictive policies (previously, we tested for the bucket's existence by running a create operation on it, which may not be permitted)
|
94 |
* Use WordPress's native HTTP functions for greater reliability when performing Google Drive authorisation
|
95 |
+
* Deal with WP-Cron racey double events (abort superceeded backups)
|
96 |
+
* Allow user to download logs from admin interface
|
97 |
|
98 |
= 1.0.5 - 12/13/2012 =
|
99 |
* Tweaked default Google Drive options
|
updraftplus.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: UpdraftPlus - Backup/Restore
|
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/updraftplus
|
5 |
Description: Uploads, themes, plugins, and your DB can be automatically backed up to Amazon S3, Google Drive, FTP, or emailed, on separate schedules.
|
6 |
Author: David Anderson.
|
7 |
-
Version: 1.0.
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
Author URI: http://wordshell.net
|
@@ -13,14 +13,8 @@ Author URI: http://wordshell.net
|
|
13 |
/*
|
14 |
TODO (some of these items mine, some from original Updraft awaiting review):
|
15 |
//Add DropBox and Microsoft Skydrive support
|
16 |
-
//
|
17 |
-
|
18 |
-
//list backups that aren't tracked (helps with double backup problem)
|
19 |
-
//investigate $php_errormsg further
|
20 |
-
//pretty up return messages in admin area
|
21 |
-
//check s3/ftp download
|
22 |
-
|
23 |
-
//Rip out the "last backup" bit, and/or put in a display of the last log
|
24 |
|
25 |
Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
|
26 |
// Does not delete old custom directories upon a restore?
|
@@ -45,22 +39,22 @@ You should have received a copy of the GNU General Public License
|
|
45 |
along with this program; if not, write to the Free Software
|
46 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
47 |
*/
|
48 |
-
// TODO: Note this might *lower* the limit - should check first.
|
49 |
|
50 |
-
|
|
|
51 |
|
52 |
$updraft = new UpdraftPlus();
|
53 |
|
54 |
if(!$updraft->memory_check(192)) {
|
55 |
# TODO: Better solution is to split the backup set into manageable chunks based on this limit
|
56 |
-
@ini_set('memory_limit', '192M'); //up the memory limit for large backup files
|
57 |
}
|
58 |
|
59 |
define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
|
60 |
|
61 |
class UpdraftPlus {
|
62 |
|
63 |
-
var $version = '1.0.
|
64 |
|
65 |
var $dbhandle;
|
66 |
var $errors = array();
|
@@ -86,26 +80,37 @@ class UpdraftPlus {
|
|
86 |
# http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
|
87 |
add_filter('cron_schedules', array($this,'modify_cron_schedules'));
|
88 |
add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
|
89 |
-
add_action('init', array($this, '
|
90 |
}
|
91 |
|
92 |
// Handle Google OAuth 2.0 - ?page=updraftplus&action=auth
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
}
|
103 |
}
|
104 |
}
|
105 |
|
106 |
-
|
107 |
-
* Acquire single-use authorization code from Google OAuth 2.0
|
108 |
-
*/
|
109 |
function gdrive_auth_request() {
|
110 |
$params = array(
|
111 |
'response_type' => 'code',
|
@@ -119,9 +124,7 @@ class UpdraftPlus {
|
|
119 |
header('Location: https://accounts.google.com/o/oauth2/auth?'.http_build_query($params));
|
120 |
}
|
121 |
|
122 |
-
|
123 |
-
* Get a Google account access token using the refresh token
|
124 |
-
*/
|
125 |
function access_token( $token, $client_id, $client_secret ) {
|
126 |
$this->log("Google Drive: requesting access token: client_id=$client_id");
|
127 |
|
@@ -309,7 +312,14 @@ class UpdraftPlus {
|
|
309 |
$this->logfile_handle = fopen($this->logfile_name, 'a');
|
310 |
}
|
311 |
|
312 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
function backup($backup_files, $backup_database) {
|
314 |
|
315 |
@ignore_user_abort(true);
|
@@ -323,7 +333,6 @@ class UpdraftPlus {
|
|
323 |
|
324 |
// Schedule the even to run later, which checks on success and can resume the backup
|
325 |
// We save the time to a variable because it is needed for un-scheduling
|
326 |
-
// $resume_delay = (get_option('updraft_debug_mode')) ? 60 : 300;
|
327 |
$resume_delay = 300;
|
328 |
wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume', array(1));
|
329 |
$this->log("In case we run out of time, scheduled a resumption at: $resume_delay seconds from now");
|
@@ -332,6 +341,8 @@ class UpdraftPlus {
|
|
332 |
global $wp_version;
|
333 |
$this->log("PHP version: ".phpversion()." WordPress version: ".$wp_version." Updraft version: ".$this->version." Backup files: $backup_files (schedule: ".get_option('updraft_interval','unset').") Backup DB: $backup_database (schedule: ".get_option('updraft_interval_database','unset').")");
|
334 |
|
|
|
|
|
335 |
# If the files and database schedules are the same, and if this the file one, then we rope in database too.
|
336 |
# On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
|
337 |
if (get_option('updraft_interval') == get_option('updraft_interval_database') || get_option('updraft_interval_database','xyz') == 'xyz' ) {
|
@@ -347,13 +358,17 @@ class UpdraftPlus {
|
|
347 |
|
348 |
$backup_array = array();
|
349 |
|
|
|
|
|
350 |
//backup directories and return a numerically indexed array of file paths to the backup files
|
351 |
if ($backup_files) {
|
352 |
$this->log("Beginning backup of directories");
|
353 |
$backup_array = $this->backup_dirs();
|
354 |
$backup_contains = "Files only (no database)";
|
355 |
}
|
356 |
-
|
|
|
|
|
357 |
//backup DB and return string of file path
|
358 |
if ($backup_database) {
|
359 |
$this->log("Beginning backup of database");
|
@@ -363,6 +378,7 @@ class UpdraftPlus {
|
|
363 |
$backup_contains = ($backup_files) ? "Files and database" : "Database only (no files)";
|
364 |
}
|
365 |
|
|
|
366 |
set_transient("updraftplus_backupcontains", $backup_contains, 3600*3);
|
367 |
|
368 |
//save this to our history so we can track backups for the retain feature
|
@@ -429,9 +445,9 @@ class UpdraftPlus {
|
|
429 |
}
|
430 |
|
431 |
function save_last_backup($backup_array) {
|
432 |
-
$success = (empty($this->errors))?1:0;
|
433 |
|
434 |
-
$last_backup = array('backup_time'=>$this->backup_time, 'backup_array'=>$backup_array, 'success'=>$success, 'errors'=>$this->errors);
|
435 |
|
436 |
update_option('updraft_last_backup', $last_backup);
|
437 |
}
|
@@ -588,6 +604,7 @@ class UpdraftPlus {
|
|
588 |
unset($backup_to_examine['themes']);
|
589 |
unset($backup_to_examine['uploads']);
|
590 |
unset($backup_to_examine['others']);
|
|
|
591 |
}
|
592 |
}
|
593 |
// Delete backup set completely if empty, o/w just remove DB
|
@@ -636,7 +653,7 @@ class UpdraftPlus {
|
|
636 |
if ($chunks < 2) {
|
637 |
if (!$s3->putObjectFile($fullpath, $bucket_name, $filepath)) {
|
638 |
$this->log("S3 regular upload: failed");
|
639 |
-
$this->error("S3 Error: Failed to upload $fullpath.
|
640 |
} else {
|
641 |
$this->log("S3 regular upload: success");
|
642 |
$this->uploaded_file($file);
|
@@ -696,8 +713,8 @@ class UpdraftPlus {
|
|
696 |
}
|
697 |
$this->prune_retained_backups('s3',$s3,$orig_bucket_name);
|
698 |
} else {
|
699 |
-
$this->log("S3 Error: Failed to create bucket $bucket_name.
|
700 |
-
$this->error("S3 Error: Failed to create bucket $bucket_name.
|
701 |
}
|
702 |
}
|
703 |
|
@@ -1002,10 +1019,10 @@ class UpdraftPlus {
|
|
1002 |
}
|
1003 |
|
1004 |
function save_backup_history($backup_array) {
|
1005 |
-
//TODO: this stores full paths right now. should probably concatenate with ABSPATH to make it easier to move sites
|
1006 |
if(is_array($backup_array)) {
|
1007 |
$backup_history = get_option('updraft_backup_history');
|
1008 |
$backup_history = (is_array($backup_history)) ? $backup_history : array();
|
|
|
1009 |
$backup_history[$this->backup_time] = $backup_array;
|
1010 |
update_option('updraft_backup_history',$backup_history);
|
1011 |
} else {
|
@@ -1034,9 +1051,7 @@ class UpdraftPlus {
|
|
1034 |
$total_tables = 0;
|
1035 |
|
1036 |
global $table_prefix, $wpdb;
|
1037 |
-
if(!$this->backup_time)
|
1038 |
-
$this->backup_time_nonce();
|
1039 |
-
}
|
1040 |
|
1041 |
$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
|
1042 |
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
|
@@ -1045,9 +1060,7 @@ class UpdraftPlus {
|
|
1045 |
//get the blog name and rip out all non-alphanumeric chars other than _
|
1046 |
$blog_name = str_replace(' ','_',get_bloginfo());
|
1047 |
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
1048 |
-
if(!$blog_name)
|
1049 |
-
$blog_name = 'non_alpha_name';
|
1050 |
-
}
|
1051 |
|
1052 |
$backup_file_base = $updraft_dir.'/backup_'.date('Y-m-d-Hi',$this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
1053 |
if (is_writable($updraft_dir)) {
|
@@ -1098,11 +1111,11 @@ class UpdraftPlus {
|
|
1098 |
}
|
1099 |
}
|
1100 |
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
|
1107 |
$this->close($this->dbhandle);
|
1108 |
|
@@ -1228,15 +1241,7 @@ class UpdraftPlus {
|
|
1228 |
$row_inc = ROWS_PER_SEGMENT;
|
1229 |
}
|
1230 |
do {
|
1231 |
-
|
1232 |
-
$excs = array('revisions' => 0, 'spam' => 1); //TODO, FIX THIS
|
1233 |
-
$where = '';
|
1234 |
-
if ( is_array($excs['spam'] ) && in_array($table, $excs['spam']) ) {
|
1235 |
-
$where = ' WHERE comment_approved != "spam"';
|
1236 |
-
} elseif ( is_array($excs['revisions'] ) && in_array($table, $excs['revisions']) ) {
|
1237 |
-
$where = ' WHERE post_type != "revision"';
|
1238 |
-
}
|
1239 |
-
|
1240 |
if ( !ini_get('safe_mode') || strtolower(ini_get('safe_mode')) == "off") @set_time_limit(15*60);
|
1241 |
$table_data = $wpdb->get_results("SELECT * FROM $table $where LIMIT {$row_start}, {$row_inc}", ARRAY_A);
|
1242 |
$entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES (';
|
@@ -1526,10 +1531,10 @@ class UpdraftPlus {
|
|
1526 |
if (@$s3->getBucketLocation($bucket_name)) {
|
1527 |
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
1528 |
if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
|
1529 |
-
$this->error("S3 Error: Failed to download $fullpath.
|
1530 |
}
|
1531 |
} else {
|
1532 |
-
$this->error("S3 Error: Failed to
|
1533 |
}
|
1534 |
}
|
1535 |
|
@@ -1590,7 +1595,7 @@ class UpdraftPlus {
|
|
1590 |
echo '</div>'; //close the updraft_restore_progress div
|
1591 |
# The 'off' check is for badly configured setups - http://wordpress.org/support/topic/plugin-wp-super-cache-warning-php-safe-mode-enabled-but-safe-mode-is-off
|
1592 |
if(ini_get('safe_mode') && strtolower(ini_get('safe_mode')) != "off") {
|
1593 |
-
echo "<p>DB could not be restored because safe_mode is active on your server. You will need to manually restore the file via phpMyAdmin or another method.</p><br/>";
|
1594 |
return false;
|
1595 |
}
|
1596 |
return true;
|
@@ -1721,23 +1726,6 @@ class UpdraftPlus {
|
|
1721 |
register_setting( 'updraft-options-group', 'updraft_include_others', 'absint' );
|
1722 |
register_setting( 'updraft-options-group', 'updraft_include_others_exclude', 'wp_filter_nohtml_kses' );
|
1723 |
|
1724 |
-
/* I see no need for this check; people can only download backups/logs if they can guess a nonce formed from a random number and if .htaccess files have no effect. The database will be encrypted. Very unlikely.
|
1725 |
-
if (current_user_can('manage_options')) {
|
1726 |
-
$updraft_dir = $this->backups_dir_location();
|
1727 |
-
if(strpos($updraft_dir,WP_CONTENT_DIR) !== false) {
|
1728 |
-
$relative_dir = str_replace(WP_CONTENT_DIR,'',$updraft_dir);
|
1729 |
-
$possible_updraft_url = WP_CONTENT_URL.$relative_dir;
|
1730 |
-
$resp = wp_remote_request($possible_updraft_url, array('timeout' => 15));
|
1731 |
-
if ( is_wp_error($resp) ) {
|
1732 |
-
add_action('admin_notices', array($this,'show_admin_warning_accessible_unknownresult') );
|
1733 |
-
} else {
|
1734 |
-
if(strpos($resp['response']['code'],'403') === false) {
|
1735 |
-
add_action('admin_notices', array($this,'show_admin_warning_accessible') );
|
1736 |
-
}
|
1737 |
-
}
|
1738 |
-
}
|
1739 |
-
}
|
1740 |
-
*/
|
1741 |
if (current_user_can('manage_options') && get_option('updraft_service') == "googledrive" && get_option('updraft_googledrive_clientid') != "" && get_option('updraft_googledrive_token','xyz') == 'xyz') {
|
1742 |
add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
|
1743 |
}
|
@@ -1824,18 +1812,15 @@ class UpdraftPlus {
|
|
1824 |
}
|
1825 |
echo '</div>';
|
1826 |
}
|
1827 |
-
|
1828 |
-
|
1829 |
-
|
1830 |
-
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_db')
|
1831 |
-
$this->backup_db();
|
1832 |
-
}
|
1833 |
|
1834 |
?>
|
1835 |
<div class="wrap">
|
1836 |
<h1>UpdraftPlus - Backup/Restore</h1>
|
1837 |
|
1838 |
-
<!-- Version: <b><?php echo $this->version; ?></b><br>-->
|
1839 |
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; ?>
|
1840 |
<br>
|
1841 |
<?php
|
@@ -1843,12 +1828,11 @@ class UpdraftPlus {
|
|
1843 |
echo "<div style=\"color:blue\">Your backup has been restored. Your old themes, uploads, and plugins directories have been retained with \"-old\" appended to their name. Remove them when you are satisfied that the backup worked properly. At this time Updraft does not automatically restore your DB. You will need to use an external tool like phpMyAdmin to perform that task.</div>";
|
1844 |
}
|
1845 |
|
1846 |
-
|
1847 |
-
|
1848 |
<div class="updated fade" style="max-width: 800px; font-size:140%; padding:14px; clear:left;">${ws_advert}</div>
|
1849 |
ENDHERE;
|
1850 |
|
1851 |
-
|
1852 |
if($deleted_old_dirs) {
|
1853 |
echo '<div style="color:blue">Old directories successfully deleted.</div>';
|
1854 |
}
|
@@ -1871,7 +1855,7 @@ ENDHERE;
|
|
1871 |
}
|
1872 |
if(!empty($this->errors)) {
|
1873 |
foreach($this->errors as $error) {
|
1874 |
-
//ignoring severity
|
1875 |
echo '<div style="color:red">'.$error['error'].'</div>';
|
1876 |
}
|
1877 |
}
|
@@ -1881,6 +1865,7 @@ ENDHERE;
|
|
1881 |
<table class="form-table" style="float:left; clear: both; width:475px">
|
1882 |
<tr>
|
1883 |
<?php
|
|
|
1884 |
$next_scheduled_backup = wp_next_scheduled('updraft_backup');
|
1885 |
$next_scheduled_backup = ($next_scheduled_backup) ? date('D, F j, Y H:i T',$next_scheduled_backup) : 'No backups are scheduled at this time.';
|
1886 |
$next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
|
@@ -1892,19 +1877,17 @@ ENDHERE;
|
|
1892 |
$current_time = date('D, F j, Y H:i T',time());
|
1893 |
$updraft_last_backup = get_option('updraft_last_backup');
|
1894 |
if($updraft_last_backup) {
|
1895 |
-
|
1896 |
-
|
1897 |
-
|
1898 |
-
|
1899 |
-
$last_backup =
|
1900 |
-
$last_backup_color = 'red';
|
1901 |
}
|
1902 |
} else {
|
1903 |
$last_backup = 'No backup has been completed.';
|
1904 |
$last_backup_color = 'blue';
|
1905 |
}
|
1906 |
|
1907 |
-
$updraft_dir = $this->backups_dir_location();
|
1908 |
if(is_writable($updraft_dir)) {
|
1909 |
$dir_info = '<span style="color:green">Backup directory specified is writable, which is good.</span>';
|
1910 |
$backup_disabled = "";
|
@@ -1984,7 +1967,7 @@ ENDHERE;
|
|
1984 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
1985 |
<input type="submit" value="Database" />
|
1986 |
</form>
|
1987 |
-
<?php } else { echo "(No database
|
1988 |
</td>
|
1989 |
<td>
|
1990 |
<?php if (isset($value['plugins'])) { ?>
|
@@ -1994,7 +1977,7 @@ ENDHERE;
|
|
1994 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
1995 |
<input type="submit" value="Plugins" />
|
1996 |
</form>
|
1997 |
-
<?php } else { echo "(No plugins
|
1998 |
</td>
|
1999 |
<td>
|
2000 |
<?php if (isset($value['themes'])) { ?>
|
@@ -2004,7 +1987,7 @@ ENDHERE;
|
|
2004 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2005 |
<input type="submit" value="Themes" />
|
2006 |
</form>
|
2007 |
-
<?php } else { echo "(No themes
|
2008 |
</td>
|
2009 |
<td>
|
2010 |
<?php if (isset($value['uploads'])) { ?>
|
@@ -2014,7 +1997,7 @@ ENDHERE;
|
|
2014 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2015 |
<input type="submit" value="Uploads" />
|
2016 |
</form>
|
2017 |
-
<?php } else { echo "(No uploads
|
2018 |
</td>
|
2019 |
<td>
|
2020 |
<?php if (isset($value['others'])) { ?>
|
@@ -2024,7 +2007,17 @@ ENDHERE;
|
|
2024 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2025 |
<input type="submit" value="Others" />
|
2026 |
</form>
|
2027 |
-
<?php } else { echo "(No others
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2028 |
</td>
|
2029 |
</tr>
|
2030 |
<?php }?>
|
@@ -2262,7 +2255,7 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
|
|
2262 |
</tr>
|
2263 |
<tr>
|
2264 |
<th>Debug mode:</th>
|
2265 |
-
<td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this for more information, if something is going wrong. Will also drop a log file in your backup directory which you can examine.</td>
|
2266 |
</tr>
|
2267 |
<tr>
|
2268 |
<td>
|
@@ -2381,17 +2374,15 @@ echo $delete_local; ?> /> <br>Check this to delete the local backup file (only s
|
|
2381 |
}
|
2382 |
|
2383 |
function show_admin_warning($message) {
|
2384 |
-
echo '<div id="updraftmessage" class="updated fade">';
|
2385 |
-
echo "<p>$message</p></div>";
|
2386 |
-
}
|
2387 |
-
function show_admin_warning_accessible() {
|
2388 |
-
$this->show_admin_warning("UpdraftPlus backup directory specified is accessible via the web. This is a potential security problem (people may be able to download your backups - which is undesirable if your database is not encrypted and if you have non-public assets amongst the files). If using Apache, enable .htaccess support to allow web access to be denied; otherwise, you should deny access manually.");
|
2389 |
}
|
|
|
2390 |
function show_admin_warning_googledrive() {
|
2391 |
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=auth&updraftplus_googleauth=doit">Click here to authenticate your Google Drive account (you will not be able to back up to Google Drive without it).</a>');
|
2392 |
}
|
2393 |
-
|
2394 |
-
|
|
|
2395 |
}
|
2396 |
|
2397 |
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/updraftplus
|
5 |
Description: Uploads, themes, plugins, and your DB can be automatically backed up to Amazon S3, Google Drive, FTP, or emailed, on separate schedules.
|
6 |
Author: David Anderson.
|
7 |
+
Version: 1.0.15
|
8 |
Donate link: http://david.dw-perspective.org.uk/donate
|
9 |
License: GPLv3 or later
|
10 |
Author URI: http://wordshell.net
|
13 |
/*
|
14 |
TODO (some of these items mine, some from original Updraft awaiting review):
|
15 |
//Add DropBox and Microsoft Skydrive support
|
16 |
+
//improve error reporting / pretty up return messages in admin area
|
17 |
+
//?? On 'backup now', open up a Lightbox, count down 5 seconds, then start examining the log file (if it can be found)
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
|
19 |
Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
|
20 |
// Does not delete old custom directories upon a restore?
|
39 |
along with this program; if not, write to the Free Software
|
40 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
41 |
*/
|
|
|
42 |
|
43 |
+
// 15 minutes
|
44 |
+
@set_time_limit(900);
|
45 |
|
46 |
$updraft = new UpdraftPlus();
|
47 |
|
48 |
if(!$updraft->memory_check(192)) {
|
49 |
# TODO: Better solution is to split the backup set into manageable chunks based on this limit
|
50 |
+
@ini_set('memory_limit', '192M'); //up the memory limit for large backup files
|
51 |
}
|
52 |
|
53 |
define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
|
54 |
|
55 |
class UpdraftPlus {
|
56 |
|
57 |
+
var $version = '1.0.15';
|
58 |
|
59 |
var $dbhandle;
|
60 |
var $errors = array();
|
80 |
# http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
|
81 |
add_filter('cron_schedules', array($this,'modify_cron_schedules'));
|
82 |
add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
|
83 |
+
add_action('init', array($this, 'handle_url_actions'));
|
84 |
}
|
85 |
|
86 |
// Handle Google OAuth 2.0 - ?page=updraftplus&action=auth
|
87 |
+
// Also handle action=downloadlog
|
88 |
+
function handle_url_actions() {
|
89 |
+
if ( is_admin() && isset( $_GET['page'] ) && $_GET['page'] == 'updraftplus' && isset($_GET['action']) ) {
|
90 |
+
if ($_GET['action'] == 'auth') {
|
91 |
+
if ( isset( $_GET['state'] ) ) {
|
92 |
+
if ( $_GET['state'] == 'token' )
|
93 |
+
$this->gdrive_auth_token();
|
94 |
+
elseif ( $_GET['state'] == 'revoke' )
|
95 |
+
$this->gdrive_auth_revoke();
|
96 |
+
} elseif (isset($_GET['updraftplus_googleauth'])) {
|
97 |
+
$this->gdrive_auth_request();
|
98 |
+
}
|
99 |
+
} elseif ($_GET['action'] == 'downloadlog' && isset($_GET['updraftplus_backup_nonce']) && preg_match("/^[0-9a-f]{12}$/",$_GET['updraftplus_backup_nonce'])) {
|
100 |
+
$updraft_dir = $this->backups_dir_location();
|
101 |
+
$log_file = $updraft_dir.'/log.'.$_GET['updraftplus_backup_nonce'].'.txt';
|
102 |
+
if (is_readable($log_file)) {
|
103 |
+
header('Content-type: text/plain');
|
104 |
+
readfile($log_file);
|
105 |
+
exit;
|
106 |
+
} else {
|
107 |
+
add_action('admin_notices', array($this,'show_admin_warning_unreadablelog') );
|
108 |
+
}
|
109 |
}
|
110 |
}
|
111 |
}
|
112 |
|
113 |
+
// Acquire single-use authorization code from Google OAuth 2.0
|
|
|
|
|
114 |
function gdrive_auth_request() {
|
115 |
$params = array(
|
116 |
'response_type' => 'code',
|
124 |
header('Location: https://accounts.google.com/o/oauth2/auth?'.http_build_query($params));
|
125 |
}
|
126 |
|
127 |
+
// Get a Google account access token using the refresh token
|
|
|
|
|
128 |
function access_token( $token, $client_id, $client_secret ) {
|
129 |
$this->log("Google Drive: requesting access token: client_id=$client_id");
|
130 |
|
312 |
$this->logfile_handle = fopen($this->logfile_name, 'a');
|
313 |
}
|
314 |
|
315 |
+
function check_backup_race() {
|
316 |
+
$cur_trans = get_transient('updraftplus_backup_job_nonce');
|
317 |
+
if ( $cur_trans != $this->nonce) {
|
318 |
+
$this->log("Another backup job ($cur_trans) appears to now be running - terminating our run");
|
319 |
+
exit;
|
320 |
+
}
|
321 |
+
}
|
322 |
+
|
323 |
function backup($backup_files, $backup_database) {
|
324 |
|
325 |
@ignore_user_abort(true);
|
333 |
|
334 |
// Schedule the even to run later, which checks on success and can resume the backup
|
335 |
// We save the time to a variable because it is needed for un-scheduling
|
|
|
336 |
$resume_delay = 300;
|
337 |
wp_schedule_single_event(time()+$resume_delay, 'updraft_backup_resume', array(1));
|
338 |
$this->log("In case we run out of time, scheduled a resumption at: $resume_delay seconds from now");
|
341 |
global $wp_version;
|
342 |
$this->log("PHP version: ".phpversion()." WordPress version: ".$wp_version." Updraft version: ".$this->version." Backup files: $backup_files (schedule: ".get_option('updraft_interval','unset').") Backup DB: $backup_database (schedule: ".get_option('updraft_interval_database','unset').")");
|
343 |
|
344 |
+
$this->check_backup_race();
|
345 |
+
|
346 |
# If the files and database schedules are the same, and if this the file one, then we rope in database too.
|
347 |
# On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
|
348 |
if (get_option('updraft_interval') == get_option('updraft_interval_database') || get_option('updraft_interval_database','xyz') == 'xyz' ) {
|
358 |
|
359 |
$backup_array = array();
|
360 |
|
361 |
+
$this->check_backup_race();
|
362 |
+
|
363 |
//backup directories and return a numerically indexed array of file paths to the backup files
|
364 |
if ($backup_files) {
|
365 |
$this->log("Beginning backup of directories");
|
366 |
$backup_array = $this->backup_dirs();
|
367 |
$backup_contains = "Files only (no database)";
|
368 |
}
|
369 |
+
|
370 |
+
$this->check_backup_race();
|
371 |
+
|
372 |
//backup DB and return string of file path
|
373 |
if ($backup_database) {
|
374 |
$this->log("Beginning backup of database");
|
378 |
$backup_contains = ($backup_files) ? "Files and database" : "Database only (no files)";
|
379 |
}
|
380 |
|
381 |
+
$this->check_backup_race();
|
382 |
set_transient("updraftplus_backupcontains", $backup_contains, 3600*3);
|
383 |
|
384 |
//save this to our history so we can track backups for the retain feature
|
445 |
}
|
446 |
|
447 |
function save_last_backup($backup_array) {
|
448 |
+
$success = (empty($this->errors)) ? 1 : 0;
|
449 |
|
450 |
+
$last_backup = array('backup_time'=>$this->backup_time, 'backup_array'=>$backup_array, 'success'=>$success, 'errors'=>$this->errors, 'backup_nonce' => $this->nonce);
|
451 |
|
452 |
update_option('updraft_last_backup', $last_backup);
|
453 |
}
|
604 |
unset($backup_to_examine['themes']);
|
605 |
unset($backup_to_examine['uploads']);
|
606 |
unset($backup_to_examine['others']);
|
607 |
+
unset($backup_to_examine['nonce']);
|
608 |
}
|
609 |
}
|
610 |
// Delete backup set completely if empty, o/w just remove DB
|
653 |
if ($chunks < 2) {
|
654 |
if (!$s3->putObjectFile($fullpath, $bucket_name, $filepath)) {
|
655 |
$this->log("S3 regular upload: failed");
|
656 |
+
$this->error("S3 Error: Failed to upload $fullpath.");
|
657 |
} else {
|
658 |
$this->log("S3 regular upload: success");
|
659 |
$this->uploaded_file($file);
|
713 |
}
|
714 |
$this->prune_retained_backups('s3',$s3,$orig_bucket_name);
|
715 |
} else {
|
716 |
+
$this->log("S3 Error: Failed to create bucket $bucket_name.");
|
717 |
+
$this->error("S3 Error: Failed to create bucket $bucket_name. Check your permissions and credentials.");
|
718 |
}
|
719 |
}
|
720 |
|
1019 |
}
|
1020 |
|
1021 |
function save_backup_history($backup_array) {
|
|
|
1022 |
if(is_array($backup_array)) {
|
1023 |
$backup_history = get_option('updraft_backup_history');
|
1024 |
$backup_history = (is_array($backup_history)) ? $backup_history : array();
|
1025 |
+
$backup_array['nonce'] = $this->nonce;
|
1026 |
$backup_history[$this->backup_time] = $backup_array;
|
1027 |
update_option('updraft_backup_history',$backup_history);
|
1028 |
} else {
|
1051 |
$total_tables = 0;
|
1052 |
|
1053 |
global $table_prefix, $wpdb;
|
1054 |
+
if(!$this->backup_time) $this->backup_time_nonce();
|
|
|
|
|
1055 |
|
1056 |
$all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
|
1057 |
$all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
|
1060 |
//get the blog name and rip out all non-alphanumeric chars other than _
|
1061 |
$blog_name = str_replace(' ','_',get_bloginfo());
|
1062 |
$blog_name = preg_replace('/[^A-Za-z0-9_]/','', $blog_name);
|
1063 |
+
if (!$blog_name) $blog_name = 'non_alpha_name';
|
|
|
|
|
1064 |
|
1065 |
$backup_file_base = $updraft_dir.'/backup_'.date('Y-m-d-Hi',$this->backup_time).'_'.$blog_name.'_'.$this->nonce;
|
1066 |
if (is_writable($updraft_dir)) {
|
1111 |
}
|
1112 |
}
|
1113 |
|
1114 |
+
if (defined("DB_CHARSET")) {
|
1115 |
+
$this->stow("/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n");
|
1116 |
+
$this->stow("/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n");
|
1117 |
+
$this->stow("/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
|
1118 |
+
}
|
1119 |
|
1120 |
$this->close($this->dbhandle);
|
1121 |
|
1241 |
$row_inc = ROWS_PER_SEGMENT;
|
1242 |
}
|
1243 |
do {
|
1244 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1245 |
if ( !ini_get('safe_mode') || strtolower(ini_get('safe_mode')) == "off") @set_time_limit(15*60);
|
1246 |
$table_data = $wpdb->get_results("SELECT * FROM $table $where LIMIT {$row_start}, {$row_inc}", ARRAY_A);
|
1247 |
$entries = 'INSERT INTO ' . $this->backquote($table) . ' VALUES (';
|
1531 |
if (@$s3->getBucketLocation($bucket_name)) {
|
1532 |
$fullpath = trailingslashit(get_option('updraft_dir')).$file;
|
1533 |
if (!$s3->getObject($bucket_name, $bucket_path.$file, $fullpath)) {
|
1534 |
+
$this->error("S3 Error: Failed to download $fullpath. Check your permissions and credentials.");
|
1535 |
}
|
1536 |
} else {
|
1537 |
+
$this->error("S3 Error: Failed to access bucket $bucket_name. Check your permissions and credentials.");
|
1538 |
}
|
1539 |
}
|
1540 |
|
1595 |
echo '</div>'; //close the updraft_restore_progress div
|
1596 |
# The 'off' check is for badly configured setups - http://wordpress.org/support/topic/plugin-wp-super-cache-warning-php-safe-mode-enabled-but-safe-mode-is-off
|
1597 |
if(ini_get('safe_mode') && strtolower(ini_get('safe_mode')) != "off") {
|
1598 |
+
echo "<p>DB could not be restored because PHP safe_mode is active on your server. You will need to manually restore the file via phpMyAdmin or another method.</p><br/>";
|
1599 |
return false;
|
1600 |
}
|
1601 |
return true;
|
1726 |
register_setting( 'updraft-options-group', 'updraft_include_others', 'absint' );
|
1727 |
register_setting( 'updraft-options-group', 'updraft_include_others_exclude', 'wp_filter_nohtml_kses' );
|
1728 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1729 |
if (current_user_can('manage_options') && get_option('updraft_service') == "googledrive" && get_option('updraft_googledrive_clientid') != "" && get_option('updraft_googledrive_token','xyz') == 'xyz') {
|
1730 |
add_action('admin_notices', array($this,'show_admin_warning_googledrive') );
|
1731 |
}
|
1812 |
}
|
1813 |
echo '</div>';
|
1814 |
}
|
1815 |
+
|
1816 |
+
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') $this->backup(true,true);
|
1817 |
+
|
1818 |
+
if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_db') $this->backup_db();
|
|
|
|
|
1819 |
|
1820 |
?>
|
1821 |
<div class="wrap">
|
1822 |
<h1>UpdraftPlus - Backup/Restore</h1>
|
1823 |
|
|
|
1824 |
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; ?>
|
1825 |
<br>
|
1826 |
<?php
|
1828 |
echo "<div style=\"color:blue\">Your backup has been restored. Your old themes, uploads, and plugins directories have been retained with \"-old\" appended to their name. Remove them when you are satisfied that the backup worked properly. At this time Updraft does not automatically restore your DB. You will need to use an external tool like phpMyAdmin to perform that task.</div>";
|
1829 |
}
|
1830 |
|
1831 |
+
$ws_advert = $this->wordshell_random_advert(1);
|
1832 |
+
echo <<<ENDHERE
|
1833 |
<div class="updated fade" style="max-width: 800px; font-size:140%; padding:14px; clear:left;">${ws_advert}</div>
|
1834 |
ENDHERE;
|
1835 |
|
|
|
1836 |
if($deleted_old_dirs) {
|
1837 |
echo '<div style="color:blue">Old directories successfully deleted.</div>';
|
1838 |
}
|
1855 |
}
|
1856 |
if(!empty($this->errors)) {
|
1857 |
foreach($this->errors as $error) {
|
1858 |
+
// ignoring severity
|
1859 |
echo '<div style="color:red">'.$error['error'].'</div>';
|
1860 |
}
|
1861 |
}
|
1865 |
<table class="form-table" style="float:left; clear: both; width:475px">
|
1866 |
<tr>
|
1867 |
<?php
|
1868 |
+
$updraft_dir = $this->backups_dir_location();
|
1869 |
$next_scheduled_backup = wp_next_scheduled('updraft_backup');
|
1870 |
$next_scheduled_backup = ($next_scheduled_backup) ? date('D, F j, Y H:i T',$next_scheduled_backup) : 'No backups are scheduled at this time.';
|
1871 |
$next_scheduled_backup_database = wp_next_scheduled('updraft_backup_database');
|
1877 |
$current_time = date('D, F j, Y H:i T',time());
|
1878 |
$updraft_last_backup = get_option('updraft_last_backup');
|
1879 |
if($updraft_last_backup) {
|
1880 |
+
$last_backup = ($updraft_last_backup['success']) ? date('D, F j, Y H:i T',$updraft_last_backup['backup_time']) : print_r($updraft_last_backup['errors'],true);
|
1881 |
+
$last_backup_color = ($updraft_last_backup['success']) ? 'green' : 'red';
|
1882 |
+
if (!empty($updraft_last_backup['backup_nonce'])) {
|
1883 |
+
$potential_log_file = $updraft_dir."/log.".$updraft_last_backup['backup_nonce'].".txt";
|
1884 |
+
if (is_readable($potential_log_file)) $last_backup .= "<br><a href=\"?page=updraftplus&action=downloadlog&updraftplus_backup_nonce=".$updraft_last_backup['backup_nonce']."\">Download log file</a>";
|
|
|
1885 |
}
|
1886 |
} else {
|
1887 |
$last_backup = 'No backup has been completed.';
|
1888 |
$last_backup_color = 'blue';
|
1889 |
}
|
1890 |
|
|
|
1891 |
if(is_writable($updraft_dir)) {
|
1892 |
$dir_info = '<span style="color:green">Backup directory specified is writable, which is good.</span>';
|
1893 |
$backup_disabled = "";
|
1967 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
1968 |
<input type="submit" value="Database" />
|
1969 |
</form>
|
1970 |
+
<?php } else { echo "(No database)"; } ?>
|
1971 |
</td>
|
1972 |
<td>
|
1973 |
<?php if (isset($value['plugins'])) { ?>
|
1977 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
1978 |
<input type="submit" value="Plugins" />
|
1979 |
</form>
|
1980 |
+
<?php } else { echo "(No plugins)"; } ?>
|
1981 |
</td>
|
1982 |
<td>
|
1983 |
<?php if (isset($value['themes'])) { ?>
|
1987 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
1988 |
<input type="submit" value="Themes" />
|
1989 |
</form>
|
1990 |
+
<?php } else { echo "(No themes)"; } ?>
|
1991 |
</td>
|
1992 |
<td>
|
1993 |
<?php if (isset($value['uploads'])) { ?>
|
1997 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
1998 |
<input type="submit" value="Uploads" />
|
1999 |
</form>
|
2000 |
+
<?php } else { echo "(No uploads)"; } ?>
|
2001 |
</td>
|
2002 |
<td>
|
2003 |
<?php if (isset($value['others'])) { ?>
|
2007 |
<input type="hidden" name="timestamp" value="<?php echo $key?>" />
|
2008 |
<input type="submit" value="Others" />
|
2009 |
</form>
|
2010 |
+
<?php } else { echo "(No others)"; } ?>
|
2011 |
+
</td>
|
2012 |
+
<td>
|
2013 |
+
<?php if (isset($value['nonce']) && preg_match("/^[0-9a-f]{12}$/",$value['nonce']) && is_readable($updraft_dir.'/log.'.$value['nonce'].'.txt')) { ?>
|
2014 |
+
<form action="options-general.php" method="get">
|
2015 |
+
<input type="hidden" name="action" value="downloadlog" />
|
2016 |
+
<input type="hidden" name="page" value="updraftplus" />
|
2017 |
+
<input type="hidden" name="updraftplus_backup_nonce" value="<?php echo $value['nonce']; ?>" />
|
2018 |
+
<input type="submit" value="Backup Log" />
|
2019 |
+
</form>
|
2020 |
+
<?php } else { echo "(No backup log)"; } ?>
|
2021 |
</td>
|
2022 |
</tr>
|
2023 |
<?php }?>
|
2255 |
</tr>
|
2256 |
<tr>
|
2257 |
<th>Debug mode:</th>
|
2258 |
+
<td><input type="checkbox" name="updraft_debug_mode" value="1" <?php echo $debug_mode; ?> /> <br>Check this for more information, if something is going wrong. Will also drop a log file in your backup directory which you can examine. You <strong>must</strong> send me this log if you are filing a bug report.</td>
|
2259 |
</tr>
|
2260 |
<tr>
|
2261 |
<td>
|
2374 |
}
|
2375 |
|
2376 |
function show_admin_warning($message) {
|
2377 |
+
echo '<div id="updraftmessage" class="updated fade">'."<p>$message</p></div>";
|
|
|
|
|
|
|
|
|
2378 |
}
|
2379 |
+
|
2380 |
function show_admin_warning_googledrive() {
|
2381 |
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> <a href="?page=updraftplus&action=auth&updraftplus_googleauth=doit">Click here to authenticate your Google Drive account (you will not be able to back up to Google Drive without it).</a>');
|
2382 |
}
|
2383 |
+
|
2384 |
+
function show_admin_warning_unreadablelog() {
|
2385 |
+
$this->show_admin_warning('<strong>UpdraftPlus notice:</strong> The log file could not be read.</a>');
|
2386 |
}
|
2387 |
|
2388 |
|