get_wordpress_version(); if (version_compare($wp_version, '4.4.0', '<')) { // Somewhat inelegant... see: https://core.trac.wordpress.org/ticket/30441 add_filter('auto_update_plugin', array($this, 'auto_update_plugin'), PHP_INT_MAX, 2); add_filter('auto_update_theme', array($this, 'auto_update_theme'), PHP_INT_MAX, 2); add_filter('auto_update_core', array($this, 'auto_update_core'), PHP_INT_MAX, 2); } else { // Action added in WP 4.4 add_action('pre_auto_update', array($this, 'pre_auto_update'), 10, 2); } // Shiny updates land in wp-admin/themes.php with WP 4.6 (and the trunk before the release, of course) if (version_compare($wp_version, '4.5.999', '>')) { add_action('load-themes.php', array($this, 'load_themes_php')); } } /** * All 3 of these hooks since JetPack 3.9.2 (assuming our patch goes in) * * @param array $plugin * @param array $plugins * @param array $update_attempted * @return array */ public function jetpack_pre_plugin_upgrade($plugin, $plugins, $update_attempted) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Filter use $this->auto_update(true, $plugin, 'plugins'); } public function jetpack_pre_theme_upgrade($theme, $themes) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Filter use $this->auto_update(true, $theme, 'themes'); } public function jetpack_pre_core_upgrade($update) { $this->auto_update(true, $update, 'core'); } public function load_themes_php() { if (!current_user_can('update_themes')) return; $this->inpage_restrict = 'themes'; add_action('admin_footer', array($this, 'admin_footer_inpage_backup')); } public function install_plugins_pre_plugin() { if (!current_user_can('update_plugins')) return; $this->inpage_restrict = 'plugins'; add_action('admin_footer', array($this, 'admin_footer_inpage_backup')); } public function wpcore_description($desc) { global $updraftplus; $is_autobackup = $updraftplus->jobdata_get('is_autobackup', false); if (empty($this->is_autobackup_core) && !$is_autobackup) return $desc; return $is_autobackup ? __('WordPress core (only)', 'updraftplus') : $desc; } public function ud_wp_maybe_auto_update($lock_value) { $lock_result = get_option($this->lock_name); if ($lock_result != $lock_value) return; // Remove the lock, to allow the WP updater to claim it and proceed delete_option($this->lock_name); $this->do_not_filter_auto_backup = true; wp_maybe_auto_update(); } public function configprint_expertoptions() { ?> : auto_backup_form(false, 'updraft_autobackup_default', '1');?> 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'); $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(); ?> internaltype)) return; $creating = sprintf(__('Creating %s and database backup with UpdraftPlus...', 'updraftplus'), $this->type).' '.__('(logs can be found in the UpdraftPlus settings page as normal)...', 'updraftplus'); $lastlog = __('Last log message', 'updraftplus').':'; global $updraftplus; $updraftplus->log(__('Starting automatic backup...', 'updraftplus')); $unexpected_response = __('Unexpected response:', 'updraftplus'); ?> 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(esc_html__('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 = __('Unexpected response:', 'updraftplus'); global $updraftplus; $updraftplus->log('Starting automatic backup...'); echo '

'.esc_html__('Automatic Backup', 'updraftplus').'

'; echo "

".esc_html($creating)."

".esc_html($lastlog)."

"; ?> type = 'core'; $this->internaltype = 'core'; $this->autobackup_go('core', true); 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 '

'.esc_html__('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 '
';
		global $updraftplus;

		if ('core' == $entity) {
			$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($entity);
		}

		if ('core' == $entity) {
			$this->is_autobackup_core = true;
		}

		add_filter('updraftplus_initial_jobdata', array($this, 'initial_jobdata2'));
		add_filter('updraftplus_autobackup_extralog', array($this, 'autobackup_extralog'));

		$updraftplus->boot_backup((int) $backup_files, 1, $backup_files_array, true);
		echo '
'; if ($updraftplus->error_count() >0) { echo '

'.esc_html__("Errors have occurred:", 'updraftplus').'

'; $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 '

'.esc_html__('Backup succeeded', 'updraftplus').' '.esc_html__('(view log...)', 'updraftplus').' - '.esc_html__('now proceeding with the updates...', 'updraftplus').'

'; } else { echo '

'.esc_html__('Backup succeeded', 'updraftplus').' '.esc_html__('(view log...)', 'updraftplus').' - '.esc_html__('now proceeding with the updates...', 'updraftplus').'

'; } } 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 '

'.esc_html__('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 '

'.esc_html__('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) { ?>

style=" padding: 6px; margin:8px 0px; max-width: 540px;">

type="checkbox" id="" value="" name=""> '; ?>

'; } } }