From af32b781af63e5f82a6d5f004527ef8d07fa0f87 Mon Sep 17 00:00:00 2001 From: hellofromtonya Date: Wed, 7 Feb 2024 10:01:11 -0600 Subject: [PATCH] Performance: hooked lambda for rendering admin notices. Doing a write to the database will have a performance hit. To avoid the hit, removes the new "wp_force_deactivation_incompatible_plugins" option in favor of hooking a callback into `'admin_notice'` and passing the global into the callback via `use()`. Isn't the global unset() within wp-settings.php? Yes. It's done to avoid leaking the handler out of the file (for future BC). Doesn't unsetting the global cause it to be unavailable to the hooked lambda? No. Notice, the global is passed to the lambda (i.e. anonymous function) via `use()`. What does this do? In PHP, the _value_ of the passed variable gets inherited within the anonymous function is it (the anonymous function) is defined, not when it (the anonymous function) is called. See the PHP Manual https://www.php.net/manual/en/functions.anonymous.php#functions.anonymous#example-541 >// Inherited variable's value is from when the function >// is defined, not when called See it in action https://3v4l.org/1BocJ. --- src/wp-admin/includes/admin-filters.php | 1 - src/wp-admin/includes/plugin.php | 66 ++++++------------------- src/wp-settings.php | 5 +- 3 files changed, 20 insertions(+), 52 deletions(-) diff --git a/src/wp-admin/includes/admin-filters.php b/src/wp-admin/includes/admin-filters.php index 66c7d98dd5d0e..b5adb946cf0d3 100644 --- a/src/wp-admin/includes/admin-filters.php +++ b/src/wp-admin/includes/admin-filters.php @@ -133,7 +133,6 @@ add_action( 'admin_notices', 'update_nag', 3 ); add_action( 'admin_notices', 'deactivated_plugins_notice', 5 ); -add_action( 'admin_notices', '_render_notice_for_deactivated_incompatible_plugins', 5 ); add_action( 'admin_notices', 'paused_plugins_notice', 5 ); add_action( 'admin_notices', 'paused_themes_notice', 5 ); add_action( 'admin_notices', 'maintenance_nag', 10 ); diff --git a/src/wp-admin/includes/plugin.php b/src/wp-admin/includes/plugin.php index 169fee8753811..8c4aa402b63da 100644 --- a/src/wp-admin/includes/plugin.php +++ b/src/wp-admin/includes/plugin.php @@ -2600,64 +2600,36 @@ function deactivated_plugins_notice() { /** * Renders an admin notice for each incompatible plugin. * - * Displays an admin notice in case a plugin was deactivated during the - * loading of WordPress due to incompatibility with the current version - * of WordPress. + * These plugins were not loaded during WordPress' early loading + * due to incompatibility with the current version of WordPress. * * @since 6.5.0 * @access private * * @global string $wp_version The WordPress version string. + * + * @param array $incompatible_plugins Incompatible plugins to generate notices. */ -function _render_notice_for_deactivated_incompatible_plugins() { +function _render_admin_notice_for_incompatible_plugins( $incompatible_plugins ) { if ( ! current_user_can( 'activate_plugins' ) ) { return; } - $blog_deactivated_plugins = get_option( 'wp_force_deactivation_incompatible_plugins' ); - $site_deactivated_plugins = array(); - - if ( false === $blog_deactivated_plugins ) { - // Option not in database, add an empty array to avoid extra DB queries on subsequent loads. - update_option( 'wp_force_deactivation_incompatible_plugins', array() ); - } - - if ( is_multisite() ) { - $site_deactivated_plugins = get_site_option( 'wp_force_deactivation_incompatible_plugins' ); - if ( false === $site_deactivated_plugins ) { - // Option not in database, add an empty array to avoid extra DB queries on subsequent loads. - update_site_option( 'wp_force_deactivation_incompatible_plugins', array() ); + foreach ( $incompatible_plugins as $plugin ) { + // Skip if information is missing. + if ( empty( $plugin['version_compatible'] ) || empty( $plugin['version_deactivated'] ) ) { + continue; } - } - - if ( empty( $blog_deactivated_plugins ) && empty( $site_deactivated_plugins ) ) { - // No deactivated plugins. - return; - } - - $deactivated_plugins = array_merge( $blog_deactivated_plugins, $site_deactivated_plugins ); - foreach ( $deactivated_plugins as $plugin ) { - if ( ! empty( $plugin['version_compatible'] ) && ! empty( $plugin['version_deactivated'] ) ) { - $explanation = sprintf( + $explanation = sprintf( /* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version, 4: Compatible plugin version. */ - __( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s, please upgrade to %1$s %4$s or later.' ), - $plugin['plugin_name'], - $plugin['version_deactivated'], - $GLOBALS['wp_version'], - $plugin['version_compatible'] - ); - } else { - $explanation = sprintf( - /* translators: 1: Name of deactivated plugin, 2: Plugin version deactivated, 3: Current WP version. */ - __( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s.' ), - $plugin['plugin_name'], - ! empty( $plugin['version_deactivated'] ) ? $plugin['version_deactivated'] : '', - $GLOBALS['wp_version'], - $plugin['version_compatible'] - ); - } + __( '%1$s %2$s was deactivated due to incompatibility with WordPress %3$s, please upgrade to %1$s %4$s or later.' ), + $plugin['plugin_name'], + $plugin['version_deactivated'], + $GLOBALS['wp_version'], + $plugin['version_compatible'] + ); $message = sprintf( '%s

%s', @@ -2667,10 +2639,4 @@ function _render_notice_for_deactivated_incompatible_plugins() { ); wp_admin_notice( $message, array( 'type' => 'warning' ) ); } - - // Empty the options. - update_option( 'wp_force_deactivation_incompatible_plugins', array() ); - if ( is_multisite() ) { - update_site_option( 'wp_force_deactivation_incompatible_plugins', array() ); - } } diff --git a/src/wp-settings.php b/src/wp-settings.php index f56f117f43cd8..c0018ae01aaee 100644 --- a/src/wp-settings.php +++ b/src/wp-settings.php @@ -523,7 +523,10 @@ update_option( 'active_plugins', $active_plugins ); // Update the list of incompatible plugins to notify user in the admin. - update_option( 'wp_force_deactivation_incompatible_plugins', $_found_incompatible_for_core_plugins ); + $admin_notices_handler = static function () use ( $_found_incompatible_for_core_plugins ) { + _render_notice_for_incompatible_plugins( $_found_incompatible_for_core_plugins ); + }; + add_action( 'admin_notices', $admin_notices_handler, 5 ); }; // End of the for-core plugins compatibility handler.