From f312173db5b69740f480a52f15970ce0ef75e0b6 Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 27 Aug 2015 20:01:37 +0000 Subject: [PATCH] Improve the efficiency of `is_user_member_of_blog()` by removing its use of `get_blogs_of_user()`. Adds additional tests. Fixes #32472 Props BinaryKitten, sammybeats, johnbillion git-svn-id: https://develop.svn.wordpress.org/trunk@33771 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/user-functions.php | 49 +++++++++++++++++++++++--- tests/phpunit/tests/user.php | 5 +++ tests/phpunit/tests/user/multisite.php | 32 +++++++++++++++-- 3 files changed, 80 insertions(+), 6 deletions(-) diff --git a/src/wp-includes/user-functions.php b/src/wp-includes/user-functions.php index 894e2b210c..fb13643757 100644 --- a/src/wp-includes/user-functions.php +++ b/src/wp-includes/user-functions.php @@ -583,17 +583,58 @@ function get_blogs_of_user( $user_id, $all = false ) { * @return bool */ function is_user_member_of_blog( $user_id = 0, $blog_id = 0 ) { + global $wpdb; + $user_id = (int) $user_id; $blog_id = (int) $blog_id; - if ( empty( $user_id ) ) + if ( empty( $user_id ) ) { $user_id = get_current_user_id(); + } - if ( empty( $blog_id ) ) + // Technically not needed, but does save calls to get_blog_details and get_user_meta + // in the event that the function is called when a user isn't logged in + if ( empty( $user_id ) ) { + return false; + } else { + $user = get_userdata( $user_id ); + if ( ! $user instanceof WP_User ) { + return false; + } + } + + if ( ! is_multisite() ) { + return true; + } + + if ( empty( $blog_id ) ) { $blog_id = get_current_blog_id(); + } - $blogs = get_blogs_of_user( $user_id ); - return array_key_exists( $blog_id, $blogs ); + $blog = get_blog_details( $blog_id ); + + if ( ! $blog || ! isset( $blog->domain ) || $blog->archived || $blog->spam || $blog->deleted ) { + return false; + } + + $keys = get_user_meta( $user_id ); + if ( empty( $keys ) ) { + return false; + } + + // no underscore before capabilities in $base_capabilities_key + $base_capabilities_key = $wpdb->base_prefix . 'capabilities'; + $site_capabilities_key = $wpdb->base_prefix . $blog_id . '_capabilities'; + + if ( isset( $keys[ $base_capabilities_key ] ) && $blog_id == 1 ) { + return true; + } + + if ( isset( $keys[ $site_capabilities_key ] ) ) { + return true; + } + + return false; } /** diff --git a/tests/phpunit/tests/user.php b/tests/phpunit/tests/user.php index f63d8382f7..206fe2b497 100644 --- a/tests/phpunit/tests/user.php +++ b/tests/phpunit/tests/user.php @@ -366,6 +366,11 @@ class Tests_User extends WP_UnitTestCase { function test_is_user_member_of_blog() { $old_current = get_current_user_id(); + $this->assertSame( 0, $old_current ); + + // test for "get current user" when not logged in + $this->assertFalse( is_user_member_of_blog() ); + $user_id = $this->factory->user->create( array( 'role' => 'subscriber' ) ); wp_set_current_user( $user_id ); diff --git a/tests/phpunit/tests/user/multisite.php b/tests/phpunit/tests/user/multisite.php index 41b0e88666..0ae955aff8 100644 --- a/tests/phpunit/tests/user/multisite.php +++ b/tests/phpunit/tests/user/multisite.php @@ -141,8 +141,15 @@ class Tests_Multisite_User extends WP_UnitTestCase { global $wpdb; $user1_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); + $user2_id = $this->factory->user->create( array( 'role' => 'administrator' ) ); $old_current = get_current_user_id(); + + $this->assertSame( 0, $old_current ); + + // test for "get current user" when not logged in + $this->assertFalse( is_user_member_of_blog() ); + wp_set_current_user( $user1_id ); $this->assertTrue( is_user_member_of_blog() ); @@ -154,15 +161,36 @@ class Tests_Multisite_User extends WP_UnitTestCase { $blog_ids = $this->factory->blog->create_many( 5 ); foreach ( $blog_ids as $blog_id ) { $this->assertInternalType( 'int', $blog_id ); + + // Current user gets added to new blogs $this->assertTrue( is_user_member_of_blog( $user1_id, $blog_id ) ); + // Other users should not + $this->assertFalse( is_user_member_of_blog( $user2_id, $blog_id ) ); + + switch_to_blog( $blog_id ); + + $this->assertTrue( is_user_member_of_blog( $user1_id ) ); + $this->assertFalse( is_user_member_of_blog( $user2_id ) ); + + // Remove user 1 from blog $this->assertTrue( remove_user_from_blog( $user1_id, $blog_id ) ); + + // Add user 2 to blog + $this->assertTrue( add_user_to_blog( $blog_id, $user2_id, 'subscriber' ) ); + + $this->assertFalse( is_user_member_of_blog( $user1_id ) ); + $this->assertTrue( is_user_member_of_blog( $user2_id ) ); + + restore_current_blog(); + $this->assertFalse( is_user_member_of_blog( $user1_id, $blog_id ) ); + $this->assertTrue( is_user_member_of_blog( $user2_id, $blog_id ) ); } wpmu_delete_user( $user1_id ); $user = new WP_User( $user1_id ); - $this->assertFalse( $user->exists(), 'WP_User->exists' ); - $this->assertFalse( is_user_member_of_blog( $user1_id ), 'is_user_member_of_blog' ); + $this->assertFalse( $user->exists() ); + $this->assertFalse( is_user_member_of_blog( $user1_id ) ); wp_set_current_user( $old_current ); }