From ecd93af74a163231749d6e190dafaebca1bc88b3 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Mon, 26 Apr 2021 01:02:34 +0000 Subject: [PATCH] Users: Share current user instance across functions. Share the `WP_User` instance for the current user between the functions `get_userdata()` and `wp_get_current_user()`. Both functions return the `$current_user` global for the current user. Force refresh the `$current_user` global within `clean_user_cache()` by immediately re-calling `wp_set_current_user()` with the current user's ID. This ensures any changes to the current user's permissions or other settings are reflected in the global. As a side-effect this immediately rewarms the current user's cache. Props chaion07, chriscct7, donmhico, hellofromtonya, lukecarbis, peterwilsoncc, rmccue, TimothyBlynJacobs. Fixes #28020. git-svn-id: https://develop.svn.wordpress.org/trunk@50790 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/pluggable.php | 7 +++++++ src/wp-includes/user.php | 12 ++++++++++++ tests/phpunit/tests/pluggable.php | 15 +++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/wp-includes/pluggable.php b/src/wp-includes/pluggable.php index b5e39d7a19..0e4cbe80e1 100644 --- a/src/wp-includes/pluggable.php +++ b/src/wp-includes/pluggable.php @@ -91,18 +91,25 @@ if ( ! function_exists( 'get_user_by' ) ) : * * @since 2.8.0 * @since 4.4.0 Added 'ID' as an alias of 'id' for the `$field` parameter. + * @since 5.8.0 Returns the global `$current_user` if it's the user being fetched. * * @param string $field The field to retrieve the user with. id | ID | slug | email | login. * @param int|string $value A value for $field. A user ID, slug, email address, or login name. * @return WP_User|false WP_User object on success, false on failure. */ function get_user_by( $field, $value ) { + global $current_user; + $userdata = WP_User::get_data_by( $field, $value ); if ( ! $userdata ) { return false; } + if ( $current_user instanceof WP_User && $current_user->ID === (int) $userdata->ID ) { + return $current_user; + } + $user = new WP_User; $user->init( $userdata ); diff --git a/src/wp-includes/user.php b/src/wp-includes/user.php index 048bb4c511..8a94526df2 100644 --- a/src/wp-includes/user.php +++ b/src/wp-includes/user.php @@ -1561,10 +1561,15 @@ function update_user_caches( $user ) { * * @since 3.0.0 * @since 4.4.0 'clean_user_cache' action was added. + * @since 5.8.0 Refreshes the global user instance if cleaning the user cache for the current user. + * + * @global WP_User $current_user The current user object which holds the user data. * * @param WP_User|int $user User object or ID to be cleaned from the cache */ function clean_user_cache( $user ) { + global $current_user; + if ( is_numeric( $user ) ) { $user = new WP_User( $user ); } @@ -1587,6 +1592,13 @@ function clean_user_cache( $user ) { * @param WP_User $user User object. */ do_action( 'clean_user_cache', $user->ID, $user ); + + // Refresh the global user instance if the cleaning current user. + if ( get_current_user_id() === (int) $user->ID ) { + $user_id = (int) $user->ID; + $current_user = null; + wp_set_current_user( $user_id, '' ); + } } /** diff --git a/tests/phpunit/tests/pluggable.php b/tests/phpunit/tests/pluggable.php index 879f31151d..3d9b2cc432 100644 --- a/tests/phpunit/tests/pluggable.php +++ b/tests/phpunit/tests/pluggable.php @@ -324,4 +324,19 @@ class Tests_Pluggable extends WP_UnitTestCase { return $signatures; } + /** + * @ticket 28020 + */ + public function test_get_user_by_should_return_same_instance_as_wp_get_current_user() { + // Create a test user + $new_user = self::factory()->user->create( array( 'role' => 'subscriber' ) ); + + // Set the test user as the current user + $current_user = wp_set_current_user( $new_user ); + + // Get the test user using get_user_by() + $from_get_user_by = get_user_by( 'id', $new_user ); + + $this->assertSame( $current_user, $from_get_user_by ); + } }