Skip to:
Content

BuddyPress.org

Changeset 11123


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

Introduce BP_Friends_Friendships::get_friendships().

Introduce a new function, BP_Friends_Friendships::get_friendships(),
for fetching and filtering friendships for a
specific user. Also add a new cache group,
bp_friends_friendships_for_user that
get_friendships() interacts with.

This is the second step in moving toward a
split cache approach for friendships.

Props dcavins, boonebgorges.

See #6978.

Location:
trunk/src/bp-friends
Files:
3 edited

Legend:

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

    r11122 r11123  
    4646 */
    4747function bp_friends_clear_bp_friends_friendships_cache( $friendship_id, $initiator_user_id, $friend_user_id ) {
     48    // Clear friendship ID cache for each user.
     49    wp_cache_delete( $initiator_user_id, 'bp_friends_friendships_for_user' );
     50    wp_cache_delete( $friend_user_id,    'bp_friends_friendships_for_user' );
     51
    4852    // Clear the friendship object cache.
    4953    wp_cache_delete( $friendship_id, 'bp_friends_friendships' );
     
    6266 */
    6367function bp_friends_clear_bp_friends_friendships_cache_remove( $friendship_id, BP_Friends_Friendship $friendship ) {
     68    // Clear friendship ID cache for each user.
     69    wp_cache_delete( $friendship->initiator_user_id, 'bp_friends_friendships_for_user' );
     70    wp_cache_delete( $friendship->friend_user_id,    'bp_friends_friendships_for_user' );
     71
    6472    // Clear the friendship object cache.
    6573    wp_cache_delete( $friendship_id, 'bp_friends_friendships' );
  • trunk/src/bp-friends/classes/class-bp-friends-component.php

    r11122 r11123  
    291291            'bp_friends_requests',
    292292            'bp_friends_friendships', // Individual friendship objects are cached here by ID.
     293            'bp_friends_friendships_for_user' // All friendship IDs for a single user.
    293294        ) );
    294295
  • trunk/src/bp-friends/classes/class-bp-friends-friendship.php

    r11122 r11123  
    219219
    220220    /** Static Methods ********************************************************/
     221
     222    /**
     223     * Get the friendships for a given user.
     224     *
     225     * @since 2.6.0
     226     *
     227     * @param int   $user_id              ID of the user whose friends are being retrieved.
     228     * @param array $args {
     229     *        Optional. Filter parameters.
     230     *        @type int    $id                ID of specific friendship to retrieve.
     231     *        @type int    $initiator_user_id ID of friendship initiator.
     232     *        @type int    $friend_user_id    ID of specific friendship to retrieve.
     233     *        @type int    $is_confirmed      Whether the friendship has been accepted.
     234     *        @type int    $is_limited        Whether the friendship is limited.
     235     *        @type string $order_by          Column name to order by.
     236     *        @type string $sort_order        ASC or DESC. Default DESC.
     237     * }
     238     * @param string $operator            Optional. Operator to use in `wp_list_filter()`.
     239     *
     240     * @return array $friendships Array of friendship objects.
     241     */
     242    public static function get_friendships( $user_id, $args = array(), $operator = 'AND' ) {
     243
     244        if ( empty( $user_id ) ) {
     245            $user_id = bp_loggedin_user_id();
     246        }
     247
     248        $r = bp_parse_args( $args, array(
     249            'id'                => null,
     250            'initiator_user_id' => null,
     251            'friend_user_id'    => null,
     252            'is_confirmed'      => null,
     253            'is_limited'        => null,
     254            'order_by'          => 'date_created',
     255            'sort_order'        => 'DESC',
     256            'page'              => null,
     257            'per_page'          => null
     258        ), 'bp_get_user_friendships' );
     259
     260        // First, we get all friendships that involve the user.
     261        $friendship_ids = wp_cache_get( $user_id, 'bp_friends_friendships_for_user' );
     262        if ( false === $friendship_ids ) {
     263            $friendship_ids = self::get_friendship_ids_for_user( $user_id );
     264            wp_cache_set( $user_id, $friendship_ids, 'bp_friends_friendships_for_user' );
     265        }
     266
     267        // Prime the membership cache.
     268        $uncached_friendship_ids = bp_get_non_cached_ids( $friendship_ids, 'bp_friends_friendships' );
     269        if ( ! empty( $uncached_friendship_ids ) ) {
     270            $uncached_friendships = self::get_friendships_by_id( $uncached_friendship_ids );
     271
     272            foreach ( $uncached_friendships as $uncached_friendship ) {
     273                wp_cache_set( $uncached_friendship->id, $uncached_friendship, 'bp_friends_friendships' );
     274            }
     275        }
     276
     277        // Assemble filter array.
     278        $filters = wp_array_slice_assoc( $r, array( 'id', 'initiator_user_id', 'friend_user_id', 'is_confirmed', 'is_limited' ) );
     279        foreach ( $filters as $filter_name => $filter_value ) {
     280            if ( is_null( $filter_value ) ) {
     281                unset( $filters[ $filter_name ] );
     282            }
     283        }
     284
     285        // Populate friendship array from cache, and normalize.
     286        $friendships = array();
     287        $int_keys    = array( 'id', 'initiator_user_id', 'friend_user_id' );
     288        $bool_keys   = array( 'is_confirmed', 'is_limited' );
     289        foreach ( $friendship_ids as $friendship_id ) {
     290            // Create a limited BP_Friends_Friendship object (don't fetch the user details).
     291            $friendship = new BP_Friends_Friendship( $friendship_id, false, false );
     292
     293            // Sanity check.
     294            if ( ! isset( $friendship->id ) ) {
     295                continue;
     296            }
     297
     298            // Integer values.
     299            foreach ( $int_keys as $index ) {
     300                $friendship->{$index} = intval( $friendship->{$index} );
     301            }
     302
     303            // Boolean values.
     304            foreach ( $bool_keys as $index ) {
     305                $friendship->{$index} = (bool) $friendship->{$index};
     306            }
     307
     308            // We need to support the same operators as wp_list_filter().
     309            if ( 'OR' == $operator || 'NOT' == $operator ) {
     310                $matched = 0;
     311
     312                foreach ( $filters as $filter_name => $filter_value ) {
     313                    if ( isset( $friendship->{$filter_name} ) && $filter_value == $friendship->{$filter_name} ) {
     314                        $matched++;
     315                    }
     316                }
     317
     318                if ( ( 'OR' == $operator && $matched > 0 )
     319                  || ( 'NOT' == $operator && 0 == $matched ) ) {
     320                    $friendships[ $friendship->id ] = $friendship;
     321                }
     322
     323            } else {
     324                /*
     325                 * This is the more typical 'AND' style of filter.
     326                 * If any of the filters miss, we move on.
     327                 */
     328                foreach ( $filters as $filter_name => $filter_value ) {
     329                    if ( ! isset( $friendship->{$filter_name} ) || $filter_value != $friendship->{$filter_name} ) {
     330                        continue 2;
     331                    }
     332                }
     333                $friendships[ $friendship->id ] = $friendship;
     334            }
     335
     336        }
     337
     338        // Sort the results on a column name.
     339        if ( in_array( $r['order_by'], array( 'id', 'initiator_user_id', 'friend_user_id' ) ) ) {
     340            $friendships = bp_sort_by_key( $friendships, $r['order_by'], 'num', true );
     341        }
     342
     343        // Adjust the sort direction of the results.
     344        if ( 'ASC' === strtoupper( $r['sort_order'] ) ) {
     345            // `true` to preserve keys.
     346            $friendships = array_reverse( $friendships, true );
     347        }
     348
     349        // Paginate the results.
     350        if ( $r['per_page'] && $r['page'] ) {
     351            $start       = ( $r['page'] - 1 ) * ( $r['per_page'] );
     352            $friendships = array_slice( $friendships, $start, $r['per_page'] );
     353        }
     354
     355        return $friendships;
     356    }
     357
     358    /**
     359     * Get all friendship IDs for a user.
     360     *
     361     * @since 2.7.0
     362     *
     363     * @param int $user_id ID of the user.
     364     * @return array
     365     */
     366    public static function get_friendship_ids_for_user( $user_id ) {
     367        global $wpdb;
     368
     369        $bp = buddypress();
     370
     371        $friendship_ids = $wpdb->get_col( $wpdb->prepare( "SELECT id FROM {$bp->friends->table_name} WHERE (initiator_user_id = %d OR friend_user_id = %d) ORDER BY date_created DESC", $user_id, $user_id ) );
     372
     373        return $friendship_ids;
     374    }
    221375
    222376    /**
     
    714868
    715869    /**
     870     * Get friendship objects by ID (or an array of IDs).
     871     *
     872     * @since 2.7.0
     873     *
     874     * @param int|string|array $friendship_ids Single friendship ID or comma-separated/array list of friendship IDs.
     875     * @return array
     876     */
     877    public static function get_friendships_by_id( $friendship_ids ) {
     878        global $wpdb;
     879
     880        $bp = buddypress();
     881
     882        $friendship_ids = implode( ',', wp_parse_id_list( $friendship_ids ) );
     883        return $wpdb->get_results( "SELECT * FROM {$bp->friends->table_name} WHERE id IN ({$friendship_ids})" );
     884    }
     885
     886    /**
    716887     * Get the friend user IDs for a given friendship.
    717888     *
Note: See TracChangeset for help on using the changeset viewer.