UpdraftPlus WordPress Backup Plugin - Version 1.9.4

Version Description

  • 2014/04/23 =

  • FEATURE: New remote storage back-end for OpenStack Swift

  • FEATURE: New remote storage back-end for Bitcasa (Premium - http://updraftplus.com/shop/updraftplus-premium/)

  • FEATURE: New Google Drive back-end now uses new SDK; resulting new capabilities include ability to rescan remote storage, and chunked downloading for huge files; also requires a shorter list of permissions

  • FEATURE: Restore backups that were created by the plugin BackWPup (Premium - http://updraftplus.com/shop/updraftplus-premium/)

  • FIX: WebDAV storage: remove requirement for PEAR to be pre-installed on server

  • FIX: Fix restoration on sites where WP did not have direct filesystem access

  • FIX: Fix regex which prevented download progress of mu-plugins zip displaying correctly

  • FIX: Fix issue preventing some useful information about URL changes being included in the migration log file

  • FIX: Restore compatibility with WordPress 3.2 (if you're using that, you're overdue an upgrade by some years!)

  • TWEAK: Enable new locations for plupload Flash/Silverlight widgets (for non-HTML5 browsers) in WP3.9+ (later reverted by core devs, but is harmless in case they re-introduce)

  • TWEAK: Take advantage of WP 3.9+'s new method (if available) for maintaining DB connectivity on very long runs

  • TWEAK: Add filter so that programmers can allow the options page to be shown to non-admins

  • TWEAK: Add filter allowing programmers to forbid a backup

  • TWEAK: Detect and adapt to cases where the site is moved to a system with different case-sensitivity and the database record of the theme is now wrong

  • TWEAK: Prevent erroneous warning about a missing table in the database backup on some WPMU installs that began life as a very old WP version

  • TWEAK: Introduce constant allowing users of pre-release WP installs to disable notices about using a version of WP that UpdraftPlus has not been tested on.

  • TWEAK: Make Dropbox uploads at least 25% faster (in our testing) by increasing the chunk size

  • TWEAK: Reduce number of rows fetched from MySQL if no activity took place on the previous resumption

  • TWEAK: AWS image in settings page will now use https if dashboard access is https - prevents non-https warnings in recent browsers

  • TWEAK: Hook into Better WP Security so that it doesn't tell the user that they have no backup plugin

  • TWEAK: New debugging tool to test remote HTTP connectivity

  • TWEAK: Tweak the MySQL version detection in the 'debug' section of the admin page to prevent a PHP message being thrown on PHP 5.5+/WP3.9+

  • TRANSLATION: New Czech (cs_CZ) translation; thanks to Martin Kek

  • TRANSLATION: Updated Russian, Swedish, Dutch and Portuguese translations

Download this release

Release Info

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

Code changes from version 1.9.0 to 1.9.4

Files changed (53) hide show
  1. admin.php +249 -64
  2. backup.php +55 -16
  3. class-zip.php +5 -1
  4. example-decrypt.php +0 -2
  5. images/bitcasa.png +0 -0
  6. images/copy.png +0 -0
  7. includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php +1 -1
  8. includes/Google/Auth/Abstract.php +41 -0
  9. includes/Google/Auth/AssertionCredentials.php +133 -0
  10. includes/Google/Auth/Exception.php +22 -0
  11. includes/Google/Auth/LoginTicket.php +69 -0
  12. includes/Google/Auth/OAuth2.php +580 -0
  13. includes/Google/Auth/Simple.php +92 -0
  14. includes/Google/Cache/Abstract.php +53 -0
  15. includes/Google/Cache/Apc.php +73 -0
  16. includes/Google/Cache/Exception.php +21 -0
  17. includes/Google/Cache/File.php +145 -0
  18. includes/Google/Cache/Memcache.php +137 -0
  19. includes/Google/Cache/Null.php +56 -0
  20. includes/Google/Client.php +608 -0
  21. includes/Google/Collection.php +94 -0
  22. includes/Google/Config.php +315 -0
  23. includes/Google/Exception.php +20 -0
  24. includes/Google/Http/Batch.php +143 -0
  25. includes/Google/Http/CacheParser.php +184 -0
  26. includes/Google/Http/MediaFileUpload.php +292 -0
  27. includes/Google/Http/REST.php +139 -0
  28. includes/Google/Http/Request.php +476 -0
  29. includes/Google/IO/Abstract.php +312 -0
  30. includes/Google/IO/Curl.php +136 -0
  31. includes/Google/IO/Exception.php +22 -0
  32. includes/Google/IO/Stream.php +189 -0
  33. includes/Google/Model.php +247 -0
  34. includes/Google/Service.php +39 -0
  35. includes/Google/Service/Drive.php +5732 -0
  36. includes/Google/Service/Exception.php +53 -0
  37. includes/Google/Service/Resource.php +210 -0
  38. includes/Google/Signer/Abstract.php +29 -0
  39. includes/Google/Signer/P12.php +90 -0
  40. includes/Google/Utils.php +135 -0
  41. includes/Google/Utils/URITemplate.php +333 -0
  42. includes/Google/Verifier/Abstract.php +30 -0
  43. includes/Google/Verifier/Pem.php +73 -0
  44. includes/class-gdocs.php +0 -641
  45. includes/updraft-admin-ui.js +219 -147
  46. languages/updraftplus-ar.mo +0 -0
  47. languages/updraftplus-ar.po +914 -758
  48. languages/updraftplus-cs_CZ.mo +0 -0
  49. languages/updraftplus-cs_CZ.po +906 -750
  50. languages/updraftplus-el.mo +0 -0
  51. languages/updraftplus-el.po +1843 -924
  52. languages/updraftplus-es_ES.mo +0 -0
  53. languages/updraftplus-es_ES.po +453 -264
admin.php CHANGED
@@ -36,14 +36,27 @@ class UpdraftPlus_Admin {
36
 
37
  $service = UpdraftPlus_Options::get_updraft_option('updraft_service');
38
 
39
- if (UpdraftPlus_Options::user_can_manage() && ('googledrive' === $service || is_array($service) && in_array('googledrive', $service)) && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid','') != '' && UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token','') == '') {
40
- add_action('all_admin_notices', array($this,'show_admin_warning_googledrive') );
 
 
 
 
 
 
 
 
41
  }
42
 
43
  if (UpdraftPlus_Options::user_can_manage() && ('dropbox' === $service || is_array($service) && in_array('dropbox', $service)) && UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','') == '') {
44
  add_action('all_admin_notices', array($this,'show_admin_warning_dropbox') );
45
  }
46
 
 
 
 
 
 
47
  if (UpdraftPlus_Options::user_can_manage() && $this->disk_space_check(1048576*35) === false) add_action('all_admin_notices', array($this, 'show_admin_warning_diskspace'));
48
 
49
  // Next, the actions that only come on the UpdraftPlus page
@@ -75,7 +88,26 @@ class UpdraftPlus_Admin {
75
 
76
  if (version_compare($wp_version, '3.2', '<')) add_action('all_admin_notices', array($this, 'show_admin_warning_wordpressversion'));
77
 
78
- wp_enqueue_script('updraftplus-admin-ui', UPDRAFTPLUS_URL.'/includes/updraft-admin-ui.js', array('jquery', 'jquery-ui-dialog', 'plupload-all'), '32');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
  wp_localize_script( 'updraftplus-admin-ui', 'updraftlion', array(
81
  'sendonlyonwarnings' => __('Send a report only when there are warnings/errors', 'updraftplus'),
@@ -127,10 +159,9 @@ class UpdraftPlus_Admin {
127
  'close' => __('Close', 'updraftplus'),
128
  'restore' => __('Restore', 'updraftplus'),
129
  ) );
130
-
131
  }
132
 
133
- function core_upgrade_preamble() {
134
  if (!class_exists('UpdraftPlus_Addon_Autobackup')) {
135
  if (defined('UPDRAFTPLUS_NOADS_A')) return;
136
  # TODO: Remove legacy/wrong use of transient any time from 1 Jun 2014
@@ -160,8 +191,11 @@ class UpdraftPlus_Admin {
160
 
161
  $chunk_size = min(wp_max_upload_size()-1024, 1024*1024*2);
162
 
 
 
 
163
  $plupload_init = array(
164
- 'runtimes' => 'html5,silverlight,flash,html4',
165
  'browse_button' => 'plupload-browse-button',
166
  'container' => 'plupload-upload-ui',
167
  'drop_element' => 'drag-drop-area',
@@ -170,7 +204,7 @@ class UpdraftPlus_Admin {
170
  'max_file_size' => '100Gb',
171
  'chunk_size' => $chunk_size.'b',
172
  'url' => admin_url('admin-ajax.php'),
173
- 'filters' => array(array('title' => __('Allowed Files'), 'extensions' => 'zip,gz,crypt,sql,txt')),
174
  'multipart' => true,
175
  'multi_selection' => true,
176
  'urlstream_upload' => true,
@@ -180,6 +214,8 @@ class UpdraftPlus_Admin {
180
  'action' => 'plupload_action'
181
  )
182
  );
 
 
183
 
184
  # WP 3.9 updated to plupload 2.0 - https://core.trac.wordpress.org/ticket/25663
185
  if (is_file(ABSPATH.'wp-includes/js/plupload/Moxie.swf')) {
@@ -294,11 +330,7 @@ class UpdraftPlus_Admin {
294
 
295
  }
296
 
297
- function googledrive_remove_folderurlprefix($input) {
298
- return preg_replace('/https:\/\/drive.google.com\/(.*)#folders\//', '', $input);
299
- }
300
-
301
- function disk_space_check($space) {
302
  global $updraftplus;
303
  $updraft_dir = $updraftplus->backups_dir_location();
304
  $disk_free_space = @disk_free_space($updraft_dir);
@@ -319,7 +351,7 @@ class UpdraftPlus_Admin {
319
  return $links;
320
  }
321
 
322
- function admin_action_upgrade_pluginortheme() {
323
 
324
  if (isset($_GET['action']) && ($_GET['action'] == 'upgrade-plugin' || $_GET['action'] == 'upgrade-theme') && !class_exists('UpdraftPlus_Addon_Autobackup') && !defined('UPDRAFTPLUS_NOADS_A')) {
325
 
@@ -390,6 +422,10 @@ class UpdraftPlus_Admin {
390
  $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?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>');
391
  }
392
 
 
 
 
 
393
  public function show_admin_warning_googledrive() {
394
  $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit">'.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Google Drive','Google Drive').'</a>');
395
  }
@@ -503,12 +539,7 @@ class UpdraftPlus_Admin {
503
  $updraftplus->jobdata_set('dlfile_'.$timestamp.'_'.$type.'_'.$findex, "downloading:$known_size:$fullpath");
504
 
505
  if ($needs_downloading) {
506
- // Close browser connection so that it can resume AJAX polling
507
- header('Content-Length: 0');
508
- header('Connection: close');
509
- header('Content-Encoding: none');
510
- if (session_id()) session_write_close();
511
- echo "\r\n\r\n";
512
  $is_downloaded = false;
513
  foreach ($services as $service) {
514
  if ($is_downloaded) continue;
@@ -546,6 +577,16 @@ class UpdraftPlus_Admin {
546
 
547
  }
548
 
 
 
 
 
 
 
 
 
 
 
549
  # Pass only a single service, as a string, into this function
550
  private function download_file($file, $service) {
551
 
@@ -577,7 +618,7 @@ class UpdraftPlus_Admin {
577
 
578
  // Test the nonce
579
  $nonce = (empty($_REQUEST['nonce'])) ? "" : $_REQUEST['nonce'];
580
- if (! wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
581
  if (isset($_REQUEST['subaction']) && 'lastlog' == $_REQUEST['subaction']) {
582
  echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '('.__('Nothing yet logged', 'updraftplus').')'));
583
  } elseif (isset($_GET['subaction']) && 'activejobs_list' == $_GET['subaction']) {
@@ -609,6 +650,70 @@ class UpdraftPlus_Admin {
609
  'j' => $active_jobs,
610
  'ds' => $download_status
611
  ));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612
  } elseif (isset($_REQUEST['subaction']) && 'dismissautobackup' == $_REQUEST['subaction']) {
613
  UpdraftPlus_Options::update_updraft_option('updraftplus_dismissedautobackup', time() + 84*86400);
614
  } elseif (isset($_REQUEST['subaction']) && 'dismissexpiry' == $_REQUEST['subaction']) {
@@ -1170,7 +1275,7 @@ class UpdraftPlus_Admin {
1170
  //$mess[] = sprintf(__('%s version: %s', 'updraftplus'), 'WordPress', $old_wp_version);
1171
  $warn[] = sprintf(__('You are importing from a newer version of WordPress (%s) into an older one (%s). There are no guarantees that WordPress can handle this.', 'updraftplus'), $old_wp_version, $wp_version);
1172
  }
1173
- } elseif ('' == $old_table_prefix && preg_match('/^\# Table prefix: (\S+)$/', $buffer, $matches)) {
1174
  $old_table_prefix = $matches[1];
1175
  // echo '<strong>'.__('Old table prefix:', 'updraftplus').'</strong> '.htmlspecialchars($old_table_prefix).'<br>';
1176
  } elseif ($gathering_siteinfo && preg_match('/^\# Site info: (\S+)$/', $buffer, $matches)) {
@@ -1348,7 +1453,7 @@ CREATE TABLE $wpdb->signups (
1348
  add_filter('sanitize_file_name', array($this, 'sanitize_file_name'));
1349
  // handle file upload
1350
 
1351
- $farray = array( 'test_form' => true, 'action' => 'plupload_action' );
1352
 
1353
  $farray['test_type'] = false;
1354
  $farray['ext'] = 'x-gzip';
@@ -1391,6 +1496,16 @@ CREATE TABLE $wpdb->signups (
1391
  }
1392
  fclose($wh);
1393
  $status['file'] = $updraft_dir.'/'.$final_file;
 
 
 
 
 
 
 
 
 
 
1394
  }
1395
  }
1396
 
@@ -1430,6 +1545,7 @@ CREATE TABLE $wpdb->signups (
1430
  exit;
1431
  }
1432
 
 
1433
  public function plupload_action2() {
1434
 
1435
  @set_time_limit(900);
@@ -1516,8 +1632,6 @@ CREATE TABLE $wpdb->signups (
1516
 
1517
  global $updraftplus;
1518
 
1519
- wp_enqueue_style('jquery-ui', UPDRAFTPLUS_URL.'/includes/jquery-ui-1.8.22.custom.css');
1520
-
1521
  /*
1522
  we use request here because the initial restore is triggered by a POSTed form. we then may need to obtain credentials
1523
  for the WP_Filesystem. to do this WP outputs a form, but we don't pass our parameters via that. So the values are
@@ -1738,7 +1852,7 @@ CREATE TABLE $wpdb->signups (
1738
 
1739
  <tr>
1740
  <th><?php echo htmlspecialchars(__('Backups, logs & restoring','updraftplus')); ?>:</th>
1741
- <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>
1742
  </tr>
1743
  <?php
1744
  if (defined('UPDRAFTPLUS_EXPERIMENTAL_MISC') && UPDRAFTPLUS_EXPERIMENTAL_MISC == true) {
@@ -1783,17 +1897,26 @@ CREATE TABLE $wpdb->signups (
1783
 
1784
  <div id="updraft-plupload-modal" title="<?php _e('UpdraftPlus - Upload backup files','updraftplus'); ?>" style="width: 75%; margin: 16px; display:none; margin-left: 100px;">
1785
  <p style="max-width: 610px;"><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>
1786
- <div id="plupload-upload-ui" style="width: 70%;">
1787
- <div id="drag-drop-area">
1788
- <div class="drag-drop-inside">
1789
- <p class="drag-drop-info"><?php _e('Drop backup files here', 'updraftplus'); ?></p>
1790
- <p><?php _ex('or', 'Uploader: Drop backup files here - or - Select Files'); ?></p>
1791
- <p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
 
 
 
 
 
 
 
 
 
1792
  </div>
1793
  </div>
1794
- <div id="filelist">
1795
- </div>
1796
- </div>
1797
 
1798
  </div>
1799
 
@@ -1959,7 +2082,17 @@ CREATE TABLE $wpdb->signups (
1959
  echo __('PHP memory limit','updraftplus').': '.ini_get('memory_limit').' <br/>';
1960
  echo sprintf(__('%s version:','updraftplus'), 'PHP').' '.phpversion().' - ';
1961
  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/>';
1962
- echo sprintf(__('%s version:','updraftplus'), 'MySQL').' '.((function_exists('mysql_get_server_info')) ? mysql_get_server_info() : '?').'<br>';
 
 
 
 
 
 
 
 
 
 
1963
 
1964
  if (version_compare(phpversion(), '5.2.0', '>=') && extension_loaded('zip')) {
1965
  $ziparchive_exists = __('Yes', 'updraftplus');
@@ -1984,6 +2117,17 @@ CREATE TABLE $wpdb->signups (
1984
 
1985
  echo __('Install plugins for debugging:', 'updraftplus').' <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=wp-crontrol'), 'install-plugin_wp-crontrol').'">WP Crontrol</a> | <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=sql-executioner'), 'install-plugin_sql-executioner').'">SQL Executioner</a> | <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=advanced-code-editor'), 'install-plugin_advanced-code-editor').'">Advanced Code Editor</a> | <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=wp-filemanager'), 'install-plugin_wp-filemanager').'">WP Filemanager</a><br>';
1986
 
 
 
 
 
 
 
 
 
 
 
 
1987
  echo '<h3>'.__('Total (uncompressed) on-disk data:','updraftplus').'</h3>';
1988
  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>';
1989
 
@@ -2033,9 +2177,9 @@ CREATE TABLE $wpdb->signups (
2033
  <?php if ($include_blurb) {
2034
  ?>
2035
  <div id="updraft_delete_old_dirs_pagediv" class="updated" style="padding:8px;"><p> <?php _e('Your WordPress install has old directories from its state before you restored/migrated (technical information: these are suffixed with -old). You should press this button to delete them as soon as you have verified that the restoration worked.','updraftplus');?></p><?php } ?>
2036
- <form method="post" onsubmit="return updraft_delete_old_dirs();" action="<?php echo remove_query_arg(array('updraft_restore_success','action')) ?>">
2037
  <?php wp_nonce_field('updraftplus-credentialtest-nonce'); ?>
2038
- <input type="hidden" name="action" value="updraft_delete_old_dirs" />
2039
  <input type="submit" class="button-primary" value="<?php echo esc_attr(__('Delete Old Directories', 'updraftplus'));?>" />
2040
  </form>
2041
  <?php
@@ -2043,7 +2187,7 @@ CREATE TABLE $wpdb->signups (
2043
  }
2044
 
2045
 
2046
- function print_active_jobs() {
2047
  $cron = get_option('cron');
2048
  if (!is_array($cron)) $cron = array();
2049
  // $found_jobs = 0;
@@ -2068,7 +2212,7 @@ CREATE TABLE $wpdb->signups (
2068
  return $ret;
2069
  }
2070
 
2071
- function print_active_job($job_id, $is_oneshot = false, $time = false, $next_resumption = false) {
2072
 
2073
  $ret = '';
2074
 
@@ -2212,7 +2356,7 @@ CREATE TABLE $wpdb->signups (
2212
 
2213
  }
2214
 
2215
- function delete_old_dirs_go($show_return = true) {
2216
  echo ($show_return) ? '<h1>UpdraftPlus - '.__('Remove old directories', 'updraftplus').'</h1>' : '<h2>'.__('Remove old directories', 'updraftplus').'</h2>';
2217
 
2218
  if($this->delete_old_dirs()) {
@@ -2224,7 +2368,7 @@ CREATE TABLE $wpdb->signups (
2224
  }
2225
 
2226
  //deletes the -old directories that are created when a backup is restored.
2227
- function delete_old_dirs() {
2228
  global $wp_filesystem, $updraftplus;
2229
  $credentials = request_filesystem_credentials(wp_nonce_url(UpdraftPlus_Options::admin_page_url()."?page=updraftplus&action=updraft_delete_old_dirs", 'updraftplus-credentialtest-nonce'));
2230
  WP_Filesystem($credentials);
@@ -2261,7 +2405,7 @@ CREATE TABLE $wpdb->signups (
2261
  return $ret && $ret3 && $ret4;
2262
  }
2263
 
2264
- function delete_old_dirs_dir($dir, $wpfs = true) {
2265
 
2266
  $dir = trailingslashit($dir);
2267
 
@@ -2302,7 +2446,7 @@ CREATE TABLE $wpdb->signups (
2302
  }
2303
 
2304
  // The aim is to get a directory that is writable by the webserver, because that's the only way we can create zip files
2305
- function create_backup_dir() {
2306
 
2307
  global $wp_filesystem, $updraftplus;
2308
 
@@ -2356,7 +2500,7 @@ CREATE TABLE $wpdb->signups (
2356
  }
2357
 
2358
  //scans the content dir to see if any -old dirs are present
2359
- function scan_old_dirs() {
2360
  global $updraftplus;
2361
  $dirs = scandir(untrailingslashit(WP_CONTENT_DIR));
2362
  if (!is_array($dirs)) $dirs = array();
@@ -2368,6 +2512,15 @@ CREATE TABLE $wpdb->signups (
2368
  return false;
2369
  }
2370
 
 
 
 
 
 
 
 
 
 
2371
  private function last_backup_html() {
2372
 
2373
  global $updraftplus;
@@ -2536,6 +2689,14 @@ CREATE TABLE $wpdb->signups (
2536
 
2537
  <div id="updraft-manualdecrypt-modal" style="width: 85%; margin: 16px; display:none; margin-left: 100px;">
2538
  <p><h3><?php _e("Manually decrypt a database backup file" ,'updraftplus');?></h3></p>
 
 
 
 
 
 
 
 
2539
  <div id="plupload-upload-ui2" style="width: 80%;">
2540
  <div id="drag-drop-area2">
2541
  <div class="drag-drop-inside">
@@ -2549,6 +2710,8 @@ CREATE TABLE $wpdb->signups (
2549
  </div>
2550
  </div>
2551
 
 
 
2552
  </div>
2553
 
2554
 
@@ -2766,41 +2929,49 @@ CREATE TABLE $wpdb->signups (
2766
  <?php
2767
  }
2768
 
2769
- function show_double_warning($text, $extraclass = '') {
2770
-
2771
- ?><div class="error updraftplusmethod <?php echo $extraclass; ?>"><p><?php echo $text; ?></p></div>
2772
 
2773
- <p style="border:1px solid; padding: 6px;"><?php echo $text; ?></p>
 
2774
 
2775
- <?php
 
2776
 
2777
  }
2778
 
2779
- function optionfilter_split_every($value) {
2780
- $value=absint($value);
2781
  if (!$value >= UPDRAFTPLUS_SPLIT_MIN) $value = UPDRAFTPLUS_SPLIT_MIN;
2782
  return $value;
2783
  }
2784
 
2785
- function curl_check($service, $has_fallback = false, $extraclass = '') {
 
 
 
2786
  // Check requirements
2787
  if (!function_exists("curl_init") || !function_exists('curl_exec')) {
2788
 
2789
- $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);
2790
 
2791
  } else {
2792
  $curl_version = curl_version();
2793
  $curl_ssl_supported= ($curl_version['features'] & CURL_VERSION_SSL);
2794
  if (!$curl_ssl_supported) {
2795
  if ($has_fallback) {
2796
- ?><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
2797
  } else {
2798
- $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);
2799
  }
2800
  } else {
2801
- ?><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
2802
  }
2803
  }
 
 
 
 
 
2804
  }
2805
 
2806
  # If $basedirs is passed as an array, then $directorieses must be too
@@ -3168,7 +3339,7 @@ ENDHERE;
3168
  }
3169
  } elseif (is_wp_error($files)) {
3170
  foreach ($files->get_error_codes() as $code) {
3171
- if ('no_settings' == $code || 'no_addon' == $code) continue;
3172
  $messages[] = array(
3173
  'method' => $method,
3174
  'desc' => $desc,
@@ -3390,7 +3561,7 @@ ENDHERE;
3390
  }
3391
 
3392
  foreach ($_POST as $key => $value) {
3393
- if (strpos($key, 'updraft_restore_') === 0 ) {
3394
  $nkey = substr($key, 16);
3395
  if (!isset($entities_to_restore[$nkey])) {
3396
  $_POST['updraft_restore'][] = $nkey;
@@ -3407,14 +3578,14 @@ ENDHERE;
3407
  }
3408
  }
3409
 
3410
- $updraftplus->log("Restore job started. Entities to restore: ".implode(', ', array_flip($entities_to_restore)));
3411
-
3412
  if (0 == count($_POST['updraft_restore'])) {
3413
  echo '<p>'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'</p>';
3414
  echo '<p>'.__('If making a request for support, please include this information:','updraftplus').' '.count($_POST).' : '.htmlspecialchars(serialize($_POST)).'</p>';
3415
  return new WP_Error('missing_info', 'Backup information not found');
3416
  }
3417
 
 
 
3418
  set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT);
3419
 
3420
  /*
@@ -3603,6 +3774,22 @@ ENDHERE;
3603
  add_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt));
3604
  }
3605
  if (!function_exists('validate_current_theme')) require_once(ABSPATH.'wp-includes/themes');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3606
  if (!validate_current_theme()) {
3607
  global $updraftplus;
3608
  echo '<strong>';
@@ -3645,11 +3832,9 @@ ENDHERE;
3645
  }
3646
 
3647
  private function get_settings_keys() {
3648
- return array('updraft_autobackup_default', 'updraftplus_tmp_googledrive_access_token', 'updraftplus_dismissedautobackup', 'updraftplus_dismissedexpiry', 'updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_wpcore', 'updraft_include_wpcore_exclude', 'updraft_include_more', 'updraft_include_blogs', 'updraft_include_mu-plugins', 'updraft_include_others_exclude', 'updraft_include_uploads_exclude', 'updraft_lastmessage', 'updraft_googledrive_token',
3649
  'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder',
3650
- 'updraft_last_backup', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_db', 'updraft_startday_files', 'updraft_sftp_settings', 'updraft_s3', 'updraft_s3generic', 'updraft_dreamhost', 'updraft_s3generic_login', 'updraft_s3generic_pass', 'updraft_s3generic_remote_path', 'updraft_s3generic_endpoint', 'updraft_webdav_settings', 'updraft_disable_ping', 'updraft_cloudfiles', 'updraft_cloudfiles_user', 'updraft_cloudfiles_apikey', 'updraft_cloudfiles_path', 'updraft_cloudfiles_authurl', 'updraft_ssl_useservercerts', 'updraft_ssl_disableverify', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dreamobjects_login', 'updraft_dreamobjects_pass', 'updraft_dreamobjects_remote_path', 'updraft_report_warningsonly', 'updraft_report_wholebackup', 'updraft_log_syslog');
3651
  }
3652
 
3653
  }
3654
-
3655
- ?>
36
 
37
  $service = UpdraftPlus_Options::get_updraft_option('updraft_service');
38
 
39
+ if (UpdraftPlus_Options::user_can_manage() && ('googledrive' === $service || is_array($service) && in_array('googledrive', $service))) {
40
+ $opts = UpdraftPlus_Options::get_updraft_option('updraft_googledrive');
41
+ if (empty($opts)) {
42
+ $clientid = UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid', '');
43
+ $token = UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token', '');
44
+ } else {
45
+ $clientid = $opts['clientid'];
46
+ $token = $opts['token'];
47
+ }
48
+ if (!empty($clientid) && empty($token)) add_action('all_admin_notices', array($this,'show_admin_warning_googledrive'));
49
  }
50
 
51
  if (UpdraftPlus_Options::user_can_manage() && ('dropbox' === $service || is_array($service) && in_array('dropbox', $service)) && UpdraftPlus_Options::get_updraft_option('updraft_dropboxtk_request_token','') == '') {
52
  add_action('all_admin_notices', array($this,'show_admin_warning_dropbox') );
53
  }
54
 
55
+ if (UpdraftPlus_Options::user_can_manage() && ('bitcasa' === $service || is_array($service) && in_array('bitcasa', $service))) {
56
+ $opts = UpdraftPlus_Options::get_updraft_option('updraft_bitcasa');
57
+ if (!empty($opts['clientid']) && !empty($opts['secret']) && empty($opts['token'])) add_action('all_admin_notices', array($this,'show_admin_warning_bitcasa') );
58
+ }
59
+
60
  if (UpdraftPlus_Options::user_can_manage() && $this->disk_space_check(1048576*35) === false) add_action('all_admin_notices', array($this, 'show_admin_warning_diskspace'));
61
 
62
  // Next, the actions that only come on the UpdraftPlus page
88
 
89
  if (version_compare($wp_version, '3.2', '<')) add_action('all_admin_notices', array($this, 'show_admin_warning_wordpressversion'));
90
 
91
+ add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
92
+
93
+ }
94
+
95
+ public function admin_enqueue_scripts() {
96
+
97
+ wp_enqueue_style('jquery-ui', UPDRAFTPLUS_URL.'/includes/jquery-ui-1.8.22.custom.css');
98
+
99
+ global $wp_version;
100
+ if (version_compare($wp_version, '3.3', '<')) {
101
+ # Require a newer jQuery (3.2.1 has 1.6.1, so we go for something not too much newer). We use .on() in a way that is incompatible with < 1.7
102
+ wp_deregister_script('jquery');
103
+ wp_register_script('jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', false, '1.7.2', false);
104
+ wp_enqueue_script('jquery');
105
+ # No plupload until 3.3
106
+ # Put in footer, to make sure that jQuery loads first
107
+ wp_enqueue_script('updraftplus-admin-ui', UPDRAFTPLUS_URL.'/includes/updraft-admin-ui.js', array('jquery', 'jquery-ui-dialog'), '35', true);
108
+ } else {
109
+ wp_enqueue_script('updraftplus-admin-ui', UPDRAFTPLUS_URL.'/includes/updraft-admin-ui.js', array('jquery', 'jquery-ui-dialog', 'plupload-all'), '35');
110
+ }
111
 
112
  wp_localize_script( 'updraftplus-admin-ui', 'updraftlion', array(
113
  'sendonlyonwarnings' => __('Send a report only when there are warnings/errors', 'updraftplus'),
159
  'close' => __('Close', 'updraftplus'),
160
  'restore' => __('Restore', 'updraftplus'),
161
  ) );
 
162
  }
163
 
164
+ public function core_upgrade_preamble() {
165
  if (!class_exists('UpdraftPlus_Addon_Autobackup')) {
166
  if (defined('UPDRAFTPLUS_NOADS_A')) return;
167
  # TODO: Remove legacy/wrong use of transient any time from 1 Jun 2014
191
 
192
  $chunk_size = min(wp_max_upload_size()-1024, 1024*1024*2);
193
 
194
+ # The multiple_queues argument is ignored in plupload 2.x (WP3.9+) - http://make.wordpress.org/core/2014/04/11/plupload-2-x-in-wordpress-3-9/
195
+ # max_file_size is also in filters as of plupload 2.x, but in its default position is still supported for backwards-compatibility. Likewise, our use of filters.extensions below is supported by a backwards-compatibility option (the current way is filters.mime-types.extensions
196
+
197
  $plupload_init = array(
198
+ 'runtimes' => 'html5,flash,silverlight,html4',
199
  'browse_button' => 'plupload-browse-button',
200
  'container' => 'plupload-upload-ui',
201
  'drop_element' => 'drag-drop-area',
204
  'max_file_size' => '100Gb',
205
  'chunk_size' => $chunk_size.'b',
206
  'url' => admin_url('admin-ajax.php'),
207
+ 'filters' => array(array('title' => __('Allowed Files'), 'extensions' => 'zip,tar,gz,bz2,crypt,sql,txt')),
208
  'multipart' => true,
209
  'multi_selection' => true,
210
  'urlstream_upload' => true,
214
  'action' => 'plupload_action'
215
  )
216
  );
217
+ // 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
218
+ // 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
219
 
220
  # WP 3.9 updated to plupload 2.0 - https://core.trac.wordpress.org/ticket/25663
221
  if (is_file(ABSPATH.'wp-includes/js/plupload/Moxie.swf')) {
330
 
331
  }
332
 
333
+ private function disk_space_check($space) {
 
 
 
 
334
  global $updraftplus;
335
  $updraft_dir = $updraftplus->backups_dir_location();
336
  $disk_free_space = @disk_free_space($updraft_dir);
351
  return $links;
352
  }
353
 
354
+ public function admin_action_upgrade_pluginortheme() {
355
 
356
  if (isset($_GET['action']) && ($_GET['action'] == 'upgrade-plugin' || $_GET['action'] == 'upgrade-theme') && !class_exists('UpdraftPlus_Addon_Autobackup') && !defined('UPDRAFTPLUS_NOADS_A')) {
357
 
422
  $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?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>');
423
  }
424
 
425
+ public function show_admin_warning_bitcasa() {
426
+ $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&action=updraftmethod-bitcasa-auth&updraftplus_bitcasaauth=doit">'.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Bitcasa','Bitcasa').'</a>');
427
+ }
428
+
429
  public function show_admin_warning_googledrive() {
430
  $this->show_admin_warning('<strong>'.__('UpdraftPlus notice:','updraftplus').'</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&action=updraftmethod-googledrive-auth&updraftplus_googleauth=doit">'.sprintf(__('Click here to authenticate your %s account (you will not be able to back up to %s without it).','updraftplus'),'Google Drive','Google Drive').'</a>');
431
  }
539
  $updraftplus->jobdata_set('dlfile_'.$timestamp.'_'.$type.'_'.$findex, "downloading:$known_size:$fullpath");
540
 
541
  if ($needs_downloading) {
542
+ $this->close_browser_connection();
 
 
 
 
 
543
  $is_downloaded = false;
544
  foreach ($services as $service) {
545
  if ($is_downloaded) continue;
577
 
578
  }
579
 
580
+ private function close_browser_connection($txt = '') {
581
+ // Close browser connection so that it can resume AJAX polling
582
+ header('Content-Length: '.((!empty($txt)) ? 4+strlen($txt) : '0'));
583
+ header('Connection: close');
584
+ header('Content-Encoding: none');
585
+ if (session_id()) session_write_close();
586
+ echo "\r\n\r\n";
587
+ echo $txt;
588
+ }
589
+
590
  # Pass only a single service, as a string, into this function
591
  private function download_file($file, $service) {
592
 
618
 
619
  // Test the nonce
620
  $nonce = (empty($_REQUEST['nonce'])) ? "" : $_REQUEST['nonce'];
621
+ if (!wp_verify_nonce($nonce, 'updraftplus-credentialtest-nonce') || empty($_REQUEST['subaction'])) die('Security check');
622
  if (isset($_REQUEST['subaction']) && 'lastlog' == $_REQUEST['subaction']) {
623
  echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_lastmessage', '('.__('Nothing yet logged', 'updraftplus').')'));
624
  } elseif (isset($_GET['subaction']) && 'activejobs_list' == $_GET['subaction']) {
650
  'j' => $active_jobs,
651
  'ds' => $download_status
652
  ));
653
+ } elseif (isset($_REQUEST['subaction']) && 'callwpaction' == $_REQUEST['subaction'] && !empty($_REQUEST['wpaction'])) {
654
+ ob_start();
655
+
656
+ $res = '<em>Request received: </em>';
657
+
658
+ if (preg_match('/^([^:]+)+:(.*)$/', stripslashes($_REQUEST['wpaction']), $matches)) {
659
+ $action = $matches[1];
660
+ if (null === ($args = json_decode($matches[2], true))) {
661
+ $res .= "The parameters (should be JSON) could not be decoded";
662
+ $action = false;
663
+ } else {
664
+ $res .= "Will despatch action: ".htmlspecialchars($action).", parameters: ".htmlspecialchars(implode(',', $args));
665
+ }
666
+ } else {
667
+ $action = $_REQUEST['wpaction'];
668
+ $res .= "Will despatch action: ".htmlspecialchars($action).", no parameters";
669
+ }
670
+
671
+ echo json_encode(array('r' => $res));
672
+ $ret = ob_get_clean();
673
+ ob_end_clean();
674
+ $this->close_browser_connection($ret);
675
+ if (!empty($action)) {
676
+ if (!empty($args)) {
677
+ do_action_ref_array($action, $args);
678
+ } else {
679
+ do_action($action);
680
+ }
681
+ }
682
+ die;
683
+ } elseif (isset($_REQUEST['subaction']) && 'httpget' == $_REQUEST['subaction']) {
684
+ if (empty($_REQUEST['uri'])) {
685
+ echo json_encode(array('r' => ''));
686
+ die;
687
+ }
688
+ $uri = $_REQUEST['uri'];
689
+ if (!empty($_REQUEST['curl'])) {
690
+ if (!function_exists('curl_exec')) {
691
+ echo json_encode(array('e' => 'No Curl installed'));
692
+ die;
693
+ }
694
+ $ch = curl_init();
695
+ curl_setopt($ch, CURLOPT_URL, $uri);
696
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
697
+ curl_setopt($ch, CURLOPT_FAILONERROR, true);
698
+ $output = curl_exec($ch);
699
+ $response = curl_exec($ch);
700
+ $error = curl_error($ch);
701
+ $getinfo = curl_getinfo($ch);
702
+ curl_close($ch);
703
+ if (false === $response) {
704
+ echo json_encode(array('e' => htmlspecialchars($error)));
705
+ die;
706
+ }
707
+ echo json_encode(array('r' => $getinfo['http_code'].': '.htmlspecialchars(substr($response, 0, 200))));
708
+ } else {
709
+ $response = wp_remote_get($uri, array('timeout' => 10));
710
+ if (is_wp_error($response)) {
711
+ echo json_encode(array('e' => htmlspecialchars($response->get_error_message())));
712
+ die;
713
+ }
714
+ echo json_encode(array('r' => $response['response']['code'].': '.htmlspecialchars(substr($response['body'], 0, 200))));
715
+ }
716
+ die;
717
  } elseif (isset($_REQUEST['subaction']) && 'dismissautobackup' == $_REQUEST['subaction']) {
718
  UpdraftPlus_Options::update_updraft_option('updraftplus_dismissedautobackup', time() + 84*86400);
719
  } elseif (isset($_REQUEST['subaction']) && 'dismissexpiry' == $_REQUEST['subaction']) {
1275
  //$mess[] = sprintf(__('%s version: %s', 'updraftplus'), 'WordPress', $old_wp_version);
1276
  $warn[] = sprintf(__('You are importing from a newer version of WordPress (%s) into an older one (%s). There are no guarantees that WordPress can handle this.', 'updraftplus'), $old_wp_version, $wp_version);
1277
  }
1278
+ } elseif ('' == $old_table_prefix && (preg_match('/^\# Table prefix: (\S+)$/', $buffer, $matches) || preg_match('/^-- Table prefix: (\S+)$/i', $buffer, $matches))) {
1279
  $old_table_prefix = $matches[1];
1280
  // echo '<strong>'.__('Old table prefix:', 'updraftplus').'</strong> '.htmlspecialchars($old_table_prefix).'<br>';
1281
  } elseif ($gathering_siteinfo && preg_match('/^\# Site info: (\S+)$/', $buffer, $matches)) {
1453
  add_filter('sanitize_file_name', array($this, 'sanitize_file_name'));
1454
  // handle file upload
1455
 
1456
+ $farray = array('test_form' => true, 'action' => 'plupload_action');
1457
 
1458
  $farray['test_type'] = false;
1459
  $farray['ext'] = 'x-gzip';
1496
  }
1497
  fclose($wh);
1498
  $status['file'] = $updraft_dir.'/'.$final_file;
1499
+ if ('.tar' == substr($final_file, -4, 4)) {
1500
+ if (file_exists($status['file'].'.gz')) unlink($status['file'].'.gz');
1501
+ if (file_exists($status['file'].'.bz2')) unlink($status['file'].'.bz2');
1502
+ } elseif ('.tar.gz' == substr($final_file, -7, 7)) {
1503
+ if (file_exists(substr($status['file'], 0, strlen($status['file'])-3))) unlink(substr($status['file'], 0, strlen($status['file'])-3));
1504
+ if (file_exists(substr($status['file'], 0, strlen($status['file'])-3).'.bz2')) unlink(substr($status['file'], 0, strlen($status['file'])-3).'.bz2');
1505
+ } elseif ('.tar.bz2' == substr($final_file, -8, 8)) {
1506
+ if (file_exists(substr($status['file'], 0, strlen($status['file'])-4))) unlink(substr($status['file'], 0, strlen($status['file'])-4));
1507
+ if (file_exists(substr($status['file'], 0, strlen($status['file'])-4).'.gz')) unlink(substr($status['file'], 0, strlen($status['file'])-3).'.gz');
1508
+ }
1509
  }
1510
  }
1511
 
1545
  exit;
1546
  }
1547
 
1548
+ # Database decrypter
1549
  public function plupload_action2() {
1550
 
1551
  @set_time_limit(900);
1632
 
1633
  global $updraftplus;
1634
 
 
 
1635
  /*
1636
  we use request here because the initial restore is triggered by a POSTed form. we then may need to obtain credentials
1637
  for the WP_Filesystem. to do this WP outputs a form, but we don't pass our parameters via that. So the values are
1852
 
1853
  <tr>
1854
  <th><?php echo htmlspecialchars(__('Backups, logs & restoring','updraftplus')); ?>:</th>
1855
+ <td><a id="updraft_showbackups" href="#" title="<?php _e('Press to see available backups','updraftplus');?>" onclick="jQuery('.download-backups').fadeToggle(); updraft_historytimertoggle(0); return false;"><?php echo sprintf(__('%d set(s) available', 'updraftplus'), count($backup_history)); ?></a></td>
1856
  </tr>
1857
  <?php
1858
  if (defined('UPDRAFTPLUS_EXPERIMENTAL_MISC') && UPDRAFTPLUS_EXPERIMENTAL_MISC == true) {
1897
 
1898
  <div id="updraft-plupload-modal" title="<?php _e('UpdraftPlus - Upload backup files','updraftplus'); ?>" style="width: 75%; margin: 16px; display:none; margin-left: 100px;">
1899
  <p style="max-width: 610px;"><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>
1900
+ <?php
1901
+ global $wp_version;
1902
+ if (version_compare($wp_version, '3.3', '<')) {
1903
+ echo '<em>'.sprintf(__('This feature requires %s version %s or later', 'updraftplus'), 'WordPress', '3.3').'</em>';
1904
+ } else {
1905
+ ?>
1906
+ <div id="plupload-upload-ui" style="width: 70%;">
1907
+ <div id="drag-drop-area">
1908
+ <div class="drag-drop-inside">
1909
+ <p class="drag-drop-info"><?php _e('Drop backup files here', 'updraftplus'); ?></p>
1910
+ <p><?php _ex('or', 'Uploader: Drop backup files here - or - Select Files'); ?></p>
1911
+ <p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
1912
+ </div>
1913
+ </div>
1914
+ <div id="filelist">
1915
  </div>
1916
  </div>
1917
+ <?php
1918
+ }
1919
+ ?>
1920
 
1921
  </div>
1922
 
2082
  echo __('PHP memory limit','updraftplus').': '.ini_get('memory_limit').' <br/>';
2083
  echo sprintf(__('%s version:','updraftplus'), 'PHP').' '.phpversion().' - ';
2084
  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/>';
2085
+ global $wpdb;
2086
+ echo sprintf(__('%s version:','updraftplus'), 'MySQL').' '.htmlspecialchars($wpdb->db_version()).'<br>';
2087
+ echo sprintf(__('%s version:','updraftplus'), 'Curl').' ';
2088
+ if (function_exists('curl_version') && function_exists('curl_exec')) {
2089
+ $cv = curl_version();
2090
+ echo $cv['version'].' / SSL: '.$cv['ssl_version'].' / libz: '.$cv['libz_version'];
2091
+ } else {
2092
+ echo '-';
2093
+ }
2094
+
2095
+ echo '<br>';
2096
 
2097
  if (version_compare(phpversion(), '5.2.0', '>=') && extension_loaded('zip')) {
2098
  $ziparchive_exists = __('Yes', 'updraftplus');
2117
 
2118
  echo __('Install plugins for debugging:', 'updraftplus').' <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=wp-crontrol'), 'install-plugin_wp-crontrol').'">WP Crontrol</a> | <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=sql-executioner'), 'install-plugin_sql-executioner').'">SQL Executioner</a> | <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=advanced-code-editor'), 'install-plugin_advanced-code-editor').'">Advanced Code Editor</a> | <a href="'.wp_nonce_url(self_admin_url('update.php?action=install-plugin&updraftplus_noautobackup=1&plugin=wp-filemanager'), 'install-plugin_wp-filemanager').'">WP Filemanager</a><br>';
2119
 
2120
+ echo "HTTP Get: ";
2121
+ echo '<input id="updraftplus_httpget_uri" type="text" style="width: 300px; height: 22px;"> ';
2122
+ echo '<a href="#" id="updraftplus_httpget_go">'.__('Fetch', 'updraftplus').'</a> ';
2123
+ echo '<a href="#" id="updraftplus_httpget_gocurl">'.__('Fetch', 'updraftplus').' (Curl)</a>';
2124
+ echo '<p id="updraftplus_httpget_results"></p>';
2125
+
2126
+ echo "Call WordPress action: ";
2127
+ echo '<input id="updraftplus_callwpaction" type="text" style="width: 300px; height: 22px;"> ';
2128
+ echo '<a href="#" id="updraftplus_callwpaction_go">'.__('Call', 'updraftplus').'</a> ';
2129
+ echo '<p id="updraftplus_callwpaction_results"></p>';
2130
+
2131
  echo '<h3>'.__('Total (uncompressed) on-disk data:','updraftplus').'</h3>';
2132
  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>';
2133
 
2177
  <?php if ($include_blurb) {
2178
  ?>
2179
  <div id="updraft_delete_old_dirs_pagediv" class="updated" style="padding:8px;"><p> <?php _e('Your WordPress install has old directories from its state before you restored/migrated (technical information: these are suffixed with -old). You should press this button to delete them as soon as you have verified that the restoration worked.','updraftplus');?></p><?php } ?>
2180
+ <form method="post" onsubmit="return updraft_delete_old_dirs();" action="<?php echo add_query_arg(array('updraft_restore_success' => false, 'action' => false, 'page' => 'updraftplus')); ?>">
2181
  <?php wp_nonce_field('updraftplus-credentialtest-nonce'); ?>
2182
+ <input type="hidden" name="action" value="updraft_delete_old_dirs">
2183
  <input type="submit" class="button-primary" value="<?php echo esc_attr(__('Delete Old Directories', 'updraftplus'));?>" />
2184
  </form>
2185
  <?php
2187
  }
2188
 
2189
 
2190
+ private function print_active_jobs() {
2191
  $cron = get_option('cron');
2192
  if (!is_array($cron)) $cron = array();
2193
  // $found_jobs = 0;
2212
  return $ret;
2213
  }
2214
 
2215
+ private function print_active_job($job_id, $is_oneshot = false, $time = false, $next_resumption = false) {
2216
 
2217
  $ret = '';
2218
 
2356
 
2357
  }
2358
 
2359
+ private function delete_old_dirs_go($show_return = true) {
2360
  echo ($show_return) ? '<h1>UpdraftPlus - '.__('Remove old directories', 'updraftplus').'</h1>' : '<h2>'.__('Remove old directories', 'updraftplus').'</h2>';
2361
 
2362
  if($this->delete_old_dirs()) {
2368
  }
2369
 
2370
  //deletes the -old directories that are created when a backup is restored.
2371
+ private function delete_old_dirs() {
2372
  global $wp_filesystem, $updraftplus;
2373
  $credentials = request_filesystem_credentials(wp_nonce_url(UpdraftPlus_Options::admin_page_url()."?page=updraftplus&action=updraft_delete_old_dirs", 'updraftplus-credentialtest-nonce'));
2374
  WP_Filesystem($credentials);
2405
  return $ret && $ret3 && $ret4;
2406
  }
2407
 
2408
+ private function delete_old_dirs_dir($dir, $wpfs = true) {
2409
 
2410
  $dir = trailingslashit($dir);
2411
 
2446
  }
2447
 
2448
  // The aim is to get a directory that is writable by the webserver, because that's the only way we can create zip files
2449
+ private function create_backup_dir() {
2450
 
2451
  global $wp_filesystem, $updraftplus;
2452
 
2500
  }
2501
 
2502
  //scans the content dir to see if any -old dirs are present
2503
+ private function scan_old_dirs() {
2504
  global $updraftplus;
2505
  $dirs = scandir(untrailingslashit(WP_CONTENT_DIR));
2506
  if (!is_array($dirs)) $dirs = array();
2512
  return false;
2513
  }
2514
 
2515
+ public function storagemethod_row($method, $header, $contents) {
2516
+ ?>
2517
+ <tr class="updraftplusmethod <?php echo $method;?>">
2518
+ <th><?php echo $header;?></th>
2519
+ <td><?php echo $contents;?></td>
2520
+ </tr>
2521
+ <?php
2522
+ }
2523
+
2524
  private function last_backup_html() {
2525
 
2526
  global $updraftplus;
2689
 
2690
  <div id="updraft-manualdecrypt-modal" style="width: 85%; margin: 16px; display:none; margin-left: 100px;">
2691
  <p><h3><?php _e("Manually decrypt a database backup file" ,'updraftplus');?></h3></p>
2692
+
2693
+ <?php
2694
+ global $wp_version;
2695
+ if (version_compare($wp_version, '3.3', '<')) {
2696
+ echo '<em>'.sprintf(__('This feature requires %s version %s or later', 'updraftplus'), 'WordPress', '3.3').'</em>';
2697
+ } else {
2698
+ ?>
2699
+
2700
  <div id="plupload-upload-ui2" style="width: 80%;">
2701
  <div id="drag-drop-area2">
2702
  <div class="drag-drop-inside">
2710
  </div>
2711
  </div>
2712
 
2713
+ <?php } ?>
2714
+
2715
  </div>
2716
 
2717
 
2929
  <?php
2930
  }
2931
 
2932
+ public function show_double_warning($text, $extraclass = '', $echo = true) {
 
 
2933
 
2934
+ $ret = "<div class=\"error updraftplusmethod $extraclass\"><p>$text</p></div>";
2935
+ $ret .= "<p style=\"border:1px solid; padding: 6px;\">$text</p>";
2936
 
2937
+ if ($echo) echo $ret;
2938
+ return $ret;
2939
 
2940
  }
2941
 
2942
+ public function optionfilter_split_every($value) {
2943
+ $value = absint($value);
2944
  if (!$value >= UPDRAFTPLUS_SPLIT_MIN) $value = UPDRAFTPLUS_SPLIT_MIN;
2945
  return $value;
2946
  }
2947
 
2948
+ public function curl_check($service, $has_fallback = false, $extraclass = '', $echo = true) {
2949
+
2950
+ $ret = '';
2951
+
2952
  // Check requirements
2953
  if (!function_exists("curl_init") || !function_exists('curl_exec')) {
2954
 
2955
+ $ret .= $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, false);
2956
 
2957
  } else {
2958
  $curl_version = curl_version();
2959
  $curl_ssl_supported= ($curl_version['features'] & CURL_VERSION_SSL);
2960
  if (!$curl_ssl_supported) {
2961
  if ($has_fallback) {
2962
+ $ret .= '<p><strong>'.__('Warning','updraftplus').':</strong> '.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>';
2963
  } else {
2964
+ $ret .= $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, false);
2965
  }
2966
  } else {
2967
+ $ret .= '<p><em>'.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>';
2968
  }
2969
  }
2970
+ if ($echo) {
2971
+ echo $ret;
2972
+ } else {
2973
+ return $ret;
2974
+ }
2975
  }
2976
 
2977
  # If $basedirs is passed as an array, then $directorieses must be too
3339
  }
3340
  } elseif (is_wp_error($files)) {
3341
  foreach ($files->get_error_codes() as $code) {
3342
+ if ('no_settings' == $code || 'no_addon' == $code || 'insufficient_php' == $code) continue;
3343
  $messages[] = array(
3344
  'method' => $method,
3345
  'desc' => $desc,
3561
  }
3562
 
3563
  foreach ($_POST as $key => $value) {
3564
+ if (0 === strpos($key, 'updraft_restore_')) {
3565
  $nkey = substr($key, 16);
3566
  if (!isset($entities_to_restore[$nkey])) {
3567
  $_POST['updraft_restore'][] = $nkey;
3578
  }
3579
  }
3580
 
 
 
3581
  if (0 == count($_POST['updraft_restore'])) {
3582
  echo '<p>'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'</p>';
3583
  echo '<p>'.__('If making a request for support, please include this information:','updraftplus').' '.count($_POST).' : '.htmlspecialchars(serialize($_POST)).'</p>';
3584
  return new WP_Error('missing_info', 'Backup information not found');
3585
  }
3586
 
3587
+ $updraftplus->log("Restore job started. Entities to restore: ".implode(', ', array_flip($entities_to_restore)));
3588
+
3589
  set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT);
3590
 
3591
  /*
3774
  add_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt));
3775
  }
3776
  if (!function_exists('validate_current_theme')) require_once(ABSPATH.'wp-includes/themes');
3777
+
3778
+ # Have seen a case where the current theme in the DB began with a capital, but not on disk - and this breaks migrating from Windows to a case-sensitive system
3779
+ $template = get_option('template');
3780
+ if (!empty($template) && $template != WP_DEFAULT_THEME && $template != strtolower($template)) {
3781
+
3782
+ $theme_root = get_theme_root($template);
3783
+ $theme_root2 = get_theme_root(strtolower($template));
3784
+
3785
+ if (!file_exists("$theme_root/$template/style.css") && file_exists("$theme_root/".strtolower($template)."/style.css")) {
3786
+ $updraftplus->log_e("Theme directory (%s) not found, but lower-case version exists; updating database option accordingly", $template);
3787
+ update_option('template', strtolower($template));
3788
+ }
3789
+
3790
+ }
3791
+
3792
+
3793
  if (!validate_current_theme()) {
3794
  global $updraftplus;
3795
  echo '<strong>';
3832
  }
3833
 
3834
  private function get_settings_keys() {
3835
+ return array('updraft_autobackup_default', 'updraft_googledrive', 'updraftplus_tmp_googledrive_access_token', 'updraftplus_dismissedautobackup', 'updraftplus_dismissedexpiry', 'updraft_interval', 'updraft_interval_database', 'updraft_retain', 'updraft_retain_db', 'updraft_encryptionphrase', 'updraft_service', 'updraft_dropbox_appkey', 'updraft_dropbox_secret', 'updraft_googledrive_clientid', 'updraft_googledrive_secret', 'updraft_googledrive_remotepath', 'updraft_ftp_login', 'updraft_ftp_pass', 'updraft_ftp_remote_path', 'updraft_server_address', 'updraft_dir', 'updraft_email', 'updraft_delete_local', 'updraft_debug_mode', 'updraft_include_plugins', 'updraft_include_themes', 'updraft_include_uploads', 'updraft_include_others', 'updraft_include_wpcore', 'updraft_include_wpcore_exclude', 'updraft_include_more', 'updraft_include_blogs', 'updraft_include_mu-plugins', 'updraft_include_others_exclude', 'updraft_include_uploads_exclude', 'updraft_lastmessage', 'updraft_googledrive_token',
3836
  'updraft_dropboxtk_request_token', 'updraft_dropboxtk_access_token', 'updraft_dropbox_folder',
3837
+ 'updraft_last_backup', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_db', 'updraft_startday_files', 'updraft_sftp_settings', 'updraft_s3', 'updraft_s3generic', 'updraft_dreamhost', 'updraft_s3generic_login', 'updraft_s3generic_pass', 'updraft_s3generic_remote_path', 'updraft_s3generic_endpoint', 'updraft_webdav_settings', 'updraft_disable_ping', 'updraft_openstack', 'updraft_bitcasa', 'updraft_cloudfiles', 'updraft_cloudfiles_user', 'updraft_cloudfiles_apikey', 'updraft_cloudfiles_path', 'updraft_cloudfiles_authurl', 'updraft_ssl_useservercerts', 'updraft_ssl_disableverify', 'updraft_s3_login', 'updraft_s3_pass', 'updraft_s3_remote_path', 'updraft_dreamobjects_login', 'updraft_dreamobjects_pass', 'updraft_dreamobjects_remote_path', 'updraft_report_warningsonly', 'updraft_report_wholebackup', 'updraft_log_syslog');
3838
  }
3839
 
3840
  }
 
 
backup.php CHANGED
@@ -141,7 +141,8 @@ class UpdraftPlus_Backup {
141
  $time_mod = (int)@filemtime($zip_name);
142
  if (file_exists($zip_name) && $time_mod>100 && ($time_now-$time_mod)<30) {
143
  $updraftplus->terminate_due_to_activity($zip_name, $time_now, $time_mod);
144
- } elseif (file_exists($zip_name)) {
 
145
  $updraftplus->log("File exists ($zip_name), but was apparently not modified within the last 30 seconds, so we assume that any previous run has now terminated (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).")");
146
  }
147
 
@@ -259,7 +260,7 @@ class UpdraftPlus_Backup {
259
  $method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
260
  if (file_exists($method_include)) require_once($method_include);
261
 
262
- if ($service == "none" || $service == "") {
263
  $updraftplus->log("No remote despatch: user chose no remote backup service");
264
  $this->prune_retained_backups(array("none" => array(null, null)));
265
  } else {
@@ -841,6 +842,16 @@ class UpdraftPlus_Backup {
841
 
842
  $total_tables = 0;
843
 
 
 
 
 
 
 
 
 
 
 
844
  $all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
845
  $all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
846
 
@@ -860,12 +871,23 @@ class UpdraftPlus_Backup {
860
  # Why not just fail now? We saw a bizarre case when the results of really_is_writable() changed during the run.
861
  }
862
 
 
 
 
 
 
 
 
 
 
863
  $stitch_files = array();
864
 
865
  $how_many_tables = count($all_tables);
866
 
867
  $found_options_table = false;
868
 
 
 
869
  foreach ($all_tables as $table) {
870
 
871
  $manyrows_warning = false;
@@ -876,14 +898,14 @@ class UpdraftPlus_Backup {
876
  // The table file may already exist if we have produced it on a previous run
877
  $table_file_prefix = $file_base.'-db-table-'.$table.'.table';
878
 
879
- if ($this->table_prefix_raw.'options' == $table) $found_options_table = true;
880
 
881
  if (file_exists($this->updraft_dir.'/'.$table_file_prefix.'.gz')) {
882
  $updraftplus->log("Table $table: corresponding file already exists; moving on");
883
  $stitch_files[] = $table_file_prefix;
884
  } else {
885
  # === is needed, otherwise 'false' matches (i.e. prefix does not match)
886
- if (empty($this->table_prefix) || strpos($table, $this->table_prefix) === 0 ) {
887
 
888
  // Open file, store the handle
889
  $opened = $this->backup_db_open($this->updraft_dir.'/'.$table_file_prefix.'.tmp.gz', true);
@@ -905,9 +927,9 @@ class UpdraftPlus_Backup {
905
  }
906
 
907
  # Don't include the job data for any backups - so that when the database is restored, it doesn't continue an apparently incomplete backup
908
- if (!empty($this->table_prefix) && $this->table_prefix.'sitemeta' == $table) {
909
  $where = 'meta_key NOT LIKE "updraft_jobdata_%"';
910
- } elseif (!empty($this->table_prefix) && $this->table_prefix.'options' == $table) {
911
  $where = 'option_name NOT LIKE "updraft_jobdata_%"';
912
  } else {
913
  $where = '';
@@ -943,7 +965,7 @@ class UpdraftPlus_Backup {
943
  # Have seen this happen; not sure how, but it was apparently deterministic; if the current process had been running for a long time, then apparently all database commands silently failed.
944
  # If we have been running that long, then the resumption may be far off; bring it closer
945
  $updraftplus->reschedule(60);
946
- $updraftplus->log("Have been running very long, and it seems the database went away; terminating");
947
  $updraftplus->record_still_alive();
948
  die;
949
  }
@@ -957,11 +979,17 @@ class UpdraftPlus_Backup {
957
  $time_mod = (int)@filemtime($backup_final_file_name);
958
  if (file_exists($backup_final_file_name) && $time_mod>100 && ($time_now-$time_mod)<30) {
959
  $updraftplus->terminate_due_to_activity($backup_final_file_name, $time_now, $time_mod);
960
- } elseif (file_exists($backup_final_file_name)) {
 
961
  $updraftplus->log("The final database file ($backup_final_file_name) exists, but was apparently not modified within the last 30 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod)."). Thus we assume that another UpdraftPlus terminated; thus we will continue.");
962
  }
963
 
964
  // Finally, stitch the files together
 
 
 
 
 
965
  $opendb = $this->backup_db_open($backup_final_file_name, true);
966
  if (false === $opendb) return false;
967
  $this->backup_db_header();
@@ -1140,12 +1168,18 @@ class UpdraftPlus_Backup {
1140
  }
1141
 
1142
  // Experimentation here shows that on large tables (we tested with 180,000 rows) on MyISAM, 1000 makes the table dump out 3x faster than the previous value of 100. After that, the benefit diminishes (increasing to 4000 only saved another 12%)
 
 
 
 
 
 
1143
  if($segment == 'none') {
1144
  $row_start = 0;
1145
- $row_inc = 1000;
1146
  } else {
1147
- $row_start = $segment * 1000;
1148
- $row_inc = 1000;
1149
  }
1150
 
1151
  $search = array("\x00", "\x0a", "\x0d", "\x1a");
@@ -1311,7 +1345,11 @@ class UpdraftPlus_Backup {
1311
  if (empty($this->attachments) || !is_array($this->attachments)) return;
1312
  foreach ($this->attachments as $attach) {
1313
  $mime_type = (preg_match('/\.gz$/', $attach)) ? 'application/x-gzip' : 'text/plain';
1314
- $phpmailer->AddAttachment($attach, '', 'base64', $mime_type);
 
 
 
 
1315
  }
1316
  }
1317
 
@@ -1691,15 +1729,16 @@ class UpdraftPlus_Backup {
1691
  # Since we don't test before the file has been created (so that zip_last_ratio has meaningful data), we rely on max_zip_batch being less than zip_split_every - which should always be the case
1692
  $reaching_split_limit = ( $this->zip_last_ratio > 0 && $original_size>0 && ($original_size + 1.1*$data_added_since_reopen*$this->zip_last_ratio) > $this->zip_split_every) ? true : false;
1693
 
1694
- if ($zipfiles_added_thisbatch > 500 || $reaching_split_limit || $data_added_since_reopen > $maxzipbatch || (time() - $this->zipfiles_lastwritetime) > 1.5) {
1695
 
 
1696
  $something_useful_sizetest = false;
1697
 
1698
  if ($data_added_since_reopen > $maxzipbatch) {
1699
  $something_useful_sizetest = true;
1700
  $updraftplus->log("Adding batch to zip file (".$this->use_zip_object."): over ".round($maxzipbatch/1048576,1)." Mb added on this batch (".round($data_added_since_reopen/1048576,1)." Mb, ".count($this->zipfiles_batched)." files batched, $zipfiles_added_thisbatch (".$this->zipfiles_added_thisrun.") added so far); re-opening (prior size: ".round($original_size/1024,1).' Kb)');
1701
- } elseif ($zipfiles_added_thisbatch >500) {
1702
- $updraftplus->log("Adding batch to zip file (".$this->use_zip_object."): over 500 files added on this batch (".round($data_added_since_reopen/1048576,1)." Mb, ".count($this->zipfiles_batched)." files batched, $zipfiles_added_thisbatch (".$this->zipfiles_added_thisrun.") added so far); re-opening (prior size: ".round($original_size/1024,1).' Kb)');
1703
  } elseif (!$reaching_split_limit) {
1704
  $updraftplus->log("Adding batch to zip file (".$this->use_zip_object."): over 1.5 seconds have passed since the last write (".round($data_added_since_reopen/1048576,1)." Mb, $zipfiles_added_thisbatch (".$this->zipfiles_added_thisrun.") files added so far); re-opening (prior size: ".round($original_size/1024,1).' Kb)');
1705
  } else {
@@ -1713,7 +1752,7 @@ class UpdraftPlus_Backup {
1713
  }
1714
  }
1715
  $zipfiles_added_thisbatch = 0;
1716
-
1717
  # This triggers a re-open, later
1718
  unset($zip);
1719
  $files_zipadded_since_open = array();
141
  $time_mod = (int)@filemtime($zip_name);
142
  if (file_exists($zip_name) && $time_mod>100 && ($time_now-$time_mod)<30) {
143
  $updraftplus->terminate_due_to_activity($zip_name, $time_now, $time_mod);
144
+ }
145
+ if (file_exists($zip_name)) {
146
  $updraftplus->log("File exists ($zip_name), but was apparently not modified within the last 30 seconds, so we assume that any previous run has now terminated (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod).")");
147
  }
148
 
260
  $method_include = UPDRAFTPLUS_DIR.'/methods/'.$service.'.php';
261
  if (file_exists($method_include)) require_once($method_include);
262
 
263
+ if ($service == "none" || '' == $service) {
264
  $updraftplus->log("No remote despatch: user chose no remote backup service");
265
  $this->prune_retained_backups(array("none" => array(null, null)));
266
  } else {
842
 
843
  $total_tables = 0;
844
 
845
+ # WP 3.9 onwards - https://core.trac.wordpress.org/browser/trunk/src/wp-includes/wp-db.php?rev=27925 - check_connection() allows us to get the database connection back if it had dropped
846
+ if (method_exists($wpdb, 'check_connection')) {
847
+ if (!$wpdb->check_connection(false)) {
848
+ $updraftplus->reschedule(60);
849
+ $updraftplus->log("It seems the database went away; scheduling a resumption and terminating for now");
850
+ $updraftplus->record_still_alive();
851
+ die;
852
+ }
853
+ }
854
+
855
  $all_tables = $wpdb->get_results("SHOW TABLES", ARRAY_N);
856
  $all_tables = array_map(create_function('$a', 'return $a[0];'), $all_tables);
857
 
871
  # Why not just fail now? We saw a bizarre case when the results of really_is_writable() changed during the run.
872
  }
873
 
874
+ # This check doesn't strictly get all possible duplicates; it's only designed for the case that can happen when moving between deprecated Windows setups and Linux
875
+ $duplicate_tables_exist = false;
876
+ foreach ($all_tables as $table) {
877
+ if (strtolower($table) != $table && in_array(strtolower($table), $all_tables)) {
878
+ $duplicate_tables_exist = true;
879
+ $updraftplus->log("Tables with names differing only based on case-sensitivity exist in the MySQL database: $table / ".strtolower($table));
880
+ }
881
+ }
882
+
883
  $stitch_files = array();
884
 
885
  $how_many_tables = count($all_tables);
886
 
887
  $found_options_table = false;
888
 
889
+ $is_multisite = is_multisite();
890
+
891
  foreach ($all_tables as $table) {
892
 
893
  $manyrows_warning = false;
898
  // The table file may already exist if we have produced it on a previous run
899
  $table_file_prefix = $file_base.'-db-table-'.$table.'.table';
900
 
901
+ if (strtolower($this->table_prefix_raw.'options') == strtolower($table) || ($is_multisite && strtolower($this->table_prefix_raw.'1_options') == strtolower($table))) $found_options_table = true;
902
 
903
  if (file_exists($this->updraft_dir.'/'.$table_file_prefix.'.gz')) {
904
  $updraftplus->log("Table $table: corresponding file already exists; moving on");
905
  $stitch_files[] = $table_file_prefix;
906
  } else {
907
  # === is needed, otherwise 'false' matches (i.e. prefix does not match)
908
+ if (empty($this->table_prefix) || ($duplicate_tables_exist == false && stripos($table, $this->table_prefix) === 0 ) || ($duplicate_tables_exist == true && strpos($table, $this->table_prefix) === 0 )) {
909
 
910
  // Open file, store the handle
911
  $opened = $this->backup_db_open($this->updraft_dir.'/'.$table_file_prefix.'.tmp.gz', true);
927
  }
928
 
929
  # Don't include the job data for any backups - so that when the database is restored, it doesn't continue an apparently incomplete backup
930
+ if (!empty($this->table_prefix) && strtolower($this->table_prefix.'sitemeta') == strtolower($table)) {
931
  $where = 'meta_key NOT LIKE "updraft_jobdata_%"';
932
+ } elseif (!empty($this->table_prefix) && strtolower($this->table_prefix.'options') == strtolower($table)) {
933
  $where = 'option_name NOT LIKE "updraft_jobdata_%"';
934
  } else {
935
  $where = '';
965
  # Have seen this happen; not sure how, but it was apparently deterministic; if the current process had been running for a long time, then apparently all database commands silently failed.
966
  # If we have been running that long, then the resumption may be far off; bring it closer
967
  $updraftplus->reschedule(60);
968
+ $updraftplus->log("Have been running very long, and it seems the database went away; scheduling a resumption and terminating for now");
969
  $updraftplus->record_still_alive();
970
  die;
971
  }
979
  $time_mod = (int)@filemtime($backup_final_file_name);
980
  if (file_exists($backup_final_file_name) && $time_mod>100 && ($time_now-$time_mod)<30) {
981
  $updraftplus->terminate_due_to_activity($backup_final_file_name, $time_now, $time_mod);
982
+ }
983
+ if (file_exists($backup_final_file_name)) {
984
  $updraftplus->log("The final database file ($backup_final_file_name) exists, but was apparently not modified within the last 30 seconds (time_mod=$time_mod, time_now=$time_now, diff=".($time_now-$time_mod)."). Thus we assume that another UpdraftPlus terminated; thus we will continue.");
985
  }
986
 
987
  // Finally, stitch the files together
988
+
989
+ if (!function_exists('gzopen')) {
990
+ $updraftplus->log("PHP function is disabled; abort expected: gzopen");
991
+ }
992
+
993
  $opendb = $this->backup_db_open($backup_final_file_name, true);
994
  if (false === $opendb) return false;
995
  $this->backup_db_header();
1168
  }
1169
 
1170
  // Experimentation here shows that on large tables (we tested with 180,000 rows) on MyISAM, 1000 makes the table dump out 3x faster than the previous value of 100. After that, the benefit diminishes (increasing to 4000 only saved another 12%)
1171
+
1172
+ $increment = 1000;
1173
+ if (!$updraftplus->something_useful_happened && !empty($updraftplus->current_resumption) && ($updraftplus->current_resumption - $updraftplus->last_successful_resumption > 1)) {
1174
+ $increment = 500;
1175
+ }
1176
+
1177
  if($segment == 'none') {
1178
  $row_start = 0;
1179
+ $row_inc = $increment;
1180
  } else {
1181
+ $row_start = $segment * $increment;
1182
+ $row_inc = $increment;
1183
  }
1184
 
1185
  $search = array("\x00", "\x0a", "\x0d", "\x1a");
1345
  if (empty($this->attachments) || !is_array($this->attachments)) return;
1346
  foreach ($this->attachments as $attach) {
1347
  $mime_type = (preg_match('/\.gz$/', $attach)) ? 'application/x-gzip' : 'text/plain';
1348
+ try {
1349
+ $phpmailer->AddAttachment($attach, '', 'base64', $mime_type);
1350
+ } catch (Exception $e) {
1351
+ $updraftplus->log("Exception occurred when adding attachment (".get_class($e)."): ".$e->getMessage());
1352
+ }
1353
  }
1354
  }
1355
 
1729
  # Since we don't test before the file has been created (so that zip_last_ratio has meaningful data), we rely on max_zip_batch being less than zip_split_every - which should always be the case
1730
  $reaching_split_limit = ( $this->zip_last_ratio > 0 && $original_size>0 && ($original_size + 1.1*$data_added_since_reopen*$this->zip_last_ratio) > $this->zip_split_every) ? true : false;
1731
 
1732
+ if ($zipfiles_added_thisbatch > UPDRAFTPLUS_MAXBATCHFILES || $reaching_split_limit || $data_added_since_reopen > $maxzipbatch || (time() - $this->zipfiles_lastwritetime) > 1.5) {
1733
 
1734
+ @set_time_limit(900);
1735
  $something_useful_sizetest = false;
1736
 
1737
  if ($data_added_since_reopen > $maxzipbatch) {
1738
  $something_useful_sizetest = true;
1739
  $updraftplus->log("Adding batch to zip file (".$this->use_zip_object."): over ".round($maxzipbatch/1048576,1)." Mb added on this batch (".round($data_added_since_reopen/1048576,1)." Mb, ".count($this->zipfiles_batched)." files batched, $zipfiles_added_thisbatch (".$this->zipfiles_added_thisrun.") added so far); re-opening (prior size: ".round($original_size/1024,1).' Kb)');
1740
+ } elseif ($zipfiles_added_thisbatch > UPDRAFTPLUS_MAXBATCHFILES) {
1741
+ $updraftplus->log("Adding batch to zip file (".$this->use_zip_object."): over ".UPDRAFTPLUS_MAXBATCHFILES." files added on this batch (".round($data_added_since_reopen/1048576,1)." Mb, ".count($this->zipfiles_batched)." files batched, $zipfiles_added_thisbatch (".$this->zipfiles_added_thisrun.") added so far); re-opening (prior size: ".round($original_size/1024,1).' Kb)');
1742
  } elseif (!$reaching_split_limit) {
1743
  $updraftplus->log("Adding batch to zip file (".$this->use_zip_object."): over 1.5 seconds have passed since the last write (".round($data_added_since_reopen/1048576,1)." Mb, $zipfiles_added_thisbatch (".$this->zipfiles_added_thisrun.") files added so far); re-opening (prior size: ".round($original_size/1024,1).' Kb)');
1744
  } else {
1752
  }
1753
  }
1754
  $zipfiles_added_thisbatch = 0;
1755
+
1756
  # This triggers a re-open, later
1757
  unset($zip);
1758
  $files_zipadded_since_open = array();
class-zip.php CHANGED
@@ -155,7 +155,11 @@ class UpdraftPlus_BinZip extends UpdraftPlus_PclZip {
155
  $ret = proc_close($process);
156
 
157
  if ($ret != 0 && $ret != 12) {
158
- $updraftplus->log("Binary zip: error (code: $ret - look it up in the Diagnostics section at http://www.info-zip.org/mans/zip.html for interpretation... and also check that your hosting account quota is not full)");
 
 
 
 
159
  if (!empty($w) && !$updraftplus_backup->debug) $updraftplus->log("Last output from zip: ".trim($w), 'debug');
160
  return false;
161
  }
155
  $ret = proc_close($process);
156
 
157
  if ($ret != 0 && $ret != 12) {
158
+ if ($ret < 128) {
159
+ $updraftplus->log("Binary zip: error (code: $ret - look it up in the Diagnostics section of the zip manual at http://www.info-zip.org/mans/zip.html for interpretation... and also check that your hosting account quota is not full)");
160
+ } else {
161
+ $updraftplus->log("Binary zip: error (code: $ret - a code above 127 normally means that the zip process was deliberately killed ... and also check that your hosting account quota is not full)");
162
+ }
163
  if (!empty($w) && !$updraftplus_backup->debug) $updraftplus->log("Last output from zip: ".trim($w), 'debug');
164
  return false;
165
  }
example-decrypt.php CHANGED
@@ -35,5 +35,3 @@ function rijndael_decrypt_file($file, $key) {
35
  print $rijndael->decrypt($ciphertext);
36
 
37
  }
38
-
39
- ?>
35
  print $rijndael->decrypt($ciphertext);
36
 
37
  }
 
 
images/bitcasa.png ADDED
Binary file
images/copy.png ADDED
Binary file
includes/Dropbox/OAuth/Consumer/ConsumerAbstract.php CHANGED
@@ -86,7 +86,7 @@ abstract class Dropbox_ConsumerAbstract
86
  header('Location: ' . $url);
87
  exit;
88
  } else {
89
- throw new Dropbox_Exception(sprintf(__('The %s authentication could not go ahead, because something else on your site is breaking it. Try disabling your other plugins and switching to a default theme. (Specifically, you are looking for the component that sends output (most likely PHP warnings/errors) before the page begins. Turning off any debugging settings may also help).', ''), 'Dropbox'));
90
  }
91
  ?><?php
92
  return false;
86
  header('Location: ' . $url);
87
  exit;
88
  } else {
89
+ throw new Dropbox_Exception(sprintf(__('The %s authentication could not go ahead, because something else on your site is breaking it. Try disabling your other plugins and switching to a default theme. (Specifically, you are looking for the component that sends output (most likely PHP warnings/errors) before the page begins. Turning off any debugging settings may also help).', 'updraftplus'), 'Dropbox'));
90
  }
91
  ?><?php
92
  return false;
includes/Google/Auth/Abstract.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once "Google/Http/Request.php";
18
+
19
+ /**
20
+ * Abstract class for the Authentication in the API client
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ *
23
+ */
24
+ abstract class Google_Auth_Abstract
25
+ {
26
+ /**
27
+ * An utility function that first calls $this->auth->sign($request) and then
28
+ * executes makeRequest() on that signed request. Used for when a request
29
+ * should be authenticated
30
+ * @param Google_Http_Request $request
31
+ * @return Google_Http_Request $request
32
+ */
33
+ abstract public function authenticatedRequest(Google_Http_Request $request);
34
+
35
+ abstract public function authenticate($code);
36
+ abstract public function sign(Google_Http_Request $request);
37
+ abstract public function createAuthUrl($scope);
38
+
39
+ abstract public function refreshToken($refreshToken);
40
+ abstract public function revokeToken();
41
+ }
includes/Google/Auth/AssertionCredentials.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google/Auth/OAuth2.php";
19
+ require_once "Google/Signer/P12.php";
20
+ require_once "Google/Utils.php";
21
+
22
+ /**
23
+ * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
24
+ *
25
+ * @author Chirag Shah <chirags@google.com>
26
+ */
27
+ class Google_Auth_AssertionCredentials
28
+ {
29
+ const MAX_TOKEN_LIFETIME_SECS = 3600;
30
+
31
+ public $serviceAccountName;
32
+ public $scopes;
33
+ public $privateKey;
34
+ public $privateKeyPassword;
35
+ public $assertionType;
36
+ public $sub;
37
+ /**
38
+ * @deprecated
39
+ * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
40
+ */
41
+ public $prn;
42
+ private $useCache;
43
+
44
+ /**
45
+ * @param $serviceAccountName
46
+ * @param $scopes array List of scopes
47
+ * @param $privateKey
48
+ * @param string $privateKeyPassword
49
+ * @param string $assertionType
50
+ * @param bool|string $sub The email address of the user for which the
51
+ * application is requesting delegated access.
52
+ * @param bool useCache Whether to generate a cache key and allow
53
+ * automatic caching of the generated token.
54
+ */
55
+ public function __construct(
56
+ $serviceAccountName,
57
+ $scopes,
58
+ $privateKey,
59
+ $privateKeyPassword = 'notasecret',
60
+ $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
61
+ $sub = false,
62
+ $useCache = true
63
+ ) {
64
+ $this->serviceAccountName = $serviceAccountName;
65
+ $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
66
+ $this->privateKey = $privateKey;
67
+ $this->privateKeyPassword = $privateKeyPassword;
68
+ $this->assertionType = $assertionType;
69
+ $this->sub = $sub;
70
+ $this->prn = $sub;
71
+ $this->useCache = $useCache;
72
+ }
73
+
74
+ /**
75
+ * Generate a unique key to represent this credential.
76
+ * @return string
77
+ */
78
+ public function getCacheKey()
79
+ {
80
+ if (!$this->useCache) {
81
+ return false;
82
+ }
83
+ $h = $this->sub;
84
+ $h .= $this->assertionType;
85
+ $h .= $this->privateKey;
86
+ $h .= $this->scopes;
87
+ $h .= $this->serviceAccountName;
88
+ return md5($h);
89
+ }
90
+
91
+ public function generateAssertion()
92
+ {
93
+ $now = time();
94
+
95
+ $jwtParams = array(
96
+ 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI,
97
+ 'scope' => $this->scopes,
98
+ 'iat' => $now,
99
+ 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
100
+ 'iss' => $this->serviceAccountName,
101
+ );
102
+
103
+ if ($this->sub !== false) {
104
+ $jwtParams['sub'] = $this->sub;
105
+ } else if ($this->prn !== false) {
106
+ $jwtParams['prn'] = $this->prn;
107
+ }
108
+
109
+ return $this->makeSignedJwt($jwtParams);
110
+ }
111
+
112
+ /**
113
+ * Creates a signed JWT.
114
+ * @param array $payload
115
+ * @return string The signed JWT.
116
+ */
117
+ private function makeSignedJwt($payload)
118
+ {
119
+ $header = array('typ' => 'JWT', 'alg' => 'RS256');
120
+
121
+ $segments = array(
122
+ Google_Utils::urlSafeB64Encode(json_encode($header)),
123
+ Google_Utils::urlSafeB64Encode(json_encode($payload))
124
+ );
125
+
126
+ $signingInput = implode('.', $segments);
127
+ $signer = new Google_Signer_P12($this->privateKey, $this->privateKeyPassword);
128
+ $signature = $signer->sign($signingInput);
129
+ $segments[] = Google_Utils::urlSafeB64Encode($signature);
130
+
131
+ return implode(".", $segments);
132
+ }
133
+ }
includes/Google/Auth/Exception.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google/Exception.php";
19
+
20
+ class Google_Auth_Exception extends Google_Exception
21
+ {
22
+ }
includes/Google/Auth/LoginTicket.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once "Google/Auth/Exception.php";
19
+
20
+ /**
21
+ * Class to hold information about an authenticated login.
22
+ *
23
+ * @author Brian Eaton <beaton@google.com>
24
+ */
25
+ class Google_Auth_LoginTicket
26
+ {
27
+ const USER_ATTR = "sub";
28
+
29
+ // Information from id token envelope.
30
+ private $envelope;
31
+
32
+ // Information from id token payload.
33
+ private $payload;
34
+
35
+ /**
36
+ * Creates a user based on the supplied token.
37
+ *
38
+ * @param string $envelope Header from a verified authentication token.
39
+ * @param string $payload Information from a verified authentication token.
40
+ */
41
+ public function __construct($envelope, $payload)
42
+ {
43
+ $this->envelope = $envelope;
44
+ $this->payload = $payload;
45
+ }
46
+
47
+ /**
48
+ * Returns the numeric identifier for the user.
49
+ * @throws Google_Auth_Exception
50
+ * @return
51
+ */
52
+ public function getUserId()
53
+ {
54
+ if (array_key_exists(self::USER_ATTR, $this->payload)) {
55
+ return $this->payload[self::USER_ATTR];
56
+ }
57
+ throw new Google_Auth_Exception("No user_id in token");
58
+ }
59
+
60
+ /**
61
+ * Returns attributes from the login ticket. This can contain
62
+ * various information about the user session.
63
+ * @return array
64
+ */
65
+ public function getAttributes()
66
+ {
67
+ return array("envelope" => $this->envelope, "payload" => $this->payload);
68
+ }
69
+ }
includes/Google/Auth/OAuth2.php ADDED
@@ -0,0 +1,580 @@