Skip to:
Content

BuddyPress.org

Changeset 8027


Ignore:
Timestamp:
03/03/2014 09:35:48 PM (11 years ago)
Author:
boonebgorges
Message:

Introduce bp_core_user_displaynames(), for quick, bulk displayname lookup

The technique BP uses for determining a user's displayname takes into
consideration whether the xprofile component is active, whether the user has a
WP display_name, and a number of other factors. Because the values are used so
often throughout BP, they are then cached in WP's object cache. However, there
are a number of places throughout BuddyPress where displaynames are fetched
in a way that is inconsistent with the "canonical" workflow (ie, by querying
the xprofile tables correctly). This causes inconsistent results, and also can
result in performance degradation when the persistent cache is skipped.
Moreover, the singular nature of bp_core_get_user_displayname() meant that
doing it the "right" way meant introducing large numbers of queries to a given
page load.

This changeset introduces bp_core_get_user_displaynames(), which contains all
the critical logic of bp_core_get_user_displayname() - including fallbacks for
various setups and support for the object cache - but allows for fetching large
numbers of displaynames without multiple queries. bp_core_get_user_displayname()
is now a wrapper for the more general function.

The function has been swapped in throughout BuddyPress as appropriate.

See #5445

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-activity/bp-activity-classes.php

    r8005 r8027  
    545545
    546546            if ( ! empty( $activity_user_ids ) ) {
    547                 $names = BP_XProfile_ProfileData::get_value_byid( 1, $activity_user_ids );
    548                 if ( ! empty( $names ) ) {
    549 
    550                     $tmp_names = array();
    551 
    552                     foreach ( (array) $names as $name ) {
    553                         $tmp_names[ $name->user_id ] = $name->value;
    554                     }
    555 
     547                $fullnames = bp_core_get_user_displaynames( $activity_user_ids );
     548                if ( ! empty( $fullnames ) ) {
    556549                    foreach ( (array) $activities as $i => $activity ) {
    557                         if ( ! empty( $tmp_names[ $activity->user_id ] ) ) {
    558                             $activities[ $i ]->user_fullname = $tmp_names[ $activity->user_id ];
     550                        if ( ! empty( $fullnames[ $activity->user_id ] ) ) {
     551                            $activities[ $i ]->user_fullname = $fullnames[ $activity->user_id ];
    559552                        }
    560553                    }
    561 
    562                     unset( $names );
    563                     unset( $tmp_names );
    564554                }
    565555            }
  • trunk/bp-members/bp-members-functions.php

    r7911 r8027  
    390390}
    391391
    392 
    393 /**
    394  * Fetch the display name for a user. This will use the "Name" field in xprofile if it is installed.
    395  * Otherwise, it will fall back to the normal WP display_name, or user_nicename, depending on what has been set.
    396  *
    397  * @package BuddyPress Core
    398  * @global BuddyPress $bp The one true BuddyPress instance
    399  * @uses wp_cache_get() Will try and fetch the value from the cache, rather than querying the DB again.
    400  * @uses get_userdata() Fetches the WP userdata for a specific user.
    401  * @uses xprofile_set_field_data() Will update the field data for a user based on field name and user id.
    402  * @uses wp_cache_set() Adds a value to the cache.
    403  * @return string|bool The display name for the user in question, or false if user not found.
     392/**
     393 * Fetch the display name for a group of users.
     394 *
     395 * Uses the 'Name' field in xprofile if available. Falls back on WP
     396 * display_name, and then user_nicename.
     397 *
     398 * @since BuddyPress (2.0.0)
     399 *
     400 * @param array $user_ids
     401 */
     402function bp_core_get_user_displaynames( $user_ids ) {
     403
     404    // Sanitize
     405    $user_ids = wp_parse_id_list( $user_ids );
     406
     407    // Remove dupes and empties
     408    $user_ids = array_unique( array_filter( $user_ids ) );
     409
     410    if ( empty( $user_ids ) ) {
     411        return array();
     412    }
     413
     414    $uncached_ids = array();
     415    foreach ( $user_ids as $user_id ) {
     416        if ( false === wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' ) ) {
     417            $uncached_ids[] = $user_id;
     418        }
     419    }
     420
     421    // Prime caches
     422    if ( ! empty( $uncached_ids ) ) {
     423        if ( bp_is_active( 'xprofile' ) ) {
     424            $fullname_data = BP_XProfile_ProfileData::get_value_byid( 1, $uncached_ids );
     425
     426            // Key by user_id
     427            $fullnames = array();
     428            foreach ( $fullname_data as $fd ) {
     429                if ( ! empty( $fd->value ) ) {
     430                    $fullnames[ intval( $fd->user_id ) ] = $fd->value;
     431                }
     432            }
     433
     434            // If xprofiledata is not found for any users,  we'll look
     435            // them up separately
     436            $no_xprofile_ids = array_diff( $uncached_ids, array_keys( $fullnames ) );
     437        } else {
     438            $fullnames = array();
     439            $no_xprofile_ids = $user_ids;
     440        }
     441
     442        if ( ! empty( $no_xprofile_ids ) ) {
     443            // Use WP_User_Query because we don't need BP information
     444            $query = new WP_User_Query( array(
     445                'include'     => $no_xprofile_ids,
     446                'fields'      => array( 'ID', 'user_nicename', 'display_name', ),
     447                'count_total' => false,
     448                'blog_id'     => 0,
     449            ) );
     450
     451            foreach ( $query->results as $qr ) {
     452                $fullnames[ $qr->ID ] = ! empty( $qr->display_name ) ? $qr->display_name : $qr->user_nicename;
     453
     454                // If xprofile is active, set this value as the
     455                // xprofile display name as well
     456                if ( bp_is_active( 'xprofile' ) ) {
     457                    xprofile_set_field_data( 1, $qr->ID, $fullnames[ $qr->ID ] );
     458                }
     459            }
     460        }
     461
     462        foreach ( $fullnames as $fuser_id => $fname ) {
     463            wp_cache_set( 'bp_user_fullname_' . $fuser_id, $fname, 'bp' );
     464        }
     465    }
     466
     467    $retval = array();
     468    foreach ( $user_ids as $user_id ) {
     469        $retval[ $user_id ] = wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' );
     470    }
     471
     472    return $retval;
     473}
     474
     475/**
     476 * Fetch the display name for a user.
     477 *
     478 * @param int|string $user_id_or_username User ID or username.
     479 * @return string|bool The display name for the user in question, or false if
     480 *         user not found.
    404481 */
    405482function bp_core_get_user_displayname( $user_id_or_username ) {
     
    408485    $fullname = '';
    409486
    410     if ( !$user_id_or_username )
    411         return false;
    412 
    413     if ( !is_numeric( $user_id_or_username ) )
     487    if ( empty( $user_id_or_username ) ) {
     488        return false;
     489    }
     490
     491    if ( ! is_numeric( $user_id_or_username ) ) {
    414492        $user_id = bp_core_get_userid( $user_id_or_username );
    415     else
     493    } else {
    416494        $user_id = $user_id_or_username;
    417 
    418     if ( !$user_id )
    419         return false;
    420 
    421     if ( !$fullname = wp_cache_get( 'bp_user_fullname_' . $user_id, 'bp' ) ) {
    422         if ( bp_is_active( 'xprofile' ) ) {
    423             $fullname = xprofile_get_field_data( 1, $user_id );
    424 
    425             if ( empty($fullname) ) {
    426                 $ud = bp_core_get_core_userdata( $user_id );
    427 
    428                 if ( !empty( $ud->display_name ) )
    429                     $fullname = $ud->display_name;
    430                 elseif ( !empty( $ud->user_nicename ) )
    431                     $fullname = $ud->user_nicename;
    432 
    433                 xprofile_set_field_data( 1, $user_id, $fullname );
    434             }
    435         } else {
    436             $ud = bp_core_get_core_userdata($user_id);
    437 
    438             if ( !empty( $ud->display_name ) )
    439                 $fullname = $ud->display_name;
    440             elseif ( !empty( $ud->user_nicename ) )
    441                 $fullname = $ud->user_nicename;
    442         }
    443 
    444         if ( !empty( $fullname ) )
    445             wp_cache_set( 'bp_user_fullname_' . $user_id, $fullname, 'bp' );
     495    }
     496
     497    if ( empty( $user_id ) ) {
     498        return false;
     499    }
     500
     501    $display_names = bp_core_get_user_displaynames( array( $user_id ) );
     502
     503    if ( ! isset( $display_names[ $user_id ] ) ) {
     504        $fullname = false;
     505    } else {
     506        $fullname = $display_names[ $user_id ];
    446507    }
    447508
  • trunk/bp-xprofile/bp-xprofile-filters.php

    r7862 r8027  
    216216
    217217    // Pull up the xprofile fullname of each commenter
    218     if ( $fullnames = BP_XProfile_ProfileData::get_value_byid( 1, $user_ids ) ) {
    219         foreach( (array) $fullnames as $user ) {
    220             $users[ $user->user_id ] = trim( stripslashes( $user->value ) );
     218    if ( $fullnames = bp_core_get_user_displaynames( $user_ids ) ) {
     219        foreach( (array) $fullnames as $user_id => $user_fullname ) {
     220            $users[ $user_id ] = trim( stripslashes( $user_fullname ) );
    221221        }
    222222    }
     
    252252    }
    253253
    254     $user_id_names = BP_XProfile_ProfileData::get_value_byid( bp_xprofile_fullname_field_id(), $user_query->user_ids );
     254    $user_id_names = bp_core_get_user_displaynames( $user_query->user_ids );
    255255
    256256    // Loop through names and override each user's fullname
    257     foreach ( $user_id_names as $user ) {
    258         if ( isset( $user_query->results[ $user->user_id ] ) ) {
    259             $user_query->results[ $user->user_id ]->fullname = $user->value;
     257    foreach ( $user_id_names as $user_id => $user_fullname ) {
     258        if ( isset( $user_query->results[ $user_id ] ) ) {
     259            $user_query->results[ $user_id ]->fullname = $user_fullname;
    260260        }
    261261    }
  • trunk/tests/testcases/members/functions.php

    r8022 r8027  
    210210        }
    211211    }
     212
     213    /**
     214     * @group bp_core_get_user_displaynames
     215     */
     216    public function test_bp_core_get_user_displayname_arrays_all_bad_entries() {
     217        $this->assertSame( array(), bp_core_get_user_displaynames( array( 0, 'foo', ) ) );
     218    }
     219
     220    /**
     221     * @group bp_core_get_user_displaynames
     222     */
     223    public function test_bp_core_get_user_displaynames_all_uncached() {
     224        $u1 = $this->create_user();
     225        $u2 = $this->create_user();
     226
     227        xprofile_set_field_data( 1, $u1, 'Foo' );
     228        xprofile_set_field_data( 1, $u2, 'Bar' );
     229
     230        $expected = array(
     231            $u1 => 'Foo',
     232            $u2 => 'Bar',
     233        );
     234
     235        $this->assertSame( $expected, bp_core_get_user_displaynames( array( $u1, $u2, ) ) );
     236    }
     237
     238    /**
     239     * @group bp_core_get_user_displaynames
     240     */
     241    public function test_bp_core_get_user_displaynames_one_not_in_xprofile() {
     242        $u1 = $this->create_user();
     243        $u2 = $this->create_user( array(
     244            'display_name' => 'Bar',
     245        ) );
     246
     247        xprofile_set_field_data( 1, $u1, 'Foo' );
     248
     249        // Delete directly because BP won't let you delete a required
     250        // field through the API
     251        global $wpdb, $bp;
     252        $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->profile->table_name_data} WHERE user_id = %d AND field_id = 1", $u2 ) );
     253        wp_cache_delete( 'bp_user_fullname_' . $u2, 'bp' );
     254        wp_cache_delete( 1, 'bp_xprofile_data_' . $u2, 'bp' );
     255
     256        $expected = array(
     257            $u1 => 'Foo',
     258            $u2 => 'Bar',
     259        );
     260
     261        $this->assertSame( $expected, bp_core_get_user_displaynames( array( $u1, $u2, ) ) );
     262    }
     263
     264    /**
     265     * @group bp_core_get_user_displaynames
     266     */
     267    public function test_bp_core_get_user_displaynames_one_in_cache() {
     268        $u1 = $this->create_user();
     269        xprofile_set_field_data( 1, $u1, 'Foo' );
     270
     271        // Fake the cache for $u2
     272        $u2 = 123;
     273        wp_cache_set( 'bp_user_fullname_' . $u2, 'Bar', 'bp' );
     274
     275        $expected = array(
     276            $u1 => 'Foo',
     277            $u2 => 'Bar',
     278        );
     279
     280        $this->assertSame( $expected, bp_core_get_user_displaynames( array( $u1, $u2, ) ) );
     281    }
    212282}
Note: See TracChangeset for help on using the changeset viewer.