UpdraftPlus WordPress Backup Plugin - Version 1.6.17

Version Description

  • 2013/06/06 =
  • FEATURE: News blog - http://updraftplus.com/news/ - please subscribe if you want to stay up to date with news of new features, tips, and special offers. RSS link: http://feeds.feedburner.com/UpdraftPlus
  • FEATURE: Restoration/migration now copes with a change of table prefix, and asks WordPress to recreate your .htaccess/web.config file
  • FEATURE: Add support for DreamHost DreamObjects (http://dreamhost.com/cloud/dreamobjects/)
  • FEATURE: Polski / Polish (pl_PL) translation: thanks to Bartosz Kaczmarek (barth.kaczmarek at gmail.com)
  • FEATURE: Add expert options to count expected uncompressed backup size, show/delete active jobs, and PHP info
  • FEATURE: Send backup reports to multiple addresses (comma-separate the addresses you wish to use)
  • FIX: Inform users of Dropbox tokens which stop working
  • FIX: Don't flag an error if mu-plugins are selected, but none are found and WordPress agrees that none exist
  • COMPATIBILITY: WordPress multisite post-3.5 does not store blog uploads separately from main uploads directory
  • COMPATIBILITY: Now marked as compatible with WordPress 3.6
  • TWEAK: When errors occur, list them in the notification email and attach the log file
  • TWEAK: Use only one transient per job, and clean it up upon completion
  • TWEAK: Added a "Clone/Migrate" button to give a visual clue for people wanting to do this
  • TWEAK: More verbose error reporting from PclZip
  • TWEAK: After database restoration, permalinks are flushed (often helps regenerate .htaccess+web.config files)
  • TWEAK: Database backups now put the options table first, to allow earlier changing of site URL upon migration
  • TWEAK: Show PHP + web server versions in the debug information
  • TWEAK: More sophisticated attempts to get a writable backup directory, and more helpful messages if we can't
  • TWEAK: Some more logging, data-gathering and algorithm-tweaking to especially improve the chances for people with astonishingly slow web hosting, but also tweaks that improve efficiency everywhere, especially for larger backup sets.
  • TWEAK: Migrator plugin now does search+replace after each table (instead of after them all)
  • TWEAK: Clean up temporary files earlier where safe+possible (can lower disk space requirements)
  • TWEAK: Re-scan of known sets now removes those known to be gone from the list
  • TWEAK: Made a few things use AJAX instead of full page loads
  • TWEAK: Replace Rackspace logo with current version
  • TWEAK: Make missing PHP component warnings more prominent
  • TWEAK: Warn users if they have W3 Total Cache's object cache (which has a bug that affects scheduled tasks) active.
  • TWEAK: Add a notice for users who have turned on debugging (some forget to turn it off, then ask for support when they see lots of debugging notices)
Download this release

Release Info

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

Code changes from version 1.6.2 to 1.6.17

Files changed (38) hide show
  1. admin.php +461 -102
  2. backup.php +254 -15
  3. images/dreamobjects_logo-horiz-2013.png +0 -0
  4. images/rackspacecloud-logo.png +0 -0
  5. includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php +8 -1
  6. includes/Dropbox/OAuth/Storage/Encrypter.php +9 -2
  7. includes/S3.php +7 -2
  8. includes/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  9. includes/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  10. includes/images/ui-bg_flat_10_000000_40x100.png +0 -0
  11. includes/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  12. includes/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  13. includes/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  14. includes/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  15. includes/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  16. includes/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  17. includes/images/ui-icons_222222_256x240.png +0 -0
  18. includes/images/ui-icons_228ef1_256x240.png +0 -0
  19. includes/images/ui-icons_ef8c08_256x240.png +0 -0
  20. includes/images/ui-icons_ffd27a_256x240.png +0 -0
  21. includes/images/ui-icons_ffffff_256x240.png +0 -0
  22. includes/updraft-restorer.php +327 -18
  23. index.html +67 -0
  24. languages/updraftplus-it_IT.mo +0 -0
  25. languages/updraftplus-it_IT.po +2256 -0
  26. languages/updraftplus-pl_PL.mo +0 -0
  27. languages/updraftplus-pl_PL.po +2020 -0
  28. languages/updraftplus.pot +715 -496
  29. methods/cloudfiles.php +16 -17
  30. methods/dreamobjects.php +35 -0
  31. methods/dropbox.php +23 -21
  32. methods/email.php +3 -1
  33. methods/ftp.php +3 -3
  34. methods/googledrive.php +18 -4
  35. methods/s3.php +141 -79
  36. options.php +4 -0
  37. readme.txt +48 -16
  38. updraftplus.php +265 -88
admin.php CHANGED
@@ -27,6 +27,7 @@ class UpdraftPlus_Admin {
27
  add_action('wp_ajax_plupload_action2', array($this,'plupload_action2'));
28
 
29
  global $updraftplus, $wp_version, $pagenow;
 
30
 
31
  // First, the checks that are on all (admin) pages:
32
 
@@ -40,12 +41,26 @@ class UpdraftPlus_Admin {
40
 
41
  if (UpdraftPlus_Options::user_can_manage() && $this->disk_space_check(1024*1024*35) === false) add_action('admin_notices', array($this, 'show_admin_warning_diskspace'));
42
 
 
 
 
43
  // Next, the actions that only come on the UpdraftPlus page
44
  if ($pagenow != 'options-general.php' || !isset($_REQUEST['page']) || 'updraftplus' != $_REQUEST['page']) return;
45
 
46
  if(UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
47
  @ini_set('display_errors',1);
48
  @error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
 
 
 
 
 
 
 
 
 
 
 
49
  }
50
 
51
  // LiteSpeed has a generic problem with terminating cron jobs
@@ -106,6 +121,13 @@ class UpdraftPlus_Admin {
106
  var updraft_downloader_nonce = '<?php wp_create_nonce("updraftplus_download"); ?>'
107
  </script>
108
  <style type="text/css">
 
 
 
 
 
 
 
109
  .drag-drop #drag-drop-area2 {
110
  border: 4px dashed #ddd;
111
  height: 200px;
@@ -182,6 +204,15 @@ class UpdraftPlus_Admin {
182
  $this->show_admin_warning('<strong>'.__('Warning','updraftplus').':</strong> '.sprintf(__('Your website is hosted using the %s web server.','updraftplus'),'LiteSpeed').' <a href="http://updraftplus.com/faqs/i-am-having-trouble-backing-up-and-my-web-hosting-company-uses-the-litespeed-webserver/">'.__('Please consult this FAQ if you have problems backing up.', 'updraftplus').'</a>');
183
  }
184
 
 
 
 
 
 
 
 
 
 
185
  function show_admin_warning_dropbox() {
186
  $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="options-general.php?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit">'.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Dropbox','Dropbox').'</a>');
187
  }
@@ -276,7 +307,7 @@ class UpdraftPlus_Admin {
276
  $updraftplus->log('The file was found locally and matched the recorded size from the backup history ('.round($known_size/1024,1).' Kb)');
277
  } else {
278
  $updraftplus->log('No file size was found recorded in the backup history. We will assume the local one is complete.');
279
- $known_size = filesize($fullpath);
280
  }
281
 
282
  // The AJAX responder that updates on progress wants to see this
@@ -348,16 +379,61 @@ class UpdraftPlus_Admin {
348
 
349
  global $updraftplus;
350
 
351
- // Test the nonce (probably not needed, since we're presumably admin-authed, but there's no harm)
352
  $nonce = (empty($_REQUEST['nonce'])) ? "" : $_REQUEST['nonce'];
353
  if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
354
 
355
  if ('lastlog' == $_GET['subaction']) {
356
  echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '('.__('Nothing yet logged', 'updraftplus').')'));
 
 
 
 
 
 
 
 
 
 
 
 
 
357
  } elseif ('lastbackup' == $_GET['subaction']) {
358
  echo $this->last_backup_html();
359
- } elseif ('diskspaceused' == $_GET['subaction']) {
360
- echo $this->recursive_directory_size($updraftplus->backups_dir_location());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  } elseif ('historystatus' == $_GET['subaction']) {
362
  $rescan = (isset($_GET['rescan']) && $_GET['rescan'] == 1);
363
  if ($rescan) $this->rebuild_backup_history();
@@ -608,11 +684,13 @@ class UpdraftPlus_Admin {
608
  */
609
  if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'updraft_restore' && isset($_REQUEST['backup_timestamp'])) {
610
  $backup_success = $this->restore_backup($_REQUEST['backup_timestamp']);
611
- if(empty($updraftplus->errors) && $backup_success == true) {
 
 
612
  echo '<p><strong>'.__('Restore successful!','updraftplus').'</strong></p>';
613
  echo '<b>'.__('Actions','updraftplus').':</b> <a href="options-general.php?page=updraftplus&updraft_restore_success=true">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
614
  return;
615
- } else {
616
  echo '<p>Restore failed...</p><ul style="list-style: disc inside;">';
617
  foreach ($updraftplus->errors as $err) {
618
  if (is_wp_error($err)) {
@@ -627,6 +705,9 @@ class UpdraftPlus_Admin {
627
  }
628
  echo '</ul><b>Actions:</b> <a href="options-general.php?page=updraftplus">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
629
  return;
 
 
 
630
  }
631
  //uncomment the below once i figure out how i want the flow of a restoration to work.
632
  //echo '<b>'__('Actions','updraftplus').':</b> <a href="options-general.php?page=updraftplus">Return to UpdraftPlus Configuration</a>';
@@ -652,27 +733,23 @@ class UpdraftPlus_Admin {
652
  if(isset($_GET['error'])) $this->show_admin_warning(htmlspecialchars($_GET['error']), 'error');
653
  if(isset($_GET['message'])) $this->show_admin_warning(htmlspecialchars($_GET['message']));
654
 
655
- if(isset($_GET['action']) && $_GET['action'] == 'updraft_create_backup_dir') {
656
- if(!$this->create_backup_dir()) {
657
- echo '<p>'.__('Backup directory could not be created','updraftplus').'...</p><br/>';
658
- } else {
 
 
 
 
 
 
659
  echo '<p>'.__('Backup directory successfully created.','updraftplus').'</p><br/>';
660
  }
661
  echo '<b>'.__('Actions','updraftplus').':</b> <a href="options-general.php?page=updraftplus">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
662
  return;
663
  }
664
 
665
- if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup') {
666
- // For unknown reasons, the <script> runs twice if put inside the <div>
667
- echo '<div class="updated fade" style="max-width: 800px; font-size:140%; line-height: 140%; padding:14px; clear:left;"><strong>',__('Schedule backup','updraftplus').':</strong> ';
668
- if (wp_schedule_single_event(time()+5, 'updraft_backup_all') === false) {
669
- $updraftplus->log("A backup run failed to schedule");
670
- echo __("Failed.",'updraftplus')."</div>";
671
- } else {
672
- echo htmlspecialchars(__('OK. Now load any page from your site to make sure the schedule can trigger. You should then see activity in the "Last log message" field below.','updraftplus'))." <a href=\"http://updraftplus.com/faqs/my-scheduled-backups-and-pressing-backup-now-does-nothing-however-pressing-debug-backup-does-produce-a-backup/\">".__('Nothing happening? Follow this link for help.','updraftplus')."</a></div><script>setTimeout(function(){updraft_showlastbackup();}, 7000);</script>";
673
- $updraftplus->log("A backup run has been scheduled");
674
- }
675
- }
676
 
677
  // updraft_file_ids is not deleted
678
  if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') { $updraftplus->boot_backup(true,true); }
@@ -690,12 +767,10 @@ class UpdraftPlus_Admin {
690
  <div class="wrap">
691
  <h1><?php echo $updraftplus->plugin_title; ?></h1>
692
 
693
- <?php _e('By UpdraftPlus.Com','updraftplus')?> ( <a href="http://updraftplus.com">UpdraftPlus.Com</a> | <a href="http://david.dw-perspective.org.uk"><?php _e("Lead developer's homepage",'updraftplus');?></a> | <?php if (!defined('UPDRAFTPLUS_NOADS')) { ?><a href="http://wordshell.net">WordShell - WordPress command line</a> | <a href="http://david.dw-perspective.org.uk/donate"><?php _e('Donate','updraftplus');?></a> | <?php } ?><a href="http://updraftplus.com/support/frequently-asked-questions/">FAQs</a> | <a href="http://profiles.wordpress.org/davidanderson/"><?php _e('Other WordPress plugins','updraftplus');?></a>). <?php _e('Version','updraftplus');?>: <?php echo $updraftplus->version; ?>
694
  <br>
695
  <?php
696
  if(isset($_GET['updraft_restore_success'])) {
697
- // If we restored the database, then that will have out-of-date information which may confuse the user - so automatically re-scan for them.
698
- $this->rebuild_backup_history();
699
  echo "<div class=\"updated fade\" style=\"padding:8px;\"><strong>".__('Your backup has been restored.','updraftplus').'</strong> '.__('Your old (themes, uploads, plugins, whatever) directories have been retained with "-old" appended to their name. Remove them when you are satisfied that the backup worked properly.')."</div>";
700
  }
701
 
@@ -787,21 +862,24 @@ class UpdraftPlus_Admin {
787
  <td id="updraft_last_backup"><?php echo $last_backup_html ?></td>
788
  </tr>
789
  </table>
790
- <div style="float:left; width:200px; padding-top: 20px;">
791
- <p><button type="button" <?php echo $backup_disabled ?> class="button-primary" style="padding-top:2px;padding-bottom:2px;font-size:22px !important; min-height: 32px;" onclick="jQuery('#updraft-backupnow-modal').dialog('open');"><?php _e('Backup Now','updraftplus');?></button></p>
792
- <div style="position:relative">
793
- <div style="position:absolute;top:0;left:0">
794
- <?php
 
795
  $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
796
  $backup_history = (is_array($backup_history))?$backup_history:array();
797
- ?>
798
- <input type="button" class="button-primary" value="<?php _e('Restore','updraftplus');?>" style="padding-top:2px;padding-bottom:2px;font-size:22px !important; min-height: 32px;" onclick="jQuery('.download-backups').slideDown(); updraft_historytimertoggle(1); jQuery('html,body').animate({scrollTop: jQuery('#updraft_lastlogcontainer').offset().top},'slow');">
799
- </div>
 
 
800
  </div>
801
  </div>
802
  <br style="clear:both" />
803
  <table class="form-table">
804
- <tr>
805
  <th><?php _e('Last log message','updraftplus');?>:</th>
806
  <td>
807
  <span id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', __('(Nothing yet logged)','updraftplus'))); ?></span><br>
@@ -810,10 +888,21 @@ class UpdraftPlus_Admin {
810
  </tr>
811
  <tr>
812
  <th><?php echo htmlspecialchars(__('Backups, logs & restoring','updraftplus')); ?>:</th>
813
- <td><a id="updraft_showbackups" href="#" title="<?php _e('Press to see available backups','updraftplus');?>" onclick="jQuery('.download-backups').toggle(); updraft_historytimertoggle(0);"><?php echo sprintf(__('%d set(s) available', 'updraftplus'), count($backup_history)); ?></a></td>
 
 
 
 
 
 
 
814
  </tr>
 
 
 
815
  <tr>
816
- <td></td><td class="download-backups" style="display:none; border: 1px dotted;">
 
817
  <p style="max-width: 740px;"><ul style="list-style: disc inside;">
818
  <li><strong><?php _e('Downloading','updraftplus');?>:</strong> <?php _e("Pressing a button for Database/Plugins/Themes/Uploads/Others will make UpdraftPlus try to bring the backup file back from the remote storage (if any - e.g. Amazon S3, Dropbox, Google Drive, FTP) to your webserver. Then you will be allowed to download it to your computer. If the fetch from the remote storage stops progressing (wait 30 seconds to make sure), then press again to resume. Remember that you can also visit the cloud storage vendor's website directly.",'updraftplus');?></li>
819
  <li><strong><?php _e('Restoring','updraftplus');?>:</strong> <?php _e("Press the button for the backup you wish to restore. If your site is large and you are using remote storage, then you should first click on each entity in order to retrieve it back to the webserver. This will prevent time-outs from occuring during the restore process itself.",'updraftplus');?> <?php _e('More tasks:','updraftplus');?> <a href="#" onclick="jQuery('#updraft-plupload-modal').slideToggle(); return false;"><?php _e('upload backup files','updraftplus');?></a> | <a href="#" onclick="updraft_updatehistory(1); return false;" title="<?php _e('Press here to look inside your UpdraftPlus directory (in your web hosting space) for any new backup sets that you have uploaded. The location of this directory is set in the expert settings, below.','updraftplus'); ?>"><?php _e('rescan folder for new backup sets','updraftplus');?></a></li>
@@ -824,7 +913,7 @@ class UpdraftPlus_Admin {
824
  <li title="<?php _e('This is a count of the contents of your Updraft directory','updraftplus');?>"><strong><?php _e('Web-server disk space in use by UpdraftPlus','updraftplus');?>:</strong> <span id="updraft_diskspaceused"><em>(calculating...)</em></span> <a href="#" onclick="updraftplus_diskspace(); return false;"><?php _e('refresh','updraftplus');?></a></li></ul>
825
 
826
  <div id="updraft-plupload-modal" title="<?php _e('UpdraftPlus - Upload backup files','updraftplus'); ?>" style="width: 75%; margin: 16px; display:none; margin-left: 100px;">
827
- <p><em><?php _e("Upload files into UpdraftPlus. Use this to import backups made on a different WordPress installation." ,'updraftplus');?></em></p>
828
  <div id="plupload-upload-ui" style="width: 70%;">
829
  <div id="drag-drop-area">
830
  <div class="drag-drop-inside">
@@ -843,7 +932,7 @@ class UpdraftPlus_Admin {
843
  <script>
844
  function updraftplus_diskspace() {
845
  jQuery('#updraft_diskspaceused').html('<em><?php _e('calculating...','updraftplus');?></em>');
846
- jQuery.get(ajaxurl, { action: 'updraft_ajax', subaction: 'diskspaceused', nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>' }, function(response) {
847
  jQuery('#updraft_diskspaceused').html(response);
848
  });
849
  }
@@ -871,9 +960,9 @@ class UpdraftPlus_Admin {
871
  // Create somewhere for the status to be found
872
  var stid = base+nonce+'_'+what;
873
  if (!jQuery('#'+stid).length) {
874
- jQuery('#ud_downloadstatus').append('<div style="clear:left; border: 1px solid; padding: 8px; margin-top: 4px; max-width:840px;" id="'+stid+'"><button onclick="jQuery(\'#'+stid+'\').fadeOut().remove();" type="button" style="float:right; margin-bottom: 8px;">X</button><strong>Download '+what+' ('+nonce+')</strong>:<div class="raw">Begun looking for this entity</div><div class="file" id="'+stid+'_st"><div class="dlfileprogress" style="width: 0;"></div></div>');
875
  // <b><span class="dlname">??</span></b> (<span class="dlsofar">?? KB</span>/<span class="dlsize">??</span> KB)
876
- setTimeout(function(){updraft_downloader_status(base, nonce, what)}, 300);
877
  }
878
  // Now send the actual request to kick it all off
879
  jQuery.post(ajaxurl, jQuery('#uddownloadform_'+what+'_'+nonce).serialize());
@@ -920,7 +1009,7 @@ class UpdraftPlus_Admin {
920
  alert('<?php _e('Download error: the server sent us a response (JSON) which we did not understand', 'updraftplus'); ?> ('+response+')');
921
  cancel_repeat = 1;
922
  }
923
- if (cancel_repeat == 0) { setTimeout(function(){updraft_downloader_status(base, nonce, what)}, nexttimer); }
924
  } catch(err) {
925
  alert('<?php _e('Download error: the server sent us a response which we did not understand.', 'updraftplus'); ?> <?php _e("Error:",'updraftplus');?> '+err);
926
  }
@@ -937,6 +1026,21 @@ class UpdraftPlus_Admin {
937
  </tr>
938
  </table>
939
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
940
  <div id="updraft-restore-modal" title="UpdraftPlus - <?php _e('Restore backup','updraftplus');?>">
941
  <p><strong><?php _e('Restore backup from','updraftplus');?>:</strong> <span id="updraft_restore_date"></span></p>
942
  <p><?php _e("Restoring will replace this site's themes, plugins, uploads, database and/or other content directories (according to what is contained in the backup set, and your selection).",'updraftplus');?> <?php _e('Choose the components to restore','updraftplus');?>:</p>
@@ -1000,12 +1104,25 @@ class UpdraftPlus_Admin {
1000
  <p><em><a href="http://updraftplus.com/faqs/what-should-i-understand-before-undertaking-a-restoration/" target="_new"><?php _e('Do read this helpful article of useful things to know before restoring.','updraftplus');?></a></em></p>
1001
  </div>
1002
 
1003
- <div id="updraft-backupnow-modal" title="UpdraftPlus - <?php _e('Perform a backup now','updraftplus'); ?>">
1004
- <p><?php _e("This will schedule a one-time backup. To proceed, press 'Backup Now', then wait 10 seconds, then visit any page on your site. WordPress should then start the backup running in the background.",'updraftplus');?></p>
1005
 
1006
- <form id="updraft-backupnow-form" method="post">
1007
- <input type="hidden" name="action" value="updraft_backup" />
1008
- </form>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1009
 
1010
  <p><?php _e('Does nothing happen when you schedule backups?','updraftplus');?> <a href="http://updraftplus.com/faqs/my-scheduled-backups-and-pressing-backup-now-does-nothing-however-pressing-debug-backup-does-produce-a-backup/"><?php _e('Go here for help.','updraft');?></a></p>
1011
  </div>
@@ -1022,52 +1139,133 @@ class UpdraftPlus_Admin {
1022
  </tr>
1023
  </table>
1024
  <?php } ?>
1025
- <h2><?php _e('Configure Backup Contents And Schedule','updraftplus');?></h2>
1026
  <?php UpdraftPlus_Options::options_form_begin(); ?>
1027
  <?php $this->settings_formcontents($last_backup_html); ?>
1028
  </form>
1029
  <div style="padding-top: 40px; display:none;" class="expertmode">
1030
  <hr>
1031
- <h3><?php _e('Debug Information And Expert Options','updraftplus');?></h3>
1032
  <p>
1033
  <?php
 
1034
  $peak_memory_usage = memory_get_peak_usage(true)/1024/1024;
1035
  $memory_usage = memory_get_usage(true)/1024/1024;
1036
  echo __('Peak memory usage','updraftplus').': '.$peak_memory_usage.' MB<br/>';
1037
  echo __('Current memory usage','updraftplus').': '.$memory_usage.' MB<br/>';
1038
  echo __('PHP memory limit','updraftplus').': '.ini_get('memory_limit').' <br/>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1039
  ?>
 
1040
  </p>
1041
- <p style="max-width: 600px;"><?php _e('The buttons below will immediately execute a backup run, independently of WordPress\'s scheduler. If these work whilst your scheduled backups and the "Backup Now" button do absolutely nothing (i.e. not even produce a log file), then it means that your scheduler is broken. You should then disable all your other plugins, and try the "Backup Now" button. If that fails, then contact your web hosting company and ask them if they have disabled wp-cron. If it succeeds, then re-activate your other plugins one-by-one, and find the one that is the problem and report a bug to them.','updraftplus');?></p>
1042
 
 
 
 
 
1043
  <form method="post">
1044
  <input type="hidden" name="action" value="updraft_backup_debug_all" />
1045
  <p><input type="submit" class="button-primary" <?php echo $backup_disabled ?> value="<?php _e('Debug Full Backup','updraftplus');?>" onclick="return(confirm('<?php echo htmlspecialchars(__('This will cause an immediate backup. The page will stall loading until it finishes (ie, unscheduled).','updraftplus'));?>'))" /></p>
1046
  </form>
 
1047
  <form method="post">
1048
  <input type="hidden" name="action" value="updraft_backup_debug_db" />
1049
  <p><input type="submit" class="button-primary" <?php echo $backup_disabled ?> value="<?php _e('Debug Database Backup','updraftplus');?>" onclick="return(confirm('<?php echo htmlspecialchars(__('This will cause an immediate DB backup. The page will stall loading until it finishes (ie, unscheduled). The backup may well run out of time; really this button is only helpful for checking that the backup is able to get through the initial stages, or for small WordPress sites..','updraftplus'));?>'))" /></p>
1050
  </form>
 
 
 
 
1051
  <h3><?php _e('Wipe Settings','updraftplus');?></h3>
1052
  <p style="max-width: 600px;"><?php _e('This button will delete all UpdraftPlus settings (but not any of your existing backups from your cloud storage). You will then need to enter all your settings again. You can also do this before deactivating/deinstalling UpdraftPlus if you wish.','updraftplus');?></p>
1053
  <form method="post">
1054
  <input type="hidden" name="action" value="updraft_wipesettings" />
1055
  <p><input type="submit" class="button-primary" value="<?php _e('Wipe All Settings','updraftplus'); ?>" onclick="return(confirm('<?php echo htmlspecialchars(__('This will delete all your UpdraftPlus settings - are you sure you want to do this?'));?>'))" /></p>
1056
  </form>
 
 
 
 
1057
  </div>
1058
 
1059
  <script type="text/javascript">
1060
  /* <![CDATA[ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1061
  jQuery(document).ready(function() {
 
1062
  jQuery('#updraft-service').change(function() {
1063
  jQuery('.updraftplusmethod').hide();
1064
  var active_class = jQuery(this).val();
1065
  jQuery('.'+active_class).show();
1066
  });
 
 
 
 
 
 
1067
  })
1068
  jQuery(window).load(function() {
1069
  //this is for hiding the restore progress at the top after it is done
1070
- setTimeout('jQuery("#updraft-restore-progress").toggle(1000)',3000)
1071
  jQuery('#updraft-restore-progress-toggle').click(function() {
1072
  jQuery('#updraft-restore-progress').toggle(500)
1073
  })
@@ -1077,6 +1275,29 @@ class UpdraftPlus_Admin {
1077
  <?php
1078
  }
1079
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1080
  //deletes the -old directories that are created when a backup is restored.
1081
  function delete_old_dirs() {
1082
  global $wp_filesystem;
@@ -1109,21 +1330,56 @@ class UpdraftPlus_Admin {
1109
  return $return_code;
1110
  }
1111
 
 
1112
  function create_backup_dir() {
 
1113
  global $wp_filesystem, $updraftplus;
1114
- $credentials = request_filesystem_credentials("options-general.php?page=updraftplus&action=updraft_create_backup_dir");
1115
- WP_Filesystem($credentials);
1116
- if ( $wp_filesystem->errors->get_error_code() ) {
1117
- foreach ( $wp_filesystem->errors->get_error_messages() as $message ) show_message($message);
1118
- exit;
 
 
 
 
1119
  }
1120
 
1121
  $updraft_dir = $updraftplus->backups_dir_location();
1122
 
1123
- $default_backup_dir = $wp_filesystem->find_folder($updraft_dir);
1124
- $updraft_dir = ($updraft_dir)?$updraft_dir:$default_backup_dir;
1125
 
1126
- if (!$wp_filesystem->mkdir($updraft_dir, 0775)) return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1127
 
1128
  return true;
1129
  }
@@ -1137,7 +1393,7 @@ class UpdraftPlus_Admin {
1137
  function scan_old_dirs() {
1138
  $dirArr = scandir(WP_CONTENT_DIR);
1139
  foreach($dirArr as $dir) {
1140
- if(strpos($dir,'-old') !== false) return true;
1141
  }
1142
  return false;
1143
  }
@@ -1275,7 +1531,7 @@ ENDHERE;
1275
  </tr>
1276
  <tr>
1277
  <th><?php _e('Email','updraftplus'); ?>:</th>
1278
- <td><input type="text" style="width:260px" name="updraft_email" value="<?php echo UpdraftPlus_Options::get_updraft_option('updraft_email'); ?>" /> <br><?php _e('Enter an address here to have a report sent (and the whole backup, if you choose) to it.','updraftplus'); ?></td>
1279
  </tr>
1280
 
1281
  <tr>
@@ -1353,11 +1609,11 @@ ENDHERE;
1353
  subaction: 'lastlog',
1354
  nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
1355
  };
1356
- function updraft_showlastlog(){
1357
  jQuery.get(ajaxurl, lastlog_sdata, function(response) {
1358
  nexttimer = 1500;
1359
  if (lastlog_lastmessage == response) { nexttimer = 4500; }
1360
- setTimeout(function(){updraft_showlastlog()}, nexttimer);
1361
  jQuery('#updraft_lastlogcontainer').html(response);
1362
  lastlog_lastmessage = response;
1363
  });
@@ -1367,11 +1623,11 @@ ENDHERE;
1367
  subaction: 'lastbackup',
1368
  nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
1369
  };
1370
- var lastbackup_laststatus = '<?php echo $last_backup_html?>'
1371
  function updraft_showlastbackup(){
1372
  jQuery.get(ajaxurl, lastbackup_sdata, function(response) {
1373
  if (lastbackup_laststatus == response) {
1374
- setTimeout(function(){updraft_showlastbackup()}, 7000);
1375
  } else {
1376
  jQuery('#updraft_last_backup').html(response);
1377
  }
@@ -1395,7 +1651,7 @@ ENDHERE;
1395
  }
1396
  function updraft_updatehistory(rescan) {
1397
  if (rescan == 1) {
1398
- jQuery('#updraft_existing_backups').html('<p style="text-align:center;"><em>Rescanning (looking for backups that you have uploaded manually into the internal backup store)...</em></p>');
1399
  }
1400
  jQuery.get(ajaxurl, { action: 'updraft_ajax', subaction: 'historystatus', nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>', rescan: rescan }, function(response) {
1401
  jQuery('#updraft_existing_backups').html(response);
@@ -1414,6 +1670,16 @@ ENDHERE;
1414
 
1415
  updraft_check_same_times();
1416
 
 
 
 
 
 
 
 
 
 
 
1417
  jQuery( "#updraft-restore-modal" ).dialog({
1418
  autoOpen: false, height: 505, width: 590, modal: true,
1419
  buttons: {
@@ -1435,22 +1701,53 @@ ENDHERE;
1435
  }
1436
  });
1437
 
1438
- jQuery( "#updraft-backupnow-modal" ).dialog({
1439
- autoOpen: false, height: 265, width: 375, modal: true,
 
 
 
 
 
1440
  buttons: {
1441
  '<?php _e('Backup Now','updraftplus');?>': function() {
1442
- jQuery('#updraft-backupnow-form').submit();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1443
  },
1444
  '<?php _e('Cancel','updraftplus');?>': function() { jQuery(this).dialog("close"); }
1445
  }
1446
  });
1447
 
 
 
 
 
 
 
 
1448
  jQuery('#enableexpertmode').click(function() {
1449
  jQuery('.expertmode').fadeIn();
 
 
 
1450
  return false;
1451
  });
1452
  <?php if (!@is_writable($updraft_dir)) echo "jQuery('.backupdirrow').show();\n"; ?>
1453
- setTimeout(function(){updraft_showlastlog();}, 1200);
1454
  jQuery('.updraftplusmethod').hide();
1455
  <?php
1456
  if ($active_service) echo "jQuery('.${active_service}').show();";
@@ -1473,7 +1770,7 @@ ENDHERE;
1473
  </tr>
1474
  <tr>
1475
  <th><?php _e('Expert settings','updraftplus');?>:</th>
1476
- <td><a id="enableexpertmode" href="#"><?php _e('Show expert settings','updraftplus');?></a> - <?php _e("click this to show some further options; don't bother with this unless you have a problem or are curious.",'updraftplus');?> <?php do_action('updraftplus_expertsettingsdescription'); ?></td>
1477
  </tr>
1478
  <?php
1479
  $delete_local = UpdraftPlus_Options::get_updraft_option('updraft_delete_local', 1);
@@ -1496,7 +1793,7 @@ ENDHERE;
1496
  if(@is_writable($updraft_dir)) {
1497
  $dir_info = '<span style="color:green">'.__('Backup directory specified is writable, which is good.','updraftplus').'</span>';
1498
  } else {
1499
- $dir_info = '<span style="color:red">'.__('Backup directory specified is <b>not</b> writable, or does not exist.','updraftplus').' <span style="font-size:110%;font-weight:bold"><a href="options-general.php?page=updraftplus&action=updraft_create_backup_dir">'.__('Click here to attempt to create the directory and set the permissions','updraftplus').'</a></span>, '.__('or, to reset this option','updraftplus').' <a href="#" onclick="jQuery(\'#updraft_dir\').val(\''.WP_CONTENT_DIR.'/updraft\'); return false;">'.__('click here','updraftplus').'</a>. '.__('If that is unsuccessful check the permissions on your server or change it to another directory that is writable by your web server process.','updraftplus').'</span>';
1500
  }
1501
 
1502
  echo $dir_info.' '.__("This is where UpdraftPlus will write the zip files it creates initially. This directory must be writable by your web server. Typically you'll want to have it inside your wp-content folder (this is the default). <b>Do not</b> place it inside your uploads dir, as that will cause recursion issues (backups of backups of backups of...).",'updraftplus');?></td>
@@ -1545,10 +1842,22 @@ ENDHERE;
1545
  <?php
1546
  }
1547
 
1548
- function curl_check($service, $has_fallback = false) {
 
 
 
 
 
 
 
 
 
 
1549
  // Check requirements
1550
  if (!function_exists("curl_init")) {
1551
- ?><p><strong><?php _e('Warning','updraftplus'); ?>:</strong> <?php echo sprintf(__('Your web server\'s PHP installation does not included a required module (%s). Please contact your web hosting provider\'s support.', 'updraftplus'), 'Curl'); ?> <?php echo sprintf(__("UpdraftPlus's %s module <strong>requires</strong> Curl. Your only options to get this working are 1) Install/enable curl or 2) Hire us or someone else to code additional support options into UpdraftPlus. 3) Wait, possibly forever, for someone else to do this.",'updraftplus'),$service);?></p><?php
 
 
1552
  } else {
1553
  $curl_version = curl_version();
1554
  $curl_ssl_supported= ($curl_version['features'] & CURL_VERSION_SSL);
@@ -1556,7 +1865,7 @@ ENDHERE;
1556
  if ($has_fallback) {
1557
  ?><p><strong><?php _e('Warning','updraftplus'); ?>:</strong> <?php echo sprintf(__("Your web server's PHP/Curl installation does not support https access. Communications with %s will be unencrypted. ask your web host to install Curl/SSL in order to gain the ability for encryption (via an add-on).",'updraftplus'),$service);?></p><?php
1558
  } else {
1559
- ?><p><strong><?php _e('Warning','updraftplus'); ?>:</strong> <?php echo sprintf(__("Your web server's PHP/Curl installation does not support https access. We cannot access %s without this support. Please contact your web hosting provider's support. %s <strong>requires</strong> Curl+https. Please do not file any support requests; there is no alternative.",'updraftplus'),$service);?></p><?php
1560
  }
1561
  } else {
1562
  ?><p><em><?php echo sprintf(__("Good news: Your site's communications with %s can be encrypted. If you see any errors to do with encryption, then look in the 'Expert Settings' for more help.", 'updraftplus'),$service);?></em></p><?php
@@ -1564,7 +1873,28 @@ ENDHERE;
1564
  }
1565
  }
1566
 
1567
- function recursive_directory_size($directory) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1568
  $size = 0;
1569
  if(substr($directory,-1) == '/') $directory = substr($directory,0,-1);
1570
 
@@ -1577,22 +1907,16 @@ ENDHERE;
1577
  if(is_file($path)) {
1578
  $size += filesize($path);
1579
  } elseif(is_dir($path)) {
1580
- $handlesize = $this->recursive_directory_size($path);
1581
- if($handlesize >= 0) { $size += $handlesize; } else { return -1; }
1582
  }
1583
  }
1584
  }
1585
  closedir($handle);
1586
  }
1587
- if ($size > 1073741824) {
1588
- return round($size / 1073741824, 1).' Gb';
1589
- } elseif ($size > 1048576) {
1590
- return round($size / 1048576, 1).' Mb';
1591
- } elseif ($size > 1024) {
1592
- return round($size / 1024, 1).' Kb';
1593
- } else {
1594
- return round($size, 1).' b';
1595
- }
1596
  }
1597
 
1598
  function existing_backup_table($backup_history = false) {
@@ -1616,7 +1940,7 @@ ENDHERE;
1616
  $entities = '';
1617
  ?>
1618
  <tr>
1619
- <td><b><?php echo $pretty_date?></b></td>
1620
  <td>
1621
  <?php if (isset($value['db'])) {
1622
  $entities .= '/db/';
@@ -1670,6 +1994,11 @@ ENDHERE;
1670
  </td>
1671
  </tr>
1672
  <script>
 
 
 
 
 
1673
  function updraft_restore_setoptions(entities) {
1674
  var howmany = 0;
1675
  jQuery('input[name="updraft_restore[]"]').each(function(x,y){
@@ -1702,21 +2031,31 @@ ENDHERE;
1702
  $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
1703
  if (!is_array($backup_history)) $backup_history = array();
1704
 
 
 
 
1705
  // Accumulate a list of known files
1706
  foreach ($backup_history as $btime => $bdata) {
 
1707
  foreach ($bdata as $key => $value) {
1708
  // Record which set this file is found in
1709
  if (preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+\.(zip|gz|gz\.crypt)$/i', $value, $matches)) {
1710
  $nonce = $matches[2];
1711
- $known_files[$value] = $nonce;
1712
- $known_nonces[$nonce] = $btime;
 
 
 
 
 
 
1713
  }
1714
  }
 
 
 
 
1715
  }
1716
-
1717
- $updraft_dir = $updraftplus->backups_dir_location();
1718
-
1719
- if (!is_dir($updraft_dir)) return;
1720
 
1721
  if (!$handle = opendir($updraft_dir)) return;
1722
 
@@ -1731,7 +2070,8 @@ ENDHERE;
1731
  $type = $matches[3];
1732
  // The time from the filename does not include seconds. Need to identify the seconds to get the right time
1733
  if (isset($known_nonces[$nonce])) $btime = $known_nonces[$nonce];
1734
- if (!isset($backup_history[$btime])) $backup_history[$btime] = array();
 
1735
  $backup_history[$btime][$type] = $entry;
1736
  $backup_history[$btime][$type.'-size'] = filesize($updraft_dir.'/'.$entry);
1737
  $backup_history[$btime]['nonce'] = $nonce;
@@ -1746,6 +2086,7 @@ ENDHERE;
1746
 
1747
  }
1748
 
 
1749
  function restore_backup($timestamp) {
1750
 
1751
  @set_time_limit(900);
@@ -1754,7 +2095,7 @@ ENDHERE;
1754
  $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
1755
  if(!is_array($backup_history[$timestamp])) {
1756
  echo '<p>'.__('This backup does not exist in the backup history - restoration aborted. Timestamp:','updraftplus')." $timestamp</p><br/>";
1757
- return false;
1758
  }
1759
 
1760
  // request_filesystem_credentials passes on fields just via hidden name/value pairs.
@@ -1806,7 +2147,7 @@ ENDHERE;
1806
  if (count($_POST['updraft_restore']) == 0) {
1807
  echo '<p>'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'</p>';
1808
  echo '<p>'.__('If making a request for support, please include this information:','updraftplus').' '.count($_POST).' : '.htmlspecialchars(serialize($_POST)).'</p>';
1809
- return false;
1810
  }
1811
 
1812
  /*
@@ -1816,7 +2157,15 @@ ENDHERE;
1816
 
1817
  $backupable_entities = $updraftplus->get_backupable_file_entities(true, true);
1818
 
1819
- foreach($backup_history[$timestamp] as $type => $file) {
 
 
 
 
 
 
 
 
1820
  // All restorable entities must be given explicitly, as we can store other arbitrary data in the history array
1821
 
1822
  if (!isset($backupable_entities[$type]) && 'db' != $type) continue;
@@ -1834,6 +2183,11 @@ ENDHERE;
1834
  continue;
1835
  }
1836
 
 
 
 
 
 
1837
  $fullpath = $updraft_dir.$file;
1838
 
1839
  echo "Looking for $type archive: file name: ".htmlspecialchars($file)."<br>";
@@ -1857,18 +2211,17 @@ ENDHERE;
1857
  # Types: uploads, themes, plugins, others, db
1858
  if(is_readable($fullpath)) {
1859
 
1860
- if(!class_exists('WP_Upgrader')) require_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
1861
- require_once(UPDRAFTPLUS_DIR.'/includes/updraft-restorer.php');
1862
- $restorer = new Updraft_Restorer();
1863
-
1864
  $info = (isset($backupable_entities[$type])) ? $backupable_entities[$type] : array();
1865
-
1866
  $val = $restorer->restore_backup($file, $type, $service, $info);
1867
 
1868
  if(is_wp_error($val)) {
1869
  foreach ($val->get_error_messages() as $msg) {
1870
  echo '<strong>'.__('Error message', 'updraftplus').':</strong> '.htmlspecialchars($msg).'<br>';
1871
  }
 
 
 
1872
  echo '</div>'; //close the updraft_restore_progress div even if we error
1873
  return false;
1874
  }
@@ -1881,7 +2234,13 @@ ENDHERE;
1881
  return true;
1882
  }
1883
 
1884
-
 
 
 
 
 
 
1885
 
1886
  }
1887
 
27
  add_action('wp_ajax_plupload_action2', array($this,'plupload_action2'));
28
 
29
  global $updraftplus, $wp_version, $pagenow;
30
+ add_filter('updraftplus_dirlist_others', array($updraftplus, 'backup_others_dirlist'));
31
 
32
  // First, the checks that are on all (admin) pages:
33
 
41
 
42
  if (UpdraftPlus_Options::user_can_manage() && $this->disk_space_check(1024*1024*35) === false) add_action('admin_notices', array($this, 'show_admin_warning_diskspace'));
43
 
44
+ // Next, the actions that only come on settings pages
45
+ // if ($pagenow != 'options-general.php') return;
46
+
47
  // Next, the actions that only come on the UpdraftPlus page
48
  if ($pagenow != 'options-general.php' || !isset($_REQUEST['page']) || 'updraftplus' != $_REQUEST['page']) return;
49
 
50
  if(UpdraftPlus_Options::get_updraft_option('updraft_debug_mode')) {
51
  @ini_set('display_errors',1);
52
  @error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
53
+ add_action('admin_notices', array($this, 'show_admin_debug_warning'));
54
+ }
55
+
56
+ // W3 Total Cache's object cache eats transients during cron jobs. Reported to them many times by multiple people.
57
+ if (defined('W3TC') && W3TC == true) {
58
+ if (function_exists('w3_instance')) {
59
+ $modules = w3_instance('W3_ModuleStatus');
60
+ if ($modules->is_enabled('objectcache')) {
61
+ add_action('admin_notices', array($this, 'show_admin_warning_w3_total_cache'));
62
+ }
63
+ }
64
  }
65
 
66
  // LiteSpeed has a generic problem with terminating cron jobs
121
  var updraft_downloader_nonce = '<?php wp_create_nonce("updraftplus_download"); ?>'
122
  </script>
123
  <style type="text/css">
124
+ .updraftplus-remove {
125
+ color: red;
126
+ }
127
+ .updraftplus-remove:hover {
128
+ background-color: red;
129
+ color: #fff;
130
+ }
131
  .drag-drop #drag-drop-area2 {
132
  border: 4px dashed #ddd;
133
  height: 200px;
204
  $this->show_admin_warning('<strong>'.__('Warning','updraftplus').':</strong> '.sprintf(__('Your website is hosted using the %s web server.','updraftplus'),'LiteSpeed').' <a href="http://updraftplus.com/faqs/i-am-having-trouble-backing-up-and-my-web-hosting-company-uses-the-litespeed-webserver/">'.__('Please consult this FAQ if you have problems backing up.', 'updraftplus').'</a>');
205
  }
206
 
207
+ function show_admin_debug_warning() {
208
+ $this->show_admin_warning('<strong>'.__('Notice','updraftplus').':</strong> '.__('UpdraftPlus\'s debug mode is on. You may see debugging notices on this page not just from UpdraftPlus, but from any other plugin installed. Please try to make sure that the notice you are seeing is from UpdraftPlus before you raise a support request.', 'updraftplus').'</a>');
209
+ }
210
+
211
+ function show_admin_warning_w3_total_cache() {
212
+ $url = (is_multisite()) ? network_admin_url('admin.php?page=w3tc_general') : admin_url('admin.php?page=w3tc_general');
213
+ $this->show_admin_warning('<strong>'.__('Warning','updraftplus').':</strong> '.__('W3 Total Cache\'s object cache is active. This is known to have a bug that messes with all scheduled tasks (including backup jobs).','updraftplus').' <a href="'.$url.'#object_cache">'.__('Go here to turn it off.','updraftplus').'</a> '.sprintf(__('<a href="%s">Go here</a> for more information.', 'updraftplus'),'http://updraftplus.com/faqs/whats-the-deal-with-w3-total-caches-object-cache/'));
214
+ }
215
+
216
  function show_admin_warning_dropbox() {
217
  $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="options-general.php?page=updraftplus&action=updraftmethod-dropbox-auth&updraftplus_dropboxauth=doit">'.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Dropbox','Dropbox').'</a>');
218
  }
307
  $updraftplus->log('The file was found locally and matched the recorded size from the backup history ('.round($known_size/1024,1).' Kb)');
308
  } else {
309
  $updraftplus->log('No file size was found recorded in the backup history. We will assume the local one is complete.');
310
+ $known_size = filesize($fullpath);
311
  }
312
 
313
  // The AJAX responder that updates on progress wants to see this
379
 
380
  global $updraftplus;
381
 
382
+ // Test the nonce
383
  $nonce = (empty($_REQUEST['nonce'])) ? "" : $_REQUEST['nonce'];
384
  if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
385
 
386
  if ('lastlog' == $_GET['subaction']) {
387
  echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '('.__('Nothing yet logged', 'updraftplus').')'));
388
+ } elseif ('phpinfo' == $_REQUEST['subaction']) {
389
+ phpinfo(INFO_ALL ^ (INFO_CREDITS | INFO_LICENSE));
390
+ } elseif ('backupnow' == $_REQUEST['subaction']) {
391
+ echo '<strong>',__('Schedule backup','updraftplus').':</strong> ';
392
+ if (wp_schedule_single_event(time()+5, 'updraft_backup_all') === false) {
393
+ $updraftplus->log("A backup run failed to schedule");
394
+ echo __("Failed.",'updraftplus')."</div>";
395
+ } else {
396
+ // For unknown reasons, the <script> runs twice if put inside the <div>
397
+ echo htmlspecialchars(__('OK. You should soon see activity in the "Last log message" field below.','updraftplus'))." <a href=\"http://updraftplus.com/faqs/my-scheduled-backups-and-pressing-backup-now-does-nothing-however-pressing-debug-backup-does-produce-a-backup/\">".__('Nothing happening? Follow this link for help.','updraftplus')."</a></div><script>setTimeout(function(){updraft_showlastbackup();}, 7000);</script>";
398
+ $updraftplus->log("A backup run has been scheduled");
399
+ }
400
+
401
  } elseif ('lastbackup' == $_GET['subaction']) {
402
  echo $this->last_backup_html();
403
+ } elseif ('activejobs_list' == $_GET['subaction']) {
404
+ $this->print_active_jobs();
405
+ } elseif ('activejobs_delete' == $_GET['subaction'] && isset($_GET['jobid'])) {
406
+
407
+ $cron = get_option('cron');
408
+ $found_it = 0;
409
+ foreach ($cron as $time => $job) {
410
+ if (isset($job['updraft_backup_resume'])) {
411
+ foreach ($job['updraft_backup_resume'] as $hook => $info) {
412
+ if (isset($info['args'][1]) && $info['args'][1] == $_GET['jobid']) {
413
+ $found_it = 1;
414
+ $args = $cron[$time]['updraft_backup_resume'][$hook]['args'];
415
+ wp_unschedule_event($time, 'updraft_backup_resume', $args);
416
+ echo 'Y:'.__('Job deleted', 'updraftplus');
417
+ }
418
+ }
419
+ }
420
+ }
421
+
422
+ if (!$found_it) { echo 'X:'.__('Could not find that job - perhaps it has already finished?', 'updraftplus'); }
423
+
424
+
425
+ } elseif ('diskspaceused' == $_GET['subaction'] && isset($_GET['entity'])) {
426
+ if ($_GET['entity'] == 'updraft') {
427
+ echo $this->recursive_directory_size($updraftplus->backups_dir_location());
428
+ } else {
429
+ $backupable_entities = $updraftplus->get_backupable_file_entities(true, false);
430
+ if (!empty($backupable_entities[$_GET['entity']])) {
431
+ $dirs = apply_filters('updraftplus_dirlist_'.$_GET['entity'], $backupable_entities[$_GET['entity']]);
432
+ echo $this->recursive_directory_size($dirs);
433
+ } else {
434
+ _e('Error','updraftplus');
435
+ }
436
+ }
437
  } elseif ('historystatus' == $_GET['subaction']) {
438
  $rescan = (isset($_GET['rescan']) && $_GET['rescan'] == 1);
439
  if ($rescan) $this->rebuild_backup_history();
684
  */
685
  if(isset($_REQUEST['action']) && $_REQUEST['action'] == 'updraft_restore' && isset($_REQUEST['backup_timestamp'])) {
686
  $backup_success = $this->restore_backup($_REQUEST['backup_timestamp']);
687
+ if(empty($updraftplus->errors) && $backup_success === true) {
688
+ // If we restored the database, then that will have out-of-date information which may confuse the user - so automatically re-scan for them.
689
+ $this->rebuild_backup_history();
690
  echo '<p><strong>'.__('Restore successful!','updraftplus').'</strong></p>';
691
  echo '<b>'.__('Actions','updraftplus').':</b> <a href="options-general.php?page=updraftplus&updraft_restore_success=true">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
692
  return;
693
+ } elseif (is_wp_error($backup_success)) {
694
  echo '<p>Restore failed...</p><ul style="list-style: disc inside;">';
695
  foreach ($updraftplus->errors as $err) {
696
  if (is_wp_error($err)) {
705
  }
706
  echo '</ul><b>Actions:</b> <a href="options-general.php?page=updraftplus">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
707
  return;
708
+ } elseif (false === $backup_success) {
709
+ # This means, "not yet - but stay on the page because we may be able to do it later, e.g. if the user types in the requested information"
710
+ return;
711
  }
712
  //uncomment the below once i figure out how i want the flow of a restoration to work.
713
  //echo '<b>'__('Actions','updraftplus').':</b> <a href="options-general.php?page=updraftplus">Return to UpdraftPlus Configuration</a>';
733
  if(isset($_GET['error'])) $this->show_admin_warning(htmlspecialchars($_GET['error']), 'error');
734
  if(isset($_GET['message'])) $this->show_admin_warning(htmlspecialchars($_GET['message']));
735
 
736
+ if(isset($_GET['action']) && $_GET['action'] == 'updraft_create_backup_dir' && isset($_GET['nonce']) && wp_verify_nonce($_GET['nonce'], 'create_backup_dir')) {
737
+ $created = $this->create_backup_dir();
738
+ if(is_wp_error($created)) {
739
+ echo '<p>'.__('Backup directory could not be created','updraftplus').'...<br/>';
740
+ echo '<ul style="list-style: disc inside;">';
741
+ foreach ($created->get_error_messages() as $key => $msg) {
742
+ echo '<li>'.htmlspecialchars($msg).'</li>';
743
+ }
744
+ echo '</ul></p>';
745
+ } elseif ($created !== false) {
746
  echo '<p>'.__('Backup directory successfully created.','updraftplus').'</p><br/>';
747
  }
748
  echo '<b>'.__('Actions','updraftplus').':</b> <a href="options-general.php?page=updraftplus">'.__('Return to UpdraftPlus Configuration','updraftplus').'</a>';
749
  return;
750
  }
751
 
752
+ echo '<div id="updraft_backup_started" class="updated fade" style="display:none; max-width: 800px; font-size:140%; line-height: 140%; padding:14px; clear:left;"></div>';
 
 
 
 
 
 
 
 
 
 
753
 
754
  // updraft_file_ids is not deleted
755
  if(isset($_POST['action']) && $_POST['action'] == 'updraft_backup_debug_all') { $updraftplus->boot_backup(true,true); }
767
  <div class="wrap">
768
  <h1><?php echo $updraftplus->plugin_title; ?></h1>
769
 
770
+ <?php _e('By UpdraftPlus.Com','updraftplus')?> ( <a href="http://updraftplus.com">UpdraftPlus.Com</a> | <a href="http://updraftplus.com/news/"><?php _e('News','updraftplus');?></a> | <?php if (!defined('UPDRAFTPLUS_NOADS')) { ?><a href="http://updraftplus.com/shop/"><?php _e("Premium",'updraftplus');?></a> | <?php } ?><a href="http://david.dw-perspective.org.uk"><?php _e("Lead developer's homepage",'updraftplus');?></a> | <?php if (1==0 && !defined('UPDRAFTPLUS_NOADS')) { ?><a href="http://wordshell.net">WordShell - WordPress command line</a> | <a href="http://david.dw-perspective.org.uk/donate"><?php _e('Donate','updraftplus');?></a> | <?php } ?><a href="http://updraftplus.com/support/frequently-asked-questions/">FAQs</a> | <a href="http://profiles.wordpress.org/davidanderson/"><?php _e('Other WordPress plugins','updraftplus');?></a>). <?php _e('Version','updraftplus');?>: <?php echo $updraftplus->version; ?>
771
  <br>
772
  <?php
773
  if(isset($_GET['updraft_restore_success'])) {
 
 
774
  echo "<div class=\"updated fade\" style=\"padding:8px;\"><strong>".__('Your backup has been restored.','updraftplus').'</strong> '.__('Your old (themes, uploads, plugins, whatever) directories have been retained with "-old" appended to their name. Remove them when you are satisfied that the backup worked properly.')."</div>";
775
  }
776
 
862
  <td id="updraft_last_backup"><?php echo $last_backup_html ?></td>
863
  </tr>
864
  </table>
865
+ <div style="float:left; width:200px; margin-top: <?php echo (class_exists('UpdraftPlus_Addons_Migrator')) ? "20" : "0" ?>px;">
866
+ <div style="margin-bottom: 10px;">
867
+ <button type="button" <?php echo $backup_disabled ?> class="button-primary" style="padding-top:2px;padding-bottom:2px;font-size:22px !important; min-height: 32px; min-width: 170px;" onclick="jQuery('#updraft-backupnow-modal').dialog('open');"><?php _e('Backup Now','updraftplus');?></button>
868
+ </div>
869
+ <div style="margin-bottom: 10px;">
870
+ <?php
871
  $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
872
  $backup_history = (is_array($backup_history))?$backup_history:array();
873
+ ?>
874
+ <input type="button" class="button-primary" value="<?php _e('Restore','updraftplus');?>" style="padding-top:2px;padding-bottom:2px;font-size:22px !important; min-height: 32px; min-width: 170px;" onclick="jQuery('.download-backups').slideDown(); updraft_historytimertoggle(1); jQuery('html,body').animate({scrollTop: jQuery('#updraft_lastlogcontainer').offset().top},'slow');">
875
+ </div>
876
+ <div>
877
+ <button type="button" class="button-primary" style="padding-top:2px;padding-bottom:2px;font-size:22px !important; min-height: 32px; min-width: 170px;" onclick="jQuery('#updraft-migrate-modal').dialog('open');"><?php _e('Clone/Migrate','updraftplus');?></button>
878
  </div>
879
  </div>
880
  <br style="clear:both" />
881
  <table class="form-table">
882
+ <tr id="updraft_lastlogmessagerow">
883
  <th><?php _e('Last log message','updraftplus');?>:</th>
884
  <td>
885
  <span id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', __('(Nothing yet logged)','updraftplus'))); ?></span><br>
888
  </tr>
889
  <tr>
890
  <th><?php echo htmlspecialchars(__('Backups, logs & restoring','updraftplus')); ?>:</th>
891
+ <td><a id="updraft_showbackups" href="#" title="<?php _e('Press to see available backups','updraftplus');?>" onclick="jQuery('.download-backups').fadeToggle(); updraft_historytimertoggle(0);"><?php echo sprintf(__('%d set(s) available', 'updraftplus'), count($backup_history)); ?></a></td>
892
+ </tr>
893
+ <?php
894
+ if (defined('UPDRAFTPLUS_EXPERIMENTAL_MISC') && UPDRAFTPLUS_EXPERIMENTAL_MISC == true) {
895
+ ?>
896
+ <tr>
897
+ <th><?php echo __('Latest UpdraftPlus.com news:', 'updraftplus'); ?></th>
898
+ <td>Blah blah blah. Move to right-hand col?</td>
899
  </tr>
900
+ <?php } ?>
901
+ </table>
902
+ <table class="form-table">
903
  <tr>
904
+ <td style="">&nbsp;</td><td class="download-backups" style="display:none; border: 2px dashed #aaa;">
905
+ <h2><?php echo __('Downloading and restoring', 'updraftplus'); ?></h2>
906
  <p style="max-width: 740px;"><ul style="list-style: disc inside;">
907
  <li><strong><?php _e('Downloading','updraftplus');?>:</strong> <?php _e("Pressing a button for Database/Plugins/Themes/Uploads/Others will make UpdraftPlus try to bring the backup file back from the remote storage (if any - e.g. Amazon S3, Dropbox, Google Drive, FTP) to your webserver. Then you will be allowed to download it to your computer. If the fetch from the remote storage stops progressing (wait 30 seconds to make sure), then press again to resume. Remember that you can also visit the cloud storage vendor's website directly.",'updraftplus');?></li>
908
  <li><strong><?php _e('Restoring','updraftplus');?>:</strong> <?php _e("Press the button for the backup you wish to restore. If your site is large and you are using remote storage, then you should first click on each entity in order to retrieve it back to the webserver. This will prevent time-outs from occuring during the restore process itself.",'updraftplus');?> <?php _e('More tasks:','updraftplus');?> <a href="#" onclick="jQuery('#updraft-plupload-modal').slideToggle(); return false;"><?php _e('upload backup files','updraftplus');?></a> | <a href="#" onclick="updraft_updatehistory(1); return false;" title="<?php _e('Press here to look inside your UpdraftPlus directory (in your web hosting space) for any new backup sets that you have uploaded. The location of this directory is set in the expert settings, below.','updraftplus'); ?>"><?php _e('rescan folder for new backup sets','updraftplus');?></a></li>
913
  <li title="<?php _e('This is a count of the contents of your Updraft directory','updraftplus');?>"><strong><?php _e('Web-server disk space in use by UpdraftPlus','updraftplus');?>:</strong> <span id="updraft_diskspaceused"><em>(calculating...)</em></span> <a href="#" onclick="updraftplus_diskspace(); return false;"><?php _e('refresh','updraftplus');?></a></li></ul>
914
 
915
  <div id="updraft-plupload-modal" title="<?php _e('UpdraftPlus - Upload backup files','updraftplus'); ?>" style="width: 75%; margin: 16px; display:none; margin-left: 100px;">
916
+ <p style="max-width: 600px;"><em><?php _e("Upload files into UpdraftPlus. Use this to import backups made on a different WordPress installation." ,'updraftplus');?> <?php echo htmlspecialchars(__('Or, you can place them manually into your UpdraftPlus directory (usually wp-content/updraft), e.g. via FTP, and then use the "rescan" link above.', 'updraftplus'));?></em></p>
917
  <div id="plupload-upload-ui" style="width: 70%;">
918
  <div id="drag-drop-area">
919
  <div class="drag-drop-inside">
932
  <script>
933
  function updraftplus_diskspace() {
934
  jQuery('#updraft_diskspaceused').html('<em><?php _e('calculating...','updraftplus');?></em>');
935
+ jQuery.get(ajaxurl, { action: 'updraft_ajax', entity: 'updraft', subaction: 'diskspaceused', nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>' }, function(response) {
936
  jQuery('#updraft_diskspaceused').html(response);
937
  });
938
  }
960
  // Create somewhere for the status to be found
961
  var stid = base+nonce+'_'+what;
962
  if (!jQuery('#'+stid).length) {
963
+ jQuery('#ud_downloadstatus').append('<div style="clear:left; border: 1px solid; padding: 8px; margin-top: 4px; max-width:840px;" id="'+stid+'"><button onclick="jQuery(\'#'+stid+'\').fadeOut().remove();" type="button" style="float:right; margin-bottom: 8px;">X</button><strong>Download '+what+' ('+nonce+')</strong>:<div class="raw"><?php _e('Begun looking for this entity','updraftplus');?></div><div class="file" id="'+stid+'_st"><div class="dlfileprogress" style="width: 0;"></div></div>');
964
  // <b><span class="dlname">??</span></b> (<span class="dlsofar">?? KB</span>/<span class="dlsize">??</span> KB)
965
+ setTimeout(function(){updraft_downloader_status(base, nonce, what);}, 300);
966
  }
967
  // Now send the actual request to kick it all off
968
  jQuery.post(ajaxurl, jQuery('#uddownloadform_'+what+'_'+nonce).serialize());
1009
  alert('<?php _e('Download error: the server sent us a response (JSON) which we did not understand', 'updraftplus'); ?> ('+response+')');
1010
  cancel_repeat = 1;
1011
  }
1012
+ if (cancel_repeat == 0) { setTimeout(function(){updraft_downloader_status(base, nonce, what);}, nexttimer); }
1013
  } catch(err) {
1014
  alert('<?php _e('Download error: the server sent us a response which we did not understand.', 'updraftplus'); ?> <?php _e("Error:",'updraftplus');?> '+err);
1015
  }
1026
  </tr>
1027
  </table>
1028
 
1029
+ <div id="updraft-delete-modal" title="<?php _e('Delete backup set', 'updraftplus');?>">
1030
+ <form id="updraft_delete_form" method="post">
1031
+ <p>
1032
+ <?php _e('Are you sure that you wish to delete this backup set?', 'updraftplus'); ?>
1033
+ </p>
1034
+ <fieldset>
1035
+ <input type="hidden" name="action" value="updraft_delete">
1036
+ <input type="hidden" name="backup_timestamp" value="0" id="updraft_delete_timestamp">
1037
+ <input type="hidden" name="backup_nonce" value="0" id="updraft_delete_nonce">
1038
+ <input type="checkbox" name="" id=""> <label for=""><?php _e('Delete from remote storage (if any)', 'updraftplus');?></label><br>
1039
+ <input type="checkbox" name="" id=""> <label for=""><?php _e('Delete from UpdraftPlus\'s memory', 'updraftplus');?></label>
1040
+ </fieldset>
1041
+ </form>
1042
+ </div>
1043
+
1044
  <div id="updraft-restore-modal" title="UpdraftPlus - <?php _e('Restore backup','updraftplus');?>">
1045
  <p><strong><?php _e('Restore backup from','updraftplus');?>:</strong> <span id="updraft_restore_date"></span></p>
1046
  <p><?php _e("Restoring will replace this site's themes, plugins, uploads, database and/or other content directories (according to what is contained in the backup set, and your selection).",'updraftplus');?> <?php _e('Choose the components to restore','updraftplus');?>:</p>
1104
  <p><em><a href="http://updraftplus.com/faqs/what-should-i-understand-before-undertaking-a-restoration/" target="_new"><?php _e('Do read this helpful article of useful things to know before restoring.','updraftplus');?></a></em></p>
1105
  </div>
1106
 
1107
+ <div id="updraft-migrate-modal" title="<?php _e('Migrate Site', 'updraftplus'); ?>">
 
1108
 
1109
+ <?php
1110
+ if (class_exists('UpdraftPlus_Addons_Migrator')) {
1111
+ echo '<p>'.str_replace('"', "&quot;", __('Migration of data from another site happens through the "Restore" button. A "migration" is ultimately the same as a restoration - but using backup archives that you import from another site. UpdraftPlus modifies the restoration operation appropriately, to fit the backup data to the new site.', 'updraftplus')).' '.sprintf(__('<a href="%s">Read this article to see step-by-step how it\'s done.</a>', 'updraftplus'),'http://updraftplus.com/faqs/how-do-i-migrate-to-a-new-site-location/');
1112
+ } else {
1113
+ echo '<p>'.__('Do you want to migrate or clone/duplicate a site?', 'updraftplus').'</p><p>'.__('Then, try out our "Migrator" add-on. After using it once, you\'ll have saved the purchase price compared to the time needed to copy a site by hand.', 'updraftplus').'</p><p><a href="http://updraftplus.com/shop/migrator/">'.__('Get it here.', 'updraftplus').'</a>';
1114
+ }
1115
+ ?>
1116
+ </p>
1117
+ </div>
1118
+
1119
+ <div id="updraft-iframe-modal">
1120
+ <div id="updraft-iframe-modal-innards">
1121
+ </div>
1122
+ </div>
1123
+
1124
+ <div id="updraft-backupnow-modal" title="UpdraftPlus - <?php _e('Perform a one-time backup','updraftplus'); ?>">
1125
+ <p><?php _e("To proceed, press 'Backup Now'. Then, watch the 'Last Log Message' field for activity after about 10 seconds. WordPress should start the backup running in the background.",'updraftplus');?></p>
1126
 
1127
  <p><?php _e('Does nothing happen when you schedule backups?','updraftplus');?> <a href="http://updraftplus.com/faqs/my-scheduled-backups-and-pressing-backup-now-does-nothing-however-pressing-debug-backup-does-produce-a-backup/"><?php _e('Go here for help.','updraft');?></a></p>
1128
  </div>
1139
  </tr>
1140
  </table>
1141
  <?php } ?>
1142
+ <h2 style="margin-top: 6px;"><?php _e('Configure Backup Contents And Schedule','updraftplus');?></h2>
1143
  <?php UpdraftPlus_Options::options_form_begin(); ?>
1144
  <?php $this->settings_formcontents($last_backup_html); ?>
1145
  </form>
1146
  <div style="padding-top: 40px; display:none;" class="expertmode">
1147
  <hr>
1148
+ <h2><?php _e('Debug Information And Expert Options','updraftplus');?></h2>
1149
  <p>
1150
  <?php
1151
+ echo sprintf(__('Web server:','updraftplus'), 'PHP').' '.htmlspecialchars($_SERVER["SERVER_SOFTWARE"]).' ('.htmlspecialchars(php_uname()).')<br />';
1152
  $peak_memory_usage = memory_get_peak_usage(true)/1024/1024;
1153
  $memory_usage = memory_get_usage(true)/1024/1024;
1154
  echo __('Peak memory usage','updraftplus').': '.$peak_memory_usage.' MB<br/>';
1155
  echo __('Current memory usage','updraftplus').': '.$memory_usage.' MB<br/>';
1156
  echo __('PHP memory limit','updraftplus').': '.ini_get('memory_limit').' <br/>';
1157
+ echo sprintf(__('%s version:','updraftplus'), 'PHP').' '.phpversion().' - ';
1158
+ echo '<a href="admin-ajax.php?page=updraftplus&action=updraft_ajax&subaction=phpinfo&nonce='.wp_create_nonce('updraftplus-credentialtest-nonce').'" id="updraftplus-phpinfo">'.__('show PHP information (phpinfo)', 'updraftplus').'</a><br/>';
1159
+
1160
+ if (version_compare(phpversion(), '5.2.0', '>=') && extension_loaded('zip')) {
1161
+ $ziparchive_exists .= __('Yes', 'updraftplus');
1162
+ } else {
1163
+ $ziparchive_exists .= (method_exists('ZipArchive', 'addFile')) ? __('Yes', 'updraftplus') : __('No', 'updraftplus');
1164
+ }
1165
+
1166
+ echo __('PHP has support for ZipArchive::addFile:', 'updraftplus').' '.$ziparchive_exists.'<br>';
1167
+
1168
+ $binzip = $updraftplus->find_working_bin_zip(false);
1169
+
1170
+ echo __('zip executable found:', 'updraftplus').' '.((is_string($binzip)) ? __('Yes').': '.$binzip : __('No')).'<br>';
1171
+
1172
+ echo '<h3>'.__('Total (uncompressed) on-disk data:','updraftplus').'</h3>';
1173
+ echo '<p style="clear: left; max-width: 600px;"><em>'.__('N.B. This count is based upon what was, or was not, excluded the last time you saved the options.', 'updraftplus').'</em></p>';
1174
+
1175
+ foreach ($backupable_entities as $key => $info) {
1176
+
1177
+ $sdescrip = preg_replace('/ \(.*\)$/', '', $info['description']);
1178
+ if (strlen($sdescrip) > 20 && isset($info['shortdescription'])) $sdescrip = $info['shortdescription'];
1179
+
1180
+ echo '<div style="clear: left;float:left; width:150px;">'.ucfirst($sdescrip).':</strong></div><div style="float:left;"><span id="updraft_diskspaceused_'.$key.'"><em></em></span> <a href="#" onclick="updraftplus_diskspace_entity(\''.$key.'\'); return false;">'.__('count','updraftplus').'</a></div>';
1181
+ }
1182
+
1183
  ?>
1184
+
1185
  </p>
1186
+ <p style="clear: left; padding-top: 20px; max-width: 600px; margin:0;"><?php _e('The buttons below will immediately execute a backup run, independently of WordPress\'s scheduler. If these work whilst your scheduled backups and the "Backup Now" button do absolutely nothing (i.e. not even produce a log file), then it means that your scheduler is broken. You should then disable all your other plugins, and try the "Backup Now" button. If that fails, then contact your web hosting company and ask them if they have disabled wp-cron. If it succeeds, then re-activate your other plugins one-by-one, and find the one that is the problem and report a bug to them.','updraftplus');?></p>
1187
 
1188
+ <table border="0" style="border: none;">
1189
+ <tbody>
1190
+ <tr>
1191
+ <td>
1192
  <form method="post">
1193
  <input type="hidden" name="action" value="updraft_backup_debug_all" />
1194
  <p><input type="submit" class="button-primary" <?php echo $backup_disabled ?> value="<?php _e('Debug Full Backup','updraftplus');?>" onclick="return(confirm('<?php echo htmlspecialchars(__('This will cause an immediate backup. The page will stall loading until it finishes (ie, unscheduled).','updraftplus'));?>'))" /></p>
1195
  </form>
1196
+ </td><td>
1197
  <form method="post">
1198
  <input type="hidden" name="action" value="updraft_backup_debug_db" />
1199
  <p><input type="submit" class="button-primary" <?php echo $backup_disabled ?> value="<?php _e('Debug Database Backup','updraftplus');?>" onclick="return(confirm('<?php echo htmlspecialchars(__('This will cause an immediate DB backup. The page will stall loading until it finishes (ie, unscheduled). The backup may well run out of time; really this button is only helpful for checking that the backup is able to get through the initial stages, or for small WordPress sites..','updraftplus'));?>'))" /></p>
1200
  </form>
1201
+ </td>
1202
+ </tr>
1203
+ </tbody>
1204
+ </table>
1205
  <h3><?php _e('Wipe Settings','updraftplus');?></h3>
1206
  <p style="max-width: 600px;"><?php _e('This button will delete all UpdraftPlus settings (but not any of your existing backups from your cloud storage). You will then need to enter all your settings again. You can also do this before deactivating/deinstalling UpdraftPlus if you wish.','updraftplus');?></p>
1207
  <form method="post">
1208
  <input type="hidden" name="action" value="updraft_wipesettings" />
1209
  <p><input type="submit" class="button-primary" value="<?php _e('Wipe All Settings','updraftplus'); ?>" onclick="return(confirm('<?php echo htmlspecialchars(__('This will delete all your UpdraftPlus settings - are you sure you want to do this?'));?>'))" /></p>
1210
  </form>
1211
+ <h3><?php _e('Active jobs', 'updraftplus');?></h3>
1212
+ <div id="updraft_activejobs">
1213
+ <?php $this->print_active_jobs(); ?>
1214
+ </div>
1215
  </div>
1216
 
1217
  <script type="text/javascript">
1218
  /* <![CDATA[ */
1219
+
1220
+ function updraft_activejobs_delete(jobid) {
1221
+ jQuery.get(ajaxurl, { action: 'updraft_ajax', subaction: 'activejobs_delete', jobid: jobid, nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>' }, function(response) {
1222
+ if (response.substr(0,2) == 'Y:') {
1223
+ jQuery('#updraft-jobid-'+jobid).html(response.substr(2)).fadeOut('slow', function() {
1224
+ jQuery(this).remove();
1225
+ });
1226
+ } else if (response.substr(0,2) == 'X:') {
1227
+ alert(response.substr(2));
1228
+ } else {
1229
+ alert('<?php _e('Unknown response:', 'updraftplus'); ?> '+response);
1230
+ }
1231
+ });
1232
+ }
1233
+
1234
+ function updraft_activejobs_update() {
1235
+ jQuery.get(ajaxurl, { action: 'updraft_ajax', subaction: 'activejobs_list', nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>' }, function(response) {
1236
+ jQuery('#updraft_activejobs').html(response);
1237
+ });
1238
+ }
1239
+
1240
+ function updraftplus_diskspace_entity(key) {
1241
+ jQuery('#updraft_diskspaceused_'+key).html('<em><?php _e('calculating...','updraftplus');?></em>');
1242
+ jQuery.get(ajaxurl, { action: 'updraft_ajax', subaction: 'diskspaceused', entity: key, nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>' }, function(response) {
1243
+ jQuery('#updraft_diskspaceused_'+key).html(response);
1244
+ });
1245
+ }
1246
+
1247
+ function updraft_iframe_modal(getwhat, title) {
1248
+ jQuery('#updraft-iframe-modal-innards').html('<iframe width="100%" height="440px" src="'+ajaxurl+'?action=updraft_ajax&subaction='+getwhat+'&nonce=<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>"></iframe>');
1249
+ jQuery('#updraft-iframe-modal').dialog('option', 'title', title).dialog('open');
1250
+ }
1251
+
1252
  jQuery(document).ready(function() {
1253
+
1254
  jQuery('#updraft-service').change(function() {
1255
  jQuery('.updraftplusmethod').hide();
1256
  var active_class = jQuery(this).val();
1257
  jQuery('.'+active_class).show();
1258
  });
1259
+
1260
+ jQuery('#updraftplus-phpinfo').click(function(e) {
1261
+ e.preventDefault();
1262
+ updraft_iframe_modal('phpinfo', '<?php _e('PHP information', 'updraftplus'); ?>');
1263
+ });
1264
+
1265
  })
1266
  jQuery(window).load(function() {
1267
  //this is for hiding the restore progress at the top after it is done
1268
+ setTimeout('jQuery("#updraft-restore-progress").toggle(1000);',3000)
1269
  jQuery('#updraft-restore-progress-toggle').click(function() {
1270
  jQuery('#updraft-restore-progress').toggle(500)
1271
  })
1275
  <?php
1276
  }
1277
 
1278
+ function print_active_jobs() {
1279
+ $cron = get_option('cron');
1280
+ $found_jobs = 0;
1281
+ foreach ($cron as $time => $job) {
1282
+ if (isset($job['updraft_backup_resume'])) {
1283
+ foreach ($job['updraft_backup_resume'] as $hook => $info) {
1284
+ if (isset($info['args'][1])) {
1285
+ $found_jobs++;
1286
+ $job_id = $info['args'][1];
1287
+ $jobdata = get_transient("updraft_jobdata_".$job_id);
1288
+ if (!is_array($jobdata)) $jobdata = array();
1289
+ $began_at = (isset($jobdata['backup_time'])) ? get_date_from_gmt(gmdate('Y-m-d H:i:s', $jobdata['backup_time']), 'D, F j, Y H:i') : '?';
1290
+ echo '<div style="clear:left; float:left;" id="updraft-jobid-'.$job_id.'">'.sprintf(__("%s: began at: %s; next resumption: %d (after %ss)", 'updraftplus'), $job_id, $began_at, $info['args'][0], $time-time()).' - <a href="?page=updraftplus&action=downloadlog&updraftplus_backup_nonce='.$job_id.'">'.__('show log', 'updraftplus').'</a> - <a href="javascript:updraft_activejobs_delete(\''.$job_id.'\')">'.__('delete schedule', 'updraftplus').'</a></div>';;
1291
+ // echo str_replace("\n", "<br>", print_r($job, true));
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+ if (0 == $found_jobs) {
1297
+ echo '<p><em>'.__('(None)', 'updraftplus').'</em></p>';
1298
+ }
1299
+ }
1300
+
1301
  //deletes the -old directories that are created when a backup is restored.
1302
  function delete_old_dirs() {
1303
  global $wp_filesystem;
1330
  return $return_code;
1331
  }
1332
 
1333
+ // The aim is to get a directory that is writable by the webserver, because that's the only way we can create zip files
1334
  function create_backup_dir() {
1335
+
1336
  global $wp_filesystem, $updraftplus;
1337
+
1338
+ if (false === ($credentials = request_filesystem_credentials('options-general.php?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir')))) {
1339
+ return false;
1340
+ }
1341
+
1342
+ if ( ! WP_Filesystem($credentials) ) {
1343
+ // our credentials were no good, ask the user for them again
1344
+ request_filesystem_credentials('options-general.php?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir'), '', true);
1345
+ return false;
1346
  }
1347
 
1348
  $updraft_dir = $updraftplus->backups_dir_location();
1349
 
1350
+ $default_backup_dir = $wp_filesystem->find_folder(dirname($updraft_dir)).basename($updraft_dir);
 
1351
 
1352
+ $updraft_dir = ($updraft_dir) ? $wp_filesystem->find_folder(dirname($updraft_dir)).basename($updraft_dir) : $default_backup_dir;
1353
+
1354
+ if (!$wp_filesystem->is_dir($default_backup_dir) && !$wp_filesystem->mkdir($default_backup_dir, 0775)) {
1355
+ $wperr = new WP_Error;
1356
+ if ( $wp_filesystem->errors->get_error_code() ) {
1357
+ foreach ( $wp_filesystem->errors->get_error_messages() as $message ) {
1358
+ $wperr->add('mkdir_error', $message);
1359
+ }
1360
+ return $wperr;
1361
+ } else {
1362
+ return new WP_Error('mkdir_error', __('The request to the filesystem to create the directory failed.', 'updraftplus'));
1363
+ }
1364
+ }
1365
+
1366
+ if ($wp_filesystem->is_dir($default_backup_dir)) {
1367
+
1368
+ if (is_writable($updraft_dir)) return true;
1369
+
1370
+ @$wp_filesystem->chmod($default_backup_dir, 0775);
1371
+ if (is_writable($updraft_dir)) return true;
1372
+
1373
+ @$wp_filesystem->chmod($default_backup_dir, 0777);
1374
+
1375
+ if (is_writable($updraft_dir)) {
1376
+ echo '<p>'.__('The folder was created, but we had to change its file permissions to 777 (world-writable) to be able to write to it. You should check with your hosting provider that this will not cause any problems', 'updraftplus').'</p>';
1377
+ return true;
1378
+ } else {
1379
+ @$wp_filesystem->chmod($default_backup_dir, 0775);
1380
+ return new WP_Error('writable_error', __('The folder exists, but your webserver does not have permission to write to it.', 'updraftplus').' '.__('You will need to consult with your web hosting provider to find out to set permissions for a WordPress plugin to write to the directory.', 'updraftplus'));
1381
+ }
1382
+ }
1383
 
1384
  return true;
1385
  }
1393
  function scan_old_dirs() {
1394
  $dirArr = scandir(WP_CONTENT_DIR);
1395
  foreach($dirArr as $dir) {
1396
+ if (preg_match('/-old$/', $dir)) return true;
1397
  }
1398
  return false;
1399
  }
1531
  </tr>
1532
  <tr>
1533
  <th><?php _e('Email','updraftplus'); ?>:</th>
1534
+ <td><input type="text" title="<?php _e('To send to more than one address, separate each address with a comma.', 'updraftplus'); ?>" style="width:260px" name="updraft_email" value="<?php echo UpdraftPlus_Options::get_updraft_option('updraft_email'); ?>" /> <br><?php _e('Enter an address here to have a report sent (and the whole backup, if you choose) to it.','updraftplus'); ?></td>
1535
  </tr>
1536
 
1537
  <tr>
1609
  subaction: 'lastlog',
1610
  nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
1611
  };
1612
+ function updraft_showlastlog(repeat){
1613
  jQuery.get(ajaxurl, lastlog_sdata, function(response) {
1614
  nexttimer = 1500;
1615
  if (lastlog_lastmessage == response) { nexttimer = 4500; }
1616
+ if (repeat) { setTimeout(function(){updraft_showlastlog(true);}, nexttimer);}
1617
  jQuery('#updraft_lastlogcontainer').html(response);
1618
  lastlog_lastmessage = response;
1619
  });
1623
  subaction: 'lastbackup',
1624
  nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>'
1625
  };
1626
+ var lastbackup_laststatus = '<?php echo esc_html($last_backup_html);?>';
1627
  function updraft_showlastbackup(){
1628
  jQuery.get(ajaxurl, lastbackup_sdata, function(response) {
1629
  if (lastbackup_laststatus == response) {
1630
+ setTimeout(function(){updraft_showlastbackup();}, 7000);
1631
  } else {
1632
  jQuery('#updraft_last_backup').html(response);
1633
  }
1651
  }
1652
  function updraft_updatehistory(rescan) {
1653
  if (rescan == 1) {
1654
+ jQuery('#updraft_existing_backups').html('<p style="text-align:center;"><em><?php _e('Rescanning (looking for backups that you have uploaded manually into the internal backup store)...', 'updraftplus'); ?></em></p>');
1655
  }
1656
  jQuery.get(ajaxurl, { action: 'updraft_ajax', subaction: 'historystatus', nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>', rescan: rescan }, function(response) {
1657
  jQuery('#updraft_existing_backups').html(response);
1670
 
1671
  updraft_check_same_times();
1672
 
1673
+ jQuery( "#updraft-delete-modal" ).dialog({
1674
+ autoOpen: false, height: 260, width: 430, modal: true,
1675
+ buttons: {
1676
+ '<?php _e('Delete','updraftplus');?>': function() {
1677
+ alert("TODO");
1678
+ },
1679
+ '<?php _e('Cancel','updraftplus');?>': function() { jQuery(this).dialog("close"); }
1680
+ }
1681
+ });
1682
+
1683
  jQuery( "#updraft-restore-modal" ).dialog({
1684
  autoOpen: false, height: 505, width: 590, modal: true,
1685
  buttons: {
1701
  }
1702
  });
1703
 
1704
+ jQuery("#updraft-iframe-modal" ).dialog({
1705
+ autoOpen: false, height: 500, width: 780, modal: true
1706
+ });
1707
+
1708
+
1709
+ jQuery("#updraft-backupnow-modal" ).dialog({
1710
+ autoOpen: false, height: 265, width: 390, modal: true,
1711
  buttons: {
1712
  '<?php _e('Backup Now','updraftplus');?>': function() {
1713
+ jQuery(this).dialog("close");
1714
+ jQuery('#updraft_backup_started').html('<em><?php _e('Requesting start of backup...', 'updraftplus');?></em>').slideDown('');
1715
+ jQuery.post(ajaxurl, { action: 'updraft_ajax', subaction: 'backupnow', nonce: '<?php echo wp_create_nonce('updraftplus-credentialtest-nonce'); ?>' }, function(response) {
1716
+ jQuery('#updraft_backup_started').html(response);
1717
+ setTimeout(function() {jQuery.get('<?php echo site_url(); ?>');}, 5100);
1718
+ setTimeout(function() {updraft_showlastlog();}, 6000);
1719
+ setTimeout(function() {updraft_activejobs_update();}, 6000);
1720
+ setTimeout(function() {
1721
+ jQuery('#updraft_lastlogmessagerow').fadeOut('slow', function() {
1722
+ jQuery(this).fadeIn('slow');
1723
+ });
1724
+ },
1725
+ 3200
1726
+ );
1727
+ setTimeout(function() {jQuery('#updraft_backup_started').fadeOut('slow');}, 60000);
1728
+ // Should be redundant (because of the polling for the last log line), but harmless (invokes page load)
1729
+ });
1730
  },
1731
  '<?php _e('Cancel','updraftplus');?>': function() { jQuery(this).dialog("close"); }
1732
  }
1733
  });
1734
 
1735
+ jQuery( "#updraft-migrate-modal" ).dialog({
1736
+ autoOpen: false, height: 265, width: 390, modal: true,
1737
+ buttons: {
1738
+ '<?php _e('Close','updraftplus');?>': function() { jQuery(this).dialog("close"); }
1739
+ }
1740
+ });
1741
+
1742
  jQuery('#enableexpertmode').click(function() {
1743
  jQuery('.expertmode').fadeIn();
1744
+ updraft_activejobs_update();
1745
+ setInterval(function() {updraft_activejobs_update()}, 15000);
1746
+ jQuery('#enableexpertmode').off('click');
1747
  return false;
1748
  });
1749
  <?php if (!@is_writable($updraft_dir)) echo "jQuery('.backupdirrow').show();\n"; ?>
1750
+ setTimeout(function(){updraft_showlastlog(true);}, 1200);
1751
  jQuery('.updraftplusmethod').hide();
1752
  <?php
1753
  if ($active_service) echo "jQuery('.${active_service}').show();";
1770
  </tr>
1771
  <tr>
1772
  <th><?php _e('Expert settings','updraftplus');?>:</th>
1773
+ <td><a id="enableexpertmode" href="#enableexpertmode"><?php _e('Show expert settings','updraftplus');?></a> - <?php _e("click this to show some further options; don't bother with this unless you have a problem or are curious.",'updraftplus');?> <?php do_action('updraftplus_expertsettingsdescription'); ?></td>
1774
  </tr>
1775
  <?php
1776
  $delete_local = UpdraftPlus_Options::get_updraft_option('updraft_delete_local', 1);
1793
  if(@is_writable($updraft_dir)) {
1794
  $dir_info = '<span style="color:green">'.__('Backup directory specified is writable, which is good.','updraftplus').'</span>';
1795
  } else {
1796
+ $dir_info = '<span style="color:red">'.__('Backup directory specified is <b>not</b> writable, or does not exist.','updraftplus').' <span style="font-size:110%;font-weight:bold"><a href="options-general.php?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir').'">'.__('Click here to attempt to create the directory and set the permissions','updraftplus').'</a></span>, '.__('or, to reset this option','updraftplus').' <a href="#" onclick="jQuery(\'#updraft_dir\').val(\''.WP_CONTENT_DIR.'/updraft\'); return false;">'.__('click here','updraftplus').'</a>. '.__('If that is unsuccessful check the permissions on your server or change it to another directory that is writable by your web server process.','updraftplus').'</span>';
1797
  }
1798
 
1799
  echo $dir_info.' '.__("This is where UpdraftPlus will write the zip files it creates initially. This directory must be writable by your web server. Typically you'll want to have it inside your wp-content folder (this is the default). <b>Do not</b> place it inside your uploads dir, as that will cause recursion issues (backups of backups of backups of...).",'updraftplus');?></td>
1842
  <?php
1843
  }
1844
 
1845
+ function show_double_warning($text, $extraclass = '') {
1846
+
1847
+ ?><div class="error updraftplusmethod <?php echo $extraclass; ?>"><p><?php echo $text; ?></p></div>
1848
+
1849
+ <p><?php echo $text; ?></p>
1850
+
1851
+ <?php
1852
+
1853
+ }
1854
+
1855
+ function curl_check($service, $has_fallback = false, $extraclass = '') {
1856
  // Check requirements
1857
  if (!function_exists("curl_init")) {
1858
+
1859
+ $this->show_double_warning('<strong>'.__('Warning','updraftplus').':</strong> '.sprintf(__('Your web server\'s PHP installation does not included a <strong>required</strong> (for %s) module (%s). Please contact your web hosting provider\'s support and ask for them to enable it.', 'updraftplus'), $service, 'Curl').' '.sprintf(__("Your options are 1) Install/enable %s or 2) Change web hosting companies - %s is a standard PHP component, and required by all cloud backup plugins that we know of.",'updraftplus'), 'Curl', 'Curl'), $extraclass);
1860
+
1861
  } else {
1862
  $curl_version = curl_version();
1863
  $curl_ssl_supported= ($curl_version['features'] & CURL_VERSION_SSL);
1865
  if ($has_fallback) {
1866
  ?><p><strong><?php _e('Warning','updraftplus'); ?>:</strong> <?php echo sprintf(__("Your web server's PHP/Curl installation does not support https access. Communications with %s will be unencrypted. ask your web host to install Curl/SSL in order to gain the ability for encryption (via an add-on).",'updraftplus'),$service);?></p><?php
1867
  } else {
1868
+ $this->show_double_warning('<p><strong>'.__('Warning','updraftplus').':</strong> '.sprintf(__("Your web server's PHP/Curl installation does not support https access. We cannot access %s without this support. Please contact your web hosting provider's support. %s <strong>requires</strong> Curl+https. Please do not file any support requests; there is no alternative.",'updraftplus'),$service).'</p>', $extraclass);
1869
  }
1870
  } else {
1871
  ?><p><em><?php echo sprintf(__("Good news: Your site's communications with %s can be encrypted. If you see any errors to do with encryption, then look in the 'Expert Settings' for more help.", 'updraftplus'),$service);?></em></p><?php
1873
  }
1874
  }
1875
 
1876
+ function recursive_directory_size($directories) {
1877
+
1878
+ if (is_string($directories)) $directories = array($directories);
1879
+
1880
+ $size = 0;
1881
+
1882
+ foreach ($directories as $dir) $size += $this->recursive_directory_size_raw($dir);
1883
+
1884
+ if ($size > 1073741824) {
1885
+ return round($size / 1073741824, 1).' Gb';
1886
+ } elseif ($size > 1048576) {
1887
+ return round($size / 1048576, 1).' Mb';
1888
+ } elseif ($size > 1024) {
1889
+ return round($size / 1024, 1).' Kb';
1890
+ } else {
1891
+ return round($size, 1).' b';
1892
+ }
1893
+
1894
+ }
1895
+
1896
+ function recursive_directory_size_raw($directory) {
1897
+
1898
  $size = 0;
1899
  if(substr($directory,-1) == '/') $directory = substr($directory,0,-1);
1900
 
1907
  if(is_file($path)) {
1908
  $size += filesize($path);
1909
  } elseif(is_dir($path)) {
1910
+ $handlesize = $this->recursive_directory_size_raw($path);
1911
+ if($handlesize >= 0) { $size += $handlesize; }# else { return -1; }
1912
  }
1913
  }
1914
  }
1915
  closedir($handle);
1916
  }
1917
+
1918
+ return $size;
1919
+
 
 
 
 
 
 
1920
  }
1921
 
1922
  function existing_backup_table($backup_history = false) {
1940
  $entities = '';
1941
  ?>
1942
  <tr>
1943
+ <td><a href="javascript:updraft_delete('<?php echo $key;?>', '<?php echo $value['nonce']; ?>');" class="updraftplus-remove" style="display: none;border-radius:100%; -moz-border-radius: 100%; -webkit-border-radius: 100%; font-size: 1.5em; width: 1em; height: 1em;text-align:center;text-decoration:none;font-weight:bold;line-height: 1;" title="<?php echo __('Delete this backup set', 'updraftplus');?>">×</a></td><td><b><?php echo $pretty_date?></b></td>
1944
  <td>
1945
  <?php if (isset($value['db'])) {
1946
  $entities .= '/db/';
1994
  </td>
1995
  </tr>
1996
  <script>
1997
+ function updraft_delete(key, nonce) {
1998
+ jQuery('#updraft_delete_timestamp').val(key);
1999
+ jQuery('#updraft_delete_nonce').val(nonce);
2000
+ jQuery('#updraft-delete-modal').dialog('open');
2001
+ }
2002
  function updraft_restore_setoptions(entities) {
2003
  var howmany = 0;
2004
  jQuery('input[name="updraft_restore[]"]').each(function(x,y){
2031
  $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
2032
  if (!is_array($backup_history)) $backup_history = array();
2033
 
2034
+ $updraft_dir = $updraftplus->backups_dir_location();
2035
+ if (!is_dir($updraft_dir)) return;
2036
+
2037
  // Accumulate a list of known files
2038
  foreach ($backup_history as $btime => $bdata) {
2039
+ $found_file = false;
2040
  foreach ($bdata as $key => $value) {
2041
  // Record which set this file is found in
2042
  if (preg_match('/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+\.(zip|gz|gz\.crypt)$/i', $value, $matches)) {
2043
  $nonce = $matches[2];
2044
+ // if (empty($bdata['service']) && !is_file($updraft_dir.'/'.$value)) {
2045
+ if (isset($bdata['service']) && $bdata['service'] == 'none' && !is_file($updraft_dir.'/'.$value)) {
2046
+ # File no longer present
2047
+ } else {
2048
+ $found_file = true;
2049
+ $known_files[$value] = $nonce;
2050
+ $known_nonces[$nonce] = $btime;
2051
+ }
2052
  }
2053
  }
2054
+ if (!$found_file) {
2055
+ unset($backup_history[$btime]);
2056
+ $changes = true;
2057
+ }
2058
  }
 
 
 
 
2059
 
2060
  if (!$handle = opendir($updraft_dir)) return;
2061
 
2070
  $type = $matches[3];
2071
  // The time from the filename does not include seconds. Need to identify the seconds to get the right time
2072
  if (isset($known_nonces[$nonce])) $btime = $known_nonces[$nonce];
2073
+ // No cloud backup known of this file
2074
+ if (!isset($backup_history[$btime])) $backup_history[$btime] = array( 'service' => 'none' );
2075
  $backup_history[$btime][$type] = $entry;
2076
  $backup_history[$btime][$type.'-size'] = filesize($updraft_dir.'/'.$entry);
2077
  $backup_history[$btime]['nonce'] = $nonce;
2086
 
2087
  }
2088
 
2089
+ // Return values: false = 'not yet' (not necessarily terminal); WP_Error = terminal failure; true = success
2090
  function restore_backup($timestamp) {
2091
 
2092
  @set_time_limit(900);
2095
  $backup_history = UpdraftPlus_Options::get_updraft_option('updraft_backup_history');
2096
  if(!is_array($backup_history[$timestamp])) {
2097
  echo '<p>'.__('This backup does not exist in the backup history - restoration aborted. Timestamp:','updraftplus')." $timestamp</p><br/>";
2098
+ return new WP_Error('does_not_exist', 'Backup does not exist in the backup history');
2099
  }
2100
 
2101
  // request_filesystem_credentials passes on fields just via hidden name/value pairs.
2147
  if (count($_POST['updraft_restore']) == 0) {
2148
  echo '<p>'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'</p>';
2149
  echo '<p>'.__('If making a request for support, please include this information:','updraftplus').' '.count($_POST).' : '.htmlspecialchars(serialize($_POST)).'</p>';
2150
+ return new WP_Error('missing_info', 'Backup information not found');
2151
  }
2152
 
2153
  /*
2157
 
2158
  $backupable_entities = $updraftplus->get_backupable_file_entities(true, true);
2159
 
2160
+ $backup_set = $backup_history[$timestamp];
2161
+ uksort($backup_set, array($this, 'sort_restoration_entities'));
2162
+
2163
+ // We use a single object for each entity, because we want to store information about the backup set
2164
+ if(!class_exists('WP_Upgrader')) require_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php');
2165
+ require_once(UPDRAFTPLUS_DIR.'/includes/updraft-restorer.php');
2166
+ $restorer = new Updraft_Restorer();
2167
+
2168
+ foreach($backup_set as $type => $file) {
2169
  // All restorable entities must be given explicitly, as we can store other arbitrary data in the history array
2170
 
2171
  if (!isset($backupable_entities[$type]) && 'db' != $type) continue;
2183
  continue;
2184
  }
2185
 
2186
+ if ($type == 'wpcore' && is_multisite() && 0 === $restorer->ud_backup_is_multisite) {
2187
+ echo "<p>$type: <strong>".__('Skipping restoration of WordPress core when importing a single site into a multisite installation. If you had anything necessary in your WordPress directory then you will need to re-add it manually from the zip file.', 'updraftplus')."</strong></p>";
2188
+ continue;
2189
+ }
2190
+
2191
  $fullpath = $updraft_dir.$file;
2192
 
2193
  echo "Looking for $type archive: file name: ".htmlspecialchars($file)."<br>";
2211
  # Types: uploads, themes, plugins, others, db
2212
  if(is_readable($fullpath)) {
2213
 
 
 
 
 
2214
  $info = (isset($backupable_entities[$type])) ? $backupable_entities[$type] : array();
2215
+
2216
  $val = $restorer->restore_backup($file, $type, $service, $info);
2217
 
2218
  if(is_wp_error($val)) {
2219
  foreach ($val->get_error_messages() as $msg) {
2220
  echo '<strong>'.__('Error message', 'updraftplus').':</strong> '.htmlspecialchars($msg).'<br>';
2221
  }
2222
+ echo '</div>'; //close the updraft_restore_progress div even if we error
2223
+ return $val;
2224
+ } elseif (false === $val) {
2225
  echo '</div>'; //close the updraft_restore_progress div even if we error
2226
  return false;
2227
  }
2234
  return true;
2235
  }
2236
 
2237
+ function sort_restoration_entities($a, $b) {
2238
+ if ($a == $b) return 0;
2239
+ # Put the database first
2240
+ if ($a == 'db') return -1;
2241
+ if ($b == 'db') return 1;
2242
+ return strcmp($a, $b);
2243
+ }
2244
 
2245
  }
2246
 
backup.php CHANGED
@@ -19,6 +19,8 @@ class UpdraftPlus_Backup {
19
 
20
  var $zip_preferpcl = false;
21
 
 
 
22
  // This function recursively packs the zip, dereferencing symlinks but packing into a single-parent tree for universal unpacking
23
  function makezip_recursive_add($zipfile, $fullpath, $use_path_when_storing, $original_fullpath) {
24
 
@@ -109,15 +111,87 @@ class UpdraftPlus_Backup {
109
  if ($this->zip_preferpcl || (!extension_loaded('zip') && !method_exists('ZipArchive', 'AddFile'))) {
110
  if(!class_exists('PclZip')) require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php');
111
  $zip_object = new PclZip($destination);
 
112
  $zipcode = $zip_object->create($source, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
113
  if ($zipcode == 0 ) {
114
- $updraftplus->log("PclZip Error: ".$zip_object->errorName());
115
  return $zip_object->errorCode();
116
  } else {
117
  return true;
118
  }
119
  }
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  $this->existing_files = array();
122
 
123
  // If the file exists, then we should grab its index of files inside, and sizes
@@ -125,12 +199,14 @@ class UpdraftPlus_Backup {
125
  if (file_exists($destination) && is_readable($destination)) {
126
  $zip = new ZipArchive;
127
  $zip->open($destination);
128
- $updraftplus->log(basename($destination).": Zip file already exists, with ".$zip->numFiles." files");
129
- for ($i=0; $i<$zip->numFiles; $i++) {
130
  $si = $zip->statIndex($i);
131
  $name = $si['name'];
132
  $this->existing_files[$name] = $si['size'];
133
  }
 
 
134
  } elseif (file_exists($destination)) {
135
  $updraftplus->log("Zip file already exists, but is not readable; will remove: $destination");
136
  @unlink($destination);
@@ -188,6 +264,9 @@ class UpdraftPlus_Backup {
188
 
189
  global $updraftplus;
190
 
 
 
 
191
  // Short-circuit the null case, because we want to detect later if something useful happenned
192
  if (count($this->zipfiles_dirbatched) == 0 && count($this->zipfiles_batched) == 0) return true;
193
 
@@ -195,7 +274,7 @@ class UpdraftPlus_Backup {
195
 
196
  $data_added_since_reopen = 0;
197
 
198
- $zip = new ZipArchive();
199
  if (file_exists($zipfile)) {
200
  $opencode = $zip->open($zipfile);
201
  $original_size = filesize($zipfile);
@@ -210,43 +289,187 @@ class UpdraftPlus_Backup {
210
  while ($dir = array_pop($this->zipfiles_dirbatched)) {
211
  $zip->addEmptyDir($dir);
212
  }
 
213
  foreach ($this->zipfiles_batched as $file => $add_as) {
214
  $fsize = filesize($file);
 
 
 
215
  if (!isset($this->existing_files[$add_as]) || $this->existing_files[$add_as] != $fsize) {
216
 
217
  @touch($zipfile);
218
  $zip->addFile($file, $add_as);
 
219
 
220
  $data_added_since_reopen += $fsize;
221
  # 25Mb - force a write-out and re-open
222
- if ($data_added_since_reopen > 26214400 || (time() - $this->zipfiles_lastwritetime) > 2) {
 
 
223
 
224
  $before_size = filesize($zipfile);
225
  clearstatcache();
226
 
227
- if ($data_added_since_reopen > 26214400) {
228
- $updraftplus->log("Adding batch to zip file: over 25Mb added on this batch (".round($data_added_since_reopen/1048576,1)." Mb); re-opening (prior size: ".round($before_size/1024,1).' Kb)');
 
 
 
 
229
  } else {
230
- $updraftplus->log("Adding batch to zip file: over 2 seconds have passed since the last write (".round($data_added_since_reopen/1048576,1)." Mb); re-opening (prior size: ".round($before_size/1024,1).' Kb)');
231
  }
232
  if (!$zip->close()) {
233
- $updraftplus->log("zip::Close returned an error");
234
  }
235
  unset($zip);
236
- $zip = new ZipArchive();
237
  $opencode = $zip->open($zipfile);
238
  if ($opencode !== true) return array($opencode, 0);
239
- $data_added_since_reopen = 0;
240
- $this->zipfiles_lastwritetime = time();
241
  // Call here, in case we've got so many big files that we don't complete the whole routine
242
- if (filesize($zipfile) > $before_size) $updraftplus->something_useful_happened();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  clearstatcache();
 
244
  }
245
  }
246
  $this->zipfiles_added++;
247
  // Don't call something_useful_happened() here - nothing necessarily happens until close() is called
248
  if ($this->zipfiles_added % 100 == 0) $updraftplus->log("Zip: ".basename($zipfile).": ".$this->zipfiles_added." files added (on-disk size: ".round(filesize($zipfile)/1024,1)." Kb)");
249
  }
 
250
  // Reset the array
251
  $this->zipfiles_batched = array();
252
  $ret = $zip->close();
@@ -264,6 +487,21 @@ class UpdraftPlus_Backup {
264
 
265
  if ($whichone != "others") $updraftplus->log("Beginning creation of dump of $whichone");
266
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
  $full_path = $create_in_dir.'/'.$backup_file_basename.'-'.$whichone.'.zip';
268
  $time_now = time();
269
 
@@ -305,10 +543,11 @@ class UpdraftPlus_Backup {
305
  $kbsize = filesize($full_path)/1024;
306
  $rate = round($kbsize/$timetaken, 1);
307
  $updraftplus->log("Created $whichone zip - file size is ".round($kbsize,1)." Kb in ".round($timetaken,1)." s ($rate Kb/s)");
 
 
308
  }
309
 
310
  return basename($full_path);
311
  }
312
 
313
-
314
- }
19
 
20
  var $zip_preferpcl = false;
21
 
22
+ var $binzip = false;
23
+
24
  // This function recursively packs the zip, dereferencing symlinks but packing into a single-parent tree for universal unpacking
25
  function makezip_recursive_add($zipfile, $fullpath, $use_path_when_storing, $original_fullpath) {
26
 
111
  if ($this->zip_preferpcl || (!extension_loaded('zip') && !method_exists('ZipArchive', 'AddFile'))) {
112
  if(!class_exists('PclZip')) require_once(ABSPATH.'/wp-admin/includes/class-pclzip.php');
113
  $zip_object = new PclZip($destination);
114
+ // TODO: WP_CONTENT_DIR: may not apply
115
  $zipcode = $zip_object->create($source, PCLZIP_OPT_REMOVE_PATH, WP_CONTENT_DIR);
116
  if ($zipcode == 0 ) {
117
+ $updraftplus->log("PclZip Error: ".$zip_object->errorInfo(true));
118
  return $zip_object->errorCode();
119
  } else {
120
  return true;
121
  }
122
  }
123
 
124
+ // TODO: Experimental: make live
125
+ if (defined('UPDRAFTPLUS_EXPERIMENTAL_BINZIP') && UPDRAFTPLUS_EXPERIMENTAL_BINZIP == true && $this->binzip === false) {
126
+ $updraftplus->log('Checking if we have a zip executable available');
127
+ $binzip = $updraftplus->find_working_bin_zip();
128
+ if (is_string($binzip)) {
129
+ $updraftplus->log("Found one: $binzip");
130
+ $this->binzip = $binzip;
131
+ }
132
+ }
133
+
134
+ // TODO: Handle stderr?
135
+ if (defined('UPDRAFTPLUS_EXPERIMENTAL_BINZIP') && UPDRAFTPLUS_EXPERIMENTAL_BINZIP == true && is_string($this->binzip)) {
136
+
137
+ if (is_string($source)) $source = array($source);
138
+
139
+ $all_ok = true;
140
+
141
+ $debug = UpdraftPlus_Options::get_updraft_option('updraft_debug_mode');
142
+
143
+ # Don't use -q, as we rely on output to process to detect useful activity
144
+ # Don't use -v either: the extra logging makes things much slower
145
+ $zip_params = ($debug) ? '-v' : '';
146
+
147
+ $orig_size = file_exists($destination) ? filesize($destination) : 0;
148
+ clearstatcache();
149
+
150
+ foreach ($source as $s) {
151
+
152
+ $exec = "cd ".escapeshellarg(dirname($s))."; /usr/bin/zip $zip_params -u -r ".escapeshellarg($destination)." ".escapeshellarg(basename($s))." ";
153
+
154
+ $updraftplus->log("Attempting binary zip ($exec)");
155
+
156
+ $handle = popen($exec, "r");
157
+
158
+ $something_useful_happened = $updraftplus->something_useful_happened;
159
+
160
+ if ($handle) {
161
+ while (!feof($handle)) {
162
+ $w = fgets($handle, 1024);
163
+ if ($w && $debug) $updraftplus->log("Output from zip: ".trim($w), false);
164
+ if (!$something_useful_happened && file_exists($destination)) {
165
+ $new_size = filesize($destination);
166
+ if ($new_size > $orig_size + 20) {
167
+ $updraftplus->something_useful_happened();
168
+ $something_useful_happened = true;
169
+ }
170
+ clearstatcache();
171
+ }
172
+ }
173
+ $ret = pclose($handle);
174
+ if ($ret != 0) {
175
+ $updraftplus->log("Binary zip: error (code: $ret)");
176
+ if ($w && !$debug) $updraftplus->log("Last output from zip: ".trim($w), false);
177
+ $all_ok = false;
178
+ }
179
+ } else {
180
+ $updraftplus->log("Error: popen failed");
181
+ $all_ok = false;
182
+ }
183
+
184
+ }
185
+
186
+ if ($all_ok) {
187
+ $updraftplus->log("Binary zip: apparently successful");
188
+ return true;
189
+ } else {
190
+ $updraftplus->log("Binary zip: an error occured, so we will run over again with ZipArchive");
191
+ }
192
+
193
+ }
194
+
195
  $this->existing_files = array();
196
 
197
  // If the file exists, then we should grab its index of files inside, and sizes
199
  if (file_exists($destination) && is_readable($destination)) {
200
  $zip = new ZipArchive;
201
  $zip->open($destination);
202
+
203
+ for ($i=0; $i < $zip->numFiles; $i++) {
204
  $si = $zip->statIndex($i);
205
  $name = $si['name'];
206
  $this->existing_files[$name] = $si['size'];
207
  }
208
+
209
+ $updraftplus->log(basename($destination).": Zip file already exists, with ".count($this->existing_files)." files");
210
  } elseif (file_exists($destination)) {
211
  $updraftplus->log("Zip file already exists, but is not readable; will remove: $destination");
212
  @unlink($destination);
264
 
265
  global $updraftplus;
266
 
267
+ $maxzipbatch = $updraftplus->jobdata_get('maxzipbatch', 26214400);
268
+ if ((int)$maxzipbatch < 1) $maxzipbatch = 26214400;
269
+
270
  // Short-circuit the null case, because we want to detect later if something useful happenned
271
  if (count($this->zipfiles_dirbatched) == 0 && count($this->zipfiles_batched) == 0) return true;
272
 
274
 
275
  $data_added_since_reopen = 0;
276
 
277
+ $zip = new ZipArchive;
278
  if (file_exists($zipfile)) {
279
  $opencode = $zip->open($zipfile);
280
  $original_size = filesize($zipfile);
289
  while ($dir = array_pop($this->zipfiles_dirbatched)) {
290
  $zip->addEmptyDir($dir);
291
  }
292
+
293
  foreach ($this->zipfiles_batched as $file => $add_as) {
294
  $fsize = filesize($file);
295
+
296
+ $sofar = 0;
297
+
298
  if (!isset($this->existing_files[$add_as]) || $this->existing_files[$add_as] != $fsize) {
299
 
300
  @touch($zipfile);
301
  $zip->addFile($file, $add_as);
302
+ $sofar++;
303
 
304
  $data_added_since_reopen += $fsize;
305
  # 25Mb - force a write-out and re-open
306
+ if ($data_added_since_reopen > $maxzipbatch || (time() - $this->zipfiles_lastwritetime) > 1.5) {
307
+
308
+ $something_useful_sizetest = false;
309
 
310
  $before_size = filesize($zipfile);
311
  clearstatcache();
312
 
313
+ if ($data_added_since_reopen > $maxzipbatch) {
314
+
315
+ $something_useful_sizetest = true;
316
+
317
+ $updraftplus->log("Adding batch to zip file: over ".round($maxzipbatch/1048576,1)." Mb added on this batch (".round($data_added_since_reopen/1048576,1)." Mb, ".count($this->zipfiles_batched)." files batched, $sofar added so far); re-opening (prior size: ".round($before_size/1024,1).' Kb)');
318
+
319
  } else {
320
+ $updraftplus->log("Adding batch to zip file: over 1.5 seconds have passed since the last write (".round($data_added_since_reopen/1048576,1)." Mb); re-opening (prior size: ".round($before_size/1024,1).' Kb)');
321
  }
322
  if (!$zip->close()) {
323
+ $updraftplus->log("ZipArchive::Close returned an error");
324
  }
325
  unset($zip);
326
+ $zip = new ZipArchive;
327
  $opencode = $zip->open($zipfile);
328
  if ($opencode !== true) return array($opencode, 0);
 
 
329
  // Call here, in case we've got so many big files that we don't complete the whole routine
330
+ if (filesize($zipfile) > $before_size) {
331
+
332
+ # Need to make sure that something_useful_happened() is always called
333
+
334
+ # How long since the current run began? If it's taken long (and we're in danger of not making it at all), or if that is forseeable in future because of general slowness, then we should reduce the parameters.
335
+ if (!$something_useful_sizetest) {
336
+ $updraftplus->something_useful_happened();
337
+ } else {
338
+
339
+ // Do this as early as possible
340
+ $updraftplus->something_useful_happened();
341
+
342
+ $time_since_began = max(microtime(true)- $this->zipfiles_lastwritetime, 0.000001);
343
+ $normalised_time_since_began = $time_since_began*($maxzipbatch/$data_added_since_reopen);
344
+
345
+ // Don't measure speed until after ZipArchive::close()
346
+ $rate = round($data_added_since_reopen/$time_since_began, 1);
347
+
348
+ $updraftplus->log(sprintf("A useful amount of data was added after this amount of zip processing: %s s (normalised: %s s, rate: %s Kb/s)", round($time_since_began, 1), round($normalised_time_since_began, 1), round($rate/1024, 1)));
349
+
350
+ // We want to detect not only that we need to reduce the size of batches, but also the capability to increase them. This is particularly important because of ZipArchive()'s (understandable, given the tendency of PHP processes being terminated without notice) practice of first creating a temporary zip file via copying before acting on that zip file (so the information is atomic). Unfortunately, once the size of the zip file gets over 100Mb, the copy operation beguns to be significant. By the time you've hit 500Mb on many web hosts the copy is the majority of the time taken. So we want to do more in between these copies if possible.
351
+
352
+ /* "Could have done more" - detect as:
353
+ - A batch operation would still leave a "good chunk" of time in a run
354
+ - "Good chunk" means that the time we took to add the batch is less than 50% of a run time
355
+ - We can do that on any run after the first (when at least one ceiling on the maximum time is known)
356
+ - But in the case where a max_execution_time is long (so that resumptions are never needed), and we're always on run 0, we will automatically increase chunk size if the batch took less than 6 seconds.
357
+ */
358
+
359
+ // At one stage we had a strategy of not allowing check-ins to have more than 20s between them. However, once the zip file got to a certain size, PHP's habit of copying the entire zip file first meant that it *always* went over 18s, and thence a drop in the max size was inevitable - which was bad, because with the copy time being something that only grew, the outcome was less data being copied every time
360
+
361
+ // Gather the data. We try not to do this unless necessary (may be time-sensitive)
362
+ if ($updraftplus->current_resumption >= 1) {
363
+ $time_passed = $updraftplus->jobdata_get('run_times');
364
+ if (!is_array($time_passed)) $time_passed = array();
365
+ list($max_time, $timings_string, $run_times_known) = $updraftplus->max_time_passed($time_passed, $updraftplus->current_resumption-1);
366
+ } else {
367
+ $run_times_known = 0;
368
+ $max_time = -1;
369
+ }
370
+
371
+ // How many is the most seconds we
372
+ // $max_tolerate_seconds =
373
+
374
+ // We set at 18, to allow approximately unexpected 10% extra in the batch to take it to 20s
375
+ // if (($run_times_known <1 && $normalised_time_since_began > 18) || ($run_times_known >=1 && $normalised_time_since_began > $max_time)) {
376
+ // TODO: This is disabled via 1==0 - remove it properly
377
+ if (1==0 && $normalised_time_since_began > 18) {
378
+
379
+ // Don't do more than would have accounted for 18 normalised seconds at the same rate
380
+ // The line below means, do whichever-is-least-of 10% less, or what would have accounted for 18 normalised seconds - but never go lower than 1Mb.
381
+ $new_maxzipbatch = max( floor(min($maxzipbatch*(18/$normalised_time_since_began), $maxzipbatch*0.9)), 1048576);
382
+ if ($new_maxzipbatch < $maxzipbatch) {
383
+ $updraftplus->jobdata_set("maxzipbatch", $new_maxzipbatch);
384
+ $updraftplus->log("More than 18 (normalised) seconds passed since the last check-in, so we will adjust the amount of data we attempt in each batch (time_passed=$time_since_began, normalised_time_passed=$normalised_time_since_began, old_max_bytes=$maxzipbatch, new_max_bytes=$new_maxzipbatch)");
385
+ $maxzipbatch = $new_maxzipbatch;
386
+ } else {
387
+ $updraftplus->log("More than 18 (normalised) seconds passed since the last check-in, but the zip-writing threshold is already at its lower limit (1Mb), so will not be further reduced (max_bytes=$maxzipbatch, time_passed=$time_since_began, normalised_time_passed=$normalised_time_since_began)");
388
+ }
389
+ } else {
390
+
391
+ if ($normalised_time_since_began<6 || ($updraftplus->current_resumption >=1 && $run_times_known >=1 && $time_since_began < 0.6*$max_time )) {
392
+
393
+ // How much can we increase it by?
394
+ if ($normalised_time_since_began <6) {
395
+ if ($run_times_known > 0 && $max_time >0) {
396
+ $new_maxzipbatch = min(floor(max(
397
+ $maxzipbatch*6/$normalised_time_since_began, $maxzipbatch*((0.6*$max_time)/$normalised_time_since_began))),
398
+ 200*1024*1024
399
+ );
400
+ } else {
401
+ # Maximum of 200Mb in a batch
402
+ $new_maxzipbatch = min( floor($maxzipbatch*6/$normalised_time_since_began),
403
+ 200*1024*1024
404
+ );
405
+ }
406
+ } else {
407
+ // Use up to 60% of available time
408
+ $new_maxzipbatch = min(
409
+ floor($maxzipbatch*((0.6*$max_time)/$normalised_time_since_began)),
410
+ 200*1024*1024
411
+ );
412
+ }
413
+
414
+ # Throttle increases - don't increase by more than 2x in one go - ???
415
+ # $new_maxzipbatch = floor(min(2*$maxzipbatch, $new_maxzipbatch));
416
+ # Also don't allow anything that is going to be more than 18 seconds - actually, that's harmful because of the basically fixed time taken to copy the file
417
+ # $new_maxzipbatch = floor(min(18*$rate ,$new_maxzipbatch));
418
+
419
+ // Final sanity check
420
+ if ($new_maxzipbatch > 1024*1024) $updraftplus->jobdata_set("maxzipbatch", $new_maxzipbatch);
421
+
422
+ if ($new_maxzipbatch <= 1024*1024) {
423
+ $updraftplus->log("Unexpected new_maxzipbatch value obtained (time=$time_since_began, normalised_time=$normalised_time_since_began, max_time=$max_time, data points known=$run_times_known, old_max_bytes=$maxzipbatch, new_max_bytes=$new_maxzipbatch)");
424
+ } elseif ($new_maxzipbatch > $maxzipbatch) {
425
+ $updraftplus->log("Performance is good - will increase the amount of data we attempt to batch (time=$time_since_began, normalised_time=$normalised_time_since_began, max_time=$max_time, data points known=$run_times_known, old_max_bytes=$maxzipbatch, new_max_bytes=$new_maxzipbatch)");
426
+ } elseif ($new_maxzipbatch < $maxzipbatch) {
427
+ // Ironically, we thought we were speedy...
428
+ $updraftplus->log("Adjust: Reducing maximum amount of batched data (time=$time_since_began, normalised_time=$normalised_time_since_began, max_time=$max_time, data points known=$run_times_known, new_max_bytes=$new_maxzipbatch, old_max_bytes=$maxzipbatch)");
429
+ } else {
430
+ $updraftplus->log("Performance is good - but we will not increase the amount of data we batch, as we are already at the present limit (time=$time_since_began, normalised_time=$normalised_time_since_began, max_time=$max_time, data points known=$run_times_known, max_bytes=$maxzipbatch)");
431
+ }
432
+
433
+ if ($new_maxzipbatch > 1024*1024) $maxzipbatch = $new_maxzipbatch;
434
+ }
435
+
436
+ // Detect excessive slowness
437
+ // Don't do this until we're on at least resumption 7, as we want to allow some time for things to settle down and the maxiumum time to be accurately known (since reducing the batch size unnecessarily can itself cause extra slowness, due to PHP's usage of temporary zip files)
438
+
439
+ // We use a percentage-based system as much as possible, to avoid the various criteria being in conflict with each other (i.e. a run being both 'slow' and 'fast' at the same time, which is increasingly likely as max_time gets smaller).
440
+
441
+ if (!$updraftplus->something_useful_happened && $updraftplus->current_resumption >= 7) {
442
+
443
+ $updraftplus->something_useful_happened();
444
+
445
+ if ($run_times_known >= 5 && ($time_since_began > 0.8 * $max_time || $time_since_began + 7 > $max_time)) {
446
+
447
+ $new_maxzipbatch = max(floor($maxzipbatch*0.8), 20971520);
448
+ if ($new_maxzipbatch < $maxzipbatch) {
449
+ $maxzipbatch = $new_maxzipbatch;
450
+ $updraftplus->jobdata_set("maxzipbatch", $new_maxzipbatch);
451
+ $updraftplus->log("We are within a small amount of the expected maximum amount of time available; the zip-writing thresholds will be reduced (time_passed=$time_since_began, normalised_time_passed=$normalised_time_since_began, max_time=$max_time, data points known=$run_times_known, old_max_bytes=$maxzipbatch, new_max_bytes=$new_maxzipbatch)");
452
+ } else {
453
+ $updraftplus->log("We are within a small amount of the expected maximum amount of time available, but the zip-writing threshold is already at its lower limit (20Mb), so will not be further reduced (max_time=$max_time, data points known=$run_times_known, max_bytes=$maxzipbatch)");
454
+ }
455
+ }
456
+
457
+ } else {
458
+ $updraftplus->something_useful_happened();
459
+ }
460
+ }
461
+ }
462
+ $data_added_since_reopen = 0;
463
+ }
464
  clearstatcache();
465
+ $this->zipfiles_lastwritetime = time();
466
  }
467
  }
468
  $this->zipfiles_added++;
469
  // Don't call something_useful_happened() here - nothing necessarily happens until close() is called
470
  if ($this->zipfiles_added % 100 == 0) $updraftplus->log("Zip: ".basename($zipfile).": ".$this->zipfiles_added." files added (on-disk size: ".round(filesize($zipfile)/1024,1)." Kb)");
471
  }
472
+
473
  // Reset the array
474
  $this->zipfiles_batched = array();
475
  $ret = $zip->close();
487
 
488
  if ($whichone != "others") $updraftplus->log("Beginning creation of dump of $whichone");
489
 
490
+ if (is_string($create_from_dir) && !file_exists($create_from_dir)) {
491
+ $flag_error = true;
492
+ $updraftplus->log("Does not exist: $create_from_dir");
493
+ if ('mu-plugins' == $whichone) {
494
+ if (!function_exists('get_mu_plugins')) require_once(ABSPATH.'wp-admin/includes/plugin.php');
495
+ $mu_plugins = get_mu_plugins();
496
+ if (count($mu_plugins) == 0) {
497
+ $updraftplus->log("There appear to be no mu-plugins to back up. Will not raise an error.");
498
+ $flag_error = false;
499
+ }
500
+ }
501
+ if ($flag_error) $updraftplus->error(sprintf(__("%s - could not back this entity up; the corresponding directory does not exist (%s)", 'updraftplus'), $whichone, $create_from_dir));
502
+ return false;
503
+ }
504
+
505
  $full_path = $create_in_dir.'/'.$backup_file_basename.'-'.$whichone.'.zip';
506
  $time_now = time();
507
 
543
  $kbsize = filesize($full_path)/1024;
544
  $rate = round($kbsize/$timetaken, 1);
545
  $updraftplus->log("Created $whichone zip - file size is ".round($kbsize,1)." Kb in ".round($timetaken,1)." s ($rate Kb/s)");
546
+ // We can now remove any left-over temporary files from this job
547
+ $updraftplus->clean_temporary_files('_'.$updraftplus->nonce."-$whichone");
548
  }
549
 
550
  return basename($full_path);
551
  }
552
 
553
+ }
 
images/dreamobjects_logo-horiz-2013.png ADDED
Binary file
images/rackspacecloud-logo.png CHANGED
Binary file
includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php CHANGED
@@ -48,6 +48,8 @@ abstract class Dropbox_ConsumerAbstract
48
  try {
49
  $this->getAccessToken();
50
  } catch(Dropbox_Exception $e) {
 
 
51
  $this->getRequestToken();
52
  $this->authorise();
53
  }
@@ -78,11 +80,16 @@ abstract class Dropbox_ConsumerAbstract
78
  private function authorise()
79
  {
80
  // Only redirect if using CLI
81
- if (PHP_SAPI !== 'cli') {
82
  $url = $this->getAuthoriseUrl();
83
  header('Location: ' . $url);
84
  exit;
85
  }
 
 
 
 
 
86
  }
87
 
88
  /**
48
  try {
49
  $this->getAccessToken();
50
  } catch(Dropbox_Exception $e) {
51
+ global $updraftplus;
52
+ $updraftplus->log($e->getMessage().' - need to reauthenticate with Dropbox');
53
  $this->getRequestToken();
54
  $this->authorise();
55
  }
80
  private function authorise()
81
  {
82
  // Only redirect if using CLI
83
+ if (PHP_SAPI !== 'cli' && (!defined('DOING_CRON') || !DOING_CRON)) {
84
  $url = $this->getAuthoriseUrl();
85
  header('Location: ' . $url);
86
  exit;
87
  }
88
+ global $updraftplus;
89
+ $updraftplus->log('Dropbox reauthorisation needed, but running from cron or CLI, so not possible');
90
+ UpdraftPlus_Options::update_updraft_option("updraft_dropboxtk_request_token",'');
91
+ $updraftplus->error(sprintf(__('You need to re-authenticate with %s, as your existing credentials are not working.', 'updraftplus'), 'Dropbox'));
92
+ exit;
93
  }
94
 
95
  /**
includes/Dropbox/OAuth/Storage/Encrypter.php CHANGED
@@ -32,7 +32,7 @@ class Dropbox_Encrypter
32
  public function __construct($key)
33
  {
34
  if (!extension_loaded('mcrypt')) {
35
- throw new Dropbox_Exception('The storage encrypter requires the MCrypt extension');
36
  } elseif (($length = mb_strlen($key, '8bit')) !== self::KEY_SIZE) {
37
  throw new Dropbox_Exception('Expecting a ' . self::KEY_SIZE . ' byte key, got ' . $length);
38
  } else {
@@ -48,15 +48,22 @@ class Dropbox_Encrypter
48
  */
49
  public function encrypt($token)
50
  {
 
51
  // Only MCRYPT_RAND is available on Windows prior to PHP 5.3
52
  if (version_compare(phpversion(), '5.3.0', '<') && strtoupper(substr(php_uname('s'), 0, 3)) === 'WIN') {
53
  $crypt_source = MCRYPT_RAND;
54
  } elseif (@is_readable("/dev/urandom")) {
 
55
  $crypt_source = MCRYPT_DEV_URANDOM;
56
  } else {
57
  $crypt_source = MCRYPT_RAND;
58
  }
59
- $iv = mcrypt_create_iv(self::IV_SIZE, $crypt_source);
 
 
 
 
 
60
  $cipherText = @mcrypt_encrypt(self::CIPHER, $this->key, $token, self::MODE, $iv);
61
  return base64_encode($iv . $cipherText);
62
  }
32
  public function __construct($key)
33
  {
34
  if (!extension_loaded('mcrypt')) {
35
+ throw new Dropbox_Exception('The storage encrypter requires the PHP MCrypt extension to be available. Please check your PHP configuration.');
36
  } elseif (($length = mb_strlen($key, '8bit')) !== self::KEY_SIZE) {
37
  throw new Dropbox_Exception('Expecting a ' . self::KEY_SIZE . ' byte key, got ' . $length);
38
  } else {
48
  */
49
  public function encrypt($token)
50