UpdraftPlus WordPress Backup Plugin - Version 0.8.50

Version Description

  • 13/10/2012 =
  • Important new feature: back up other directories found in the WP content directory (not just plugins/themes/uploads, as in original Updraft)
Download this release

Release Info

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

Code changes from version 0.8.37 to 0.8.50

Files changed (3) hide show
  1. includes/updraft-restorer.php +37 -8
  2. readme.txt +24 -2
  3. updraftplus.php +95 -19
includes/updraft-restorer.php CHANGED
@@ -34,20 +34,49 @@ class Updraft_Restorer extends WP_Upgrader {
34
  if ( is_wp_error($working_dir) )
35
  return $working_dir;
36
 
37
- show_message($this->strings['moving_old']);
38
- if ( !$wp_filesystem->move($wp_dir . "wp-content/$type", $wp_dir . "wp-content/$type-old", true) ) {
39
- return new WP_Error('old_move_failed', $this->strings['old_move_failed']);
40
- }
41
 
42
- show_message($this->strings['moving_backup']);
43
- if ( !$wp_filesystem->move($working_dir . "/$type", $wp_dir . "wp-content/$type", true) ) {
44
- return new WP_Error('new_move_failed', $this->strings['new_move_failed']);
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  show_message($this->strings['cleaning_up']);
48
  if ( !$wp_filesystem->delete($working_dir) ) {
49
  return new WP_Error('delete_failed', $this->strings['delete_failed']);
50
  }
 
51
 
52
  switch($type) {
53
  case 'uploads':
34
  if ( is_wp_error($working_dir) )
35
  return $working_dir;
36
 
37
+ if ($type == "others" ) {
 
 
 
38
 
39
+ // In this special case, the backup contents are not in a folder, so it is not simply a case of moving the folder around, but rather looping over all that we find
40
+
41
+ $upgrade_files = $wp_filesystem->dirlist($working_dir);
42
+ if ( !empty($upgrade_files) ) {
43
+ foreach ( $upgrade_files as $filestruc ) {
44
+ $file = $filestruc['name'];
45
+ # Sanity check (should not be possible as these were excluded at backup time)
46
+ if ($file != "plugins" && $file != "themes" && $file != "uploads" && $file != "upgrade") {
47
+ # First, move the existing one, if necessary (may not be present)
48
+ if ($wp_filesystem->exists($wp_dir . "wp-content/$file")) {
49
+ if ( !$wp_filesystem->move($wp_dir . "wp-content/$file", $wp_dir . "wp-content/$file-old", true) ) {
50
+ return new WP_Error('old_move_failed', $this->strings['old_move_failed']);
51
+ }
52
+ }
53
+ # Now, move in the new one
54
+ if ( !$wp_filesystem->move($working_dir . "/$file", $wp_dir . "wp-content/$file", true) ) {
55
+ return new WP_Error('new_move_failed', $this->strings['new_move_failed']);
56
+ }
57
+ }
58
+ }
59
+ }
60
+
61
+ } else {
62
 
63
+ show_message($this->strings['moving_old']);
64
+ if ( !$wp_filesystem->move($wp_dir . "wp-content/$type", $wp_dir . "wp-content/$type-old", true) ) {
65
+ return new WP_Error('old_move_failed', $this->strings['old_move_failed']);
66
+ }
67
+
68
+ show_message($this->strings['moving_backup']);
69
+ if ( !$wp_filesystem->move($working_dir . "/$type", $wp_dir . "wp-content/$type", true) ) {
70
+ return new WP_Error('new_move_failed', $this->strings['new_move_failed']);
71
+ }
72
+
73
+ }
74
+
75
  show_message($this->strings['cleaning_up']);
76
  if ( !$wp_filesystem->delete($working_dir) ) {
77
  return new WP_Error('delete_failed', $this->strings['delete_failed']);
78
  }
79
+
80
 
81
  switch($type) {
82
  case 'uploads':
readme.txt CHANGED
@@ -12,7 +12,7 @@ License: GPLv2 or later
12
  UpdraftPlus simplifies backups (and restoration). Backup into the cloud (S3, Google Drive, FTP, and email) and restore with a single click. Backups of files and database can have separate schedules.
13
 
14
  == Upgrade Notice ==
15
- Bug fix: Don't whinge about failed GoogleDrive authentication if that method is not the live one
16
 
17
  == Installation ==
18
 
@@ -27,12 +27,31 @@ Standard WordPress plugin installation:
27
 
28
  = How is this better than the original Updraft? =
29
 
30
- You can check the changelog for changes; but the original Updraft, before I forked it, had two major problems. Firstly, it only backed up WP core tables from the database; if any of your plugins stored data in extra tables, then they were not backed up. Secondly, the database backup did not include charset information, which meant that you needed to know some SQL wizardry to actually be able to use the backup. I made UpdraftPlus out of my experience of trying to back up several sites with Updraft. Then, I added encryption for the database file for extra peace of mind, and future-proofed by getting rid of some deprecated aspects.
31
 
32
  = I like automating WordPress, and using the command-line. Please tell me more. =
33
 
34
  That's very good of you, thank you. You are looking for WordShell, <a href="http://wordshell.net">http://wordshell.net</a>.
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  = I encrypted my database - how do I decrypt it? =
37
 
38
  If you have the encryption key entered in your settings and you are restoring from the settings interface, then it will automatically decrypt. Otherwise, use the file example-decrypt.php found in the plugin directory.
@@ -47,6 +66,9 @@ Contact me! This is a complex plugin and the only way I can ensure it's robust i
47
 
48
  == Changelog ==
49
 
 
 
 
50
  = 0.8.37 - 12/10/2012 =
51
  * Don't whinge about Google Drive authentication if that method is not current
52
 
12
  UpdraftPlus simplifies backups (and restoration). Backup into the cloud (S3, Google Drive, FTP, and email) and restore with a single click. Backups of files and database can have separate schedules.
13
 
14
  == Upgrade Notice ==
15
+ Now backs up all directories found in the WP content directory (not just plugins/themes/uploads)
16
 
17
  == Installation ==
18
 
27
 
28
  = How is this better than the original Updraft? =
29
 
30
+ You can check the changelog for changes; but the original Updraft, before I forked it, had three major problems. Firstly, it only backed up WP core tables from the database; if any of your plugins stored data in extra tables, then they were not backed up. Secondly, it only backed up your plugins/themes/uploads and not any further directories inside wp-content that other plugins might have created. Thirdly, the database backup did not include charset information, which meant that you needed to know some SQL wizardry to actually be able to use the backup. I made UpdraftPlus out of my experience of trying to back up several sites with Updraft. Then, I added encryption for the database file for extra peace of mind, and future-proofed by getting rid of some deprecated aspects.
31
 
32
  = I like automating WordPress, and using the command-line. Please tell me more. =
33
 
34
  That's very good of you, thank you. You are looking for WordShell, <a href="http://wordshell.net">http://wordshell.net</a>.
35
 
36
+ = I want to restore, but cannot do so from the WP Admin console =
37
+
38
+ That's no problem. If you have your backed files, then you simply need to unzip them into the right places. UpdraftPlus does not back up the WordPress core - you can just get a fresh copy of that from www.wordpress.org. After installing that, then unzip the zip files for your uploads, themes and plugins back into the wp-content directory. Then re-install the database (e.g. by running it through PHPMyAdmin). Please don't ask me how to carry out these steps - they are basic operations which you can hire any of hundreds of thousands of people to show you how to do.
39
+
40
+ = Anything essential to know? =
41
+
42
+ After you have set up UpdraftPlus, you must check that your backups are taking place successfully. WordPress is a complex piece of software that runs in many situations. Don't wait until you need your backups before you find out that they never worked in the first place. Remember, there's no warranty.
43
+
44
+ = What exactly does UpdraftPlus back up ? =
45
+
46
+ Unless you disable any of these, it will back up your database (all tables which have been prefixed with the prefix for this WordPress installation, both core tables and extra ones added by plugins), your plugins folder, your themes folder, your uploads folder and any extra folders that other plugins have created in the WordPress content directory.
47
+
48
+ = What does UpdraftPlus not back up ? =
49
+
50
+ It does not back up WordPress core (since you can always get another copy of this from wordpress.org), and does not back up any extra files which you have added outside of the WordPress content directory (files which, by their nature, are unknown to WordPress). By default the WordPress content directory is "wp-content" in your WordPress root. It will not back up database tables which do not have the WordPress prefix (i.e. database tables from other applications but sharing a database with WordPress).
51
+
52
+ = Any known bugs ? =
53
+ The major one is that backups of very large sites (lots of uploaded media) can fail due to timing out. If your site is very large, then be doubly-sure to test when setting up that your backups are not empty.
54
+
55
  = I encrypted my database - how do I decrypt it? =
56
 
57
  If you have the encryption key entered in your settings and you are restoring from the settings interface, then it will automatically decrypt. Otherwise, use the file example-decrypt.php found in the plugin directory.
66
 
67
  == Changelog ==
68
 
69
+ = 0.8.50 - 13/10/2012 =
70
+ * Important new feature: back up other directories found in the WP content directory (not just plugins/themes/uploads, as in original Updraft)
71
+
72
  = 0.8.37 - 12/10/2012 =
73
  * Don't whinge about Google Drive authentication if that method is not current
74
 
updraftplus.php CHANGED
@@ -2,14 +2,14 @@
2
  /*
3
  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. Files and DB can be on separate schedules.
6
  Author: David Anderson.
7
- Version: 0.8.37
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  Author URI: http://wordshell.net
10
  */
11
 
12
- //TODO:
13
  //Add DropBox support
14
  //Struggles with large uploads - runs out of time before finishing. Break into chunks? Resume download on later run? (Add a new scheduled event to check on progress? Separate the upload from the creation?). Add in some logging (in a .php file that exists first).
15
  //improve error reporting. s3 and dir backup have decent reporting now, but not sure i know what to do from here
@@ -18,10 +18,8 @@ Author URI: http://wordshell.net
18
  //pretty up return messages in admin area
19
  //check s3/ftp download
20
 
21
- //If someone tries Google Drive then switches away, then they get a whinge about unauthenticated details
22
-
23
  /* More TODO:
24
- Are all directories in wp-content covered? No; only plugins, themes, content. We should check for others and allow the user the chance to choose which ones he wants
25
  Use only one entry in WP options database
26
  Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
27
  */
@@ -54,9 +52,11 @@ if(!$updraft->memory_check(192)) {
54
  @ini_set('memory_limit', '192M'); //up the memory limit for large backup files... should split the backup set into manageable chunks based on the limit
55
  }
56
 
 
 
57
  class UpdraftPlus {
58
 
59
- var $version = '0.8.37';
60
 
61
  var $dbhandle;
62
  var $errors = array();
@@ -490,7 +490,7 @@ class UpdraftPlus {
490
 
491
  // Log some information that may be helpful
492
  global $wp_version;
493
- $this->log("PHP version: ".phpversion()." WordPress version: ".$wp_version." Backup files: $backup_files (schedule: ".get_option('updraft_interval','unset').") Backup DB: $backup_database (schedule: ".get_option('updraft_interval_database','unset').")");
494
 
495
  # If the files and database schedules are the same, and if this the file one, then we rope in database too.
496
  # On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
@@ -655,7 +655,7 @@ class UpdraftPlus {
655
  unset($backup_to_examine['db']);
656
  }
657
  }
658
- if (isset($backup_to_examine['plugins']) || isset($backup_to_examine['themes']) || isset($backup_to_examine['uploads'])) {
659
  $file_backups_found++;
660
  $this->log("$backup_datestamp: this set includes files; fileset count is now $file_backups_found");
661
  if ($file_backups_found > $retain) {
@@ -663,7 +663,8 @@ class UpdraftPlus {
663
  $file = isset($backup_to_examine['plugins']) ? $backup_to_examine['plugins'] : "";
664
  $file2 = isset($backup_to_examine['themes']) ? $backup_to_examine['themes'] : "";
665
  $file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
666
- foreach (array($file,$file2,$file3) as $dofile) {
 
667
  if ($dofile) {
668
  $this->log("$backup_datestamp: Delete this file: $dofile");
669
  $fullpath = trailingslashit(get_option('updraft_dir')).$dofile;
@@ -699,6 +700,7 @@ class UpdraftPlus {
699
  unset($backup_to_examine['plugins']);
700
  unset($backup_to_examine['themes']);
701
  unset($backup_to_examine['uploads']);
 
702
  }
703
  }
704
  // Delete backup set completely if empty, o/w just remove DB
@@ -797,11 +799,9 @@ class UpdraftPlus {
797
  $wp_upload_dir = wp_upload_dir();
798
  $wp_upload_dir = $wp_upload_dir['basedir'];
799
  $wp_plugins_dir = WP_PLUGIN_DIR;
800
- if(!class_exists('PclZip')) {
801
- if (file_exists(ABSPATH.'/wp-admin/includes/class-pclzip.php')) {
802
- require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php');
803
- }
804
- }
805
  $updraft_dir = $this->backups_dir_location();
806
  if(!is_writable($updraft_dir)) {
807
  $this->error('Backup directory is not writable.','fatal');
@@ -822,8 +822,10 @@ class UpdraftPlus {
822
  if (get_option('updraft_include_plugins', true)) {
823
  $this->log("Beginning backup of plugins");
824
  $plugins = new PclZip($backup_file_base.'-plugins.zip');
 
825
  if (!$plugins->create($wp_plugins_dir,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
826
  $this->error('Could not create plugins zip. Error was '.$php_errmsg,'fatal');
 
827
  }
828
  $backup_array['plugins'] = basename($backup_file_base.'-plugins.zip');
829
  } else {
@@ -837,6 +839,7 @@ class UpdraftPlus {
837
  $themes = new PclZip($backup_file_base.'-themes.zip');
838
  if (!$themes->create($wp_themes_dir,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
839
  $this->error('Could not create themes zip. Error was '.$php_errmsg,'fatal');
 
840
  }
841
  $backup_array['themes'] = basename($backup_file_base.'-themes.zip');
842
  } else {
@@ -850,11 +853,68 @@ class UpdraftPlus {
850
  $uploads = new PclZip($backup_file_base.'-uploads.zip');
851
  if (!$uploads->create($wp_upload_dir,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
852
  $this->error('Could not create uploads zip. Error was '.$php_errmsg,'fatal');
 
853
  }
854
  $backup_array['uploads'] = basename($backup_file_base.'-uploads.zip');
855
  } else {
856
  $this->log("No backup of uploads: excluded by user's options");
857
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
858
  return $backup_array;
859
  }
860
 
@@ -1376,7 +1436,7 @@ class UpdraftPlus {
1376
  global $wp_filesystem;
1377
  $backup_history = get_option('updraft_backup_history');
1378
  if(!is_array($backup_history[$timestamp])) {
1379
- echo '<p>This backup does not exist in the backup history -- restoration aborted! timestamp: '.$timestamp.'</p><br/>';
1380
  return false;
1381
  }
1382
 
@@ -1397,6 +1457,7 @@ class UpdraftPlus {
1397
  if(!is_readable($fullpath) && $type != 'db') {
1398
  $this->download_backup($file);
1399
  }
 
1400
  if(is_readable($fullpath) && $type != 'db') {
1401
  if(!class_exists('WP_Upgrader')) {
1402
  require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
@@ -1431,7 +1492,7 @@ class UpdraftPlus {
1431
  exit;
1432
  }
1433
 
1434
- $to_delete = array('themes-old','plugins-old','uploads-old');
1435
 
1436
  foreach($to_delete as $name) {
1437
  //recursively delete
@@ -1542,6 +1603,8 @@ class UpdraftPlus {
1542
  register_setting( 'updraft-options-group', 'updraft_include_plugins', 'absint' );
1543
  register_setting( 'updraft-options-group', 'updraft_include_themes', 'absint' );
1544
  register_setting( 'updraft-options-group', 'updraft_include_uploads', 'absint' );
 
 
1545
 
1546
  /* 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.
1547
  if (current_user_can('manage_options')) {
@@ -1649,7 +1712,7 @@ ENDHERE;
1649
  <h2>UpdraftPlus - Backup/Restore</h2>
1650
 
1651
  Version: <b><?php echo $this->version; ?></b><br />
1652
- 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>)
1653
  <br />
1654
  Based on Updraft by <b>Paul Kehrer</b> (<a href="http://langui.sh" target="_blank">Blog</a> | <a href="http://twitter.com/reaperhulk" target="_blank">Twitter</a> )
1655
  <br />
@@ -1761,7 +1824,7 @@ ENDHERE;
1761
  </select>
1762
 
1763
  <input type="hidden" name="action" value="updraft_restore" />
1764
- <input type="submit" <?php echo $restore_disabled ?> class="button-primary" value="Restore Now!" style="padding-top:7px;margin-top:5px;padding-bottom:7px;font-size:24px !important" onclick="return(confirm('Restoring from backup will replace this site\'s themes, plugins, and uploads directories. DB restoration must be done separately at this time. Continue with the restoration process?'))" />
1765
  </form>
1766
  </div>
1767
  </div>
@@ -1821,6 +1884,16 @@ ENDHERE;
1821
  </form>
1822
  <?php } else { echo "(No uploads in backup)"; } ?>
1823
  </td>
 
 
 
 
 
 
 
 
 
 
1824
  </tr>
1825
  <?php }?>
1826
  </table>
@@ -1871,6 +1944,8 @@ ENDHERE;
1871
  $include_themes = (get_option('updraft_include_themes',true)) ? 'checked="checked"' : "";
1872
  $include_plugins = (get_option('updraft_include_plugins',true)) ? 'checked="checked"' : "";
1873
  $include_uploads = (get_option('updraft_include_uploads',true)) ? 'checked="checked"' : "";
 
 
1874
  ?>
1875
  <tr>
1876
  <th>Include in Files Backup:</th>
@@ -1878,6 +1953,7 @@ ENDHERE;
1878
  <input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br />
1879
  <input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br />
1880
  <input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br />
 
1881
  Include all of these, unless you are backing them up separately. Note that presently UpdraftPlus backs up these directories only - which is usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way.<br />(<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br /></td>
1882
  </td>
1883
  </tr>
2
  /*
3
  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: 0.8.50
8
  Donate link: http://david.dw-perspective.org.uk/donate
9
  Author URI: http://wordshell.net
10
  */
11
 
12
+ //TODO (some of these items mine, some from original Updraft awaiting review):
13
  //Add DropBox support
14
  //Struggles with large uploads - runs out of time before finishing. Break into chunks? Resume download on later run? (Add a new scheduled event to check on progress? Separate the upload from the creation?). Add in some logging (in a .php file that exists first).
15
  //improve error reporting. s3 and dir backup have decent reporting now, but not sure i know what to do from here
18
  //pretty up return messages in admin area
19
  //check s3/ftp download
20
 
 
 
21
  /* More TODO:
22
+ DONE, TESTING: Are all directories in wp-content covered? No; only plugins, themes, content. We should check for others and allow the user the chance to choose which ones he wants
23
  Use only one entry in WP options database
24
  Encrypt filesystem, if memory allows (and have option for abort if not); split up into multiple zips when needed
25
  */
52
  @ini_set('memory_limit', '192M'); //up the memory limit for large backup files... should split the backup set into manageable chunks based on the limit
53
  }
54
 
55
+ define('UPDRAFT_DEFAULT_OTHERS_EXCLUDE','upgrade,cache,updraft,index.php');
56
+
57
  class UpdraftPlus {
58
 
59
+ var $version = '0.8.50';
60
 
61
  var $dbhandle;
62
  var $errors = array();
490
 
491
  // Log some information that may be helpful
492
  global $wp_version;
493
+ $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').")");
494
 
495
  # If the files and database schedules are the same, and if this the file one, then we rope in database too.
496
  # On the other hand, if the schedules were the same and this was the database run, then there is nothing to do.
655
  unset($backup_to_examine['db']);
656
  }
657
  }
658
+ if (isset($backup_to_examine['plugins']) || isset($backup_to_examine['themes']) || isset($backup_to_examine['uploads']) || isset($backup_to_examine['others'])) {
659
  $file_backups_found++;
660
  $this->log("$backup_datestamp: this set includes files; fileset count is now $file_backups_found");
661
  if ($file_backups_found > $retain) {
663
  $file = isset($backup_to_examine['plugins']) ? $backup_to_examine['plugins'] : "";
664
  $file2 = isset($backup_to_examine['themes']) ? $backup_to_examine['themes'] : "";
665
  $file3 = isset($backup_to_examine['uploads']) ? $backup_to_examine['uploads'] : "";
666
+ $file4 = isset($backup_to_examine['others']) ? $backup_to_examine['others'] : "";
667
+ foreach (array($file,$file2,$file3,$file4) as $dofile) {
668
  if ($dofile) {
669
  $this->log("$backup_datestamp: Delete this file: $dofile");
670
  $fullpath = trailingslashit(get_option('updraft_dir')).$dofile;
700
  unset($backup_to_examine['plugins']);
701
  unset($backup_to_examine['themes']);
702
  unset($backup_to_examine['uploads']);
703
+ unset($backup_to_examine['others']);
704
  }
705
  }
706
  // Delete backup set completely if empty, o/w just remove DB
799
  $wp_upload_dir = wp_upload_dir();
800
  $wp_upload_dir = $wp_upload_dir['basedir'];
801
  $wp_plugins_dir = WP_PLUGIN_DIR;
802
+
803
+ if(!class_exists('PclZip')) { require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php'); }
804
+
 
 
805
  $updraft_dir = $this->backups_dir_location();
806
  if(!is_writable($updraft_dir)) {
807
  $this->error('Backup directory is not writable.','fatal');
822
  if (get_option('updraft_include_plugins', true)) {
823
  $this->log("Beginning backup of plugins");
824
  $plugins = new PclZip($backup_file_base.'-plugins.zip');
825
+ # The paths in the zip should then begin with 'plugins', having removed WP_CONTENT_DIR from the front
826
  if (!$plugins->create($wp_plugins_dir,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
827
  $this->error('Could not create plugins zip. Error was '.$php_errmsg,'fatal');
828
+ $this->log('ERROR: PclZip failure: Could not create plugins zip');
829
  }
830
  $backup_array['plugins'] = basename($backup_file_base.'-plugins.zip');
831
  } else {
839
  $themes = new PclZip($backup_file_base.'-themes.zip');
840
  if (!$themes->create($wp_themes_dir,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
841
  $this->error('Could not create themes zip. Error was '.$php_errmsg,'fatal');
842
+ $this->log('ERROR: PclZip failure: Could not create themes zip');
843
  }
844
  $backup_array['themes'] = basename($backup_file_base.'-themes.zip');
845
  } else {
853
  $uploads = new PclZip($backup_file_base.'-uploads.zip');
854
  if (!$uploads->create($wp_upload_dir,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
855
  $this->error('Could not create uploads zip. Error was '.$php_errmsg,'fatal');
856
+ $this->log('ERROR: PclZip failure: Could not create uploads zip');
857
  }
858
  $backup_array['uploads'] = basename($backup_file_base.'-uploads.zip');
859
  } else {
860
  $this->log("No backup of uploads: excluded by user's options");
861
  }
862
+
863
+ # Others
864
+ @set_time_limit(900);
865
+ if (get_option('updraft_include_others', true)) {
866
+ $this->log("Beginning backup of other directories found in the content directory");
867
+ $others = new PclZip($backup_file_base.'-others.zip');
868
+ // http://www.phpconcept.net/pclzip/user-guide/53
869
+ /* First parameter to create is:
870
+ An array of filenames or dirnames,
871
+ or
872
+ A string containing the filename or a dirname,
873
+ or
874
+ A string containing a list of filename or dirname separated by a comma.
875
+ */
876
+ // First, see what we can find. We always want to exclude these:
877
+ $wp_themes_dir = WP_CONTENT_DIR.'/themes';
878
+ $wp_upload_dir = wp_upload_dir();
879
+ $wp_upload_dir = $wp_upload_dir['basedir'];
880
+ $wp_plugins_dir = WP_PLUGIN_DIR;
881
+ $updraft_dir = untrailingslashit(get_option('updraft_dir'));
882
+
883
+ # Initialise
884
+ $other_dirlist = array();
885
+
886
+ $others_skip = preg_split("/,/",get_option('updraft_include_others_exclude',UPDRAFT_DEFAULT_OTHERS_EXCLUDE));
887
+ # Make the values into the keys
888
+ $others_skip = array_flip($others_skip);
889
+
890
+ $this->log('Looking for candidates to back up in: '.WP_CONTENT_DIR);
891
+ if ($handle = opendir(WP_CONTENT_DIR)) {
892
+ while (false !== ($entry = readdir($handle))) {
893
+ $candidate = WP_CONTENT_DIR.'/'.$entry;
894
+ if ($entry == "." || $entry == "..") { ; }
895
+ elseif ($candidate == $updraft_dir) { $this->log("$entry: skipping: this is the updraft directory"); }
896
+ elseif ($candidate == $wp_themes_dir) { $this->log("$entry: skipping: this is the themes directory"); }
897
+ elseif ($candidate == $wp_upload_dir) { $this->log("$entry: skipping: this is the uploads directory"); }
898
+ elseif ($candidate == $wp_plugins_dir) { $this->log("$entry: skipping: this is the plugins directory"); }
899
+ elseif (isset($others_skip[$entry])) { $this->log("$entry: skipping: excluded by options"); }
900
+ else { $this->log("$entry: adding to list"); array_push($other_dirlist,$candidate); }
901
+ }
902
+ } else {
903
+ $this->log('ERROR: Could not read the content directory: '.WP_CONTENT_DIR);
904
+ }
905
+
906
+ if (count($other_dirlist)>0) {
907
+ if (!$others->create($other_dirlist,PCLZIP_OPT_REMOVE_PATH,WP_CONTENT_DIR)) {
908
+ $this->error('Could not create other zip. Error was '.$php_errmsg,'fatal');
909
+ $this->log('ERROR: PclZip failure: Could not create other zip');
910
+ }
911
+ $backup_array['others'] = basename($backup_file_base.'-others.zip');
912
+ } else {
913
+ $this->log("No backup of other directories: there was nothing found to back up");
914
+ }
915
+ } else {
916
+ $this->log("No backup of other directories: excluded by user's options");
917
+ }
918
  return $backup_array;
919
  }
920
 
1436
  global $wp_filesystem;
1437
  $backup_history = get_option('updraft_backup_history');
1438
  if(!is_array($backup_history[$timestamp])) {
1439
+ echo '<p>This backup does not exist in the backup history - restoration aborted. Timestamp: '.$timestamp.'</p><br/>';
1440
  return false;
1441
  }
1442
 
1457
  if(!is_readable($fullpath) && $type != 'db') {
1458
  $this->download_backup($file);
1459
  }
1460
+ # Types: uploads, themes, plugins, others, db
1461
  if(is_readable($fullpath) && $type != 'db') {
1462
  if(!class_exists('WP_Upgrader')) {
1463
  require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
1492
  exit;
1493
  }
1494
 
1495
+ $to_delete = array('themes-old','plugins-old','uploads-old','others-old');
1496
 
1497
  foreach($to_delete as $name) {
1498
  //recursively delete
1603
  register_setting( 'updraft-options-group', 'updraft_include_plugins', 'absint' );
1604
  register_setting( 'updraft-options-group', 'updraft_include_themes', 'absint' );
1605
  register_setting( 'updraft-options-group', 'updraft_include_uploads', 'absint' );
1606
+ register_setting( 'updraft-options-group', 'updraft_include_others', 'absint' );
1607
+ register_setting( 'updraft-options-group', 'updraft_include_others_exclude', 'wp_filter_nohtml_kses' );
1608
 
1609
  /* 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.
1610
  if (current_user_can('manage_options')) {
1712
  <h2>UpdraftPlus - Backup/Restore</h2>
1713
 
1714
  Version: <b><?php echo $this->version; ?></b><br />
1715
+ 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>)
1716
  <br />
1717
  Based on Updraft by <b>Paul Kehrer</b> (<a href="http://langui.sh" target="_blank">Blog</a> | <a href="http://twitter.com/reaperhulk" target="_blank">Twitter</a> )
1718
  <br />
1824
  </select>
1825
 
1826
  <input type="hidden" name="action" value="updraft_restore" />
1827
+ <input type="submit" <?php echo $restore_disabled ?> class="button-primary" value="Restore Now!" style="padding-top:7px;margin-top:5px;padding-bottom:7px;font-size:24px !important" onclick="return(confirm('Restoring from backup will replace this site\'s themes, plugins, uploads and other content directories (according to what is contained in the backup set which you select). Database restoration cannot be done through this process - you must download the database and import yourself (e.g. through PHPMyAdmin). Do you wish to continue with the restoration process?'))" />
1828
  </form>
1829
  </div>
1830
  </div>
1884
  </form>
1885
  <?php } else { echo "(No uploads in backup)"; } ?>
1886
  </td>
1887
+ <td>
1888
+ <?php if (isset($value['others'])) { ?>
1889
+ <form action="admin-ajax.php" method="post">
1890
+ <input type="hidden" name="action" value="updraft_download_backup" />
1891
+ <input type="hidden" name="type" value="others" />
1892
+ <input type="hidden" name="timestamp" value="<?php echo $key?>" />
1893
+ <input type="submit" value="Others" />
1894
+ </form>
1895
+ <?php } else { echo "(No others in backup)"; } ?>
1896
+ </td>
1897
  </tr>
1898
  <?php }?>
1899
  </table>
1944
  $include_themes = (get_option('updraft_include_themes',true)) ? 'checked="checked"' : "";
1945
  $include_plugins = (get_option('updraft_include_plugins',true)) ? 'checked="checked"' : "";
1946
  $include_uploads = (get_option('updraft_include_uploads',true)) ? 'checked="checked"' : "";
1947
+ $include_others = (get_option('updraft_include_others',true)) ? 'checked="checked"' : "";
1948
+ $include_others_exclude = get_option('updraft_include_others_exclude',UPDRAFT_DEFAULT_OTHERS_EXCLUDE);
1949
  ?>
1950
  <tr>
1951
  <th>Include in Files Backup:</th>
1953
  <input type="checkbox" name="updraft_include_plugins" value="1" <?php echo $include_plugins; ?> /> Plugins<br />
1954
  <input type="checkbox" name="updraft_include_themes" value="1" <?php echo $include_themes; ?> /> Themes<br />
1955
  <input type="checkbox" name="updraft_include_uploads" value="1" <?php echo $include_uploads; ?> /> Uploads<br />
1956
+ <input type="checkbox" name="updraft_include_others" value="1" <?php echo $include_others; ?> /> Any other directories found inside wp-content - but exclude these directories: <input type="text" name="updraft_include_others_exclude" size="32" value="<?php echo htmlspecialchars($include_others_exclude); ?>"/><br />
1957
  Include all of these, unless you are backing them up separately. Note that presently UpdraftPlus backs up these directories only - which is usually everything (except for WordPress core itself which you can download afresh from WordPress.org). But if you have made customised modifications outside of these directories, you need to back them up another way.<br />(<a href="http://wordshell.net">Use WordShell</a> for automatic backup, version control and patching).<br /></td>
1958
  </td>
1959
  </tr>