Skip to:
Content

BuddyPress.org

Changeset 11124


Ignore:
Timestamp:
09/20/2016 02:42:15 PM (5 years ago)
Author:
dcavins
Message:

Use new function BP_Friends_Friendships::get_friendships().

Take advantage of the caching introduced
in BP_Friends_Friendships::get_friendships()
by using get_friendships() as the underlying function in
get_friend_user_ids(), get_friendship_id(), total_friend_count(),
check_is_friend(),
and delete_all_for_user().

Props dcavins, boonebgorges.

Fixes #6978.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-friends/bp-friends-filters.php

    r10417 r11124  
    2929
    3030    // Stop if user isn't logged in.
    31     if ( ! is_user_logged_in() ) {
     31    if ( ! $user_id = bp_loggedin_user_id() ) {
    3232        return;
    3333    }
    3434
    35     $bp = buddypress();
     35    $maybe_friend_ids = wp_parse_id_list( $user_ids_sql );
    3636
    37     // Fetch whether or not the user is a friend of the current user.
    38     $friend_status = $wpdb->get_results( $wpdb->prepare( "SELECT initiator_user_id, friend_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id IN ( {$user_ids_sql} ) ) OR (initiator_user_id IN ( {$user_ids_sql} ) AND friend_user_id = %d )", bp_loggedin_user_id(), bp_loggedin_user_id() ) );
    39 
    40     // Keep track of members that have a friendship status with the current user.
    41     $friend_user_ids = array();
    42 
    43     // The "friend" is the user ID in the pair who is *not* the logged in user.
    44     foreach ( (array) $friend_status as $fs ) {
    45         $friend_id = bp_loggedin_user_id() == $fs->initiator_user_id ? $fs->friend_user_id : $fs->initiator_user_id;
    46         $friend_user_ids[] = $friend_id;
    47 
    48         if ( isset( $user_query->results[ $friend_id ] ) ) {
    49             if ( 0 == $fs->is_confirmed ) {
    50                 $status = $fs->initiator_user_id == bp_loggedin_user_id() ? 'pending' : 'awaiting_response';
    51             } else {
    52                 $status = 'is_friend';
    53             }
    54 
    55             $user_query->results[ $friend_id ]->is_friend         = $fs->is_confirmed;
    56             $user_query->results[ $friend_id ]->friendship_status = $status;
    57         }
    58     }
    59 
    60     // The rest are not friends with the current user, so set status accordingly.
    61     $not_friends = array_diff( $user_query->user_ids, $friend_user_ids );
    62     foreach ( (array) $not_friends as $nf ) {
    63         if ( bp_loggedin_user_id() == $nf ) {
    64             continue;
    65         }
    66 
    67         if ( isset( $user_query->results[ $nf ] ) ) {
    68             $user_query->results[ $nf ]->friendship_status = 'not_friends';
     37    foreach ( $maybe_friend_ids as $friend_id ) {
     38        $status = BP_Friends_Friendship::check_is_friend( $user_id, $friend_id );
     39        $user_query->results[ $friend_id ]->friendship_status = $status;
     40        if ( 'is_friend' == $status ) {
     41            $user_query->results[ $friend_id ]->is_friend = 1;
    6942        }
    7043    }
  • trunk/src/bp-friends/classes/class-bp-friends-friendship.php

    r11123 r11124  
    390390        global $wpdb;
    391391
    392         if ( !empty( $friend_requests_only ) ) {
    393             $oc_sql = 'AND is_confirmed = 0';
    394             $friend_sql = $wpdb->prepare( " WHERE friend_user_id = %d", $user_id );
     392        if ( ! empty( $friend_requests_only ) ) {
     393            $args = array(
     394                'is_confirmed' => 0,
     395                'friend_user_id' => $user_id
     396            );
    395397        } else {
    396             $oc_sql = 'AND is_confirmed = 1';
    397             $friend_sql = $wpdb->prepare( " WHERE (initiator_user_id = %d OR friend_user_id = %d)", $user_id, $user_id );
    398         }
    399 
    400         $bp = buddypress();
    401         $friends = $wpdb->get_results( "SELECT friend_user_id, initiator_user_id FROM {$bp->friends->table_name} {$friend_sql} {$oc_sql} ORDER BY date_created DESC" );
     398            $args = array(
     399                'is_confirmed' => 1,
     400            );
     401        }
     402
     403        $friendships = self::get_friendships( $user_id, $args );
     404
    402405        $fids = array();
    403 
    404         for ( $i = 0, $count = count( $friends ); $i < $count; ++$i ) {
    405             if ( !empty( $assoc_arr ) ) {
    406                 $fids[] = array( 'user_id' => ( $friends[$i]->friend_user_id == $user_id ) ? $friends[$i]->initiator_user_id : $friends[$i]->friend_user_id );
     406        foreach ( $friendships as $friendship ) {
     407            if ( ! empty( $assoc_arr ) ) {
     408                $fids[] = array( 'user_id' => ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id );
    407409            } else {
    408                 $fids[] = ( $friends[$i]->friend_user_id == $user_id ) ? $friends[$i]->initiator_user_id : $friends[$i]->friend_user_id;
     410                $fids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id;
    409411            }
    410412        }
     
    423425     */
    424426    public static function get_friendship_id( $user_id, $friend_id ) {
    425         global $wpdb;
    426 
    427         $bp = buddypress();
    428 
    429         $query = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$bp->friends->table_name} WHERE ( initiator_user_id = %d AND friend_user_id = %d ) OR ( initiator_user_id = %d AND friend_user_id = %d ) AND is_confirmed = 1", $user_id, $friend_id, $friend_id, $user_id ) );
    430 
    431         return is_numeric( $query ) ? (int) $query : $query;
     427        $friendship_id = null;
     428
     429        // Can't friend yourself.
     430        if ( $user_id == $friend_id ) {
     431            return $friendship_id;
     432        }
     433
     434        /*
     435         * Find friendships where the possible_friend_userid is the
     436         * initiator or friend.
     437         */
     438        $args = array(
     439            'initiator_user_id' => $friend_id,
     440            'friend_user_id'    => $friend_id
     441        );
     442        $result = self::get_friendships( $user_id, $args, 'OR' );
     443        if ( $result ) {
     444            $friendship_id = current( $result )->id;
     445        }
     446        return $friendship_id;
    432447    }
    433448
     
    445460
    446461        if ( false === $friend_requests ) {
    447             global $wpdb;
    448 
    449             $bp = buddypress();
    450 
    451             $friend_requests = $wpdb->get_col( $wpdb->prepare( "SELECT initiator_user_id FROM {$bp->friends->table_name} WHERE friend_user_id = %d AND is_confirmed = 0", $user_id ) );
     462            $friend_requests = self::get_friend_user_ids( $user_id, true );
    452463
    453464            wp_cache_set( $user_id, $friend_requests, 'bp_friends_requests' );
     
    475486        global $wpdb;
    476487
    477         if ( empty( $user_id ) )
     488        if ( empty( $user_id ) ) {
    478489            $user_id = ( bp_displayed_user_id() ) ? bp_displayed_user_id() : bp_loggedin_user_id();
    479 
    480         $bp = buddypress();
     490        }
    481491
    482492        /*
     
    485495         */
    486496
    487         $count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(id) FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d OR friend_user_id = %d) AND is_confirmed = 1", $user_id, $user_id ) );
     497        $args = array(
     498            'is_confirmed' => 1,
     499        );
     500        $friendships = self::get_friendships( $user_id, $args );
     501        $count       = count( $friendships );
    488502
    489503        // Do not update meta if user has never had friends.
    490         if ( empty( $count ) && !bp_get_user_meta( $user_id, 'total_friend_count', true ) )
     504        if ( ! $count && ! bp_get_user_meta( $user_id, 'total_friend_count', true ) ) {
    491505            return 0;
     506        }
    492507
    493508        bp_update_user_meta( $user_id, 'total_friend_count', (int) $count );
     
    584599        }
    585600
    586         $bp = buddypress();
    587 
    588         $result = $wpdb->get_results( $wpdb->prepare( "SELECT id, initiator_user_id, is_confirmed FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d AND friend_user_id = %d) OR (initiator_user_id = %d AND friend_user_id = %d)", $initiator_userid, $possible_friend_userid, $possible_friend_userid, $initiator_userid ) );
    589 
    590         if ( ! empty( $result ) ) {
    591             if ( 0 == (int) $result[0]->is_confirmed ) {
    592                 $status = $initiator_userid == $result[0]->initiator_user_id ? 'pending' : 'awaiting_response';
     601        // Can't friend yourself.
     602        if ( $initiator_userid == $possible_friend_userid ) {
     603            return 'not_friends';
     604        }
     605
     606        /*
     607         * Find friendships where the possible_friend_userid is the
     608         * initiator or friend.
     609         */
     610        $args = array(
     611            'initiator_user_id' => $possible_friend_userid,
     612            'friend_user_id'    => $possible_friend_userid
     613        );
     614        $result = self::get_friendships( $initiator_userid, $args, 'OR' );
     615
     616        if ( $result ) {
     617            $friendship = current( $result );
     618            if ( ! $friendship->is_confirmed ) {
     619                $status = $initiator_userid == $friendship->initiator_user_id ? 'pending' : 'awaiting_response';
    593620            } else {
    594621                $status = 'is_friend';
     
    919946        $bp = buddypress();
    920947
    921         // Get friends of $user_id.
    922         $friend_ids = BP_Friends_Friendship::get_friend_user_ids( $user_id );
    923 
    924         // Delete all friendships related to $user_id.
    925         $wpdb->query( $wpdb->prepare( "DELETE FROM {$bp->friends->table_name} WHERE friend_user_id = %d OR initiator_user_id = %d", $user_id, $user_id ) );
     948        // Get all friendships, of any status, for the user.
     949        $friendships    = self::get_friendships( $user_id );
     950        $friend_ids     = array();
     951        $friendship_ids = array();
     952        foreach ( $friendships as $friendship ) {
     953            $friendship_ids[] = $friendship->id;
     954            if ( $friendship->is_confirmed ) {
     955                $friend_ids[] = ( $friendship->friend_user_id == $user_id ) ? $friendship->initiator_user_id : $friendship->friend_user_id;
     956            }
     957        }
     958
     959        // Delete the friendships from the database.
     960        if ( $friendship_ids ) {
     961            $friendship_ids_sql = implode( ',', wp_parse_id_list( $friendship_ids ) );
     962            $wpdb->query( "DELETE FROM {$bp->friends->table_name} WHERE id IN ({$friendship_ids_sql})" );
     963        }
    926964
    927965        // Delete friend request notifications for members who have a
     
    931969        }
    932970
    933         // Loop through friend_ids and update their counts.
     971        // Clean up the friendships cache.
     972        foreach ( $friendship_ids as $friendship_id ) {
     973            wp_cache_delete( $friendship_id, 'bp_friends_friendships' );
     974        }
     975
     976        // Loop through friend_ids to scrub user caches and update total count metas.
    934977        foreach ( (array) $friend_ids as $friend_id ) {
     978            // Delete cached friendships.
     979            wp_cache_delete( $friend_id, 'bp_friends_friendships_for_user' );
    935980            BP_Friends_Friendship::total_friend_count( $friend_id );
    936981        }
     982
     983        // Delete cached friendships.
     984        wp_cache_delete( $user_id, 'bp_friends_friendships_for_user' );
    937985    }
    938986}
  • trunk/tests/phpunit/testcases/friends/functions.php

    r9819 r11124  
    268268        return $value;
    269269    }
     270
     271    /**
     272     * @group friendship_caching
     273     */
     274    public function test_friends_check_friendship_should_hit_user_cache() {
     275        global $wpdb;
     276        $now = time();
     277        $u1 = $this->factory->user->create( array(
     278            'last_activity' => date( 'Y-m-d H:i:s', $now ),
     279        ) );
     280        $u2 = $this->factory->user->create( array(
     281            'last_activity' => date( 'Y-m-d H:i:s', $now - 100 ),
     282        ) );
     283        $u3 = $this->factory->user->create( array(
     284            'last_activity' => date( 'Y-m-d H:i:s', $now - 200 ),
     285        ) );
     286
     287        friends_add_friend( $u1, $u2, true );
     288        friends_add_friend( $u1, $u3, false );
     289
     290        friends_check_friendship_status( $u1, $u2 );
     291        $first_query_count = $wpdb->num_queries;
     292
     293        friends_check_friendship_status( $u1, $u3 );
     294
     295        $this->assertEquals( $first_query_count, $wpdb->num_queries );
     296    }
     297
     298    /**
     299     * @group friendship_caching
     300     */
     301    public function test_friends_check_friendship_should_hit_friendship_object_cache() {
     302        global $wpdb;
     303        $now = time();
     304        $u1 = $this->factory->user->create( array(
     305            'last_activity' => date( 'Y-m-d H:i:s', $now ),
     306        ) );
     307        $u2 = $this->factory->user->create( array(
     308            'last_activity' => date( 'Y-m-d H:i:s', $now - 100 ),
     309        ) );
     310
     311        friends_add_friend( $u1, $u2, true );
     312
     313        friends_check_friendship_status( $u1, $u2 );
     314        $first_query_count = $wpdb->num_queries;
     315
     316        /*
     317         * We expect this to generate one query to find $u2's friendships,
     318         * but the friendship object itself should come from cache.
     319         */
     320        friends_check_friendship_status( $u2, $u1 );
     321
     322        $this->assertEquals( $first_query_count + 1, $wpdb->num_queries );
     323    }
    270324}
Note: See TracChangeset for help on using the changeset viewer.