Skip to:
Content

BuddyPress.org


Ignore:
Timestamp:
09/13/2016 04:05:07 AM (10 years ago)
Author:
boonebgorges
Message:

Groups: Improve query efficiency for 'admins' and 'mods' properties of group objects.

Previously, the 'admins' and 'mods' property of BP_Groups_Group
objects were only populated when setting the 'populate_extras' flag.
Even then, the query used to populate these properties was uncached,
and required a join against a global table.

This changeset reworks the way that the 'admins' and 'mods' properties
are accessed and set. The properties are now marked protected, and
are accessible by magic __get(). When requested, the cache for the
both properties is set by a single pair of queries: one to fetch
membership data from the BP table, and one to get user objects from
WordPress. The BP table query is cached, and neither query takes place
if the property is never accessed.

This moves us a step closer to eliminating the populate_extras flag
on BP_Groups_Group objects.

See #5451.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bp-groups/classes/class-bp-groups-group.php

    r11086 r11087  
    9090     * @var array
    9191     */
    92     public $admins;
     92    protected $admins;
    9393
    9494    /**
     
    9898     * @var array
    9999     */
    100     public $mods;
     100    protected $mods;
    101101
    102102    /**
     
    220220        // Are we getting extra group data?
    221221        if ( ! empty( $this->args['populate_extras'] ) ) {
    222 
    223             /**
    224              * Filters the SQL prepared statement used to fetch group admins and mods.
    225              *
    226              * @since 1.5.0
    227              *
    228              * @param string $value SQL select statement used to fetch admins and mods.
    229              */
    230             $admin_mods = $wpdb->get_results( apply_filters( 'bp_group_admin_mods_user_join_filter', $wpdb->prepare( "SELECT u.ID as user_id, u.user_login, u.user_email, u.user_nicename, m.is_admin, m.is_mod FROM {$wpdb->users} u, {$bp->groups->table_name_members} m WHERE u.ID = m.user_id AND m.group_id = %d AND ( m.is_admin = 1 OR m.is_mod = 1 )", $this->id ) ) );
    231 
    232             // Add admins and moderators to their respective arrays.
    233             foreach ( (array) $admin_mods as $user ) {
    234                 $user->user_id  = (int) $user->user_id;
    235                 $user->is_admin = (int) $user->is_admin;
    236                 $user->is_mod   = (int) $user->is_mod;
    237 
    238                 if ( !empty( $user->is_admin ) ) {
    239                     $this->admins[] = $user;
    240                 } else {
    241                     $this->mods[] = $user;
    242                 }
    243             }
    244222
    245223            // Set user-specific data.
     
    441419                return (int) groups_get_groupmeta( $this->id, 'total_member_count' );
    442420
     421            case 'admins' :
     422                return $this->get_admins();
     423
     424            case 'mods' :
     425                return $this->get_mods();
     426
    443427            default :
    444428            break;
     
    466450                return false;
    467451        }
     452    }
     453
     454    /**
     455     * Get a list of the group's admins.
     456     *
     457     * Used to provide cache-friendly access to the 'admins' property of
     458     * the group object.
     459     *
     460     * @since 2.7.0
     461     *
     462     * @return array
     463     */
     464    protected function get_admins() {
     465        if ( isset( $this->admins ) ) {
     466            return $this->admins;
     467        }
     468
     469        $this->set_up_admins_and_mods();
     470        return $this->admins;
     471    }
     472
     473    /**
     474     * Get a list of the group's mods.
     475     *
     476     * Used to provide cache-friendly access to the 'mods' property of
     477     * the group object.
     478     *
     479     * @since 2.7.0
     480     *
     481     * @return array
     482     */
     483    protected function get_mods() {
     484        if ( isset( $this->mods ) ) {
     485            return $this->mods;
     486        }
     487
     488        $this->set_up_admins_and_mods();
     489        return $this->mods;
     490    }
     491
     492    /**
     493     * Set up admins and mods for the current group object.
     494     *
     495     * Called only when the 'admins' or 'mods' property is accessed.
     496     *
     497     * @since 2.7.0
     498     */
     499    protected function set_up_admins_and_mods() {
     500        $admin_ids = BP_Groups_Member::get_group_administrator_ids( $this->id );
     501        $admin_ids_plucked = wp_list_pluck( $admin_ids, 'user_id' );
     502
     503        $mod_ids = BP_Groups_Member::get_group_moderator_ids( $this->id );
     504        $mod_ids_plucked = wp_list_pluck( $mod_ids, 'user_id' );
     505
     506        $admin_mod_users = get_users( array(
     507            'include' => array_merge( $admin_ids_plucked, $mod_ids_plucked ),
     508        ) );
     509
     510        $admin_objects = $mod_objects = array();
     511        foreach ( $admin_mod_users as $admin_mod_user ) {
     512            $obj = new stdClass();
     513            $obj->user_id = $admin_mod_user->ID;
     514            $obj->user_login = $admin_mod_user->user_login;
     515            $obj->user_email = $admin_mod_user->user_email;
     516            $obj->user_nicename = $admin_mod_user->user_nicename;
     517
     518            if ( in_array( $admin_mod_user->ID, $admin_ids_plucked, true ) ) {
     519                $obj->is_admin = 1;
     520                $obj->is_mod = 0;
     521                $admin_objects[] = $obj;
     522            } else {
     523                $obj->is_admin = 0;
     524                $obj->is_mod = 1;
     525                $mod_objects[] = $obj;
     526            }
     527        }
     528
     529        $this->admins = $admin_objects;
     530        $this->mods   = $mod_objects;
    468531    }
    469532
     
    10301093        // Prefetch all administrator IDs, if requested.
    10311094        if ( $r['update_admin_cache'] ) {
    1032             BP_Groups_Member::prime_group_administrator_ids_cache( $group_ids );
     1095            BP_Groups_Member::prime_group_admins_mods_cache( $group_ids );
    10331096        }
    10341097
Note: See TracChangeset for help on using the changeset viewer.