From be2ec734f22cf7a5ec70afc7419851d4491f29db Mon Sep 17 00:00:00 2001 From: desrosj Date: Tue, 11 Feb 2020 20:14:05 +0000 Subject: [PATCH] Upgrade/Install: Enable maintenance mode when plugins are auto-updated. When an attempt is made to update an active plugin automatically, there is the potential currently for two negative scenarios: - The plugin can be deactivated if the Plugins admin screen is loaded when the plugin update is incomplete, causing a PHP error. - The WSOD protection could be triggered, sending a false alarm email to the site administrator. By enabling maintenance mode before an active plugin update is attempted, these scenarios can be avoided. This change implements the same approach as the `Theme_Upgrader` class of using the `upgrader_pre_install` and `upgrader_post_install` hooks to toggle maintenance mode. Props desrosj, SergeyBiryukov. Fixes #49400. Built from https://develop.svn.wordpress.org/trunk@47275 git-svn-id: http://core.svn.wordpress.org/trunk@47075 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/class-plugin-upgrader.php | 74 +++++++++++++++++++++ wp-includes/version.php | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/wp-admin/includes/class-plugin-upgrader.php b/wp-admin/includes/class-plugin-upgrader.php index 28523e9db8..be5b926e4a 100644 --- a/wp-admin/includes/class-plugin-upgrader.php +++ b/wp-admin/includes/class-plugin-upgrader.php @@ -167,7 +167,9 @@ class Plugin_Upgrader extends WP_Upgrader { $r = $current->response[ $plugin ]; add_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ), 10, 2 ); + add_filter( 'upgrader_pre_install', array( $this, 'active_before' ), 10, 2 ); add_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ), 10, 4 ); + add_filter( 'upgrader_post_install', array( $this, 'active_after' ), 10, 2 ); // There's a Trac ticket to move up the directory for zips which are made a bit differently, useful for non-.org plugins. // 'source_selection' => array( $this, 'source_selection' ), if ( $parsed_args['clear_update_cache'] ) { @@ -192,7 +194,9 @@ class Plugin_Upgrader extends WP_Upgrader { // Cleanup our hooks, in case something else does a upgrade on this connection. remove_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9 ); remove_filter( 'upgrader_pre_install', array( $this, 'deactivate_plugin_before_upgrade' ) ); + remove_filter( 'upgrader_pre_install', array( $this, 'active_before' ) ); remove_filter( 'upgrader_clear_destination', array( $this, 'delete_old_plugin' ) ); + remove_filter( 'upgrader_post_install', array( $this, 'active_after' ) ); if ( ! $this->result || is_wp_error( $this->result ) ) { return $this->result; @@ -439,6 +443,76 @@ class Plugin_Upgrader extends WP_Upgrader { return $return; } + /** + * Turn on maintenance mode before attempting to background update an active plugin. + * + * Hooked to the {@see 'upgrader_pre_install'} filter by Plugin_Upgrader::upgrade(). + * + * @since 5.4.0 + * + * @param bool|WP_Error $return + * @param array $plugin + * @return bool|WP_Error + */ + public function active_before( $return, $plugin ) { + if ( is_wp_error( $return ) ) { + return $return; + } + + // Only enable maintenance mode when in cron (background update). + if ( ! wp_doing_cron() ) { + return $return; + } + + $plugin = isset( $plugin['plugin'] ) ? $plugin['plugin'] : ''; + + if ( ! is_plugin_active( $plugin ) ) { // If not active. + return $return; + } + + // Bulk edit handles maintenance mode separately. + if ( ! $this->bulk ) { + $this->maintenance_mode( true ); + } + + return $return; + } + + /** + * Turn off maintenance mode after upgrading an active plugin. + * + * Hooked to the {@see 'upgrader_post_install'} filter by Plugin_Upgrader::upgrade(). + * + * @since 5.4.0 + * + * @param bool|WP_Error $return + * @param array $plugin + * @return bool|WP_Error + */ + public function active_after( $return, $plugin ) { + if ( is_wp_error( $return ) ) { + return $return; + } + + // Only disable maintenance mode when in cron (background update). + if ( ! wp_doing_cron() ) { + return $return; + } + + $plugin = isset( $plugin['plugin'] ) ? $plugin['plugin'] : ''; + + if ( ! is_plugin_active( $plugin ) ) { // If not active. + return $return; + } + + // Bulk edit handles maintenance mode separately. + if ( ! $this->bulk ) { + $this->maintenance_mode( false ); + } + + return $return; + } + /** * Delete the old plugin during an upgrade. * diff --git a/wp-includes/version.php b/wp-includes/version.php index 1a35f7dfae..c54dc27c87 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -13,7 +13,7 @@ * * @global string $wp_version */ -$wp_version = '5.4-alpha-47274'; +$wp_version = '5.4-alpha-47275'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.