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
This commit is contained in:
desrosj 2020-02-11 20:14:05 +00:00
parent a2accf4db7
commit be2ec734f2
2 changed files with 75 additions and 1 deletions

View File

@ -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.
*

View File

@ -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.