<?php $this->settings_formcontents(); ?>
$our_keys = UpdraftPlus_Options::get_updraft_option('updraft_central_localkeys');
if (!is_array($our_keys)) $our_keys = array();
// Hide the UpdraftCentral Cloud wizard If the user already has a key created for either
// updraftplus.com or self hosted version.
<div id="updraftcentral_cloud_connect_container" class="updraftcentral_cloud_connect hidden-in-updraftcentral">
// Checking email from "Premium / Extensions" tab
if (defined('UDADDONS2_SLUG')) {
global $updraftplus_addons2;
if (is_a($updraftplus_addons2, 'UpdraftPlusAddons2') && is_callable(array($updraftplus_addons2, 'get_option'))) {
$options = $updraftplus_addons2->get_option(UDADDONS2_SLUG.'_options');
if (!empty($options['email'])) {
$email = htmlspecialchars($options['email']);
// Check the vault's email if we fail to get the "email" from the "Premium / Extensions" tab
$settings = UpdraftPlus_Storage_Methods_Interface::update_remote_storage_options_format('updraftvault');
if (!is_wp_error($settings)) {
if (!empty($settings['settings'])) {
foreach ($settings['settings'] as $storage_options) {
if (!empty($storage_options['email'])) {
$email = $storage_options['email'];
// Checking any possible email we could find from the "updraft_email" option in case the
// above two checks failed.
$possible_emails = $updraftplus->just_one_email(UpdraftPlus_Options::get_updraft_option('updraft_email'));
if (!empty($possible_emails)) {
// If we get an array from the 'just_one_email' result then we're going
// to pull the very first entry and make use of that on the succeeding process.
if (is_array($possible_emails)) $possible_emails = array_shift($possible_emails);
if (is_string($possible_emails)) {
$emails = explode(',', $possible_emails);
$email = trim($emails[0]);
$this->include_template('wp-admin/settings/updraftcentral-connect.php', false, array('email' => $email));
<div id="updraft-navtab-expert-content"<?php if ('expert' != $tabflag) echo ' class="updraft-hidden"'; ?> style="<?php if ('expert' != $tabflag) echo 'display:none;'; ?>">
<?php $this->settings_advanced_tools(); ?>
<div id="updraft-navtab-addons-content"<?php if ('addons' != $tabflag) echo ' class="updraft-hidden"'; ?> style="<?php if ('addons' != $tabflag) echo 'display:none;'; ?>">
$tab_addons = $this->include_template('wp-admin/settings/tab-addons.php', true, array('tabflag' => $tabflag));
echo apply_filters('updraftplus_addonstab_content', $tab_addons);
do_action('updraftplus_after_main_tab_content', $tabflag);
// settings_header() opens a div
$this->settings_footer();
* @return Array Array which have key as a tab key and value as tab label
private function get_main_tabs_array() {
'backups' => __('Backup / Restore', 'updraftplus'),
'migrate' => __('Migrate / Clone', 'updraftplus'),
'settings' => __('Settings', 'updraftplus'),
'expert' => __('Advanced Tools', 'updraftplus'),
'addons' => __('Premium / Extensions', 'updraftplus'),
* Potentially register an action for showing restore progress
private function print_restore_in_progress_box_if_needed() {
$check_restore_progress = $updraftplus->check_restore_progress();
// Check to see if the restore is still in progress
if (is_array($check_restore_progress) && true == $check_restore_progress['status']) {
$restore_jobdata = $check_restore_progress['restore_jobdata'];
$restore_jobdata['jobid'] = $check_restore_progress['restore_in_progress'];
$this->restore_in_progress_jobdata = $restore_jobdata;
add_action('all_admin_notices', array($this, 'show_admin_restore_in_progress_notice'));
* This function is called via the command class, it will get the resume restore notice to be shown when a restore is taking place over AJAX
* @param string $job_id - the id of the job
* @return WP_Error|string - can return a string containing html or a WP_Error
public function get_restore_resume_notice($job_id) {
if (empty($job_id)) return new WP_Error('missing_parameter', 'Missing parameters.');
$restore_jobdata = $updraftplus->jobdata_getarray($job_id);
if (!is_array($restore_jobdata) && empty($restore_jobdata)) return new WP_Error('missing_jobdata', 'Job data not found.');
$restore_jobdata['jobid'] = $job_id;
$this->restore_in_progress_jobdata = $restore_jobdata;
$html = $this->show_admin_restore_in_progress_notice(true, true);
if (empty($html)) return new WP_Error('job_aborted', 'Job aborted.');
* If added, then runs upon the WP action all_admin_notices, or can be called via get_restore_resume_notice() for when a restore is running over AJAX
* @param Boolean $return_instead_of_echo - indicates if we want to add the tfa UI
* @param Boolean $exclude_js - indicates if we want to exclude the js in the returned html
* @return void|string - can return a string containing html or echo the html to page
public function show_admin_restore_in_progress_notice($return_instead_of_echo = false, $exclude_js = false) {
if (isset($_REQUEST['action']) && 'updraft_restore_abort' === $_REQUEST['action'] && !empty($_REQUEST['job_id'])) {
delete_site_option('updraft_restore_in_progress');
$restore_jobdata = $this->restore_in_progress_jobdata;
$seconds_ago = time() - (int) $restore_jobdata['job_time_ms'];
$minutes_ago = floor($seconds_ago/60);
$seconds_ago = $seconds_ago - $minutes_ago*60;
$time_ago = sprintf(__("%s minutes, %s seconds", 'updraftplus'), $minutes_ago, $seconds_ago);
$html = '<div class="updated show_admin_restore_in_progress_notice">';
$html .= '<span class="unfinished-restoration"><strong>UpdraftPlus: '.__('Unfinished restoration', 'updraftplus').'</strong></span><br>';
$html .= '<p>'.sprintf(__('You have an unfinished restoration operation, begun %s ago.', 'updraftplus'), $time_ago).'</p>';
$html .= '<form method="post" action="'.UpdraftPlus_Options::admin_page_url().'?page=updraftplus">';
$html .= wp_nonce_field('updraftplus-credentialtest-nonce');
$html .= '<input id="updraft_restore_continue_action" type="hidden" name="action" value="updraft_restore_continue">';
$html .= '<input type="hidden" name="updraftplus_ajax_restore" value="continue_ajax_restore">';
$html .= '<input type="hidden" name="job_id" value="'.$restore_jobdata['jobid'].'" value="'.esc_attr($restore_jobdata['jobid']).'">';
$html .= '<button id="updraft_restore_resume" type="submit" class="button-primary">'.__('Continue restoration', 'updraftplus').'</button>';
$html .= '<button id="updraft_restore_resume" onclick="jQuery(\'#updraft_restore_continue_action\').val(\'updraft_restore_continue\'); jQuery(this).parent(\'form\').trigger(\'submit\');" type="submit" class="button-primary">'.__('Continue restoration', 'updraftplus').'</button>';
$html .= '<button id="updraft_restore_abort" onclick="jQuery(\'#updraft_restore_continue_action\').val(\'updraft_restore_abort\'); jQuery(this).parent(\'form\').trigger(\'submit\');" class="button-secondary">'.__('Dismiss', 'updraftplus').'</button>';
$html .= '</form></div>';
if ($return_instead_of_echo) return $html;
* This method will build the UpdraftPlus.com login form and echo it to the page.
* @param String $option_page - the option page this form is being output to
* @param Boolean $tfa - indicates if we want to add the tfa UI
* @param Boolean $include_form_container - indicates if we want the form container
* @param Array $further_options - other options (see below for the possibilities + defaults)
public function build_credentials_form($option_page, $tfa = false, $include_form_container = true, $further_options = array()) {
$further_options = wp_parse_args($further_options, array(
'under_username' => __("Not yet got an account (it's free)? Go get one!", 'updraftplus'),
'under_username_link' => $updraftplus->get_url('my-account')
if ($include_form_container) {
$enter_credentials_begin = UpdraftPlus_Options::options_form_begin('', false, array(), 'updraftplus_com_login');
if (is_multisite()) $enter_credentials_begin .= '<input type="hidden" name="action" value="update">';
$enter_credentials_begin = '<div class="updraftplus_com_login">';
$interested = htmlspecialchars(__('Interested in knowing about your UpdraftPlus.Com password security? Read about it here.', 'updraftplus'));
$connect = htmlspecialchars(__('Connect', 'updraftplus'));
$enter_credentials_end = '<p class="updraft-after-form-table">';
if ($include_form_container) {
$enter_credentials_end .= '<input type="submit" class="button-primary ud_connectsubmit" value="'.$connect.'" />';
$enter_credentials_end .= '<button class="button-primary ud_connectsubmit">'.$connect.'</button>';
$enter_credentials_end .= '<span class="updraftplus_spinner spinner">' . __('Processing', 'updraftplus') . '...</span></p>';
$enter_credentials_end .= '<p class="updraft-after-form-table" style="font-size: 70%"><em><a href="https://updraftplus.com/faqs/tell-me-about-my-updraftplus-com-account/" target="_blank">'.$interested.'</a></em></p>';
$enter_credentials_end .= $include_form_container ? '</form>' : '</div>';
echo $enter_credentials_begin;
$options = apply_filters('updraftplus_com_login_options', array("email" => "", "password" => ""));
if ($include_form_container) {
// We have to duplicate settings_fields() in order to set our referer
// settings_fields(UDADDONS2_SLUG.'_options');
$option_group = $option_page.'_options';
echo "<input type='hidden' name='option_page' value='" . esc_attr($option_group) . "' />";
echo '<input type="hidden" name="action" value="update" />';
// wp_nonce_field("$option_group-options");
// This one is used on multisite
echo '<input type="hidden" name="tab" value="addons" />';
$action = esc_attr($option_group."-options");
$nonce_field = '<input type="hidden" name="' . $name . '" value="' . wp_create_nonce($action) . '" />';
$referer = esc_attr(UpdraftPlus_Manipulation_Functions::wp_unslash($_SERVER['REQUEST_URI']));
// This one is used on single site installs
if (false === strpos($referer, '?')) {
$referer .= '?tab=addons';
$referer .= '&tab=addons';
echo '<input type="hidden" name="_wp_http_referer" value="'.$referer.'" />';
// End of duplication of settings-fields()
<h2> <?php _e('Connect with your UpdraftPlus.Com account', 'updraftplus'); ?></h2>
<p class="updraftplus_com_login_status"></p>
<table class="form-table">
<tr class="non_tfa_fields">
<th><?php _e('Email', 'updraftplus'); ?></th>
<label for="<?php echo $option_page; ?>_options_email">
<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']); ?>" />
<a target="_blank" href="<?php echo $further_options['under_username_link']; ?>"><?php echo $further_options['under_username']; ?></a>
<tr class="non_tfa_fields">
<th><?php _e('Password', 'updraftplus'); ?></th>
<label for="<?php echo $option_page; ?>_options_password">
<input id="<?php echo $option_page; ?>_options_password" type="password" size="36" name="<?php echo $option_page; ?>_options[password]" value="<?php echo empty($options['password']) ? '' : htmlspecialchars($options['password']); ?>" />
<a target="_blank" href="<?php echo $updraftplus->get_url('lost-password'); ?>"><?php _e('Forgotten your details?', 'updraftplus'); ?></a>
if ('updraftplus-addons' == $option_page) {
<tr class="non_tfa_fields">
<input type="checkbox" id="<?php echo $option_page; ?>_options_auto_updates" data-updraft_settings_test="updraft_auto_updates" name="<?php echo $option_page; ?>_options[updraft_auto_update]" value="1" <?php if ($updraftplus->is_automatic_updating_enabled()) echo 'checked="checked"'; ?> />
<?php _e('Ask WordPress to update UpdraftPlus automatically when an update is available', 'updraftplus');?>
$our_keys = UpdraftPlus_Options::get_updraft_option('updraft_central_localkeys');
if (!is_array($our_keys)) $our_keys = array();
<p class="<?php echo $option_page; ?>-connect-to-udc">
<input type="checkbox" id="<?php echo $option_page; ?>_options_auto_udc_connect" name="<?php echo $option_page; ?>_options[updraft_auto_udc_connect]" value="1" checked="checked" />
<?php _e('Add this website to UpdraftCentral (remote, centralised control) - free for up to 5 sites.', 'updraftplus'); ?> <a target="_blank" href="https://updraftcentral.com"><?php _e('Learn more about UpdraftCentral', 'updraftplus'); ?></a>
if (isset($further_options['terms_and_conditions']) && isset($further_options['terms_and_conditions_link'])) {
<tr class="non_tfa_fields">
<input type="checkbox" class="<?php echo $option_page; ?>_terms_and_conditions" name="<?php echo $option_page; ?>_terms_and_conditions" value="1">
<a target="_blank" href="<?php echo $further_options['terms_and_conditions_link']; ?>"><?php echo $further_options['terms_and_conditions']; ?></a>
<tr class="tfa_fields" style="display:none;">
<th><?php _e('One Time Password (check your OTP app to get this password)', 'updraftplus'); ?></th>
<label for="<?php echo $option_page; ?>_options_two_factor_code">
<input id="<?php echo $option_page; ?>_options_two_factor_code" type="text" size="10" name="<?php echo $option_page; ?>_options[two_factor_code]" />
echo $enter_credentials_end;
* Return widgetry for the 'backup now' modal.
* Don't optimise this method away; it's used by third-party plugins (e.g. EUM).
public function backupnow_modal_contents() {
return $this->include_template('wp-admin/settings/backupnow-modal.php', true);
* Also used by the auto-backups add-on
* @param Boolean $wide_format Whether to return data in a wide format
* @param Boolean $print_active_jobs Whether to include currently active jobs
* @return String - the HTML output
public function render_active_jobs_and_log_table($wide_format = false, $print_active_jobs = true) {
<div id="updraft_activejobs_table">
<?php $active_jobs = ($print_active_jobs) ? $this->print_active_jobs() : '';?>
<div id="updraft_activejobsrow" class="<?php
if (!$active_jobs && !$wide_format) {
<div id="updraft_activejobs" class="<?php echo $wide_format ? 'wide-format' : ''; ?>">
<?php echo $active_jobs;?>
<div id="updraft_lastlogmessagerow">
<?php if ($wide_format) {
// Hide for now - too ugly
<div class="last-message"><strong><?php _e('Last log message', 'updraftplus');?>:</strong><br>
<span id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_lastmessage()); ?></span><br>
<?php $this->most_recently_modified_log_link(); ?>
<strong><?php _e('Last log message', 'updraftplus');?>:</strong>
<span id="updraft_lastlogcontainer"><?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_lastmessage()); ?></span><br>
<?php $this->most_recently_modified_log_link(); ?>
// Currently disabled - not sure who we want to show this to
if (1==0 && !defined('UPDRAFTPLUS_NOADS_B')) {
$feed = $updraftplus->get_updraftplus_rssfeed();
if (is_a($feed, 'SimplePie')) {
echo '<tr><th style="vertical-align:top;">'.__('Latest UpdraftPlus.com news:', 'updraftplus').'</th><td class="updraft_simplepie">';
echo '<ul class="disc;">';
foreach ($feed->get_items(0, 5) as $item) {
echo '<a href="'.esc_attr($item->get_permalink()).'">';
echo htmlspecialchars($item->get_title());
echo "</a> (".htmlspecialchars($item->get_date('j F Y')).")";
* Output directly a link allowing download of the most recently modified log file
private function most_recently_modified_log_link() {
list($mod_time, $log_file, $nonce) = $updraftplus->last_modified_log();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
<a href="?page=updraftplus&action=downloadlatestmodlog&wpnonce=<?php echo wp_create_nonce('updraftplus_download'); ?>" <?php if (!$mod_time) echo 'style="display:none;"'; ?> class="updraft-log-link" onclick="event.preventDefault(); updraft_popuplog('');"><?php _e('Download most recently modified log file', 'updraftplus');?></a>
public function settings_downloading_and_restoring($backup_history = array(), $return_result = false, $options = array()) {
return $this->include_template('wp-admin/settings/downloading-and-restoring.php', $return_result, array('backup_history' => $backup_history, 'options' => $options));
* Renders take backup content
public function take_backup_content() {
$updraft_dir = $updraftplus->backups_dir_location();
$backup_disabled = UpdraftPlus_Filesystem_Functions::really_is_writable($updraft_dir) ? '' : 'disabled="disabled"';
$this->include_template('wp-admin/settings/take-backup.php', false, array('backup_disabled' => $backup_disabled));
* Output a table row using the updraft_debugrow class
* @param String $head - header cell contents
* @param String $content - content cell contents
public function settings_debugrow($head, $content) {
echo "<tr class=\"updraft_debugrow\"><th>$head</th><td>$content</td></tr>";
public function settings_advanced_tools($return_instead_of_echo = false, $pass_through = array()) {
return $this->include_template('wp-admin/advanced/advanced-tools.php', $return_instead_of_echo, $pass_through);
* Paint the HTML for the form for deleting old directories
* @param Boolean $include_blurb - whether to include explanatory text
* @param Boolean $include_div - whether to wrap inside a div tag
public function print_delete_old_dirs_form($include_blurb = true, $include_div = true) {
echo '<div id="updraft_delete_old_dirs_pagediv" class="updated delete-old-directories">';
echo '<p>'.__('Your WordPress install has old directories from its state before you restored/migrated (technical information: these are suffixed with -old). You should press this button to delete them as soon as you have verified that the restoration worked.', 'updraftplus').'</p>';
<form method="post" action="<?php echo esc_url(add_query_arg(array('error' => false, 'updraft_restore_success' => false, 'action' => false, 'page' => 'updraftplus'), UpdraftPlus_Options::admin_page_url())); ?>">
<?php wp_nonce_field('updraftplus-credentialtest-nonce', 'updraft_delete_old_dirs_nonce'); ?>
<input type="hidden" name="action" value="updraft_delete_old_dirs">
<input type="submit" class="button-primary" value="<?php echo esc_attr(__('Delete Old Directories', 'updraftplus'));?>">
if ($include_blurb && $include_div) echo '</div>';
* Return cron status information about a specified in-progress job