[wp-trac] [WordPress Trac] #32472: is_user_member_of_blog() can be very slow when a user is a member of hundreds of sites
WordPress Trac
noreply at wordpress.org
Sat May 23 15:44:22 UTC 2015
#32472: is_user_member_of_blog() can be very slow when a user is a member of
hundreds of sites
------------------------------------+-----------------------------
Reporter: sammybeats | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Users | Version: 3.0
Severity: normal | Keywords:
Focuses: multisite, performance |
------------------------------------+-----------------------------
This problem would partly be fixed if the solution in #31746 were adopted,
however it is still a separate issue.
`is_user_member_of_blog()` uses `get_blogs_of_user()` which is very slow
when the user is a member of hundreds of sites. And because
`is_user_member_of_blog()` is called on every admin page load by
`wp_user_settings()` in `admin-header.php`, this adds a TON of database
queries to every admin page load.
`get_blog_details()`, which is called on every blog of which the user is a
member in `get_blogs_of_user()`, only needs to be done on the blog in
question when `is_user_member_of_blog()` is called. I propose a solution
like this, though it may duplicate too much code from
`get_blogs_of_user()`:
{{{
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 ) )
$user_id = get_current_user_id();
if ( empty( $blog_id ) )
$blog_id = get_current_blog_id();
if ( empty( $user_id ) )
return false;
if( ! is_multisite() )
return true;
$keys = get_user_meta( $user_id );
if ( empty( $keys ) )
return false;
$blog = get_blog_details( $blog_id );
if( ! $blog || ! isset( $blog->domain ) || $blog->archived ||
$blog->spam || $blog->deleted )
return false;
if ( isset( $keys[ $wpdb->base_prefix . 'capabilities' ] ) && defined(
'MULTISITE' ) && $blog_id == 1 )
return true;
$is_member = false;
$keys = array_keys( $keys );
foreach ( $keys as $key ) {
if ( 'capabilities' !== substr( $key, -12 ) )
continue;
if ( $wpdb->base_prefix && 0 !== strpos( $key, $wpdb->base_prefix
) )
continue;
$key_blog_id = str_replace( array( $wpdb->base_prefix,
'_capabilities' ), '', $key );
if ( ! is_numeric( $key_blog_id ) )
continue;
if ( $key_blog_id == $blog_id ) {
$is_member = true;
break;
}
}
return $is_member;
}
}}}
I just tested it and it reduced my admin page load time by 5 seconds.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/32472>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list