Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
05/21/2016 02:16:38 AM (10 years ago)
Author:
boonebgorges
Message:

Introduce caching for group memberships.

The new system works like this: The bp_groups_memberships_for_user cache
group stores arrays of membership IDs for individual users. The
bp_groups_memberships cache group stores data about individual memberships.
The new function bp_get_user_groups() populates a user's group memberships
from these caches, and filters them as requested in the function parameters.
Then, the various groups_is_user_*() functions use bp_get_user_groups()
instead of direct, uncached database queries to fetch their data.

In addition, the get_group_extras() method of BP_Groups_Group can now be
greatly simplified, since all necessary pre-fetching of current-user group
memberships happens via the bp_get_user_groups() cache.

Props boonebgorges, dcavins.
See #6327.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-groups/bp-groups-functions.php

    r10767 r10794  
    792792
    793793/**
     794 * Get a list of groups of which the specified user is a member.
     795 *
     796 * @since 2.6.0
     797 *
     798 * @param int $user_id ID of the user.
     799 * @param array $args {
     800 *     Array of optional args.
     801 *     @param bool|null   $is_confirmed Whether to return only confirmed memberships. Pass `null` to disable this
     802 *                                      filter. Default: true.
     803 *     @param bool|null   $is_banned    Whether to return only banned memberships. Pass `null` to disable this filter.
     804 *                                      Default: false.
     805 *     @param bool|null   $is_admin     Whether to return only admin memberships. Pass `null` to disable this filter.
     806 *                                      Default: false.
     807 *     @param bool|null   $is_mod       Whether to return only mod memberships. Pass `null` to disable this filter.
     808 *                                      Default: false.
     809 *     @param bool|null   $invite_sent  Whether to return only memberships with 'invite_sent'. Pass `null` to disable
     810 *                                      this filter. Default: false.
     811 *     @param string      $orderby      Field to order by. Accepts 'id' (membership ID), 'group_id', 'date_modified'.
     812 *                                      Default: 'group_id'.
     813 *     @param string      $order        Sort order. Accepts 'ASC' or 'DESC'. Default: 'ASC'.
     814 * }
     815 * @return array Array of matching group memberships, keyed by group ID.
     816 */
     817function bp_get_user_groups( $user_id, $args = array() ) {
     818    $r = bp_parse_args( $args, array(
     819        'is_confirmed' => true,
     820        'is_banned'    => false,
     821        'is_admin'     => false,
     822        'is_mod'       => false,
     823        'invite_sent'  => null,
     824        'orderby'      => 'group_id',
     825        'order'        => 'ASC',
     826    ), 'get_user_groups' );
     827
     828    $user_id = intval( $user_id );
     829
     830    $membership_ids = wp_cache_get( $user_id, 'bp_groups_memberships_for_user' );
     831    if ( false === $membership_ids ) {
     832        $membership_ids = BP_Groups_Member::get_membership_ids_for_user( $user_id );
     833        wp_cache_set( $user_id, $membership_ids, 'bp_groups_memberships_for_user' );
     834    }
     835
     836    // Prime the membership cache.
     837    $uncached_membership_ids = bp_get_non_cached_ids( $membership_ids, 'bp_groups_memberships' );
     838    if ( ! empty( $uncached_membership_ids ) ) {
     839        $uncached_memberships = BP_Groups_Member::get_memberships_by_id( $uncached_membership_ids );
     840
     841        foreach ( $uncached_memberships as $uncached_membership ) {
     842            wp_cache_set( $uncached_membership->id, $uncached_membership, 'bp_groups_memberships' );
     843        }
     844    }
     845
     846    // Populate group membership array from cache.
     847    $groups = array();
     848    foreach ( $membership_ids as $membership_id ) {
     849        $membership = wp_cache_get( $membership_id, 'bp_groups_memberships' );
     850
     851        // Sanity check.
     852        if ( ! isset( $membership->group_id ) ) {
     853            continue;
     854        }
     855
     856        $group_id = (int) $membership->group_id;
     857
     858        $groups[ $group_id ] = $membership;
     859    }
     860
     861    // Normalize group data.
     862    foreach ( $groups as &$group ) {
     863        // Integer values.
     864        foreach ( array( 'id', 'group_id', 'user_id', 'inviter_id' ) as $index ) {
     865            $group->{$index} = intval( $group->{$index} );
     866        }
     867
     868        // Boolean values.
     869        foreach ( array( 'is_admin', 'is_mod', 'is_confirmed', 'is_banned', 'invite_sent' ) as $index ) {
     870            $group->{$index} = (bool) $group->{$index};
     871        }
     872    }
     873
     874    // Assemble filter array for use in `wp_list_filter()`.
     875    $filters = wp_array_slice_assoc( $r, array( 'is_confirmed', 'is_banned', 'is_admin', 'is_mod', 'invite_sent' ) );
     876    foreach ( $filters as $filter_name => $filter_value ) {
     877        if ( is_null( $filter_value ) ) {
     878            unset( $filters[ $filter_name ] );
     879        }
     880    }
     881
     882    if ( ! empty( $filters ) ) {
     883        $groups = wp_list_filter( $groups, $filters );
     884    }
     885
     886    // By default, results are ordered by membership id.
     887    if ( 'group_id' === $r['orderby'] ) {
     888        ksort( $groups );
     889    } elseif ( in_array( $r['orderby'], array( 'id', 'date_modified' ) ) ) {
     890        $groups = bp_sort_by_key( $groups, $r['orderby'] );
     891    }
     892
     893    // By default, results are ordered ASC.
     894    if ( 'DESC' === strtoupper( $r['order'] ) ) {
     895        // `true` to preserve keys.
     896        $groups = array_reverse( $groups, true );
     897    }
     898
     899    return $groups;
     900}
     901
     902/**
    794903 * Get the count of groups of which the specified user is a member.
    795904 *
     
    890999 */
    8911000function groups_is_user_admin( $user_id, $group_id ) {
    892     return BP_Groups_Member::check_is_admin( $user_id, $group_id );
     1001    $is_admin = false;
     1002
     1003    $user_groups = bp_get_user_groups( $user_id, array(
     1004        'is_admin' => true,
     1005    ) );
     1006
     1007    if ( isset( $user_groups[ $group_id ] ) ) {
     1008        $is_admin = $user_groups[ $group_id ]->id;
     1009    }
     1010
     1011    return $is_admin;
    8931012}
    8941013
     
    9031022 */
    9041023function groups_is_user_mod( $user_id, $group_id ) {
    905     return BP_Groups_Member::check_is_mod( $user_id, $group_id );
     1024    $is_mod = false;
     1025
     1026    $user_groups = bp_get_user_groups( $user_id, array(
     1027        'is_mod' => true,
     1028    ) );
     1029
     1030    if ( isset( $user_groups[ $group_id ] ) ) {
     1031        $is_mod = $user_groups[ $group_id ]->id;
     1032    }
     1033
     1034    return $is_mod;
    9061035}
    9071036
     
    9161045 */
    9171046function groups_is_user_member( $user_id, $group_id ) {
    918     return BP_Groups_Member::check_is_member( $user_id, $group_id );
     1047    $is_member = false;
     1048
     1049    $user_groups = bp_get_user_groups( $user_id, array(
     1050        'is_admin' => null,
     1051        'is_mod' => null,
     1052    ) );
     1053
     1054    if ( isset( $user_groups[ $group_id ] ) ) {
     1055        $is_member = $user_groups[ $group_id ]->id;
     1056    }
     1057
     1058    return $is_member;
    9191059}
    9201060
     
    9301070 */
    9311071function groups_is_user_banned( $user_id, $group_id ) {
    932     return BP_Groups_Member::check_is_banned( $user_id, $group_id );
     1072    $is_banned = false;
     1073
     1074    $user_groups = bp_get_user_groups( $user_id, array(
     1075        'is_confirmed' => null,
     1076        'is_banned' => true,
     1077    ) );
     1078
     1079    if ( isset( $user_groups[ $group_id ] ) ) {
     1080        $is_banned = $user_groups[ $group_id ]->id;
     1081    }
     1082
     1083    return $is_banned;
     1084}
     1085
     1086/**
     1087 * Check whether a user has an outstanding invitation to a group.
     1088 *
     1089 * @since 2.6.0
     1090 *
     1091 * @param int $user_id ID of the user.
     1092 * @param int $group_id ID of the group.
     1093 * @return int|null ID of the membership if found.
     1094 */
     1095function groups_is_user_invited( $user_id, $group_id ) {
     1096    $is_invited = false;
     1097
     1098    $user_groups = bp_get_user_groups( $user_id, array(
     1099        'invite_sent' => true,
     1100        'is_confirmed' => false,
     1101    ) );
     1102
     1103    if ( isset( $user_groups[ $group_id ] ) ) {
     1104        $is_invited = $user_groups[ $group_id ]->id;
     1105    }
     1106
     1107    return $is_invited;
     1108}
     1109
     1110/**
     1111 * Check whether a user has a pending membership request for a group.
     1112 *
     1113 * @since 2.6.0
     1114 *
     1115 * @param int $user_id ID of the user.
     1116 * @param int $group_id ID of the group.
     1117 * @return int|null ID of the membership if found.
     1118 */
     1119function groups_is_user_pending( $user_id, $group_id ) {
     1120    $is_pending = false;
     1121
     1122    $user_groups = bp_get_user_groups( $user_id, array(
     1123        'invite_sent' => false,
     1124        'is_confirmed' => false,
     1125    ) );
     1126
     1127    if ( isset( $user_groups[ $group_id ] ) ) {
     1128        $is_pending = $user_groups[ $group_id ]->id;
     1129    }
     1130
     1131    return $is_pending;
    9331132}
    9341133
Note: See TracChangeset for help on using the changeset viewer.