jobdata_get('job_file_entities'));
if (empty($backup_entities) || empty($extralog)) return $extralog;
$entities = join(', ', $backup_entities);
if (!empty($entities)) $extralog .= " caused by entities ($entities)";
return $extralog;
}
/**
* WP 4.4+
*
* @param array $type This is the type such as plugin or theme
* @param object $item THis is the item
* @return string
*/
public function pre_auto_update($type, $item) {
// Can also be 'translation'. We don't auto-backup for those.
if ('plugin' == $type || 'theme' == $type) {
$this->auto_update(true, $item, $type.'s');
} elseif ('core' == $type) {
$this->auto_update(true, $item, $type);
}
}
/**
* Before WP 4.4
*
* @param string $update
* @param object $item
* @return string
*/
public function auto_update_plugin($update, $item) {
return $this->auto_update($update, $item, 'plugins');
}
public function auto_update_theme($update, $item) {
return $this->auto_update($update, $item, 'themes');
}
public function auto_update_core($update, $item) {
return $this->auto_update($update, $item, 'core');
}
/**
* Note - with the addition of support for JetPack remote updates (via manual action in a user's wordpress.com dashboard), this is now more accurately a method to handle *background* updates, rather than "automatic" ones.
*
* @param string $update
* @param object $item
* @param array $type
* @return string
*/
public function auto_update($update, $item, $type) {
if (!$update || !empty($this->do_not_filter_auto_backup) || in_array($type, $this->already_backed_up) || !UpdraftPlus_Options::get_updraft_option('updraft_autobackup_default') || (!$this->doing_filter('wp_maybe_auto_update') && !$this->doing_filter('jetpack_pre_plugin_upgrade') && !$this->doing_filter('jetpack_pre_theme_upgrade') && !$this->doing_filter('jetpack_pre_core_upgrade'))) return $update;
if ('core' == $type) {
// This has to be copied from WP_Automatic_Updater::should_update() because it's another reason why the eventual decision may be false.
// If it's a core update, are we actually compatible with its requirements?
global $wpdb;
$php_compat = version_compare(phpversion(), $item->php_version, '>=');
if (file_exists(WP_CONTENT_DIR . '/db.php') && empty($wpdb->is_mysql))
$mysql_compat = true;
else $mysql_compat = version_compare($wpdb->db_version(), $item->mysql_version, '>=');
if (!$php_compat || !$mysql_compat)
return false;
}
// Go ahead - it's auto-backup-before-auto-update time.
// Add job data to indicate that a resumption should be scheduled if the backup completes before the cloud-backup stage
add_filter('updraftplus_initial_jobdata', array($this, 'initial_jobdata'));
add_filter('updraftplus_initial_jobdata', array($this, 'initial_jobdata2'));
add_filter('updraftplus_autobackup_extralog', array($this, 'autobackup_extralog'));
// Reschedule the real background update for 10 minutes from now (i.e. lessen the risk of a timeout by chaining it).
$this->reschedule(600);
global $updraftplus;
$backup_database = !in_array('db', $this->already_backed_up);
if ('core' == $type) {
$entities = $updraftplus->get_backupable_file_entities();
if (isset($entities['wpcore'])) {
$backup_files = true;
$backup_files_array = array('wpcore');
} else {
$backup_files = false;
$backup_files_array = false;
}
} else {
$backup_files = true;
$backup_files_array = array($type);
}
if ('core' == $type) {
$this->is_autobackup_core = true;
}
$updraftplus->boot_backup((int) $backup_files, (int) $backup_database, $backup_files_array, true);
$this->already_backed_up[] = $type;
if ($backup_database) $this->already_backed_up[] = 'db';
// The backup apparently completed. Reschedule for very soon, in case not enough PHP time remains to complete an update too.
$this->reschedule(120);
// But then, also go ahead anyway, in case there's enough time (we want to minimise the time between the backup and the update)
return $update;
}
public function updraftplus_dirlist_wpcore_override($l, $whichdir) {
global $updraftplus;
$is_autobackup = $updraftplus->jobdata_get('is_autobackup', false);
if (empty($this->is_autobackup_core) && !$is_autobackup) return $l;
// This does not need to include everything - only code
$possible = array('wp-admin', 'wp-includes', 'index.php', 'xmlrpc.php', 'wp-config.php', 'wp-activate.php', 'wp-app.php', 'wp-atom.php', 'wp-blog-header.php', 'wp-comments-post.php', 'wp-commentsrss2.php', 'wp-cron.php', 'wp-feed.php', 'wp-links-opml.php', 'wp-load.php', 'wp-login.php', 'wp-mail.php', 'wp-pass.php', 'wp-rdf.php', 'wp-register.php', 'wp-rss2.php', 'wp-rss.php', 'wp-settings.php', 'wp-signup.php', 'wp-trackback.php', '.htaccess');
$wpcore_dirlist = array();
$whichdir = trailingslashit($whichdir);
foreach ($possible as $file) {
if (file_exists($whichdir.$file)) $wpcore_dirlist[] = $whichdir.$file;
}
return (!empty($wpcore_dirlist)) ? $wpcore_dirlist : $l;
}
/**
* Reschedule the automatic update check event
*
* @param Integer $how_long - how many seconds in the future from now to reschedule for
*/
private function reschedule($how_long) {
wp_clear_scheduled_hook('ud_wp_maybe_auto_update');
if (!$how_long) return;
global $updraftplus;
$updraftplus->log("Rescheduling WP's automatic update check for $how_long seconds ahead");
$lock_result = get_option($this->lock_name);
wp_schedule_single_event(time() + $how_long, 'ud_wp_maybe_auto_update', array($lock_result));
}
/**
* This appears on the page listing several updates
*/
public function updraftplus_autobackup_blurb() {
$ret = '
';
$ret .= '
'. __('Be safe with an automatic backup', 'updraftplus').'
';
$ret .= '
'.__('Read more about how this works...', 'updraftplus').'';
// New-style widgets
add_action('admin_footer', array($this, 'admin_footer_inpage_backup'));
add_action('admin_footer', array($this, 'admin_footer_insertintoform'));
$ret .= '
';
return $ret;
}
public function admin_footer_insertintoform() {
$def = UpdraftPlus_Options::get_updraft_option('updraft_autobackup_default', true);
$godef = $def ? 'yes' : 'no';
// Note - now, in the new-style widgetised setup (Feb 2015), we always set updraftplus_noautobackup=1 - because the actual backup will be done in-page. But that is not done here - it is done when the form is submitted, in updraft_try_inpage();
echo <<
jQuery(function($) {
$('form.upgrade').append('');
$('form.upgrade').append('');
$('#updraft_autobackup').on('click', function() {
var doauto = $(this).attr('checked');
if ('checked' == doauto) {
$('.updraft_autobackup_go').attr('value', 'yes');
} else {
$('.updraft_autobackup_go').attr('value', 'no');
}
});
$('#updraft_autobackup_sdefault').on('click', function() {
var sdef = $(this).attr('checked');
if ('checked' == sdef) {
$('.updraft_autobackup_setdefault').attr('value', 'yes');
} else {
$('.updraft_autobackup_setdefault').attr('value', 'no');
}
});
});
ENDHERE;
}
public function admin_footer() {
if (!current_user_can('update_'.$this->internaltype)) return;
$creating = esc_js(sprintf(__('Creating %s and database backup with UpdraftPlus...', 'updraftplus'), $this->type).' '.__('(logs can be found in the UpdraftPlus settings page as normal)...', 'updraftplus'));
$lastlog = esc_js(__('Last log message', 'updraftplus')).':';
global $updraftplus;
$updraftplus->log(__('Starting automatic backup...', 'updraftplus'));
$unexpected_response = esc_js(__('Unexpected response:', 'updraftplus'));
echo <<
jQuery('h2').first().after('
$creating
$lastlog
');
var lastlog_sdata = {
oneshot: 'yes'
};
setInterval(function() {updraft_autobackup_showlastlog(true);}, 3000);
function updraft_autobackup_showlastlog(repeat) {
updraft_send_command('activejobs_list', lastlog_sdata, function(response) {
try {
resp = ud_parse_json(response);
if (resp.l != null) { jQuery('#updraft_lastlogcontainer').html(resp.l); }
if (resp.j != null && resp.j != '') {
jQuery('#updraft_activejobs').html(resp.j);
} else {
if (!jQuery('#updraft_activejobs').is(':hidden')) {
jQuery('#updraft_activejobs').hide();
}
}
} catch(err) {
console.log('$unexpected_response '+response);
}
}, { type: GET, json_parse: false });
}
ENDHERE;
}
private function process_form() {
// We use 0 instead of false, because false is the default for get_option(), and thus setting an unset value to false with update_option() actually sets nothing (since update_option() first checks for the existing value) - which is unhelpful if you want to call get_option() with a different default (as we do)
$autobackup = (isset($_POST['updraft_autobackup']) && 'yes' == $_POST['updraft_autobackup']) ? 1 : 0;
if (!empty($_POST['updraft_autobackup_setdefault']) && 'yes' == $_POST['updraft_autobackup_setdefault']) UpdraftPlus_Options::update_updraft_option('updraft_autobackup_default', $autobackup);
// Having dealt with the saving, now see if we really wanted to do it
if (!empty($_REQUEST['updraftplus_noautobackup'])) $autobackup = 0;
UpdraftPlus_Options::update_updraft_option('updraft_autobackup_go', $autobackup);
if ($autobackup) add_action('admin_footer', array($this, 'admin_footer'));
}
/**
* The initial form submission from the updates page
*/
public function admin_action_do_plugin_upgrade() {
if (!current_user_can('update_plugins')) return;
$this->type = __('plugins', 'updraftplus');
$this->internaltype = 'plugins';
$this->process_form();
}
public function admin_action_do_theme_upgrade() {
if (!current_user_can('update_themes')) return;
$this->type = __('themes', 'updraftplus');
$this->internaltype = 'themes';
$this->process_form();
}
/**
* Into the updating iframe...
*/
public function admin_action_update_selected() {
if (!current_user_can('update_plugins')) return;
$autobackup = UpdraftPlus_Options::get_updraft_option('updraft_autobackup_go');
if ($autobackup) $this->autobackup_go('plugins');
}
public function admin_action_update_selected_themes() {
if (!current_user_can('update_themes')) return;
$autobackup = UpdraftPlus_Options::get_updraft_option('updraft_autobackup_go');
if ($autobackup) $this->autobackup_go('themes');
}
public function admin_action_do_core_upgrade() {
if (!isset($_POST['upgrade'])) return;
if (!empty($_REQUEST['updraftplus_noautobackup'])) return;
if (!current_user_can('update_core')) wp_die(__('You do not have sufficient permissions to update this site.'));
check_admin_referer('upgrade-core');
// It is important to not use (bool)false here, as that conflicts with using get_option() with a non-false default value
$autobackup = (isset($_POST['updraft_autobackup']) && 'yes' == $_POST['updraft_autobackup']) ? 1 : 0;
if (!empty($_POST['updraft_autobackup_setdefault']) && 'yes' == $_POST['updraft_autobackup_setdefault']) UpdraftPlus_Options::update_updraft_option('updraft_autobackup_default', $autobackup);
if ($autobackup) {
include_once(ABSPATH . 'wp-admin/admin-header.php');
$creating = __('Creating database backup with UpdraftPlus...', 'updraftplus').' '.__('(logs can be found in the UpdraftPlus settings page as normal)...', 'updraftplus');
$lastlog = __('Last log message', 'updraftplus').':';
$unexpected_response = esc_js(__('Unexpected response:', 'updraftplus'));
global $updraftplus;
$updraftplus->log(__('Starting automatic backup...', 'updraftplus'));
echo '
';
}
}
/**
* This is in WP 3.9 and later as a global function (but we support earlier)
*
* @param string $filter null
* @return array
*/
private function doing_filter($filter = null) {
if (function_exists('doing_filter')) return doing_filter($filter);
global $wp_current_filter;
if (null === $filter) {
return !empty($wp_current_filter);
}
return in_array($filter, $wp_current_filter);
}
private function autobackup_go($entity, $jquery = false) {
define('UPDRAFTPLUS_BROWSERLOG', true);
echo '
'.__('Creating backup with UpdraftPlus...', 'updraftplus')."
";
@ob_end_flush();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function.
echo '
';
$updraftplus->list_errors();
if ($jquery) include(ABSPATH . 'wp-admin/admin-footer.php');
die;
}
$this->autobackup_finish($jquery);
}
private function autobackup_finish($jquery = false) {
global $updraftplus, $wpdb;
if (method_exists($wpdb, 'check_connection') && !$wpdb->check_connection(false) && (!defined('UPDRAFTPLUS_SUPPRESS_CONNECTION_CHECKS') || !UPDRAFTPLUS_SUPPRESS_CONNECTION_CHECKS)) {
$updraftplus->log("It seems the database went away, and could not be reconnected to");
die;
}
echo "";
if ($jquery) {
echo '
';
}
}
public function admin_action_upgrade_plugin() {
if (!current_user_can('update_plugins')) return;
$plugin = isset($_REQUEST['plugin']) ? trim($_REQUEST['plugin']) : '';
check_admin_referer('upgrade-plugin_' . $plugin);
$autobackup = $this->get_setting_and_check_default_setting_save();
if (!empty($_REQUEST['updraftplus_noautobackup'])) return;
$title = __('Update Plugin');// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Passed though to wp-admin/admin-header.php.
$parent_file = 'plugins.php';// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Passed though to wp-admin/admin-header.php.
$submenu_file = 'plugins.php';// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Passed though to wp-admin/admin-header.php.
include_once(ABSPATH . 'wp-admin/admin-header.php');
$this->inpage_restrict = 'plugins';
// Did the user get the opportunity to indicate whether they wanted a backup?
if (!isset($_POST['updraft_autobackup_answer'])) $this->auto_backup_form_and_die();
if ($autobackup) {
echo '
'.__('Automatic Backup', 'updraftplus').'
';
$this->autobackup_go('plugins', true);
echo '
';
}
// Now, the backup is (if chosen) done... but the upgrade may not directly proceed. If WP needed filesystem credentials, then it may put up an intermediate screen, which we need to insert a field in to prevent an endless circle
add_filter('request_filesystem_credentials', array($this, 'request_filesystem_credentials'));
}
public function get_setting_and_check_default_setting_save() {
// Do not use bools here - conflicts with get_option() with a non-default value
$autobackup = (isset($_REQUEST['updraft_autobackup']) && 'yes' == $_REQUEST['updraft_autobackup']) ? 1 : 0;
if (!empty($_REQUEST['updraft_autobackup_setdefault']) && 'yes' == $_REQUEST['updraft_autobackup_setdefault']) UpdraftPlus_Options::update_updraft_option('updraft_autobackup_default', $autobackup);
return $autobackup;
}
public function request_filesystem_credentials($input) {
echo <<
jQuery(function() {
jQuery('#upgrade').before('');
});
ENDHERE;
return $input;
}
public function admin_action_upgrade_theme() {
if (!current_user_can('update_themes')) return;
$theme = isset($_REQUEST['theme']) ? urldecode($_REQUEST['theme']) : '';
check_admin_referer('upgrade-theme_' . $theme);
$autobackup = $this->get_setting_and_check_default_setting_save();
if (!empty($_REQUEST['updraftplus_noautobackup'])) return;
$title = __('Update Theme');// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Passed though to wp-admin/admin-header.php.
$parent_file = 'themes.php';// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Passed though to wp-admin/admin-header.php.
$submenu_file = 'themes.php';// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Passed though to wp-admin/admin-header.php.
include_once(ABSPATH.'wp-admin/admin-header.php');
$this->inpage_restrict = 'themes';
// Did the user get the opportunity to indicate whether they wanted a backup?
if (!isset($_POST['updraft_autobackup_answer'])) $this->auto_backup_form_and_die();
if ($autobackup) {
echo '
'.__('Automatic Backup', 'updraftplus').'
';
$this->autobackup_go('themes', true);
echo '
';
}
// Now, the backup is (if chosen) done... but the upgrade may not directly proceed. If WP needed filesystem credentials, then it may put up an intermediate screen, which we need to insert a field in to prevent an endless circle
add_filter('request_filesystem_credentials', array($this, 'request_filesystem_credentials'));
}
private function auto_backup_form_and_die() {
$this->auto_backup_form();
// Prevent rest of the page - unnecessary since we die() anyway
// unset($_GET['action']);
add_action('admin_footer', array($this, 'admin_footer_inpage_backup'));
include(ABSPATH . 'wp-admin/admin-footer.php');
die;
}
public function admin_footer_possibly_network_themes() {
$hook_suffix = $GLOBALS['hook_suffix'];
if ('themes.php' == $hook_suffix && is_multisite() && is_network_admin() && current_user_can('update_themes')) {
$this->inpage_restrict = 'themes';
// Don't add an action - we're already in the footer action; just do it
$this->admin_footer_inpage_backup();
}
}
public function pre_current_active_plugins() {
if (!current_user_can('update_plugins')) return;
$this->inpage_restrict = 'plugins';
add_action('admin_footer', array($this, 'admin_footer_inpage_backup'));
}
/**
* Inserts the HTML and JavaScript for in-page backup pre-update scaffolding. Should be called during admin_footer. Since Feb 2015.
* Basically, this function renders the minimum necessary of the admin furniture to be able to get everything up and running. It is an _alternative_ to the full set of furniture.
* Mar 2015: Tweaks added for WP's new "shiny updates" method (wp-admin/js/updates.js) - principally, the update lock.
*/
public function admin_footer_inpage_backup() {
if (!empty($this->inpage_restrict) && !current_user_can('update_'.$this->inpage_restrict)) return;
static $already_printed = false;
if ($already_printed) return;
$already_printed = true;
global $updraftplus_admin;
// Import original value of $wp_version
include(ABSPATH.WPINC.'/version.php');
$lock_variable = version_compare($wp_version, "4.5.999", "<") ? 'updateLock' : 'ajaxLocked';// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- Passed to javascript function below.
$queue_variable = version_compare($wp_version, "4.5.999", "<") ? 'updateQueue' : 'queue';// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- Passed to javascript function below.
?>
add_backup_scaffolding(__('Automatic backup before update', 'updraftplus'), array($this, 'backupnow_modal_contents'));
} else {
error_log("UpdraftPlus_Addon_Autobackup::admin_footer_inpage_backup() - unexpected failure for accessing UpdraftPlus_Admin object");
}
?>
auto_backup_form(true, 'updraft_autobackup', 'yes', false);
}
private function auto_backup_form($include_wrapper = true, $id = 'updraft_autobackup', $value = 'yes', $form_tags = true) {
if ($include_wrapper) {
if ($form_tags) {
?>