Version Description
24/May/2018 =
FEATURE: Make it more seamless to sign up to UpdraftCentral Cloud
FEATURE: Microsoft Azure storage (Premium) compatibility with Azure Germany
FEATURE: Added the ability to create migration keys from WP-CLI (Premium)
FIX: A backup icon/storage shows for a storage type even if all instances were disabled
FIX: WP CLI updraftplus command was not running on few enviroments like the Windows command line
FIX: A PHP fatal error was occurring when a user try to restore an encrypted DB when defining the "UPDRAFTPLUS_DECRYPTION_ENGINE" constant
TWEAK: Added the ability to schedule incremental backups (Note you can not yet take incremental backups)
REFACTOR: Completed factoring for tabs of the settings page.
TWEAK: Some re-factoring and tidying of the restoration code for easier maintenance
TWEAK: Add a longer timeout on SFTP logins to cope with a 'long delay, but then worked' situation seen in the wild
TWEAK: An "Incremental backups" extension was displayed in the Premium / Extensions tab, causing confusion since it is not yet finished/launched
TWEAK: Displays a Byte Order Mark (BOM) warning by giving the file names along with the path in the "Existing Backups" tab, if a BOM is detected at the start of common files that people tend to edit
TWEAK: A WP CLI Existing backup command didn't display a date time in the "job_identifier" column
TWEAK: Add links to the relevant app privacy policies within the settings sections for storage methods using OAuth authorization apps
TWEAK: Log user and group IDs of process and file/folder, when permissions for an operation is denied
TWEAK: Prevent a potential PHP debugging notice when showing the 'Upload' button
TWEAK: Update an out-of-date "wrong password" link
TWEAK: Added the "Web-server disk space in use by UpdraftPlus" information to "Site information" section in the "Advanced Tools" tab; it won't show in the 'Existing Backups' tab if you are using less than 100MB.
TWEAK: When a Google Cloud token was invalid, a PHP Fatal could result instead of catching the error and informing/logging nicely
TWEAK: If php-xml (SimpleXMLElement) is not installed, then show an appropriate warning in the Azure configuration section
TWEAK: If the user tries to install another version of UpdraftPlus, then tweak the default error message that they are shown by WP, which is too obscure/cryptic for many users
Release Info
Developer | DavidAnderson |
Plugin | UpdraftPlus WordPress Backup Plugin |
Version | 1.14.9 |
Comparing to | |
See all releases |
Code changes from version 1.14.7 to 1.14.9
- admin.php +562 -543
- backup.php +21 -20
- class-updraftplus.php +476 -546
- class-zip.php +30 -2
- css/updraftplus-admin.css +75 -1
- css/updraftplus-admin.min.css +1 -1
- css/updraftplus-admin.min.css.map +1 -1
- images/updraftcentral_cloud.png +0 -0
- includes/class-backup-history.php +35 -0
- includes/class-commands.php +79 -8
- includes/class-database-utility.php +2 -2
- includes/class-manipulation-functions.php +352 -0
- includes/class-updraftplus-encryption.php +353 -0
- includes/class-wpadmin-commands.php +34 -8
- includes/deprecated-actions.php +2 -2
- includes/updraftcentral.php +65 -0
- includes/updraftplus-admin.js +428 -8
- includes/updraftplus-admin.min.js +3 -3
- includes/updraftplus-clone.php +61 -0
- includes/updraftplus-login.php +115 -0
- languages/updraftplus-af.po +1325 -1112
- languages/updraftplus-ar.mo +0 -0
- languages/updraftplus-ar.po +1329 -1112
- languages/updraftplus-bg_BG.po +644 -439
@@ -17,6 +17,10 @@ class UpdraftPlus_Admin {
|
|
17 |
|
18 |
private $auth_instance_ids = array('dropbox' => array(), 'onedrive' => array(), 'googledrive' => array(), 'googlecloud' => array());
|
19 |
|
|
|
|
|
|
|
|
|
20 |
public function __construct() {
|
21 |
$this->admin_init();
|
22 |
}
|
@@ -224,7 +228,7 @@ class UpdraftPlus_Admin {
|
|
224 |
}
|
225 |
|
226 |
private function setup_all_admin_notices_udonly($service, $override = false) {
|
227 |
-
global $
|
228 |
|
229 |
if (UpdraftPlus_Options::user_can_manage() && defined('DISABLE_WP_CRON') && DISABLE_WP_CRON && (!defined('UPDRAFTPLUS_DISABLE_WP_CRON_NOTICE') || !UPDRAFTPLUS_DISABLE_WP_CRON_NOTICE)) {
|
230 |
add_action('all_admin_notices', array($this, 'show_admin_warning_disabledcron'));
|
@@ -261,7 +265,7 @@ class UpdraftPlus_Admin {
|
|
261 |
}
|
262 |
}
|
263 |
|
264 |
-
if (version_compare($
|
265 |
}
|
266 |
|
267 |
/**
|
@@ -349,7 +353,7 @@ class UpdraftPlus_Admin {
|
|
349 |
// UpdraftPlus templates
|
350 |
$this->register_template_directories();
|
351 |
|
352 |
-
global $updraftplus, $
|
353 |
add_filter('updraftplus_dirlist_others', array($updraftplus, 'backup_others_dirlist'));
|
354 |
add_filter('updraftplus_dirlist_uploads', array($updraftplus, 'backup_uploads_dirlist'));
|
355 |
|
@@ -598,13 +602,16 @@ class UpdraftPlus_Admin {
|
|
598 |
$this->include_template('wp-admin/notices/thanks-for-using-main-dash.php');
|
599 |
}
|
600 |
|
|
|
|
|
|
|
601 |
private function ensure_sufficient_jquery_and_enqueue() {
|
602 |
-
global $updraftplus
|
603 |
|
604 |
$enqueue_version = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? $updraftplus->version.'.'.time() : $updraftplus->version;
|
605 |
$min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
|
606 |
|
607 |
-
if (version_compare($
|
608 |
// 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
|
609 |
wp_deregister_script('jquery');
|
610 |
$jquery_enqueue_version = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '1.7.2'.'.'.time() : '1.7.2';
|
@@ -798,7 +805,19 @@ class UpdraftPlus_Admin {
|
|
798 |
'local_upload_started' => __('Local backup upload has started; please check the current status tab to see the upload progress', 'updraftplus'),
|
799 |
'local_upload_error' => __('You must select at least one remote storage destination to upload this backup set to.', 'updrafplus'),
|
800 |
'already_uploaded' => __('(already uploaded)', 'updraftplus'),
|
801 |
-
'onedrive_folder_url_warning' => __('Please specify the Microsoft OneDrive folder name, not the URL.', 'updraftplus')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
802 |
));
|
803 |
}
|
804 |
|
@@ -1064,22 +1083,6 @@ class UpdraftPlus_Admin {
|
|
1064 |
}
|
1065 |
}
|
1066 |
|
1067 |
-
/**
|
1068 |
-
* This options filter removes ABSPATH off the front of updraft_dir, if it is given absolutely and contained within it
|
1069 |
-
*
|
1070 |
-
* @param string $updraft_dir Directory
|
1071 |
-
* @return string
|
1072 |
-
*/
|
1073 |
-
public function prune_updraft_dir_prefix($updraft_dir) {
|
1074 |
-
if ('/' == substr($updraft_dir, 0, 1) || "\\" == substr($updraft_dir, 0, 1) || preg_match('/^[a-zA-Z]:/', $updraft_dir)) {
|
1075 |
-
$wcd = trailingslashit(WP_CONTENT_DIR);
|
1076 |
-
if (strpos($updraft_dir, $wcd) === 0) {
|
1077 |
-
$updraft_dir = substr($updraft_dir, strlen($wcd));
|
1078 |
-
}
|
1079 |
-
}
|
1080 |
-
return $updraft_dir;
|
1081 |
-
}
|
1082 |
-
|
1083 |
/**
|
1084 |
* Start a download of a backup. This method is called via the AJAX action updraft_download_backup. May die instead of returning depending upon the mode in which it is called.
|
1085 |
*/
|
@@ -1256,7 +1259,7 @@ class UpdraftPlus_Admin {
|
|
1256 |
} else {
|
1257 |
$updraftplus->close_browser_connection(json_encode($msg));
|
1258 |
}
|
1259 |
-
$
|
1260 |
}
|
1261 |
|
1262 |
// Now, be ready to spool the thing to the browser
|
@@ -1286,129 +1289,6 @@ class UpdraftPlus_Admin {
|
|
1286 |
|
1287 |
}
|
1288 |
|
1289 |
-
/**
|
1290 |
-
* This method gets the remote storage information and objects and loops over each of them until we get a successful download of the passed in file.
|
1291 |
-
*
|
1292 |
-
* @param Array $services - a list of connected service identifiers (e.g. 'dropbox', 's3', etc.)
|
1293 |
-
* @param String $file - the name of the file
|
1294 |
-
* @param Integer $timestamp - the backup timestamp
|
1295 |
-
* @param Boolean $restore - a boolean to indicate if the caller of this method is a restore or not; if so, different messages are logged
|
1296 |
-
*/
|
1297 |
-
private function get_remote_file($services, $file, $timestamp, $restore = false) {
|
1298 |
-
global $updraftplus;
|
1299 |
-
|
1300 |
-
$fullpath = $updraftplus->backups_dir_location().'/'.$file;
|
1301 |
-
|
1302 |
-
$storage_objects_and_ids = $updraftplus->get_storage_objects_and_ids($services);
|
1303 |
-
|
1304 |
-
$is_downloaded = false;
|
1305 |
-
|
1306 |
-
$updraftplus->register_wp_http_option_hooks();
|
1307 |
-
|
1308 |
-
foreach ($services as $service) {
|
1309 |
-
|
1310 |
-
if (empty($service) || 'none' == $service) continue;
|
1311 |
-
|
1312 |
-
if ($is_downloaded) continue;
|
1313 |
-
|
1314 |
-
if ($restore) {
|
1315 |
-
$service_description = empty($updraftplus->backup_methods[$service]) ? $service : $updraftplus->backup_methods[$service];
|
1316 |
-
$updraftplus->log(__("File is not locally present - needs retrieving from remote storage", 'updraftplus')." ($service_description)", 'notice-restore');
|
1317 |
-
}
|
1318 |
-
|
1319 |
-
$object = $storage_objects_and_ids[$service]['object'];
|
1320 |
-
|
1321 |
-
if (!$object->supports_feature('multi_options')) {
|
1322 |
-
error_log("UpdraftPlus_Admin::get_remote_file(): Multi-options not supported by: ".$service);
|
1323 |
-
continue;
|
1324 |
-
}
|
1325 |
-
|
1326 |
-
$instance_ids = $storage_objects_and_ids[$service]['instance_settings'];
|
1327 |
-
$backups_instance_ids = isset($backup_history[$timestamp]['service_instance_ids'][$service]) ? $backup_history[$timestamp]['service_instance_ids'][$service] : array(false);
|
1328 |
-
|
1329 |
-
foreach ($backups_instance_ids as $instance_id) {
|
1330 |
-
|
1331 |
-
if (isset($instance_ids[$instance_id])) {
|
1332 |
-
$options = $instance_ids[$instance_id];
|
1333 |
-
} else {
|
1334 |
-
// If we didn't find a instance id match, it could be a new UpdraftPlus upgrade or a wipe settings with the same details entered so try the default options saved.
|
1335 |
-
$options = $object->get_options();
|
1336 |
-
}
|
1337 |
-
|
1338 |
-
$object->set_options($options, false, $instance_id);
|
1339 |
-
|
1340 |
-
$download = $this->download_file($file, $object);
|
1341 |
-
|
1342 |
-
if (is_readable($fullpath) && false !== $download) {
|
1343 |
-
if ($restore) {
|
1344 |
-
$updraftplus->log(__("OK", 'updraftplus'), 'notice-restore');
|
1345 |
-
} else {
|
1346 |
-
clearstatcache();
|
1347 |
-
$updraftplus->log('Remote fetch was successful (file size: '.round(filesize($fullpath)/1024, 1).' KB)');
|
1348 |
-
$is_downloaded = true;
|
1349 |
-
}
|
1350 |
-
break 2;
|
1351 |
-
} else {
|
1352 |
-
if ($restore) {
|
1353 |
-
$updraftplus->log(__("Error", 'updraftplus'), 'notice-restore');
|
1354 |
-
} else {
|
1355 |
-
clearstatcache();
|
1356 |
-
if (0 === @filesize($fullpath)) @unlink($fullpath);
|
1357 |
-
$updraftplus->log('Remote fetch failed');
|
1358 |
-
}
|
1359 |
-
}
|
1360 |
-
}
|
1361 |
-
}
|
1362 |
-
$updraftplus->register_wp_http_option_hooks(false);
|
1363 |
-
}
|
1364 |
-
|
1365 |
-
/**
|
1366 |
-
* Downloads a specified file into UD's directory
|
1367 |
-
*
|
1368 |
-
* @param String $file The name of the file
|
1369 |
-
* @param array $object The object of the service to use to download with. UpdraftPlus_BackupModule.
|
1370 |
-
* @return Boolean - Whether the operation succeeded. Inherited from the storage module's download() method. N.B. At the time of writing it looks like not all modules necessarily return true upon success; but false can be relied upon for detecting failure.
|
1371 |
-
*/
|
1372 |
-
private function download_file($file, $object) {
|
1373 |
-
|
1374 |
-
global $updraftplus;
|
1375 |
-
|
1376 |
-
@set_time_limit(UPDRAFTPLUS_SET_TIME_LIMIT);
|
1377 |
-
|
1378 |
-
$service = $object->get_id();
|
1379 |
-
|
1380 |
-
$updraftplus->log("Requested file from remote service: $service: $file");
|
1381 |
-
|
1382 |
-
if (method_exists($object, 'download')) {
|
1383 |
-
|
1384 |
-
try {
|
1385 |
-
return $object->download($file);
|
1386 |
-
} catch (Exception $e) {
|
1387 |
-
$log_message = 'Exception ('.get_class($e).') occurred during download: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1388 |
-
error_log($log_message);
|
1389 |
-
// @codingStandardsIgnoreLine
|
1390 |
-
if (function_exists('wp_debug_backtrace_summary')) $log_message .= ' Backtrace: '.wp_debug_backtrace_summary();
|
1391 |
-
$updraftplus->log($log_message);
|
1392 |
-
$updraftplus->log(sprintf(__('A PHP exception (%s) has occurred: %s', 'updraftplus'), get_class($e), $e->getMessage()), 'error');
|
1393 |
-
return false;
|
1394 |
-
// @codingStandardsIgnoreLine
|
1395 |
-
} catch (Error $e) {
|
1396 |
-
$log_message = 'PHP Fatal error ('.get_class($e).') has occurred during download. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1397 |
-
error_log($log_message);
|
1398 |
-
// @codingStandardsIgnoreLine
|
1399 |
-
if (function_exists('wp_debug_backtrace_summary')) $log_message .= ' Backtrace: '.wp_debug_backtrace_summary();
|
1400 |
-
$updraftplus->log($log_message);
|
1401 |
-
$updraftplus->log(sprintf(__('A PHP fatal error (%s) has occurred: %s', 'updraftplus'), get_class($e), $e->getMessage()), 'error');
|
1402 |
-
return false;
|
1403 |
-
}
|
1404 |
-
} else {
|
1405 |
-
$updraftplus->log("Automatic backup restoration is not available with the method: $service.");
|
1406 |
-
$updraftplus->log("$file: ".sprintf(__("The backup archive for this file could not be found. The remote storage method in use (%s) does not allow us to retrieve files. To perform any restoration using UpdraftPlus, you will need to obtain a copy of this file and place it inside UpdraftPlus's working folder", 'updraftplus'), $service)." (".$this->prune_updraft_dir_prefix($updraftplus->backups_dir_location()).")", 'error');
|
1407 |
-
return false;
|
1408 |
-
}
|
1409 |
-
|
1410 |
-
}
|
1411 |
-
|
1412 |
/**
|
1413 |
* This is used as a callback
|
1414 |
*
|
@@ -1450,7 +1330,7 @@ class UpdraftPlus_Admin {
|
|
1450 |
$data = in_array($subaction, $data_in_get) ? $_GET : $_POST;
|
1451 |
|
1452 |
// Undo WP's slashing of GET/POST data
|
1453 |
-
$data =
|
1454 |
|
1455 |
// TODO: Once all commands come through here and through updraft_send_command(), the data should always come from this attribute (once updraft_send_command() is modified appropriately).
|
1456 |
if (isset($data['action_data'])) $data = $data['action_data'];
|
@@ -1498,7 +1378,7 @@ class UpdraftPlus_Admin {
|
|
1498 |
try {
|
1499 |
// N.B. Also called from autobackup.php
|
1500 |
// TODO: This should go into UpdraftPlus_Commands, once the add-ons have been ported to use updraft_send_command()
|
1501 |
-
echo json_encode($this->get_activejobs_list(
|
1502 |
} catch (Exception $e) {
|
1503 |
$log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1504 |
error_log($log_message);
|
@@ -1520,7 +1400,7 @@ class UpdraftPlus_Admin {
|
|
1520 |
try {
|
1521 |
// httpget
|
1522 |
$curl = empty($_REQUEST['curl']) ? false : true;
|
1523 |
-
echo $this->http_get(
|
1524 |
// @codingStandardsIgnoreLine
|
1525 |
} catch (Error $e) {
|
1526 |
$log_message = 'PHP Fatal error ('.get_class($e).') has occurred during http get. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
@@ -1542,7 +1422,7 @@ class UpdraftPlus_Admin {
|
|
1542 |
$subsubaction = $_REQUEST['subsubaction'];
|
1543 |
try {
|
1544 |
// These generally echo and die - they will need further work to port to one of the command classes. Some may already have equivalents in UpdraftPlus_Commands, if they are used from UpdraftCentral.
|
1545 |
-
do_action(
|
1546 |
} catch (Exception $e) {
|
1547 |
$log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during doaction subaction with '.$subsubaction.' subsubaction. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1548 |
error_log($log_message);
|
@@ -1862,19 +1742,55 @@ class UpdraftPlus_Admin {
|
|
1862 |
'data' => $data,
|
1863 |
'cksum' => md5($output),
|
1864 |
'logs_exist' => $logs_exist,
|
|
|
1865 |
));
|
1866 |
}
|
1867 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1868 |
/**
|
1869 |
* Get information on disk space used by an entity, or by UD's internal directory. Returns as a human-readable string.
|
1870 |
*
|
1871 |
* @param String $entity - the entity (e.g. 'plugins'; 'all' for all entities, or 'ud' for UD's internal directory)
|
1872 |
-
*
|
1873 |
-
* @return String
|
1874 |
*/
|
1875 |
-
public function get_disk_space_used($entity) {
|
1876 |
global $updraftplus;
|
1877 |
-
if ('updraft' == $entity) return $this->recursive_directory_size($updraftplus->backups_dir_location());
|
1878 |
|
1879 |
$backupable_entities = $updraftplus->get_backupable_file_entities(true, false);
|
1880 |
|
@@ -1887,12 +1803,18 @@ class UpdraftPlus_Admin {
|
|
1887 |
$size = $this->recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, 'numeric');
|
1888 |
if (is_numeric($size) && $size>0) $total_size += $size;
|
1889 |
}
|
1890 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1891 |
} elseif (!empty($backupable_entities[$entity])) {
|
1892 |
// Might be an array
|
1893 |
$basedir = $backupable_entities[$entity];
|
1894 |
$dirs = apply_filters('updraftplus_dirlist_'.$entity, $basedir);
|
1895 |
-
return $this->recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir);
|
1896 |
}
|
1897 |
|
1898 |
// Default fallback
|
@@ -2401,6 +2323,9 @@ class UpdraftPlus_Admin {
|
|
2401 |
$this->include_template('wp-admin/settings/header.php');
|
2402 |
}
|
2403 |
|
|
|
|
|
|
|
2404 |
public function settings_output() {
|
2405 |
|
2406 |
if (false == ($render = apply_filters('updraftplus_settings_page_render', true))) {
|
@@ -2461,16 +2386,17 @@ class UpdraftPlus_Admin {
|
|
2461 |
if ('db' != $v) $s_val = 2;
|
2462 |
}
|
2463 |
}
|
2464 |
-
$pval =
|
2465 |
|
2466 |
echo '<strong>'.__('Actions', 'updraftplus').':</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&updraft_restore_success='.$s_val.'&pval='.$pval.'">'.__('Return to UpdraftPlus Configuration', 'updraftplus').'</a>';
|
2467 |
return;
|
|
|
2468 |
} elseif (is_wp_error($backup_success)) {
|
2469 |
echo '<p>';
|
2470 |
$updraftplus->log_e('Restore failed...');
|
2471 |
echo '</p>';
|
2472 |
$updraftplus->log_wp_error($backup_success);
|
2473 |
-
$updraftplus->log(
|
2474 |
$updraftplus->list_errors();
|
2475 |
echo '<strong>'.__('Actions', 'updraftplus').':</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus">'.__('Return to UpdraftPlus Configuration', 'updraftplus').'</a>';
|
2476 |
return;
|
@@ -2603,36 +2529,29 @@ class UpdraftPlus_Admin {
|
|
2603 |
$backup_history = UpdraftPlus_Backup_History::get_history();
|
2604 |
}
|
2605 |
|
2606 |
-
|
2607 |
-
|
2608 |
-
|
2609 |
-
|
2610 |
-
|
2611 |
-
|
|
|
|
|
|
|
|
|
|
|
2612 |
|
2613 |
if (isset($_REQUEST['tab'])) {
|
2614 |
-
|
2615 |
-
|
2616 |
-
|
2617 |
-
|
2618 |
-
|
2619 |
-
|
2620 |
-
break;
|
2621 |
-
case 'settings':
|
2622 |
-
$tabflag = 3;
|
2623 |
-
break;
|
2624 |
-
case 'expert':
|
2625 |
-
$tabflag = 4;
|
2626 |
-
break;
|
2627 |
-
case 'addons':
|
2628 |
-
$tabflag = 5;
|
2629 |
-
break;
|
2630 |
-
default:
|
2631 |
-
$tabflag = 1;
|
2632 |
}
|
2633 |
}
|
2634 |
-
|
2635 |
-
$this->include_template('wp-admin/settings/tab-bar.php', false, array('backup_history' => $backup_history, 'tabflag' => $tabflag));
|
2636 |
|
2637 |
$updraft_dir = $updraftplus->backups_dir_location();
|
2638 |
$backup_disabled = $updraftplus->really_is_writable($updraft_dir) ? '' : 'disabled="disabled"';
|
@@ -2644,7 +2563,7 @@ class UpdraftPlus_Admin {
|
|
2644 |
|
2645 |
<?php $this->include_template('wp-admin/settings/tab-status.php', false, array('tabflag' => $tabflag, 'backup_disabled' => $backup_disabled)); ?>
|
2646 |
|
2647 |
-
<div id="updraft-navtab-backups-content" <?php if (
|
2648 |
<?php
|
2649 |
$is_opera = (false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'OPR/'));
|
2650 |
$tmp_opts = array('include_opera_warning' => $is_opera);
|
@@ -2653,19 +2572,82 @@ class UpdraftPlus_Admin {
|
|
2653 |
$this->include_template('wp-admin/settings/upload-backups-modal.php');
|
2654 |
?>
|
2655 |
</div>
|
2656 |
-
|
2657 |
-
<div id="updraft-navtab-settings-content" <?php if (
|
2658 |
<h2 class="updraft_settings_sectionheading"><?php _e('Backup Contents And Schedule', 'updraftplus');?></h2>
|
2659 |
<?php UpdraftPlus_Options::options_form_begin(); ?>
|
2660 |
<?php $this->settings_formcontents(); ?>
|
2661 |
</form>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2662 |
</div>
|
2663 |
|
2664 |
-
<div id="updraft-navtab-expert-content"<?php if (
|
2665 |
<?php $this->settings_advanced_tools(); ?>
|
2666 |
</div>
|
2667 |
|
2668 |
-
<div id="updraft-navtab-addons-content"<?php if (
|
2669 |
|
2670 |
<?php
|
2671 |
$tab_addons = $this->include_template('wp-admin/settings/tab-addons.php', true, array('tabflag' => $tabflag));
|
@@ -2677,6 +2659,7 @@ class UpdraftPlus_Admin {
|
|
2677 |
</div>
|
2678 |
|
2679 |
<?php
|
|
|
2680 |
// settings_header() opens a div
|
2681 |
echo '</div>';
|
2682 |
}
|
@@ -2726,11 +2709,13 @@ class UpdraftPlus_Admin {
|
|
2726 |
/**
|
2727 |
* This method will build the UpdraftPlus.com login form and echo it to the page.
|
2728 |
*
|
2729 |
-
* @param string
|
|
|
2730 |
*
|
2731 |
* @return void
|
2732 |
*/
|
2733 |
-
public function build_credentials_form($option_page) {
|
|
|
2734 |
|
2735 |
$enter_credentials_begin = UpdraftPlus_Options::options_form_begin('', false, array(), 'updraftplus_com_login');
|
2736 |
|
@@ -2746,22 +2731,6 @@ class UpdraftPlus_Admin {
|
|
2746 |
|
2747 |
$enter_credentials_end .= '</form>';
|
2748 |
|
2749 |
-
$this->show_credentials_form($enter_credentials_begin, $enter_credentials_end, $option_page);
|
2750 |
-
}
|
2751 |
-
|
2752 |
-
/**
|
2753 |
-
* This method will build the UpdraftPlus.com login form and echo it to the page.
|
2754 |
-
*
|
2755 |
-
* @param string $enter_credentials_begin - a string that contains the start of the form
|
2756 |
-
* @param string $enter_credentials_end - a string that contains the end of the form
|
2757 |
-
* @param string $option_page - the option page this form is being output to
|
2758 |
-
*
|
2759 |
-
* @return void
|
2760 |
-
*/
|
2761 |
-
private function show_credentials_form($enter_credentials_begin, $enter_credentials_end, $option_page) {
|
2762 |
-
|
2763 |
-
global $updraftplus;
|
2764 |
-
|
2765 |
echo $enter_credentials_begin;
|
2766 |
|
2767 |
// We have to duplicate settings_fields() in order to set our referer
|
@@ -2782,7 +2751,7 @@ class UpdraftPlus_Admin {
|
|
2782 |
|
2783 |
echo $nonce_field;
|
2784 |
|
2785 |
-
$referer = esc_attr(
|
2786 |
|
2787 |
// This one is used on single site installs
|
2788 |
if (false === strpos($referer, '?')) {
|
@@ -2791,10 +2760,53 @@ class UpdraftPlus_Admin {
|
|
2791 |
$referer .= '&tab=addons';
|
2792 |
}
|
2793 |
|
|
|
|
|
2794 |
echo '<input type="hidden" name="_wp_http_referer" value="'.$referer.'" />';
|
2795 |
// End of duplication of settings-fields()
|
2796 |
|
2797 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2798 |
echo $enter_credentials_end;
|
2799 |
}
|
2800 |
|
@@ -3223,6 +3235,7 @@ class UpdraftPlus_Admin {
|
|
3223 |
if (!$wp_filesystem->delete($plugs.'-old', true)) {
|
3224 |
$ret3 = false;
|
3225 |
echo "<strong>".__('Failed', 'updraftplus')."</strong><br>";
|
|
|
3226 |
} else {
|
3227 |
$ret3 = true;
|
3228 |
echo "<strong>".__('OK', 'updraftplus')."</strong><br>";
|
@@ -3258,6 +3271,7 @@ class UpdraftPlus_Admin {
|
|
3258 |
if (!$wp_filesystem->delete($dir.$name, true)) {
|
3259 |
$ret = false;
|
3260 |
echo "<strong>".__('Failed', 'updraftplus')."</strong><br>";
|
|
|
3261 |
} else {
|
3262 |
echo "<strong>".__('OK', 'updraftplus')."</strong><br>";
|
3263 |
}
|
@@ -3267,6 +3281,7 @@ class UpdraftPlus_Admin {
|
|
3267 |
} else {
|
3268 |
$ret = false;
|
3269 |
echo "<strong>".__('Failed', 'updraftplus')."</strong><br>";
|
|
|
3270 |
}
|
3271 |
}
|
3272 |
}
|
@@ -3493,7 +3508,7 @@ class UpdraftPlus_Admin {
|
|
3493 |
} else {
|
3494 |
$dir_info .= __('Backup directory specified exists, but is <b>not</b> writable.', 'updraftplus');
|
3495 |
}
|
3496 |
-
$dir_info .= '<span class="updraft-directory-not-writable-blurb"><span class="directory-permissions"><a class="updraft_create_backup_dir" href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir').'">'.__('Follow this link to attempt to create the directory and set the permissions', 'updraftplus').'</a></span>, '.__('or, to reset this option', 'updraftplus').' <a href="#" class="updraft_backup_dir_reset">'.__('
|
3497 |
}
|
3498 |
return $dir_info;
|
3499 |
}
|
@@ -3700,7 +3715,7 @@ class UpdraftPlus_Admin {
|
|
3700 |
if ('numeric' == $format) return $size;
|
3701 |
|
3702 |
global $updraftplus;
|
3703 |
-
return
|
3704 |
|
3705 |
}
|
3706 |
|
@@ -3802,7 +3817,7 @@ class UpdraftPlus_Admin {
|
|
3802 |
$rawbackup .= $show_services;
|
3803 |
|
3804 |
if (false !== $total_size) {
|
3805 |
-
$rawbackup .= '</p><strong>'.__('Total backup size:', 'updraftplus').'</strong> '
|
3806 |
}
|
3807 |
|
3808 |
|
@@ -4014,11 +4029,8 @@ class UpdraftPlus_Admin {
|
|
4014 |
if (!empty($jobdata) && 'finished' != $jobdata['jobstatus']) return '';
|
4015 |
|
4016 |
// Check that the user has remote storage setup.
|
4017 |
-
$services =
|
4018 |
-
|
4019 |
-
if (is_string($service)) $service = array($service);
|
4020 |
-
if (!is_array($service)) $service = array('none');
|
4021 |
-
if (empty($service) || array('none') == $service || array('') == $service || 'none' == $service) return '';
|
4022 |
|
4023 |
$show_upload = false;
|
4024 |
$not_uploaded = array();
|
@@ -4176,7 +4188,7 @@ ENDHERE;
|
|
4176 |
$blog_name = $matches[2];
|
4177 |
}
|
4178 |
|
4179 |
-
if (
|
4180 |
|
4181 |
if (is_array($db_info) && isset($db_info['status'])) {
|
4182 |
$db_backups[$key]['status'] = $status;
|
@@ -4231,25 +4243,65 @@ ENDHERE;
|
|
4231 |
}
|
4232 |
|
4233 |
/**
|
4234 |
-
*
|
|
|
4235 |
*
|
4236 |
-
* @param
|
4237 |
-
*
|
4238 |
-
* @return
|
4239 |
*/
|
4240 |
-
private function
|
4241 |
-
|
4242 |
-
|
4243 |
-
|
4244 |
-
@set_time_limit(UPDRAFTPLUS_SET_TIME_LIMIT);
|
4245 |
|
4246 |
-
$
|
4247 |
-
|
4248 |
-
|
4249 |
-
|
4250 |
-
|
|
|
|
|
|
|
|
|
|
|
4251 |
}
|
4252 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4253 |
// request_filesystem_credentials passes on fields just via hidden name/value pairs.
|
4254 |
// Build array of parameters to be passed via this
|
4255 |
$extra_fields = array();
|
@@ -4280,10 +4332,35 @@ ENDHERE;
|
|
4280 |
foreach ($wp_filesystem->errors->get_error_messages() as $message) show_message($message);
|
4281 |
exit;
|
4282 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4283 |
|
4284 |
-
//
|
|
|
|
|
|
|
|
|
4285 |
|
4286 |
-
// Set up logging
|
4287 |
$updraftplus->backup_time_nonce();
|
4288 |
$updraftplus->jobdata_set('job_type', 'restore');
|
4289 |
$updraftplus->jobdata_set('job_time_ms', $updraftplus->job_time_ms);
|
@@ -4293,49 +4370,13 @@ ENDHERE;
|
|
4293 |
// TODO: Automatic purging of old log files
|
4294 |
// TODO: Provide option to auto-email the log file
|
4295 |
|
4296 |
-
echo '<h1>'.__('UpdraftPlus Restoration: Progress', 'updraftplus').'</h1><div id="updraft-restore-progress">';
|
4297 |
-
|
4298 |
$this->show_admin_warning('<a target="_blank" href="?action=downloadlog&page=updraftplus&updraftplus_backup_nonce='.htmlspecialchars($updraftplus->nonce).'">'.__('Follow this link to download the log file for this restoration (needed for any support requests).', 'updraftplus').'</a>');
|
4299 |
|
4300 |
-
$updraft_dir = trailingslashit($updraftplus->backups_dir_location());
|
4301 |
-
$foreign_known = apply_filters('updraftplus_accept_archivename', array());
|
4302 |
-
|
4303 |
-
$service = isset($backup_set['service']) ? $backup_set['service'] : array('none');
|
4304 |
-
if (is_string($service)) $service = array($service);
|
4305 |
-
|
4306 |
// Now, need to turn any updraft_restore_<entity> fields (that came from a potential WP_Filesystem form) back into parts of the _POST array (which we want to use)
|
4307 |
if (empty($_POST['updraft_restore']) || (!is_array($_POST['updraft_restore']))) $_POST['updraft_restore'] = array();
|
4308 |
|
4309 |
-
|
4310 |
-
|
4311 |
-
if (empty($backup_set['meta_foreign'])) {
|
4312 |
-
$entities_to_restore[$entity] = $entity;
|
4313 |
-
} else {
|
4314 |
-
if ('db' == $entity && !empty($foreign_known[$backup_set['meta_foreign']]) && !empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) {
|
4315 |
-
$entities_to_restore[$entity] = 'db';
|
4316 |
-
} else {
|
4317 |
-
$entities_to_restore[$entity] = 'wpcore';
|
4318 |
-
}
|
4319 |
-
}
|
4320 |
-
}
|
4321 |
-
|
4322 |
-
foreach ($_POST as $key => $value) {
|
4323 |
-
if (0 === strpos($key, 'updraft_restore_')) {
|
4324 |
-
$nkey = substr($key, 16);
|
4325 |
-
if (!isset($entities_to_restore[$nkey])) {
|
4326 |
-
$_POST['updraft_restore'][] = $nkey;
|
4327 |
-
if (empty($backup_set['meta_foreign'])) {
|
4328 |
-
$entities_to_restore[$nkey] = $nkey;
|
4329 |
-
} else {
|
4330 |
-
if ('db' == $entity && !empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) {
|
4331 |
-
$entities_to_restore[$nkey] = 'db';
|
4332 |
-
} else {
|
4333 |
-
$entities_to_restore[$nkey] = 'wpcore';
|
4334 |
-
}
|
4335 |
-
}
|
4336 |
-
}
|
4337 |
-
}
|
4338 |
-
}
|
4339 |
|
4340 |
if (0 == count($_POST['updraft_restore'])) {
|
4341 |
echo '<p>'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'</p>';
|
@@ -4343,17 +4384,17 @@ ENDHERE;
|
|
4343 |
return new WP_Error('missing_info', 'Backup information not found');
|
4344 |
}
|
4345 |
|
|
|
4346 |
$this->entities_to_restore = $entities_to_restore;
|
4347 |
|
|
|
4348 |
set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT);
|
4349 |
|
4350 |
-
|
4351 |
-
$_POST['updraft_restore'] is typically something like: array(0=>'db', 1=>'plugins', 2=>'themes'), etc.
|
4352 |
-
i.e. array ('db', 'plugins', themes')
|
4353 |
-
*/
|
4354 |
|
|
|
4355 |
if (empty($restore_options)) {
|
4356 |
-
// Gather the restore
|
4357 |
$restore_options = array();
|
4358 |
if (!empty($_POST['updraft_restorer_restore_options'])) {
|
4359 |
parse_str(stripslashes($_POST['updraft_restorer_restore_options']), $restore_options);
|
@@ -4364,17 +4405,12 @@ ENDHERE;
|
|
4364 |
$updraftplus->jobdata_set('restore_options', $restore_options);
|
4365 |
}
|
4366 |
|
4367 |
-
$backupable_entities = $updraftplus->get_backupable_file_entities(true, true);
|
4368 |
-
|
4369 |
// If updraft_incremental_restore_point is equal to -1 then this is either not a incremental restore or we are going to restore up to the latest increment, so there is no need to prune the backup set of any unwanted backup archives.
|
4370 |
if (isset($restore_options['updraft_incremental_restore_point']) && $restore_options['updraft_incremental_restore_point'] > 0) {
|
4371 |
$restore_point = $restore_options['updraft_incremental_restore_point'];
|
4372 |
-
foreach ($backup_set['incremental_sets'] as $
|
4373 |
-
|
4374 |
-
if ($timestamp > $restore_point) {
|
4375 |
-
|
4376 |
foreach ($entities as $entity => $backups) {
|
4377 |
-
|
4378 |
foreach ($backups as $key => $value) {
|
4379 |
unset($backup_set[$entity][$key]);
|
4380 |
}
|
@@ -4384,282 +4420,113 @@ ENDHERE;
|
|
4384 |
}
|
4385 |
|
4386 |
// Restore in the most helpful order
|
4387 |
-
uksort($backup_set, array(
|
4388 |
|
4389 |
-
// Now log
|
4390 |
$copy_restore_options = $restore_options;
|
4391 |
if (!empty($copy_restore_options['updraft_encryptionphrase'])) $copy_restore_options['updraft_encryptionphrase'] = '***';
|
4392 |
$updraftplus->log("Restore job started. Entities to restore: ".implode(', ', array_flip($entities_to_restore)).'. Restore options: '.json_encode($copy_restore_options));
|
4393 |
|
4394 |
$backup_set['timestamp'] = $timestamp;
|
4395 |
|
4396 |
-
// Allow add-ons to adjust the restore directory (but only in the case of restore - otherwise, they could just use the filter built into UpdraftPlus::get_backupable_file_entities)
|
4397 |
-
$backupable_entities = apply_filters('updraft_backupable_file_entities_on_restore', $backupable_entities, $restore_options, $backup_set);
|
4398 |
-
|
4399 |
// We use a single object for each entity, because we want to store information about the backup set
|
4400 |
-
include_once(UPDRAFTPLUS_DIR.'/restorer.php');
|
|
|
|
|
4401 |
|
4402 |
global $updraftplus_restorer;
|
4403 |
|
4404 |
$updraftplus_restorer = new Updraft_Restorer(new Updraft_Restorer_Skin, $backup_set, false, $restore_options);
|
4405 |
-
|
4406 |
-
|
4407 |
-
|
4408 |
-
|
4409 |
-
|
4410 |
-
if (
|
4411 |
-
$
|
4412 |
-
|
4413 |
-
|
4414 |
-
|
4415 |
-
|
4416 |
-
$
|
4417 |
-
|
4418 |
-
|
4419 |
-
$entities_to_download['wpcore'] = 1;
|
4420 |
-
}
|
4421 |
-
} else {
|
4422 |
-
$entities_to_download = array('wpcore' => 1);
|
4423 |
-
}
|
4424 |
-
}
|
4425 |
-
|
4426 |
-
// First loop: make sure that files are present + readable; and populate array for second loop
|
4427 |
-
foreach ($backup_set as $type => $files) {
|
4428 |
-
// All restorable entities must be given explicitly, as we can store other arbitrary data in the history array
|
4429 |
-
if (!isset($backupable_entities[$type]) && 'db' != $type) continue;
|
4430 |
-
if (isset($backupable_entities[$type]['restorable']) && false == $backupable_entities[$type]['restorable']) continue;
|
4431 |
-
|
4432 |
-
if (!isset($entities_to_download[$type])) continue;
|
4433 |
-
if ('wpcore' == $type && is_multisite() && 0 === $updraftplus_restorer->ud_backup_is_multisite) {
|
4434 |
-
echo "<p>$type: <strong>";
|
4435 |
-
$updraftplus->log(__('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'), 'notice-restore');
|
4436 |
-
// TODO
|
4437 |
-
// $updraftplus->log_e('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.');
|
4438 |
-
echo "</strong></p>";
|
4439 |
-
continue;
|
4440 |
-
}
|
4441 |
-
|
4442 |
-
if (is_string($files)) $files = array($files);
|
4443 |
-
|
4444 |
-
foreach ($files as $ind => $file) {
|
4445 |
-
|
4446 |
-
$fullpath = $updraft_dir.$file;
|
4447 |
-
$updraftplus->log(sprintf(__("Looking for %s archive: file name: %s", 'updraftplus'), $type, $file), 'notice-restore');
|
4448 |
-
|
4449 |
-
if (is_array($continuation_data) && isset($continuation_data['second_loop_entities'][$type]) && !in_array($file, $continuation_data['second_loop_entities'][$type])) {
|
4450 |
-
echo __('Skipping: this archive was already restored.', 'updraftplus')."<br>";
|
4451 |
-
// Set the marker so that the existing directory isn't moved out of the way
|
4452 |
-
$updraftplus_restorer->been_restored[$type] = true;
|
4453 |
-
continue;
|
4454 |
-
}
|
4455 |
-
|
4456 |
-
if (!is_readable($fullpath) || 0 == filesize($fullpath)) $this->get_remote_file($service, $file, $timestamp, true);
|
4457 |
-
|
4458 |
-
$index = (0 == $ind) ? '' : $ind;
|
4459 |
-
// If a file size is stored in the backup data, then verify correctness of the local file
|
4460 |
-
if (isset($backup_set[$type.$index.'-size'])) {
|
4461 |
-
$fs = $backup_set[$type.$index.'-size'];
|
4462 |
-
$print_message = __("Archive is expected to be size:", 'updraftplus')." ".round($fs/1024, 1)." KB: ";
|
4463 |
-
$as = @filesize($fullpath);
|
4464 |
-
if ($as == $fs) {
|
4465 |
-
$updraftplus->log($print_message.__('OK', 'updraftplus'), 'notice-restore');
|
4466 |
-
} else {
|
4467 |
-
$updraftplus->log($print_message.__('Error:', 'updraftplus')." ".__('file is size:', 'updraftplus')." ".round($as/1024)." ($fs, $as)", 'warning-restore');
|
4468 |
-
}
|
4469 |
-
} else {
|
4470 |
-
$updraftplus->log(__("The backup records do not contain information about the proper size of this file.", 'updraftplus'), 'notice-restore');
|
4471 |
-
}
|
4472 |
-
if (!is_readable($fullpath)) {
|
4473 |
-
$updraftplus->log(__('Could not find one of the files for restoration', 'updraftplus')." ($file)", 'warning-restore');
|
4474 |
-
$updraftplus->log("$file: ".__('Could not find one of the files for restoration', 'updraftplus'), 'error');
|
4475 |
-
echo '</div>';
|
4476 |
-
restore_error_handler();
|
4477 |
-
return false;
|
4478 |
-
}
|
4479 |
-
}
|
4480 |
-
|
4481 |
-
if (empty($updraftplus_restorer->ud_foreign)) {
|
4482 |
-
$types = array($type);
|
4483 |
-
} else {
|
4484 |
-
if ('db' != $type || empty($foreign_known[$updraftplus_restorer->ud_foreign]['separatedb'])) {
|
4485 |
-
$types = array('wpcore');
|
4486 |
-
} else {
|
4487 |
-
$types = array('db');
|
4488 |
-
}
|
4489 |
-
}
|
4490 |
-
|
4491 |
-
foreach ($types as $check_type) {
|
4492 |
-
$info = (isset($backupable_entities[$check_type])) ? $backupable_entities[$check_type] : array();
|
4493 |
-
$val = $updraftplus_restorer->pre_restore_backup($files, $check_type, $info, $continuation_data);
|
4494 |
-
if (is_wp_error($val)) {
|
4495 |
-
$updraftplus->log_wp_error($val);
|
4496 |
-
foreach ($val->get_error_messages() as $msg) {
|
4497 |
-
$updraftplus->log(__('Error:', 'updraftplus').' '.$msg, 'warning-restore');
|
4498 |
-
}
|
4499 |
-
foreach ($val->get_error_codes() as $code) {
|
4500 |
-
if ('already_exists' == $code) $this->print_delete_old_dirs_form(false);
|
4501 |
-
}
|
4502 |
-
echo '</div>'; // close the updraft_restore_progress div even if we error
|
4503 |
-
restore_error_handler();
|
4504 |
-
return $val;
|
4505 |
-
} elseif (false === $val) {
|
4506 |
-
echo '</div>'; // close the updraft_restore_progress div even if we error
|
4507 |
-
restore_error_handler();
|
4508 |
-
return false;
|
4509 |
-
}
|
4510 |
-
}
|
4511 |
-
|
4512 |
-
foreach ($entities_to_restore as $entity => $via) {
|
4513 |
-
if ($via == $type) {
|
4514 |
-
if ('wpcore' == $via && 'db' == $entity && count($files) > 1) {
|
4515 |
-
$second_loop[$entity] = apply_filters('updraftplus_select_wpcore_file_with_db', $files, $updraftplus_restorer->ud_foreign);
|
4516 |
-
} else {
|
4517 |
-
$second_loop[$entity] = $files;
|
4518 |
}
|
4519 |
}
|
|
|
4520 |
}
|
4521 |
-
|
4522 |
}
|
4523 |
-
|
4524 |
-
|
4525 |
-
|
4526 |
-
|
4527 |
-
$
|
4528 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4529 |
|
4530 |
-
|
4531 |
-
|
4532 |
-
// Second loop: now actually do the restoration
|
4533 |
-
uksort($second_loop, array($this, 'sort_restoration_entities'));
|
4534 |
-
|
4535 |
-
// If continuing, then prune those already done
|
4536 |
-
if (is_array($continuation_data)) {
|
4537 |
-
foreach ($second_loop as $type => $files) {
|
4538 |
-
if (isset($continuation_data['second_loop_entities'][$type])) $second_loop[$type] = $continuation_data['second_loop_entities'][$type];
|
4539 |
}
|
4540 |
-
}
|
4541 |
|
4542 |
-
|
4543 |
-
|
4544 |
-
// use a site option, as otherwise on multisite when all the array of options is updated via UpdraftPlus_Options::update_site_option(), it will over-write any restored UD options from the backup
|
4545 |
-
update_site_option('updraft_restore_in_progress', $updraftplus->nonce);
|
4546 |
|
4547 |
-
|
4548 |
-
|
4549 |
-
|
4550 |
|
4551 |
-
|
4552 |
-
|
4553 |
|
4554 |
-
|
4555 |
-
|
4556 |
-
|
4557 |
-
$last_entity = (1 == count($files));
|
4558 |
-
try {
|
4559 |
-
$val = $updraftplus_restorer->restore_backup($file, $type, $info, $last_one, $last_entity);
|
4560 |
-
} catch (Exception $e) {
|
4561 |
-
$log_message = 'Exception ('.get_class($e).') occurred during restore: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
4562 |
-
$display_log_message = sprintf(__('A PHP exception (%s) has occurred: %s', 'updraftplus'), get_class($e), $e->getMessage());
|
4563 |
-
error_log($log_message);
|
4564 |
-
// @codingStandardsIgnoreLine
|
4565 |
-
if (function_exists('wp_debug_backtrace_summary')) $log_message .= ' Backtrace: '.wp_debug_backtrace_summary();
|
4566 |
-
$updraftplus->log($log_message);
|
4567 |
-
$updraftplus->log($display_log_message, 'notice-restore');
|
4568 |
-
die();
|
4569 |
-
// @codingStandardsIgnoreLine
|
4570 |
-
} catch (Error $e) {
|
4571 |
-
$log_message = 'PHP Fatal error ('.get_class($e).') has occurred. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
4572 |
-
error_log($log_message);
|
4573 |
-
// @codingStandardsIgnoreLine
|
4574 |
-
if (function_exists('wp_debug_backtrace_summary')) $log_message .= ' Backtrace: '.wp_debug_backtrace_summary();
|
4575 |
-
$updraftplus->log($log_message);
|
4576 |
-
$display_log_message = sprintf(__('A PHP fatal error (%s) has occurred: %s', 'updraftplus'), get_class($e), $e->getMessage());
|
4577 |
-
$updraftplus->log($display_log_message, 'notice-restore');
|
4578 |
-
die();
|
4579 |
}
|
4580 |
-
if (is_wp_error($val)) {
|
4581 |
-
$codes = $val->get_error_codes();
|
4582 |
-
if (is_array($codes) && in_array('not_found', $codes) && !empty($updraftplus_restorer->ud_foreign) && apply_filters('updraftplus_foreign_allow_missing_entity', false, $type, $updraftplus_restorer->ud_foreign)) {
|
4583 |
-
$updraftplus->log("Entity to move not found in this zip - but this is possible with this foreign backup type");
|
4584 |
-
} else {
|
4585 |
-
|
4586 |
-
$updraftplus->log_e($val);
|
4587 |
-
foreach ($val->get_error_messages() as $msg) {
|
4588 |
-
$updraftplus->log(__('Error message', 'updraftplus').': '.$msg, 'notice-restore');
|
4589 |
-
}
|
4590 |
-
$codes = $val->get_error_codes();
|
4591 |
-
if (is_array($codes)) {
|
4592 |
-
foreach ($codes as $code) {
|
4593 |
-
$data = $val->get_error_data($code);
|
4594 |
-
if (!empty($data)) {
|
4595 |
-
$pdata = (is_string($data)) ? $data : serialize($data);
|
4596 |
-
$updraftplus->log(__('Error data:', 'updraftplus').' '.$pdata, 'warning-restore');
|
4597 |
-
if (false !== strpos($pdata, 'PCLZIP_ERR_BAD_FORMAT (-10)')) {
|
4598 |
-
echo '<a href="'.apply_filters('updraftplus_com_link', "https://updraftplus.com/faqs/error-message-pclzip_err_bad_format-10-invalid-archive-structure-mean/").'"><strong>'.__('Follow this link for more information', 'updraftplus').'</strong></a><br>';
|
4599 |
-
}
|
4600 |
-
}
|
4601 |
-
}
|
4602 |
-
}
|
4603 |
-
echo '</div>'; // close the updraft_restore_progress div even if we error
|
4604 |
-
restore_error_handler();
|
4605 |
-
return $val;
|
4606 |
-
}
|
4607 |
-
} elseif (false === $val) {
|
4608 |
-
echo '</div>'; // close the updraft_restore_progress div even if we error
|
4609 |
-
restore_error_handler();
|
4610 |
-
return false;
|
4611 |
-
}
|
4612 |
-
unset($files[$fkey]);
|
4613 |
-
$second_loop[$type] = $files;
|
4614 |
-
$updraftplus->jobdata_set('second_loop_entities', $second_loop);
|
4615 |
-
$updraftplus->jobdata_set('backup_timestamp', $timestamp);
|
4616 |
-
|
4617 |
-
do_action('updraft_restored_archive', $file, $type, $val, $fkey, $timestamp);
|
4618 |
|
4619 |
}
|
4620 |
-
unset($second_loop[$type]);
|
4621 |
-
update_site_option('updraft_restore_in_progress', $updraftplus->nonce);
|
4622 |
-
$updraftplus->jobdata_set('second_loop_entities', $second_loop);
|
4623 |
-
$updraftplus->jobdata_set('backup_timestamp', $timestamp);
|
4624 |
-
}
|
4625 |
-
|
4626 |
-
// All done - remove
|
4627 |
-
delete_site_option('updraft_restore_in_progress');
|
4628 |
-
|
4629 |
-
foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) {
|
4630 |
-
add_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt));
|
4631 |
-
}
|
4632 |
|
4633 |
-
|
4634 |
-
$updraftplus_restorer->clear_cache();
|
4635 |
|
4636 |
-
|
4637 |
-
|
4638 |
-
|
4639 |
-
|
4640 |
-
if (!empty($template) && WP_DEFAULT_THEME != $template && strtolower($template) != $template) {
|
4641 |
-
|
4642 |
-
$theme_root = get_theme_root($template);
|
4643 |
-
$theme_root2 = get_theme_root(strtolower($template));
|
4644 |
-
|
4645 |
-
if (!file_exists("$theme_root/$template/style.css") && file_exists("$theme_root/".strtolower($template)."/style.css")) {
|
4646 |
-
$updraftplus->log_e("Theme directory (%s) not found, but lower-case version exists; updating database option accordingly", $template);
|
4647 |
-
update_option('template', strtolower($template));
|
4648 |
}
|
4649 |
-
|
4650 |
}
|
4651 |
|
4652 |
-
if (
|
4653 |
-
echo '<strong>';
|
4654 |
-
$updraftplus->log_e("The current theme was not found; to prevent this stopping the site from loading, your theme has been reverted to the default theme");
|
4655 |
-
echo '</strong>';
|
4656 |
-
}
|
4657 |
-
|
4658 |
-
echo '</div>'; // Close the updraft_restore_progress div
|
4659 |
|
4660 |
restore_error_handler();
|
4661 |
|
4662 |
-
return true;
|
4663 |
}
|
4664 |
|
4665 |
public function option_filter_template($val) {
|
@@ -4682,21 +4549,6 @@ ENDHERE;
|
|
4682 |
return $updraftplus->option_filter_get('stylesheet_root');
|
4683 |
}
|
4684 |
|
4685 |
-
public function sort_restoration_entities($a, $b) {
|
4686 |
-
if ($a == $b) return 0;
|
4687 |
-
// Put the database first
|
4688 |
-
// Put wpcore after plugins/uploads/themes (needed for restores of foreign all-in-one formats)
|
4689 |
-
if ('db' == $a || 'wpcore' == $b) return -1;
|
4690 |
-
if ('db' == $b || 'wpcore' == $a) return 1;
|
4691 |
-
// After wpcore, next last is others
|
4692 |
-
if ('others' == $b) return -1;
|
4693 |
-
if ('others' == $a) return 1;
|
4694 |
-
// And then uploads - this is only because we want to make sure uploads is after plugins, so that we know before we get to the uploads whether the version of UD which might have to unpack them can do this new-style or not.
|
4695 |
-
if ('uploads' == $b) return -1;
|
4696 |
-
if ('uploads' == $a) return 1;
|
4697 |
-
return strcmp($a, $b);
|
4698 |
-
}
|
4699 |
-
|
4700 |
public function return_array($input) {
|
4701 |
if (!is_array($input)) $input = array();
|
4702 |
return $input;
|
@@ -4838,7 +4690,7 @@ ENDHERE;
|
|
4838 |
|
4839 |
$return_array = array('saved' => true);
|
4840 |
|
4841 |
-
$add_to_post_keys = array('updraft_interval', 'updraft_interval_database', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_files', 'updraft_startday_db');
|
4842 |
|
4843 |
// If database and files are on same schedule, override the db day/time settings
|
4844 |
if (isset($settings['updraft_interval_database']) && isset($settings['updraft_interval_database']) && $settings['updraft_interval_database'] == $settings['updraft_interval'] && isset($settings['updraft_starttime_files'])) {
|
@@ -5223,7 +5075,7 @@ ENDHERE;
|
|
5223 |
/**
|
5224 |
* This will call any wp_action
|
5225 |
*
|
5226 |
-
* @param Array
|
5227 |
* @param Callable|Boolean $close_connection_callable A callable to call to close the browser connection, or true for a default suitable for internal use, or false for none
|
5228 |
* @return Array - results
|
5229 |
*/
|
@@ -5297,4 +5149,171 @@ ENDHERE;
|
|
5297 |
wp_enqueue_script('jstree', UPDRAFTPLUS_URL.'/includes/jstree/jstree'.$min_or_not.'.js', array('jquery'), $jstree_enqueue_version);
|
5298 |
wp_enqueue_style('jstree', UPDRAFTPLUS_URL.'/includes/jstree/themes/default/style'.$min_or_not.'.css', array(), $jstree_enqueue_version);
|
5299 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5300 |
}
|
17 |
|
18 |
private $auth_instance_ids = array('dropbox' => array(), 'onedrive' => array(), 'googledrive' => array(), 'googlecloud' => array());
|
19 |
|
20 |
+
private $php_versions = array('5.4', '5.5', '5.6', '7.0', '7.1', '7.2');
|
21 |
+
|
22 |
+
private $wp_versions = array('3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9', '4.0', '4.1', '4.2', '4.3', '4.4', '4.5', '4.6', '4.7', '4.8', '4.9');
|
23 |
+
|
24 |
public function __construct() {
|
25 |
$this->admin_init();
|
26 |
}
|
228 |
}
|
229 |
|
230 |
private function setup_all_admin_notices_udonly($service, $override = false) {
|
231 |
+
global $updraftplus;
|
232 |
|
233 |
if (UpdraftPlus_Options::user_can_manage() && defined('DISABLE_WP_CRON') && DISABLE_WP_CRON && (!defined('UPDRAFTPLUS_DISABLE_WP_CRON_NOTICE') || !UPDRAFTPLUS_DISABLE_WP_CRON_NOTICE)) {
|
234 |
add_action('all_admin_notices', array($this, 'show_admin_warning_disabledcron'));
|
265 |
}
|
266 |
}
|
267 |
|
268 |
+
if (version_compare($updraftplus->get_wordpress_version(), '3.2', '<')) add_action('all_admin_notices', array($this, 'show_admin_warning_wordpressversion'));
|
269 |
}
|
270 |
|
271 |
/**
|
353 |
// UpdraftPlus templates
|
354 |
$this->register_template_directories();
|
355 |
|
356 |
+
global $updraftplus, $pagenow;
|
357 |
add_filter('updraftplus_dirlist_others', array($updraftplus, 'backup_others_dirlist'));
|
358 |
add_filter('updraftplus_dirlist_uploads', array($updraftplus, 'backup_uploads_dirlist'));
|
359 |
|
602 |
$this->include_template('wp-admin/notices/thanks-for-using-main-dash.php');
|
603 |
}
|
604 |
|
605 |
+
/**
|
606 |
+
* Enqueue sufficient versions of jQuery and our own scripts
|
607 |
+
*/
|
608 |
private function ensure_sufficient_jquery_and_enqueue() {
|
609 |
+
global $updraftplus;
|
610 |
|
611 |
$enqueue_version = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? $updraftplus->version.'.'.time() : $updraftplus->version;
|
612 |
$min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
|
613 |
|
614 |
+
if (version_compare($updraftplus->get_wordpress_version(), '3.3', '<')) {
|
615 |
// 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
|
616 |
wp_deregister_script('jquery');
|
617 |
$jquery_enqueue_version = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '1.7.2'.'.'.time() : '1.7.2';
|
805 |
'local_upload_started' => __('Local backup upload has started; please check the current status tab to see the upload progress', 'updraftplus'),
|
806 |
'local_upload_error' => __('You must select at least one remote storage destination to upload this backup set to.', 'updrafplus'),
|
807 |
'already_uploaded' => __('(already uploaded)', 'updraftplus'),
|
808 |
+
'onedrive_folder_url_warning' => __('Please specify the Microsoft OneDrive folder name, not the URL.', 'updraftplus'),
|
809 |
+
'updraftcentral_cloud' => __('UpdraftCentral Cloud', 'updraftplus'),
|
810 |
+
'login_successful' => __('Login successful.', 'updraftplus').' '.__('Please follow this link to open %s in a new window.', 'updraftplus'),
|
811 |
+
'registration_successful' => __('Registration successful.', 'updraftplus').' '.__('Please follow this link to open %s in a new window.', 'updraftplus'),
|
812 |
+
'username_password_required' => __('Both email and password fields are required.', 'updraftplus'),
|
813 |
+
'valid_email_required' => __('An email is required and needs to be in a valid format.', 'updraftplus'),
|
814 |
+
'trouble_connecting' => __('Trouble connecting? Try using an alternative method in the advanced security options.', 'updraftplus'),
|
815 |
+
'perhaps_login' => __('Perhaps you would want to login instead.', 'updraftplus'),
|
816 |
+
'generating_key' => __('Please wait while the system generates and registers an encryption key for your website with UpdraftCentral Cloud.', 'updraftplus'),
|
817 |
+
'updraftcentral_cloud_redirect' => __('Please wait while you are redirected to UpdraftCentral Cloud.', 'updraftplus'),
|
818 |
+
'data_consent_required' => __('You need to read and accept the UpdraftCentral Cloud data and privacy policies before you can proceed.', 'updraftplus'),
|
819 |
+
'close_wizard' => __('You can also close this wizard.', 'updraftplus'),
|
820 |
+
'control_udc_connections' => __('For future control of all your UpdraftCentral connections, go to the "Advanced Tools" tab.', 'updraftplus'),
|
821 |
));
|
822 |
}
|
823 |
|
1083 |
}
|
1084 |
}
|
1085 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1086 |
/**
|
1087 |
* Start a download of a backup. This method is called via the AJAX action updraft_download_backup. May die instead of returning depending upon the mode in which it is called.
|
1088 |
*/
|
1259 |
} else {
|
1260 |
$updraftplus->close_browser_connection(json_encode($msg));
|
1261 |
}
|
1262 |
+
$updraftplus->get_remote_file($services, $file, $timestamp);
|
1263 |
}
|
1264 |
|
1265 |
// Now, be ready to spool the thing to the browser
|
1289 |
|
1290 |
}
|
1291 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1292 |
/**
|
1293 |
* This is used as a callback
|
1294 |
*
|
1330 |
$data = in_array($subaction, $data_in_get) ? $_GET : $_POST;
|
1331 |
|
1332 |
// Undo WP's slashing of GET/POST data
|
1333 |
+
$data = UpdraftPlus_Manipulation_Functions::wp_unslash($data);
|
1334 |
|
1335 |
// TODO: Once all commands come through here and through updraft_send_command(), the data should always come from this attribute (once updraft_send_command() is modified appropriately).
|
1336 |
if (isset($data['action_data'])) $data = $data['action_data'];
|
1378 |
try {
|
1379 |
// N.B. Also called from autobackup.php
|
1380 |
// TODO: This should go into UpdraftPlus_Commands, once the add-ons have been ported to use updraft_send_command()
|
1381 |
+
echo json_encode($this->get_activejobs_list(UpdraftPlus_Manipulation_Functions::wp_unslash($_GET)));
|
1382 |
} catch (Exception $e) {
|
1383 |
$log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during get active job list. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1384 |
error_log($log_message);
|
1400 |
try {
|
1401 |
// httpget
|
1402 |
$curl = empty($_REQUEST['curl']) ? false : true;
|
1403 |
+
echo $this->http_get(UpdraftPlus_Manipulation_Functions::wp_unslash($_REQUEST['uri']), $curl);
|
1404 |
// @codingStandardsIgnoreLine
|
1405 |
} catch (Error $e) {
|
1406 |
$log_message = 'PHP Fatal error ('.get_class($e).') has occurred during http get. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1422 |
$subsubaction = $_REQUEST['subsubaction'];
|
1423 |
try {
|
1424 |
// These generally echo and die - they will need further work to port to one of the command classes. Some may already have equivalents in UpdraftPlus_Commands, if they are used from UpdraftCentral.
|
1425 |
+
do_action(UpdraftPlus_Manipulation_Functions::wp_unslash($subsubaction), $_REQUEST);
|
1426 |
} catch (Exception $e) {
|
1427 |
$log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during doaction subaction with '.$subsubaction.' subsubaction. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')';
|
1428 |
error_log($log_message);
|
1742 |
'data' => $data,
|
1743 |
'cksum' => md5($output),
|
1744 |
'logs_exist' => $logs_exist,
|
1745 |
+
'web_server_disk_space' => $this->web_server_disk_space(true),
|
1746 |
));
|
1747 |
}
|
1748 |
|
1749 |
+
/**
|
1750 |
+
* Get the html of "Web-server disk space" line which resides above of the existing backup table
|
1751 |
+
*
|
1752 |
+
* @param Boolean $will_immediately_calculate_disk_space Whether disk space should be counted now or when user click Refresh link
|
1753 |
+
* @return String Web server disk space html to render
|
1754 |
+
*/
|
1755 |
+
public function web_server_disk_space($will_immediately_calculate_disk_space = true) {
|
1756 |
+
global $updraftplus, $updraftplus_admin;
|
1757 |
+
if ($will_immediately_calculate_disk_space) {
|
1758 |
+
$disk_space_used = $updraftplus_admin->get_disk_space_used('updraft', 'numeric');
|
1759 |
+
if ($disk_space_used > apply_filters('updraftplus_display_usage_line_threshold_size', 104857600)) { // 104857600 = 100 MB = (100 * 1024 * 1024)
|
1760 |
+
$disk_space_text = UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($disk_space_used);
|
1761 |
+
$refresh_link_text = __('refresh', 'updraftplus');
|
1762 |
+
return $this->web_server_disk_space_html($disk_space_text, $refresh_link_text);
|
1763 |
+
} else {
|
1764 |
+
return '';
|
1765 |
+
}
|
1766 |
+
} else {
|
1767 |
+
$disk_space_text = '';
|
1768 |
+
$refresh_link_text = __('calculate', 'updraftplus');
|
1769 |
+
return $this->web_server_disk_space_html($disk_space_text, $refresh_link_text);
|
1770 |
+
}
|
1771 |
+
}
|
1772 |
+
|
1773 |
+
/**
|
1774 |
+
* Get the html of "Web-server disk space" line which resides above of the existing backup table
|
1775 |
+
*
|
1776 |
+
* @param String $disk_space_text The texts which represents disk space usage
|
1777 |
+
* @param String $refresh_link_text Refresh disk space link text
|
1778 |
+
* @return String Web server disk space html
|
1779 |
+
*/
|
1780 |
+
private function web_server_disk_space_html($disk_space_text, $refresh_link_text) {
|
1781 |
+
return '<li class="updraft-server-disk-space" title="'.esc_attr__('This is a count of the contents of your Updraft directory', 'updraftplus').'"><strong>'.__('Web-server disk space in use by UpdraftPlus', 'updraftplus').':</strong> <span class="updraft_diskspaceused"><em>'.$disk_space_text.'</em></span> <a class="updraft_diskspaceused_update" href="#">'.$refresh_link_text.'</a></li>';
|
1782 |
+
}
|
1783 |
+
|
1784 |
/**
|
1785 |
* Get information on disk space used by an entity, or by UD's internal directory. Returns as a human-readable string.
|
1786 |
*
|
1787 |
* @param String $entity - the entity (e.g. 'plugins'; 'all' for all entities, or 'ud' for UD's internal directory)
|
1788 |
+
* @param String $format Return format - 'text' or 'numeric'
|
1789 |
+
* @return String|Integer If $format is text, It returns strings. Otherwise integer value.
|
1790 |
*/
|
1791 |
+
public function get_disk_space_used($entity, $format = 'text') {
|
1792 |
global $updraftplus;
|
1793 |
+
if ('updraft' == $entity) return $this->recursive_directory_size($updraftplus->backups_dir_location(), array(), '', $format);
|
1794 |
|
1795 |
$backupable_entities = $updraftplus->get_backupable_file_entities(true, false);
|
1796 |
|
1803 |
$size = $this->recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, 'numeric');
|
1804 |
if (is_numeric($size) && $size>0) $total_size += $size;
|
1805 |
}
|
1806 |
+
|
1807 |
+
if ('numeric' == $format) {
|
1808 |
+
return $total_size;
|
1809 |
+
} else {
|
1810 |
+
return UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($total_size);
|
1811 |
+
}
|
1812 |
+
|
1813 |
} elseif (!empty($backupable_entities[$entity])) {
|
1814 |
// Might be an array
|
1815 |
$basedir = $backupable_entities[$entity];
|
1816 |
$dirs = apply_filters('updraftplus_dirlist_'.$entity, $basedir);
|
1817 |
+
return $this->recursive_directory_size($dirs, $updraftplus->get_exclude($entity), $basedir, $format);
|
1818 |
}
|
1819 |
|
1820 |
// Default fallback
|
2323 |
$this->include_template('wp-admin/settings/header.php');
|
2324 |
}
|
2325 |
|
2326 |
+
/**
|
2327 |
+
* Output the settings page content. Will also run a restore if $_REQUEST so indicates.
|
2328 |
+
*/
|
2329 |
public function settings_output() {
|
2330 |
|
2331 |
if (false == ($render = apply_filters('updraftplus_settings_page_render', true))) {
|
2386 |
if ('db' != $v) $s_val = 2;
|
2387 |
}
|
2388 |
}
|
2389 |
+
$pval = $updraftplus->have_addons ? 1 : 0;
|
2390 |
|
2391 |
echo '<strong>'.__('Actions', 'updraftplus').':</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&updraft_restore_success='.$s_val.'&pval='.$pval.'">'.__('Return to UpdraftPlus Configuration', 'updraftplus').'</a>';
|
2392 |
return;
|
2393 |
+
|
2394 |
} elseif (is_wp_error($backup_success)) {
|
2395 |
echo '<p>';
|
2396 |
$updraftplus->log_e('Restore failed...');
|
2397 |
echo '</p>';
|
2398 |
$updraftplus->log_wp_error($backup_success);
|
2399 |
+
$updraftplus->log('Restore failed');
|
2400 |
$updraftplus->list_errors();
|
2401 |
echo '<strong>'.__('Actions', 'updraftplus').':</strong> <a href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus">'.__('Return to UpdraftPlus Configuration', 'updraftplus').'</a>';
|
2402 |
return;
|
2529 |
$backup_history = UpdraftPlus_Backup_History::get_history();
|
2530 |
}
|
2531 |
|
2532 |
+
$tabflag = 'status';
|
2533 |
+
$main_tabs = apply_filters(
|
2534 |
+
'updraftplus_main_tabs',
|
2535 |
+
array(
|
2536 |
+
'status' => __('Current Status', 'updraftplus'),
|
2537 |
+
'backups' => __('Existing Backups', 'updraftplus').' ('.count($backup_history).')',
|
2538 |
+
'settings' => __('Settings', 'updraftplus'),
|
2539 |
+
'expert' => __('Advanced Tools', 'updraftplus'),
|
2540 |
+
'addons' => __('Premium / Extensions', 'updraftplus'),
|
2541 |
+
)
|
2542 |
+
);
|
2543 |
|
2544 |
if (isset($_REQUEST['tab'])) {
|
2545 |
+
$request_tab = sanitize_text_field($_REQUEST['tab']);
|
2546 |
+
$valid_tabflags = array_keys($main_tabs);
|
2547 |
+
if (in_array($request_tab, $valid_tabflags)) {
|
2548 |
+
$tabflag = $request_tab;
|
2549 |
+
} else {
|
2550 |
+
$tabflag = 'status';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2551 |
}
|
2552 |
}
|
2553 |
+
|
2554 |
+
$this->include_template('wp-admin/settings/tab-bar.php', false, array('main_tabs' => $main_tabs, 'backup_history' => $backup_history, 'tabflag' => $tabflag));
|
2555 |
|
2556 |
$updraft_dir = $updraftplus->backups_dir_location();
|
2557 |
$backup_disabled = $updraftplus->really_is_writable($updraft_dir) ? '' : 'disabled="disabled"';
|
2563 |
|
2564 |
<?php $this->include_template('wp-admin/settings/tab-status.php', false, array('tabflag' => $tabflag, 'backup_disabled' => $backup_disabled)); ?>
|
2565 |
|
2566 |
+
<div id="updraft-navtab-backups-content" <?php if ('backups' != $tabflag) echo 'class="updraft-hidden"'; ?> style="<?php if ('backups' != $tabflag) echo 'display:none;'; ?>">
|
2567 |
<?php
|
2568 |
$is_opera = (false !== strpos($_SERVER['HTTP_USER_AGENT'], 'Opera') || false !== strpos($_SERVER['HTTP_USER_AGENT'], 'OPR/'));
|
2569 |
$tmp_opts = array('include_opera_warning' => $is_opera);
|
2572 |
$this->include_template('wp-admin/settings/upload-backups-modal.php');
|
2573 |
?>
|
2574 |
</div>
|
2575 |
+
|
2576 |
+
<div id="updraft-navtab-settings-content" <?php if ('settings' != $tabflag) echo 'class="updraft-hidden"'; ?> style="<?php if ('settings' != $tabflag) echo 'display:none;'; ?>">
|
2577 |
<h2 class="updraft_settings_sectionheading"><?php _e('Backup Contents And Schedule', 'updraftplus');?></h2>
|
2578 |
<?php UpdraftPlus_Options::options_form_begin(); ?>
|
2579 |
<?php $this->settings_formcontents(); ?>
|
2580 |
</form>
|
2581 |
+
<?php
|
2582 |
+
$our_keys = UpdraftPlus_Options::get_updraft_option('updraft_central_localkeys');
|
2583 |
+
if (!is_array($our_keys)) $our_keys = array();
|
2584 |
+
|
2585 |
+
// Hide the UpdraftCentral Cloud wizard If the user already has a key created for either
|
2586 |
+
// updraftplus.com or self hosted version.
|
2587 |
+
if (empty($our_keys)) {
|
2588 |
+
?>
|
2589 |
+
<div id="updraftcentral_cloud_connect_container" class="updraftcentral_cloud_connect hidden-in-updraftcentral">
|
2590 |
+
<?php
|
2591 |
+
|
2592 |
+
$email = '';
|
2593 |
+
|
2594 |
+
// Checking email from "Premium / Extensions" tab
|
2595 |
+
if (defined('UDADDONS2_SLUG')) {
|
2596 |
+
global $updraftplus_addons2;
|
2597 |
+
|
2598 |
+
if (is_a($updraftplus_addons2, 'UpdraftPlusAddons2') && is_callable(array($updraftplus_addons2, 'get_option'))) {
|
2599 |
+
$options = $updraftplus_addons2->get_option(UDADDONS2_SLUG.'_options');
|
2600 |
+
|
2601 |
+
if (!empty($options['email'])) {
|
2602 |
+
$email = htmlspecialchars($options['email']);
|
2603 |
+
}
|
2604 |
+
}
|
2605 |
+
}
|
2606 |
+
|
2607 |
+
// Check the vault's email if we fail to get the "email" from the "Premium / Extensions" tab
|
2608 |
+
if (empty($email)) {
|
2609 |
+
$settings = $updraftplus->update_remote_storage_options_format('updraftvault');
|
2610 |
+
if (!is_wp_error($settings)) {
|
2611 |
+
if (!empty($settings['settings'])) {
|
2612 |
+
foreach ($settings['settings'] as $instance_id => $storage_options) {
|
2613 |
+
if (!empty($storage_options['email'])) {
|
2614 |
+
$email = $storage_options['email'];
|
2615 |
+
break;
|
2616 |
+
}
|
2617 |
+
}
|
2618 |
+
}
|
2619 |
+
}
|
2620 |
+
}
|
2621 |
+
|
2622 |
+
// Checking any possible email we could find from the "updraft_email" option in case the
|
2623 |
+
// above two checks failed.
|
2624 |
+
if (empty($email)) {
|
2625 |
+
$possible_emails = $updraftplus->just_one_email(UpdraftPlus_Options::get_updraft_option('updraft_email'));
|
2626 |
+
if (!empty($possible_emails)) {
|
2627 |
+
// If we get an array from the 'just_one_email' result then we're going
|
2628 |
+
// to pull the very first entry and make use of that on the succeeding process.
|
2629 |
+
if (is_array($possible_emails)) $possible_emails = array_shift($possible_emails);
|
2630 |
+
|
2631 |
+
if (is_string($possible_emails)) {
|
2632 |
+
$emails = explode(',', $possible_emails);
|
2633 |
+
$email = trim($emails[0]);
|
2634 |
+
}
|
2635 |
+
}
|
2636 |
+
}
|
2637 |
+
|
2638 |
+
$this->include_template('wp-admin/settings/updraftcentral-connect.php', false, array('email' => $email));
|
2639 |
+
?>
|
2640 |
+
</div>
|
2641 |
+
<?php
|
2642 |
+
}
|
2643 |
+
?>
|
2644 |
</div>
|
2645 |
|
2646 |
+
<div id="updraft-navtab-expert-content"<?php if ('expert' != $tabflag) echo ' class="updraft-hidden"'; ?> style="<?php if ('expert' != $tabflag) echo 'display:none;'; ?>">
|
2647 |
<?php $this->settings_advanced_tools(); ?>
|
2648 |
</div>
|
2649 |
|
2650 |
+
<div id="updraft-navtab-addons-content"<?php if ('addons' != $tabflag) echo ' class="updraft-hidden"'; ?> style="<?php if ('addons' != $tabflag) echo 'display:none;'; ?>">
|
2651 |
|
2652 |
<?php
|
2653 |
$tab_addons = $this->include_template('wp-admin/settings/tab-addons.php', true, array('tabflag' => $tabflag));
|
2659 |
</div>
|
2660 |
|
2661 |
<?php
|
2662 |
+
do_action('updraftplus_after_main_tab_content', $tabflag);
|
2663 |
// settings_header() opens a div
|
2664 |
echo '</div>';
|
2665 |
}
|
2709 |
/**
|
2710 |
* This method will build the UpdraftPlus.com login form and echo it to the page.
|
2711 |
*
|
2712 |
+
* @param string $option_page - the option page this form is being output to
|
2713 |
+
* @param boolean $tfa - indicates if we want to add the tfa UI
|
2714 |
*
|
2715 |
* @return void
|
2716 |
*/
|
2717 |
+
public function build_credentials_form($option_page, $tfa = false) {
|
2718 |
+
global $updraftplus;
|
2719 |
|
2720 |
$enter_credentials_begin = UpdraftPlus_Options::options_form_begin('', false, array(), 'updraftplus_com_login');
|
2721 |
|
2731 |
|
2732 |
$enter_credentials_end .= '</form>';
|
2733 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2734 |
echo $enter_credentials_begin;
|
2735 |
|
2736 |
// We have to duplicate settings_fields() in order to set our referer
|
2751 |
|
2752 |
echo $nonce_field;
|
2753 |
|
2754 |
+
$referer = esc_attr(UpdraftPlus_Manipulation_Functions::wp_unslash($_SERVER['REQUEST_URI']));
|
2755 |
|
2756 |
// This one is used on single site installs
|
2757 |
if (false === strpos($referer, '?')) {
|
2760 |
$referer .= '&tab=addons';
|
2761 |
}
|
2762 |
|
2763 |
+
$options = apply_filters('updraftplus_com_login_options', array("email" => "", "password" => ""));
|
2764 |
+
|
2765 |
echo '<input type="hidden" name="_wp_http_referer" value="'.$referer.'" />';
|
2766 |
// End of duplication of settings-fields()
|
2767 |
|
2768 |
+
?>
|
2769 |
+
|
2770 |
+
<h2> <?php _e('Connect with your UpdraftPlus.Com account', 'updraftplus'); ?></h2>
|
2771 |
+
<p class="updraftplus_com_login_status"></p>
|
2772 |
+
|
2773 |
+
<table class="form-table">
|
2774 |
+
<tbody>
|
2775 |
+
<tr class="non_tfa_fields">
|
2776 |
+
<th><?php _e('Email', 'updraftplus'); ?></th>
|
2777 |
+
<td>
|
2778 |
+
<label for="<?php echo $option_page; ?>_options_email">
|
2779 |
+
<input id="<?php echo $option_page; ?>_options_email" type="text" size="36" name="<?php echo $option_page; ?>_options[email]" value="<?php echo htmlspecialchars($options['email']); ?>" />
|
2780 |
+
<br/>
|
2781 |
+
<a href="https://updraftplus.com/my-account/"><?php _e("Not yet got an account (it's free)? Go get one!", 'updraftplus'); ?></a>
|
2782 |
+
</label>
|
2783 |
+
</td>
|
2784 |
+
</tr>
|
2785 |
+
<tr class="non_tfa_fields">
|
2786 |
+
<th><?php _e('Password', 'updraftplus'); ?></th>
|
2787 |
+
<td>
|
2788 |
+
<label for="<?php echo $option_page; ?>'_options_password">
|
2789 |
+
<input id="<?php echo $option_page; ?>_options_password" type="password" size="36" name="<?php echo $option_page; ?>_options[password]" value="<?php echo htmlspecialchars($options['password']); ?>" />
|
2790 |
+
<br/>
|
2791 |
+
<a href="https://updraftplus.com/my-account/?action=lostpassword"><?php _e('Forgotten your details?', 'updraftplus'); ?></a>
|
2792 |
+
</label>
|
2793 |
+
</td>
|
2794 |
+
</tr>
|
2795 |
+
<?php if ($tfa) { ?>
|
2796 |
+
<tr class="tfa_fields" style="display:none;">
|
2797 |
+
<th><?php _e('One Time Password (check your OTP app to get this password)', 'updraftplus'); ?></th>
|
2798 |
+
<td>
|
2799 |
+
<label for="<?php echo $option_page; ?>_options_two_factor_code">
|
2800 |
+
<input id="<?php echo $option_page; ?>_options_two_factor_code" type="text" size="10" name="<?php echo $option_page; ?>_options[two_factor_code]" />
|
2801 |
+
</label>
|
2802 |
+
</td>
|
2803 |
+
</tr>
|
2804 |
+
<?php } ?>
|
2805 |
+
</tbody>
|
2806 |
+
</table>
|
2807 |
+
|
2808 |
+
<?php
|
2809 |
+
|
2810 |
echo $enter_credentials_end;
|
2811 |
}
|
2812 |
|
3235 |
if (!$wp_filesystem->delete($plugs.'-old', true)) {
|
3236 |
$ret3 = false;
|
3237 |
echo "<strong>".__('Failed', 'updraftplus')."</strong><br>";
|
3238 |
+
echo $updraftplus->log_permission_failure_message($wp_filesystem->wp_content_dir(), 'Delete '.$plugs.'-old');
|
3239 |
} else {
|
3240 |
$ret3 = true;
|
3241 |
echo "<strong>".__('OK', 'updraftplus')."</strong><br>";
|
3271 |
if (!$wp_filesystem->delete($dir.$name, true)) {
|
3272 |
$ret = false;
|
3273 |
echo "<strong>".__('Failed', 'updraftplus')."</strong><br>";
|
3274 |
+
echo $updraftplus->log_permission_failure_message($dir, 'Delete '.$dir.$name);
|
3275 |
} else {
|
3276 |
echo "<strong>".__('OK', 'updraftplus')."</strong><br>";
|
3277 |
}
|
3281 |
} else {
|
3282 |
$ret = false;
|
3283 |
echo "<strong>".__('Failed', 'updraftplus')."</strong><br>";
|
3284 |
+
echo $updraftplus->log_permission_failure_message($dir, 'Delete '.$dir.$name);
|
3285 |
}
|
3286 |
}
|
3287 |
}
|
3508 |
} else {
|
3509 |
$dir_info .= __('Backup directory specified exists, but is <b>not</b> writable.', 'updraftplus');
|
3510 |
}
|
3511 |
+
$dir_info .= '<span class="updraft-directory-not-writable-blurb"><span class="directory-permissions"><a class="updraft_create_backup_dir" href="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&action=updraft_create_backup_dir&nonce='.wp_create_nonce('create_backup_dir').'">'.__('Follow this link to attempt to create the directory and set the permissions', 'updraftplus').'</a></span>, '.__('or, to reset this option', 'updraftplus').' <a href="#" class="updraft_backup_dir_reset">'.__('press 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>';
|
3512 |
}
|
3513 |
return $dir_info;
|
3514 |
}
|
3715 |
if ('numeric' == $format) return $size;
|
3716 |
|
3717 |
global $updraftplus;
|
3718 |
+
return UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($size);
|
3719 |
|
3720 |
}
|
3721 |
|
3817 |
$rawbackup .= $show_services;
|
3818 |
|
3819 |
if (false !== $total_size) {
|
3820 |
+
$rawbackup .= '</p><strong>'.__('Total backup size:', 'updraftplus').'</strong> '.UpdraftPlus_Manipulation_Functions::convert_numeric_size_to_text($total_size).'<p>';
|
3821 |
}
|
3822 |
|
3823 |
|
4029 |
if (!empty($jobdata) && 'finished' != $jobdata['jobstatus']) return '';
|
4030 |
|
4031 |
// Check that the user has remote storage setup.
|
4032 |
+
$services = (array) $updraftplus->just_one($updraftplus->get_canonical_service_list());
|
4033 |
+
if (empty($services)) return '';
|
|
|
|
|
|
|
4034 |
|
4035 |
$show_upload = false;
|
4036 |
$not_uploaded = array();
|
4188 |
$blog_name = $matches[2];
|
4189 |
}
|
4190 |
|
4191 |
+
if (UpdraftPlus_Encryption::is_file_encrypted($db_backup_name)) $status = 'encrypted';
|
4192 |
|
4193 |
if (is_array($db_info) && isset($db_info['status'])) {
|
4194 |
$db_backups[$key]['status'] = $status;
|
4243 |
}
|
4244 |
|
4245 |
/**
|
4246 |
+
* Processes $_POST (keys: updraft_restore and updraft_restore_*) to build an array of entities to restore.
|
4247 |
+
* Can also edit $_POST['updraft_restore']
|
4248 |
*
|
4249 |
+
* @param Array $backup_set - information on the backup to restore
|
4250 |
+
*
|
4251 |
+
* @return Array
|
4252 |
*/
|
4253 |
+
private function get_entities_to_restore($backup_set) {
|
4254 |
+
|
4255 |
+
$entities_to_restore = array();
|
4256 |
+
$foreign_known = apply_filters('updraftplus_accept_archivename', array());
|
|
|
4257 |
|
4258 |
+
foreach ($_POST['updraft_restore'] as $entity) {
|
4259 |
+
if (empty($backup_set['meta_foreign'])) {
|
4260 |
+
$entities_to_restore[$entity] = $entity;
|
4261 |
+
} else {
|
4262 |
+
if ('db' == $entity && !empty($foreign_known[$backup_set['meta_foreign']]) && !empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) {
|
4263 |
+
$entities_to_restore[$entity] = 'db';
|
4264 |
+
} else {
|
4265 |
+
$entities_to_restore[$entity] = 'wpcore';
|
4266 |
+
}
|
4267 |
+
}
|
4268 |
}
|
4269 |
|
4270 |
+
foreach ($_POST as $key => $value) {
|
4271 |
+
if (0 === strpos($key, 'updraft_restore_')) {
|
4272 |
+
$nkey = substr($key, 16);
|
4273 |
+
if (!isset($entities_to_restore[$nkey])) {
|
4274 |
+
$_POST['updraft_restore'][] = $nkey;
|
4275 |
+
if (empty($backup_set['meta_foreign'])) {
|
4276 |
+
$entities_to_restore[$nkey] = $nkey;
|
4277 |
+
} else {
|
4278 |
+
if ('db' == $entity && !empty($foreign_known[$backup_set['meta_foreign']]['separatedb'])) {
|
4279 |
+
$entities_to_restore[$nkey] = 'db';
|
4280 |
+
} else {
|
4281 |
+
$entities_to_restore[$nkey] = 'wpcore';
|
4282 |
+
}
|
4283 |
+
}
|
4284 |
+
}
|
4285 |
+
}
|
4286 |
+
}
|
4287 |
+
|
4288 |
+
return $entities_to_restore;
|
4289 |
+
}
|
4290 |
+
|
4291 |
+
/**
|
4292 |
+
* Ensure that WP_Filesystem is instantiated and functional. Otherwise, outputs necessary HTML and dies.
|
4293 |
+
*
|
4294 |
+
* @param Array $continuation_data - continuation data
|
4295 |
+
* @param Integer $timestamp - backup timestamp
|
4296 |
+
*
|
4297 |
+
* @return Array|Null - restore options to use, if any
|
4298 |
+
*/
|
4299 |
+
private function ensure_wp_filesystem_set_up($continuation_data, $timestamp) {
|
4300 |
+
|
4301 |
+
global $wp_filesystem;
|
4302 |
+
|
4303 |
+
$restore_options = null;
|
4304 |
+
|
4305 |
// request_filesystem_credentials passes on fields just via hidden name/value pairs.
|
4306 |
// Build array of parameters to be passed via this
|
4307 |
$extra_fields = array();
|
4332 |
foreach ($wp_filesystem->errors->get_error_messages() as $message) show_message($message);
|
4333 |
exit;
|
4334 |
}
|
4335 |
+
|
4336 |
+
return $restore_options;
|
4337 |
+
}
|
4338 |
+
|
4339 |
+
/**
|
4340 |
+
* Carry out the restore process
|
4341 |
+
*
|
4342 |
+
* @param Integer $timestamp Identifying the backup to be restored
|
4343 |
+
* @param Array|null $continuation_data For continuing a multi-stage restore (code believed to be incomplete)
|
4344 |
+
* @return Boolean|WP_Error WP_Error indicates a terminal failure; false indicates not-yet complete (not necessarily terminal); true indicates complete.
|
4345 |
+
*/
|
4346 |
+
private function restore_backup($timestamp, $continuation_data = null) {
|
4347 |
+
|
4348 |
+
global $updraftplus;
|
4349 |
+
|
4350 |
+
$backup_set = UpdraftPlus_Backup_History::get_history($timestamp);
|
4351 |
+
|
4352 |
+
if (empty($backup_set)) {
|
4353 |
+
echo '<p>'.__('This backup does not exist in the backup history - restoration aborted. Timestamp:', 'updraftplus')." $timestamp</p><br>";
|
4354 |
+
return new WP_Error('does_not_exist', __('Backup does not exist in the backup history', 'updraftplus')." ($timestamp)");
|
4355 |
+
}
|
4356 |
|
4357 |
+
// Will print HTML and die() if necessary
|
4358 |
+
$restore_options = $this->ensure_wp_filesystem_set_up($continuation_data, $timestamp);
|
4359 |
+
|
4360 |
+
// The <div> is closed by self::post_restore_clean_up()
|
4361 |
+
echo '<h1>'.__('UpdraftPlus Restoration: Progress', 'updraftplus').'</h1><div id="updraft-restore-progress">';
|
4362 |
|
4363 |
+
// Set up job ID, time and logging
|
4364 |
$updraftplus->backup_time_nonce();
|
4365 |
$updraftplus->jobdata_set('job_type', 'restore');
|
4366 |
$updraftplus->jobdata_set('job_time_ms', $updraftplus->job_time_ms);
|
4370 |
// TODO: Automatic purging of old log files
|
4371 |
// TODO: Provide option to auto-email the log file
|
4372 |
|
|
|
|
|
4373 |
$this->show_admin_warning('<a target="_blank" href="?action=downloadlog&page=updraftplus&updraftplus_backup_nonce='.htmlspecialchars($updraftplus->nonce).'">'.__('Follow this link to download the log file for this restoration (needed for any support requests).', 'updraftplus').'</a>');
|
4374 |
|
|
|
|
|
|
|
|
|
|
|
|
|
4375 |
// Now, need to turn any updraft_restore_<entity> fields (that came from a potential WP_Filesystem form) back into parts of the _POST array (which we want to use)
|
4376 |
if (empty($_POST['updraft_restore']) || (!is_array($_POST['updraft_restore']))) $_POST['updraft_restore'] = array();
|
4377 |
|
4378 |
+
// N.B. This both processes, and edits, $_POST['updraft_restore']
|
4379 |
+
$entities_to_restore = $this->get_entities_to_restore($backup_set);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4380 |
|
4381 |
if (0 == count($_POST['updraft_restore'])) {
|
4382 |
echo '<p>'.__('ABORT: Could not find the information on which entities to restore.', 'updraftplus').'</p>';
|
4384 |
return new WP_Error('missing_info', 'Backup information not found');
|
4385 |
}
|
4386 |
|
4387 |
+
// This is used in painting the admin page after a successful restore
|
4388 |
$this->entities_to_restore = $entities_to_restore;
|
4389 |
|
4390 |
+
// This will be removed by self::post_restore_clean_up()
|
4391 |
set_error_handler(array($updraftplus, 'php_error'), E_ALL & ~E_STRICT);
|
4392 |
|
4393 |
+
// $_POST['updraft_restore'] is typically something like: array('db', 'plugins', 'themes'), etc.
|
|
|
|
|
|
|
4394 |
|
4395 |
+
// If not options were supplied in $restore_options, then process things in $_POST to get them
|
4396 |
if (empty($restore_options)) {
|
4397 |
+
// Gather the restore options into one place - code after here should read the options, and not the HTTP variables
|
4398 |
$restore_options = array();
|
4399 |
if (!empty($_POST['updraft_restorer_restore_options'])) {
|
4400 |
parse_str(stripslashes($_POST['updraft_restorer_restore_options']), $restore_options);
|
4405 |
$updraftplus->jobdata_set('restore_options', $restore_options);
|
4406 |
}
|
4407 |
|
|
|
|
|
4408 |
// If updraft_incremental_restore_point is equal to -1 then this is either not a incremental restore or we are going to restore up to the latest increment, so there is no need to prune the backup set of any unwanted backup archives.
|
4409 |
if (isset($restore_options['updraft_incremental_restore_point']) && $restore_options['updraft_incremental_restore_point'] > 0) {
|
4410 |
$restore_point = $restore_options['updraft_incremental_restore_point'];
|
4411 |
+
foreach ($backup_set['incremental_sets'] as $increment_timestamp => $entities) {
|
4412 |
+
if ($increment_timestamp > $restore_point) {
|
|
|
|
|
4413 |
foreach ($entities as $entity => $backups) {
|
|
|
4414 |
foreach ($backups as $key => $value) {
|
4415 |
unset($backup_set[$entity][$key]);
|
4416 |
}
|
4420 |
}
|
4421 |
|
4422 |
// Restore in the most helpful order
|
4423 |
+
uksort($backup_set, array('UpdraftPlus_Manipulation_Functions', 'sort_restoration_entities'));
|
4424 |
|
4425 |
+
// Now log. We first remove any encryption passphrase from the log data.
|
4426 |
$copy_restore_options = $restore_options;
|
4427 |
if (!empty($copy_restore_options['updraft_encryptionphrase'])) $copy_restore_options['updraft_encryptionphrase'] = '***';
|
4428 |
$updraftplus->log("Restore job started. Entities to restore: ".implode(', ', array_flip($entities_to_restore)).'. Restore options: '.json_encode($copy_restore_options));
|
4429 |
|
4430 |
$backup_set['timestamp'] = $timestamp;
|
4431 |
|
|
|
|
|
|
|
4432 |
// We use a single object for each entity, because we want to store information about the backup set
|
4433 |
+
if (!class_exists('Updraft_Restorer')) include_once(UPDRAFTPLUS_DIR.'/restorer.php');
|
4434 |
+
|
4435 |
+
echo "<h2>".__('Final checks', 'updraftplus').'</h2>';
|
4436 |
|
4437 |
global $updraftplus_restorer;
|
4438 |
|
4439 |
$updraftplus_restorer = new Updraft_Restorer(new Updraft_Restorer_Skin, $backup_set, false, $restore_options);
|
4440 |
+
|
4441 |
+
add_action('updraftplus_restoration_title', array($this, 'restoration_title'));
|
4442 |
+
|
4443 |
+
$restore_result = $updraftplus_restorer->perform_restore($entities_to_restore, $restore_options, $continuation_data);
|
4444 |
+
|
4445 |
+
if (is_wp_error($restore_result)) {
|
4446 |
+
foreach ($restore_result->get_error_codes() as $code) {
|
4447 |
+
if ('already_exists' == $code) $this->print_delete_old_dirs_form(false);
|
4448 |
+
$data = $restore_result->get_error_data($code);
|
4449 |
+
if (!empty($data)) {
|
4450 |
+
$pdata = is_string($data) ? $data : serialize($data);
|
4451 |
+
$updraftplus->log(__('Error data:', 'updraftplus').' '.$pdata, 'warning-restore');
|
4452 |
+
if (false !== strpos($pdata, 'PCLZIP_ERR_BAD_FORMAT (-10)')) {
|
4453 |
+
echo '<a href="'.apply_filters('updraftplus_com_link', "https://updraftplus.com/faqs/error-message-pclzip_err_bad_format-10-invalid-archive-structure-mean/").'"><strong>'.__('Follow this link for more information', 'updraftplus').'</strong></a><br>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4454 |
}
|
4455 |
}
|
4456 |
+
|
4457 |
}
|
|
|
4458 |
}
|
4459 |
+
|
4460 |
+
if (true === $restore_result) {
|
4461 |
+
$this->post_restore_clean_up(true);
|
4462 |
+
} else {
|
4463 |
+
$this->post_restore_clean_up(false);
|
4464 |
}
|
4465 |
+
|
4466 |
+
return $restore_result;
|
4467 |
+
|
4468 |
+
}
|
4469 |
+
|
4470 |
+
/**
|
4471 |
+
* Called when the restore process wants to print a title
|
4472 |
+
*
|
4473 |
+
* @param String $title - title
|
4474 |
+
*/
|
4475 |
+
public function restoration_title($title) {
|
4476 |
+
echo '<h2>'.$title.'</h2>';
|
4477 |
+
}
|
4478 |
+
|
4479 |
+
/**
|
4480 |
+
* Restore has been completed - clean some things up
|
4481 |
+
*
|
4482 |
+
* @param Boolean $successful - if the restore was successful or not. If not, then only a minimum of necessary clean-up things is done.
|
4483 |
+
* @param Boolean $browser_context - if true, then extra messages will be echo-ed
|
4484 |
+
*
|
4485 |
+
* @uses $GLOBALS['updraftplus_restorer']
|
4486 |
+
* @uses UpdraftPlus::log()
|
4487 |
+
*/
|
4488 |
+
private function post_restore_clean_up($successful = true, $browser_context = true) {
|
4489 |
+
|
4490 |
+
global $updraftplus_restorer, $updraftplus;
|
4491 |
+
|
4492 |
+
if ($successful) {
|
4493 |
+
// All done - remove the intermediate marker
|
4494 |
+
delete_site_option('updraft_restore_in_progress');
|
4495 |
|
4496 |
+
foreach (array('template', 'stylesheet', 'template_root', 'stylesheet_root') as $opt) {
|
4497 |
+
add_filter('pre_option_'.$opt, array($this, 'option_filter_'.$opt));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4498 |
}
|
|
|
4499 |
|
4500 |
+
// Clear any cached pages after the restore
|
4501 |
+
$updraftplus_restorer->clear_cache();
|
|
|
|
|
4502 |
|
4503 |
+
// 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
|
4504 |
+
$template = get_option('template');
|
4505 |
+
if (!empty($template) && WP_DEFAULT_THEME != $template && strtolower($template) != $template) {
|
4506 |
|
4507 |
+
$theme_root = get_theme_root($template);
|
4508 |
+
$theme_root2 = get_theme_root(strtolower($template));
|
4509 |
|
4510 |
+
if (!file_exists("$theme_root/$template/style.css") && file_exists("$theme_root/".strtolower($template)."/style.css")) {
|
4511 |
+
$updraftplus->log_e("Theme directory (%s) not found, but lower-case version exists; updating database option accordingly", $template);
|
4512 |
+
update_option('template', strtolower($template));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4513 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4514 |
|
4515 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4516 |
|
4517 |
+
if (!function_exists('validate_current_theme')) include_once(ABSPATH.WPINC.'/themes');
|
|
|
4518 |
|
4519 |
+
if (!validate_current_theme()) {
|
4520 |
+
if ($browser_context) echo '<strong>';
|
4521 |
+
$updraftplus->log_e("The current theme was not found; to prevent this stopping the site from loading, your theme has been reverted to the default theme");
|
4522 |
+
if ($browser_context) echo '</strong>';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4523 |
}
|
|
|
4524 |
}
|
4525 |
|
4526 |
+
if ($browser_context) echo '</div>'; // Close the updraft_restore_progress div
|
|
|
|
|
|
|
|
|
|
|
|
|
4527 |
|
4528 |
restore_error_handler();
|
4529 |
|
|
|
4530 |
}
|
4531 |
|
4532 |
public function option_filter_template($val) {
|
4549 |
return $updraftplus->option_filter_get('stylesheet_root');
|
4550 |
}
|
4551 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4552 |
public function return_array($input) {
|
4553 |
if (!is_array($input)) $input = array();
|
4554 |
return $input;
|
4690 |
|
4691 |
$return_array = array('saved' => true);
|
4692 |
|
4693 |
+
$add_to_post_keys = array('updraft_interval', 'updraft_interval_database', 'updraft_interval_increments', 'updraft_starttime_files', 'updraft_starttime_db', 'updraft_startday_files', 'updraft_startday_db');
|
4694 |
|
4695 |
// If database and files are on same schedule, override the db day/time settings
|
4696 |
if (isset($settings['updraft_interval_database']) && isset($settings['updraft_interval_database']) && $settings['updraft_interval_database'] == $settings['updraft_interval'] && isset($settings['updraft_starttime_files'])) {
|
5075 |
/**
|
5076 |
* This will call any wp_action
|
5077 |
*
|
5078 |
+
* @param Array|Null $data The array of data with the vaules for wpaction
|
5079 |
* @param Callable|Boolean $close_connection_callable A callable to call to close the browser connection, or true for a default suitable for internal use, or false for none
|
5080 |
* @return Array - results
|
5081 |
*/
|
5149 |
wp_enqueue_script('jstree', UPDRAFTPLUS_URL.'/includes/jstree/jstree'.$min_or_not.'.js', array('jquery'), $jstree_enqueue_version);
|
5150 |
wp_enqueue_style('jstree', UPDRAFTPLUS_URL.'/includes/jstree/themes/default/style'.$min_or_not.'.css', array(), $jstree_enqueue_version);
|
5151 |
}
|
5152 |
+
|
5153 |
+
/**
|
5154 |
+
* Detects byte-order mark at the start of common files and change waning message texts
|
5155 |
+
*
|
5156 |
+
* @return string|boolean BOM warning text or false if not bom characters detected
|
5157 |
+
*/
|
5158 |
+
public function get_bom_warning_text() {
|
5159 |
+
$files_to_check = array(
|
5160 |
+
ABSPATH.'wp-config.php',
|
5161 |
+
get_template_directory().DIRECTORY_SEPARATOR.'functions.php',
|
5162 |
+
);
|
5163 |
+
if (is_child_theme()) {
|
5164 |
+
$files_to_check[] = get_stylesheet_directory().DIRECTORY_SEPARATOR.'functions.php';
|
5165 |
+
}
|
5166 |
+
$corrupted_files = array();
|
5167 |
+
foreach ($files_to_check as $file) {
|
5168 |
+
if (false === ($fp = fopen($file, 'r'))) continue;
|
5169 |
+
if (false === ($file_data = fread($fp, 8192)));
|
5170 |
+
fclose($fp);
|
5171 |
+
$substr_file_data = array();
|
5172 |
+
for ($substr_length = 2; $substr_length <= 5; $substr_length++) {
|
5173 |
+
$substr_file_data[$substr_length] = substr($file_data, 0, $substr_length);
|
5174 |
+
}
|
5175 |
+
// Detect UTF-7, UTF-8, UTF-16 (BE), UTF-16 (LE), UTF-32 (BE) & UTF-32 (LE) Byte order marks (BOM)
|
5176 |
+
$bom_decimal_representations = array(
|
5177 |
+
array(43, 47, 118, 56), // UTF-7 (Hexadecimal: 2B 2F 76 38)
|
5178 |
+
array(43, 47, 118, 57), // UTF-7 (Hexadecimal: 2B 2F 76 39)
|
5179 |
+
array(43, 47, 118, 43), // UTF-7 (Hexadecimal: 2B 2F 76 2B)
|
5180 |
+
array(43, 47, 118, 47), // UTF-7 (Hexadecimal: 2B 2F 76 2F)
|
5181 |
+
array(43, 47, 118, 56, 45), // UTF-7 (Hexadecimal: 2B 2F 76 38 2D)
|
5182 |
+
array(239, 187, 191), // UTF-8 (Hexadecimal: 2B 2F 76 38 2D)
|
5183 |
+
array(254, 255), // UTF-16 (BE) (Hexadecimal: FE FF)
|
5184 |
+
array(255, 254), // UTF-16 (LE) (Hexadecimal: FF FE)
|
5185 |
+
array(0, 0, 254, 255), // UTF-32 (BE) (Hexadecimal: 00 00 FE FF)
|
5186 |
+
array(255, 254, 0, 0), // UTF-32 (LE) (Hexadecimal: FF FE 00 00)
|
5187 |
+
);
|
5188 |
+
foreach ($bom_decimal_representations as $bom_decimal_representation) {
|
5189 |
+
$no_of_chars = count($bom_decimal_representation);
|
5190 |
+
array_unshift($bom_decimal_representation, 'C*');
|
5191 |
+
$binary = call_user_func_array('pack', $bom_decimal_representation);
|
5192 |
+
if ($binary == $substr_file_data[$no_of_chars]) {
|
5193 |
+
$corrupted_files[] = $file;
|
5194 |
+
break;
|
5195 |
+
}
|
5196 |
+
}
|
5197 |
+
}
|
5198 |
+
if (empty($corrupted_files)) {
|
5199 |
+
return false;
|
5200 |
+
} else {
|
5201 |
+
$corrupted_files_count = count($corrupted_files);
|
5202 |
+
return '<strong>'.__('Warning', 'updraftplus').':</strong> '.sprintf(_n('The file %s has a "byte order mark" (BOM) at its beginning.', 'The files %s have a "byte order mark" (BOM) at their beginning.', $corrupted_files_count, 'updraftplus'), '<strong>'.implode('</strong>, <strong>', $corrupted_files).'</strong>').' <a href="'.apply_filters('updraftplus_com_link', "https://updraftplus.com/problems-with-extra-white-space/").'">'.__('Follow this link for more information', 'updraftplus').'</a>';
|
5203 |
+
}
|
5204 |
+
}
|
5205 |
+
|
5206 |
+
/**
|
5207 |
+
* Gets an instance of the "UpdraftPlus_UpdraftCentral_Cloud" class which will be
|
5208 |
+
* used to login or register the user to the UpdraftCentral cloud
|
5209 |
+
*
|
5210 |
+
* @return object
|
5211 |
+
*/
|
5212 |
+
public function get_updraftcentral_cloud() {
|
5213 |
+
if (!class_exists('UpdraftPlus_UpdraftCentral_Cloud')) include_once(UPDRAFTPLUS_DIR.'/includes/updraftcentral.php');
|
5214 |
+
return new UpdraftPlus_UpdraftCentral_Cloud();
|
5215 |
+
}
|
5216 |
+
|
5217 |
+
/**
|
5218 |
+
* Gets an instance of the "UpdraftPlus_Clone" class which will be
|
5219 |
+
* used to login the user to UpdraftPlus.com
|
5220 |
+
*
|
5221 |
+
* @return object
|
5222 |
+
*/
|
5223 |
+
public function get_updraftplus_clone() {
|
5224 |
+
if (!class_exists('UpdraftPlus_Clone')) include_once(UPDRAFTPLUS_DIR.'/includes/updraftplus-clone.php');
|
5225 |
+
return new UpdraftPlus_Clone();
|
5226 |
+
}
|
5227 |
+
|
5228 |
+
/**
|
5229 |
+
* This function will build and return the UpdraftPlus tempoaray clone version select widget
|
5230 |
+
*
|
5231 |
+
* @return string - the UpdraftPlus tempoary clone version select widget
|
5232 |
+
*/
|
5233 |
+
public function updraftplus_clone_versions() {
|
5234 |
+
$output = sprintf(__('%s version:', 'updraftplus'), 'PHP').' ';
|
5235 |
+
$output .= $this->output_select_data($this->php_versions, 'php');
|
5236 |
+
$output .= ' '.sprintf(__('%s version:', 'updraftplus'), 'WordPress').' ';
|
5237 |
+
$output .= $this->output_select_data($this->get_wordpress_versions(), 'wp');
|
5238 |
+
$output .= '<br><input type="checkbox" class="updraftplus_clone_admin_login_options" id="" name="updraftplus_clone_admin_login_options" value="1" checked="checked">';
|
5239 |
+
$output .= '<label for="updraftplus_clone_admin_login_options" class="updraftplus_clone_admin_login_options_label">'.__('Forbid logins from non-administrators on this clone', 'updraftplus').'</label><br>';
|
5240 |
+
|
5241 |
+
return $output;
|
5242 |
+
}
|
5243 |
+
|
5244 |
+
/**
|
5245 |
+
* This function will output a select input using the passed in values.
|
5246 |
+
*
|
5247 |
+
* @param array $data - the keys and values for the select
|
5248 |
+
* @param string $name - the name of the items in the select input
|
5249 |
+
*
|
5250 |
+
* @return string - the output of the select input
|
5251 |
+
*/
|