Ejemplo n.º 1
0
/**
 * Pre-fetch member type data when initializing a Members loop.
 *
 * @since BuddyPress (2.2.0)
 *
 * @param BP_User_Query $bp_user_query BP_User_Query object.
 */
function bp_members_prefetch_member_type( BP_User_Query $bp_user_query ) {
	$uncached_member_ids = bp_get_non_cached_ids( $bp_user_query->user_ids, 'bp_member_type' );

	$member_types = bp_get_object_terms( $uncached_member_ids, 'bp_member_type', array(
		'fields' => 'all_with_object_id',
	) );

	// Rekey by user ID.
	$keyed_member_types = array();
	foreach ( $member_types as $member_type ) {
		if ( ! isset( $keyed_member_types[ $member_type->object_id ] ) ) {
			$keyed_member_types[ $member_type->object_id ] = array();
		}

		$keyed_member_types[ $member_type->object_id ][] = $member_type->name;
	}

	$cached_member_ids = array();
	foreach ( $keyed_member_types as $user_id => $user_member_types ) {
		wp_cache_set( $user_id, $user_member_types, 'bp_member_type' );
		$cached_member_ids[] = $user_id;
	}

	// Cache an empty value for users with no type.
	foreach ( array_diff( $uncached_member_ids, $cached_member_ids ) as $no_type_id ) {
		wp_cache_set( $no_type_id, '', 'bp_member_type' );
	}
}
 /**
  * Get a user's profile data for a set of fields.
  *
  * @param int $user_id
  * @param array $field_ids
  * @return array
  */
 public static function get_data_for_user($user_id, $field_ids)
 {
     global $wpdb;
     $data = array();
     $cache_group = 'bp_xprofile_data_' . $user_id;
     $uncached_field_ids = bp_get_non_cached_ids($field_ids, $cache_group);
     // Prime the cache
     if (!empty($uncached_field_ids)) {
         $bp = buddypress();
         $uncached_field_ids_sql = implode(',', wp_parse_id_list($uncached_field_ids));
         $uncached_data = $wpdb->get_results($wpdb->prepare("SELECT id, user_id, field_id, value, last_updated FROM {$bp->profile->table_name_data} WHERE field_id IN ({$uncached_field_ids_sql}) AND user_id = %d", $user_id));
         // Rekey
         $queried_data = array();
         foreach ($uncached_data as $ud) {
             $d = new stdClass();
             $d->id = $ud->id;
             $d->user_id = $ud->user_id;
             $d->field_id = $ud->field_id;
             $d->value = $ud->value;
             $d->last_updated = $ud->last_updated;
             $queried_data[$ud->field_id] = $d;
         }
         // Set caches
         foreach ($uncached_field_ids as $field_id) {
             // If a value was found, cache it
             if (isset($queried_data[$field_id])) {
                 wp_cache_set($field_id, $queried_data[$field_id], $cache_group);
                 // If no value was found, cache an empty item
                 // to avoid future cache misses
             } else {
                 $d = new stdClass();
                 $d->id = '';
                 $d->user_id = '';
                 $d->field_id = $field_id;
                 $d->value = '';
                 $d->last_updated = '';
                 wp_cache_set($field_id, $d, $cache_group);
             }
         }
     }
     // Now that all items are cached, fetch them
     foreach ($field_ids as $field_id) {
         $data[] = wp_cache_get($field_id, $cache_group);
     }
     return $data;
 }
Ejemplo n.º 3
0
 /**
  * Get last activity data for a user or set of users.
  *
  * @param int|array User IDs or multiple user IDs.
  * @return array
  */
 public static function get_last_activity($user_id)
 {
     global $wpdb;
     // Sanitize and remove empty values
     $user_ids = array_filter(wp_parse_id_list($user_id));
     if (empty($user_ids)) {
         return false;
     }
     $uncached_user_ids = bp_get_non_cached_ids($user_ids, 'bp_last_activity');
     if (!empty($uncached_user_ids)) {
         $bp = buddypress();
         $user_ids_sql = implode(',', $uncached_user_ids);
         $user_count = count($uncached_user_ids);
         $last_activities = $wpdb->get_results($wpdb->prepare("SELECT id, user_id, date_recorded FROM {$bp->members->table_name_last_activity} WHERE component = %s AND type = 'last_activity' AND user_id IN ({$user_ids_sql}) LIMIT {$user_count}", $bp->members->id));
         foreach ($last_activities as $last_activity) {
             wp_cache_set($last_activity->user_id, array('user_id' => $last_activity->user_id, 'date_recorded' => $last_activity->date_recorded, 'activity_id' => $last_activity->id), 'bp_last_activity');
         }
     }
     // Fetch all user data from the cache
     $retval = array();
     foreach ($user_ids as $user_id) {
         $retval[$user_id] = wp_cache_get($user_id, 'bp_last_activity');
     }
     return $retval;
 }
Ejemplo n.º 4
0
/**
 * Update the metadata cache for the specified objects.
 *
 * Based on WordPress's {@link update_meta_cache()}, this function primes the
 * cache with metadata related to a set of objects. This is typically done when
 * querying for a loop of objects; pre-fetching metadata for each queried
 * object can lead to dramatic performance improvements when using metadata
 * in the context of template loops.
 *
 * @since BuddyPress (1.6.0)
 *
 * @global object $wpdb WordPress database object for queries..
 *
 * @param array $args {
 *     Array of arguments.
 *     @type array|string $object_ids       List of object IDs to fetch metadata for.
 *                                          Accepts an array or a comma-separated list of numeric IDs.
 *     @type string       $object_type      The type of object, eg 'groups' or 'activity'.
 *     @type string       $meta_table       The name of the metadata table being queried.
 *     @type string       $object_column    Optional. The name of the database column where IDs
 *                                          (those provided by $object_ids) are found. Eg, 'group_id'
 *                                          for the groups metadata tables. Default: $object_type . '_id'.
 *     @type string       $cache_key_prefix Optional. The prefix to use when creating
 *                                          cache key names. Default: the value of $meta_table.
 * }
 *
 * @return array|bool Metadata cache for the specified objects, or false on failure.
 */
function bp_update_meta_cache($args = array())
{
    global $wpdb;
    $defaults = array('object_ids' => array(), 'object_type' => '', 'cache_group' => '', 'meta_table' => '', 'object_column' => '', 'cache_key_prefix' => '');
    $r = wp_parse_args($args, $defaults);
    extract($r);
    if (empty($object_ids) || empty($object_type) || empty($meta_table) || empty($cache_group)) {
        return false;
    }
    if (empty($cache_key_prefix)) {
        $cache_key_prefix = $meta_table;
    }
    if (empty($object_column)) {
        $object_column = $object_type . '_id';
    }
    if (!$cache_group) {
        return false;
    }
    $object_ids = wp_parse_id_list($object_ids);
    $uncached_ids = bp_get_non_cached_ids($object_ids, $cache_group);
    $cache = array();
    // Get meta info
    if (!empty($uncached_ids)) {
        $id_list = join(',', wp_parse_id_list($uncached_ids));
        $meta_list = $wpdb->get_results(esc_sql("SELECT {$object_column}, meta_key, meta_value FROM {$meta_table} WHERE {$object_column} IN ({$id_list})"), ARRAY_A);
        if (!empty($meta_list)) {
            foreach ($meta_list as $metarow) {
                $mpid = intval($metarow[$object_column]);
                $mkey = $metarow['meta_key'];
                $mval = $metarow['meta_value'];
                // Force subkeys to be array type:
                if (!isset($cache[$mpid]) || !is_array($cache[$mpid])) {
                    $cache[$mpid] = array();
                }
                if (!isset($cache[$mpid][$mkey]) || !is_array($cache[$mpid][$mkey])) {
                    $cache[$mpid][$mkey] = array();
                }
                // Add a value to the current pid/key:
                $cache[$mpid][$mkey][] = $mval;
            }
        }
        foreach ($uncached_ids as $uncached_id) {
            // Cache empty values as well
            if (!isset($cache[$uncached_id])) {
                $cache[$uncached_id] = array();
            }
            wp_cache_set($uncached_id, $cache[$uncached_id], $cache_group);
        }
    }
    return $cache;
}
Ejemplo n.º 5
0
/**
 * Slurp up xprofilemeta for a specified set of profile objects.
 *
 * We do not use bp_update_meta_cache() for the xprofile component. This is
 * because the xprofile component has three separate object types (group,
 * field, and data) and three corresponding cache groups. Using the technique
 * in bp_update_meta_cache(), pre-fetching would take three separate database
 * queries. By grouping them together, we can reduce the required queries to
 * one.
 *
 * This function is called within a bp_has_profile() loop.
 *
 * @since BuddyPress (2.0.0)
 *
 * @param array $object_ids Multi-dimensional array of object_ids, keyed by
 *        object type ('group', 'field', 'data')
 */
function bp_xprofile_update_meta_cache($object_ids = array())
{
    global $wpdb;
    // Bail if no objects
    if (empty($object_ids)) {
        return false;
    }
    $bp = buddypress();
    // Define the array where uncached object IDs will be stored
    $uncached_object_ids = array('group', 'field', 'data');
    // Define the cache groups for the 3 types of XProfile metadata
    $cache_groups = array('group' => 'xprofile_group_meta', 'field' => 'xprofile_field_meta', 'data' => 'xprofile_data_meta');
    // No reason to query yet
    $do_query = false;
    // Loop through object types and look for uncached data
    foreach ($uncached_object_ids as $object_type) {
        // Skip if empty object type
        if (empty($object_ids[$object_type])) {
            continue;
        }
        // Sanitize $object_ids passed to the function
        $object_type_ids = wp_parse_id_list($object_ids[$object_type]);
        // Get non-cached IDs for each object type
        $uncached_object_ids[$object_type] = bp_get_non_cached_ids($object_type_ids, $cache_groups[$object_type]);
        // Set the flag to do the meta query
        if (!empty($uncached_object_ids[$object_type]) && false === $do_query) {
            $do_query = true;
        }
    }
    // Bail if no uncached items
    if (false === $do_query) {
        return;
    }
    // Setup where conditions for query
    $where_sql = '';
    $where_conditions = array();
    // Loop through uncached objects and prepare to query for them
    foreach ($uncached_object_ids as $otype => $oids) {
        // Skip empty object IDs
        if (empty($oids)) {
            continue;
        }
        // Compile WHERE query conditions for uncached metadata
        $oids_sql = implode(',', wp_parse_id_list($oids));
        $where_conditions[] = $wpdb->prepare("( object_type = %s AND object_id IN ({$oids_sql}) )", $otype);
    }
    // Bail if no where conditions
    if (empty($where_conditions)) {
        return;
    }
    // Setup the WHERE query part
    $where_sql = implode(" OR ", $where_conditions);
    // Attempt to query meta values
    $meta_list = $wpdb->get_results("SELECT object_id, object_type, meta_key, meta_value FROM {$bp->profile->table_name_meta} WHERE {$where_sql}");
    // Bail if no results found
    if (empty($meta_list) || is_wp_error($meta_list)) {
        return;
    }
    // Setup empty cache array
    $cache = array();
    // Loop through metas
    foreach ($meta_list as $meta) {
        $oid = $meta->object_id;
        $otype = $meta->object_type;
        $okey = $meta->meta_key;
        $ovalue = $meta->meta_value;
        // Force subkeys to be array type
        if (!isset($cache[$otype][$oid]) || !is_array($cache[$otype][$oid])) {
            $cache[$otype][$oid] = array();
        }
        if (!isset($cache[$otype][$oid][$okey]) || !is_array($cache[$otype][$oid][$okey])) {
            $cache[$otype][$oid][$okey] = array();
        }
        // Add to the cache array
        $cache[$otype][$oid][$okey][] = maybe_unserialize($ovalue);
    }
    // Loop through data and cache to the appropriate object
    foreach ($cache as $object_type => $object_caches) {
        // Determine the cache group for this data
        $cache_group = $cache_groups[$object_type];
        // Loop through objects and cache appropriately
        foreach ($object_caches as $object_id => $object_cache) {
            wp_cache_set($object_id, $object_cache, $cache_group);
        }
    }
}
 /**
  * Convert activity IDs to activity objects, as expected in template loop.
  *
  * @since 2.0.0
  *
  * @param array $activity_ids Array of activity IDs.
  * @return array
  */
 protected static function get_activity_data($activity_ids = array())
 {
     global $wpdb;
     // Bail if no activity ID's passed.
     if (empty($activity_ids)) {
         return array();
     }
     // Get BuddyPress.
     $bp = buddypress();
     $activities = array();
     $uncached_ids = bp_get_non_cached_ids($activity_ids, 'bp_activity');
     // Prime caches as necessary.
     if (!empty($uncached_ids)) {
         // Format the activity ID's for use in the query below.
         $uncached_ids_sql = implode(',', wp_parse_id_list($uncached_ids));
         // Fetch data from activity table, preserving order.
         $queried_adata = $wpdb->get_results("SELECT * FROM {$bp->activity->table_name} WHERE id IN ({$uncached_ids_sql})");
         // Put that data into the placeholders created earlier,
         // and add it to the cache.
         foreach ((array) $queried_adata as $adata) {
             wp_cache_set($adata->id, $adata, 'bp_activity');
         }
     }
     // Now fetch data from the cache.
     foreach ($activity_ids as $activity_id) {
         $activities[] = wp_cache_get($activity_id, 'bp_activity');
     }
     // Then fetch user data.
     $user_query = new BP_User_Query(array('user_ids' => wp_list_pluck($activities, 'user_id'), 'populate_extras' => false));
     // Associated located user data with activity items.
     foreach ($activities as $a_index => $a_item) {
         $a_user_id = intval($a_item->user_id);
         $a_user = isset($user_query->results[$a_user_id]) ? $user_query->results[$a_user_id] : '';
         if (!empty($a_user)) {
             $activities[$a_index]->user_email = $a_user->user_email;
             $activities[$a_index]->user_nicename = $a_user->user_nicename;
             $activities[$a_index]->user_login = $a_user->user_login;
             $activities[$a_index]->display_name = $a_user->display_name;
         }
     }
     return $activities;
 }
 /**
  * Populates the BP_XProfile_Group object with profile field groups, fields,
  * and field data
  *
  * @package BuddyPress XProfile
  *
  * @global object $wpdb WordPress DB access object.
  *
  * @param array $args {
  *  Array of optional arguments:
  *      @type int          $profile_group_id  Limit results to a single profile group.
  *      @type int          $user_id           Required if you want to load a specific user's data.
  *                                            Default: displayed user's ID.
  *      @type array|string $member_type       Limit fields by those restricted to a given member type, or array of
  *                                            member types. If `$user_id` is provided, the value of `$member_type`
  *                                            will be overridden by the member types of the provided user. The
  *                                            special value of 'any' will return only those fields that are
  *                                            unrestricted by member type - i.e., those applicable to any type.
  *      @type bool         $hide_empty_groups True to hide groups that don't have any fields. Default: false.
  *      @type bool         $hide_empty_fields True to hide fields where the user has not provided data.
  *                                            Default: false.
  *      @type bool         $fetch_fields      Whether to fetch each group's fields. Default: false.
  *      @type bool         $fetch_field_data  Whether to fetch data for each field. Requires a $user_id.
  *                                            Default: false.
  *      @type array        $exclude_groups    Comma-separated list or array of group IDs to exclude.
  *      @type array        $exclude_fields    Comma-separated list or array of field IDs to exclude.
  *      @type bool         $update_meta_cache Whether to pre-fetch xprofilemeta for all retrieved groups, fields,
  *                                            and data. Default: true.
  * }
  * @return array $groups
  */
 public static function get($args = array())
 {
     global $wpdb;
     // Parse arguments.
     $r = wp_parse_args($args, array('profile_group_id' => false, 'user_id' => bp_displayed_user_id(), 'member_type' => false, 'hide_empty_groups' => false, 'hide_empty_fields' => false, 'fetch_fields' => false, 'fetch_field_data' => false, 'fetch_visibility_level' => false, 'exclude_groups' => false, 'exclude_fields' => false, 'update_meta_cache' => true));
     // Keep track of object IDs for cache-priming.
     $object_ids = array('group' => array(), 'field' => array(), 'data' => array());
     // WHERE.
     if (!empty($r['profile_group_id'])) {
         $where_sql = $wpdb->prepare('WHERE g.id = %d', $r['profile_group_id']);
     } elseif ($r['exclude_groups']) {
         $exclude = join(',', wp_parse_id_list($r['exclude_groups']));
         $where_sql = "WHERE g.id NOT IN ({$exclude})";
     } else {
         $where_sql = '';
     }
     $bp = buddypress();
     // Include or exclude empty groups.
     if (!empty($r['hide_empty_groups'])) {
         $group_ids = $wpdb->get_col("SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g INNER JOIN {$bp->profile->table_name_fields} f ON g.id = f.group_id {$where_sql} ORDER BY g.group_order ASC");
     } else {
         $group_ids = $wpdb->get_col("SELECT DISTINCT g.id FROM {$bp->profile->table_name_groups} g {$where_sql} ORDER BY g.group_order ASC");
     }
     // Get all group data.
     $groups = self::get_group_data($group_ids);
     // Bail if not also getting fields.
     if (empty($r['fetch_fields'])) {
         return $groups;
     }
     // Get the group ids from the groups we found.
     $group_ids = wp_list_pluck($groups, 'id');
     // Store for meta cache priming.
     $object_ids['group'] = $group_ids;
     // Bail if no groups found.
     if (empty($group_ids)) {
         return $groups;
     }
     // Setup IN query from group IDs.
     $group_ids_in = implode(',', (array) $group_ids);
     // Support arrays and comma-separated strings.
     $exclude_fields_cs = wp_parse_id_list($r['exclude_fields']);
     // Visibility - Handled here so as not to be overridden by sloppy use of the
     // exclude_fields parameter. See bp_xprofile_get_hidden_fields_for_user().
     $hidden_user_fields = bp_xprofile_get_hidden_fields_for_user($r['user_id']);
     $exclude_fields_cs = array_merge($exclude_fields_cs, $hidden_user_fields);
     $exclude_fields_cs = implode(',', $exclude_fields_cs);
     // Set up NOT IN query for excluded field IDs.
     if (!empty($exclude_fields_cs)) {
         $exclude_fields_sql = "AND id NOT IN ({$exclude_fields_cs})";
     } else {
         $exclude_fields_sql = '';
     }
     // Set up IN query for included field IDs.
     $include_field_ids = array();
     // Member-type restrictions.
     if (bp_get_member_types()) {
         if ($r['user_id'] || false !== $r['member_type']) {
             $member_types = $r['member_type'];
             if ($r['user_id']) {
                 $member_types = bp_get_member_type($r['user_id'], false);
                 if (empty($member_types)) {
                     $member_types = array('null');
                 }
             }
             $member_types_fields = BP_XProfile_Field::get_fields_for_member_type($member_types);
             $include_field_ids += array_keys($member_types_fields);
         }
     }
     $in_sql = '';
     if (!empty($include_field_ids)) {
         $include_field_ids_cs = implode(',', array_map('intval', $include_field_ids));
         $in_sql = " AND id IN ({$include_field_ids_cs}) ";
     }
     // Fetch the fields.
     $field_ids = $wpdb->get_col("SELECT id FROM {$bp->profile->table_name_fields} WHERE group_id IN ( {$group_ids_in} ) AND parent_id = 0 {$exclude_fields_sql} {$in_sql} ORDER BY field_order");
     // Bail if no fields.
     if (empty($field_ids)) {
         return $groups;
     }
     $field_ids = array_map('intval', $field_ids);
     // Prime the field cache.
     $uncached_field_ids = bp_get_non_cached_ids($field_ids, 'bp_xprofile_fields');
     if (!empty($uncached_field_ids)) {
         $_uncached_field_ids = implode(',', array_map('intval', $uncached_field_ids));
         $uncached_fields = $wpdb->get_results("SELECT * FROM {$bp->profile->table_name_fields} WHERE id IN ({$_uncached_field_ids})");
         foreach ($uncached_fields as $uncached_field) {
             $fid = intval($uncached_field->id);
             wp_cache_set($fid, $uncached_field, 'bp_xprofile_fields');
         }
     }
     // Pull field objects from the cache.
     $fields = array();
     foreach ($field_ids as $field_id) {
         $fields[] = xprofile_get_field($field_id);
     }
     // Store field IDs for meta cache priming.
     $object_ids['field'] = $field_ids;
     // Maybe fetch field data.
     if (!empty($r['fetch_field_data'])) {
         // Get field data for user ID.
         if (!empty($field_ids) && !empty($r['user_id'])) {
             $field_data = BP_XProfile_ProfileData::get_data_for_user($r['user_id'], $field_ids);
         }
         // Remove data-less fields, if necessary.
         if (!empty($r['hide_empty_fields']) && !empty($field_ids) && !empty($field_data)) {
             // Loop through the results and find the fields that have data.
             foreach ((array) $field_data as $data) {
                 // Empty fields may contain a serialized empty array.
                 $maybe_value = maybe_unserialize($data->value);
                 // Valid field values of 0 or '0' get caught by empty(), so we have an extra check for these. See #BP5731.
                 if ((!empty($maybe_value) || '0' == $maybe_value) && false !== ($key = array_search($data->field_id, $field_ids))) {
                     // Fields that have data get removed from the list.
                     unset($field_ids[$key]);
                 }
             }
             // The remaining members of $field_ids are empty. Remove them.
             foreach ($fields as $field_key => $field) {
                 if (in_array($field->id, $field_ids)) {
                     unset($fields[$field_key]);
                 }
             }
             // Reset indexes.
             $fields = array_values($fields);
         }
         // Field data was found.
         if (!empty($fields) && !empty($field_data) && !is_wp_error($field_data)) {
             // Loop through fields.
             foreach ((array) $fields as $field_key => $field) {
                 // Loop through the data in each field.
                 foreach ((array) $field_data as $data) {
                     // Assign correct data value to the field.
                     if ($field->id == $data->field_id) {
                         $fields[$field_key]->data = new stdClass();
                         $fields[$field_key]->data->value = $data->value;
                         $fields[$field_key]->data->id = $data->id;
                     }
                     // Store for meta cache priming.
                     $object_ids['data'][] = $data->id;
                 }
             }
         }
     }
     // Prime the meta cache, if necessary.
     if (!empty($r['update_meta_cache'])) {
         bp_xprofile_update_meta_cache($object_ids);
     }
     // Maybe fetch visibility levels.
     if (!empty($r['fetch_visibility_level'])) {
         $fields = self::fetch_visibility_level($r['user_id'], $fields);
     }
     // Merge the field array back in with the group array.
     foreach ((array) $groups as $group) {
         // Indexes may have been shifted after previous deletions, so we get a
         // fresh one each time through the loop.
         $index = array_search($group, $groups);
         foreach ((array) $fields as $field) {
             if ($group->id === $field->group_id) {
                 $groups[$index]->fields[] = $field;
             }
         }
         // When we unset fields above, we may have created empty groups.
         // Remove them, if necessary.
         if (empty($group->fields) && !empty($r['hide_empty_groups'])) {
             unset($groups[$index]);
         }
         // Reset indexes.
         $groups = array_values($groups);
     }
     return $groups;
 }
Ejemplo n.º 8
0
/**
 * Update the metadata cache for the specified objects.
 *
 * Based on WordPress's {@link update_meta_cache()}, this function primes the
 * cache with metadata related to a set of objects. This is typically done when
 * querying for a loop of objects; pre-fetching metadata for each queried
 * object can lead to dramatic performance improvements when using metadata
 * in the context of template loops.
 *
 * @since BuddyPress (1.6.0)
 *
 * @global $wpdb WordPress database object for queries..
 *
 * @param array $args {
 *     Array of arguments.
 *     @type array|string $object_ids List of object IDs to fetch metadata for.
 *           Accepts an array or a comma-separated list of numeric IDs.
 *     @type string $object_type The type of object, eg 'groups' or 'activity'.
 *     @type string $meta_table The name of the metadata table being queried.
 *     @type string $object_column Optional. The name of the database column
 *           where IDs (those provided by $object_ids) are found. Eg, 'group_id'
 *           for the groups metadata tables. Default: $object_type . '_id'.
 *     @type string $cache_key_prefix Optional. The prefix to use when creating
 *           cache key names. Default: the value of $meta_table.
 * }
 * @return array|bool Metadata cache for the specified objects, or false on failure.
 */
function bp_update_meta_cache( $args = array() ) {
	global $wpdb;

	$defaults = array(
		'object_ids' 	   => array(), // Comma-separated list or array of item ids
		'object_type' 	   => '',      // Canonical component id: groups, members, etc
		'cache_group'      => '',      // Cache group
		'meta_table' 	   => '',      // Name of the table containing the metadata
		'object_column'    => '',      // DB column for the object ids (group_id, etc)
		'cache_key_prefix' => ''       // Prefix to use when creating cache key names. Eg
					       //    'bp_groups_groupmeta'
	);
	$r = wp_parse_args( $args, $defaults );
	extract( $r );

	if ( empty( $object_ids ) || empty( $object_type ) || empty( $meta_table ) || empty( $cache_group ) ) {
		return false;
	}

	if ( empty( $cache_key_prefix ) ) {
		$cache_key_prefix = $meta_table;
	}

	if ( empty( $object_column ) ) {
		$object_column = $object_type . '_id';
	}

	if ( ! $cache_group ) {
		return false;
	}

	$object_ids   = wp_parse_id_list( $object_ids );
	$uncached_ids = bp_get_non_cached_ids( $object_ids, $cache_group );

	$cache = array();

	// Get meta info
	if ( ! empty( $uncached_ids ) ) {
		$id_list   = join( ',', wp_parse_id_list( $uncached_ids ) );
		$meta_list = $wpdb->get_results( esc_sql( "SELECT {$object_column}, meta_key, meta_value FROM {$meta_table} WHERE {$object_column} IN ({$id_list})" ), ARRAY_A );

		if ( ! empty( $meta_list ) ) {
			foreach ( $meta_list as $metarow ) {
				$mpid = intval( $metarow[$object_column] );
				$mkey = $metarow['meta_key'];
				$mval = $metarow['meta_value'];

				// Force subkeys to be array type:
				if ( !isset( $cache[$mpid] ) || !is_array( $cache[$mpid] ) )
					$cache[$mpid] = array();
				if ( !isset( $cache[$mpid][$mkey] ) || !is_array( $cache[$mpid][$mkey] ) )
					$cache[$mpid][$mkey] = array();

				// Add a value to the current pid/key:
				$cache[$mpid][$mkey][] = $mval;
			}
		}

		foreach ( $uncached_ids as $uncached_id ) {
			// Cache empty values as well
			if ( ! isset( $cache[ $uncached_id ] ) ) {
				$cache[ $uncached_id ] = array();
			}

			wp_cache_set( $uncached_id, $cache[ $uncached_id ], $cache_group );
		}
	}

	return $cache;
}
 /**
  * Get the friendships for a given user.
  *
  * @since 2.6.0
  *
  * @param int   $user_id              ID of the user whose friends are being retrieved.
  * @param array $args {
  *        Optional. Filter parameters.
  *        @type int    $id                ID of specific friendship to retrieve.
  *        @type int    $initiator_user_id ID of friendship initiator.
  *        @type int    $friend_user_id    ID of specific friendship to retrieve.
  *        @type int    $is_confirmed      Whether the friendship has been accepted.
  *        @type int    $is_limited        Whether the friendship is limited.
  *        @type string $order_by          Column name to order by.
  *        @type string $sort_order        ASC or DESC. Default DESC.
  * }
  * @param string $operator            Optional. Operator to use in `wp_list_filter()`.
  *
  * @return array $friendships Array of friendship objects.
  */
 public static function get_friendships($user_id, $args = array(), $operator = 'AND')
 {
     if (empty($user_id)) {
         $user_id = bp_loggedin_user_id();
     }
     $r = bp_parse_args($args, array('id' => null, 'initiator_user_id' => null, 'friend_user_id' => null, 'is_confirmed' => null, 'is_limited' => null, 'order_by' => 'date_created', 'sort_order' => 'DESC', 'page' => null, 'per_page' => null), 'bp_get_user_friendships');
     // First, we get all friendships that involve the user.
     $friendship_ids = wp_cache_get($user_id, 'bp_friends_friendships_for_user');
     if (false === $friendship_ids) {
         $friendship_ids = self::get_friendship_ids_for_user($user_id);
         wp_cache_set($user_id, $friendship_ids, 'bp_friends_friendships_for_user');
     }
     // Prime the membership cache.
     $uncached_friendship_ids = bp_get_non_cached_ids($friendship_ids, 'bp_friends_friendships');
     if (!empty($uncached_friendship_ids)) {
         $uncached_friendships = self::get_friendships_by_id($uncached_friendship_ids);
         foreach ($uncached_friendships as $uncached_friendship) {
             wp_cache_set($uncached_friendship->id, $uncached_friendship, 'bp_friends_friendships');
         }
     }
     // Assemble filter array.
     $filters = wp_array_slice_assoc($r, array('id', 'initiator_user_id', 'friend_user_id', 'is_confirmed', 'is_limited'));
     foreach ($filters as $filter_name => $filter_value) {
         if (is_null($filter_value)) {
             unset($filters[$filter_name]);
         }
     }
     // Populate friendship array from cache, and normalize.
     $friendships = array();
     $int_keys = array('id', 'initiator_user_id', 'friend_user_id');
     $bool_keys = array('is_confirmed', 'is_limited');
     foreach ($friendship_ids as $friendship_id) {
         // Create a limited BP_Friends_Friendship object (don't fetch the user details).
         $friendship = new BP_Friends_Friendship($friendship_id, false, false);
         // Sanity check.
         if (!isset($friendship->id)) {
             continue;
         }
         // Integer values.
         foreach ($int_keys as $index) {
             $friendship->{$index} = intval($friendship->{$index});
         }
         // Boolean values.
         foreach ($bool_keys as $index) {
             $friendship->{$index} = (bool) $friendship->{$index};
         }
         // We need to support the same operators as wp_list_filter().
         if ('OR' == $operator || 'NOT' == $operator) {
             $matched = 0;
             foreach ($filters as $filter_name => $filter_value) {
                 if (isset($friendship->{$filter_name}) && $filter_value == $friendship->{$filter_name}) {
                     $matched++;
                 }
             }
             if ('OR' == $operator && $matched > 0 || 'NOT' == $operator && 0 == $matched) {
                 $friendships[$friendship->id] = $friendship;
             }
         } else {
             /*
              * This is the more typical 'AND' style of filter.
              * If any of the filters miss, we move on.
              */
             foreach ($filters as $filter_name => $filter_value) {
                 if (!isset($friendship->{$filter_name}) || $filter_value != $friendship->{$filter_name}) {
                     continue 2;
                 }
             }
             $friendships[$friendship->id] = $friendship;
         }
     }
     // Sort the results on a column name.
     if (in_array($r['order_by'], array('id', 'initiator_user_id', 'friend_user_id'))) {
         $friendships = bp_sort_by_key($friendships, $r['order_by'], 'num', true);
     }
     // Adjust the sort direction of the results.
     if ('ASC' === strtoupper($r['sort_order'])) {
         // `true` to preserve keys.
         $friendships = array_reverse($friendships, true);
     }
     // Paginate the results.
     if ($r['per_page'] && $r['page']) {
         $start = ($r['page'] - 1) * $r['per_page'];
         $friendships = array_slice($friendships, $start, $r['per_page']);
     }
     return $friendships;
 }
/**
 * Get a list of groups of which the specified user is a member.
 *
 * Get a list of the groups to which this member belongs,
 * filtered by group membership status and role.
 * Usage examples: Used with no arguments specified,
 *
 *    bp_get_user_groups( bp_loggedin_user_id() );
 *
 * returns an array of the groups in which the logged-in user
 * is an unpromoted member. To fetch an array of all groups that
 * the current user belongs to, in any membership role,
 * member, moderator or administrator, use
 *
 *    bp_get_user_groups( $user_id, array(
 *        'is_admin' => null,
 *        'is_mod' => null,
 *    ) );
 *
 * @since 2.6.0
 *
 * @param int $user_id ID of the user.
 * @param array $args {
 *     Array of optional args.
 *     @param bool|null   $is_confirmed Whether to return only confirmed memberships. Pass `null` to disable this
 *                                      filter. Default: true.
 *     @param bool|null   $is_banned    Whether to return only banned memberships. Pass `null` to disable this filter.
 *                                      Default: false.
 *     @param bool|null   $is_admin     Whether to return only admin memberships. Pass `null` to disable this filter.
 *                                      Default: false.
 *     @param bool|null   $is_mod       Whether to return only mod memberships. Pass `null` to disable this filter.
 *                                      Default: false.
 *     @param bool|null   $invite_sent  Whether to return only memberships with 'invite_sent'. Pass `null` to disable
 *                                      this filter. Default: false.
 *     @param string      $orderby      Field to order by. Accepts 'id' (membership ID), 'group_id', 'date_modified'.
 *                                      Default: 'group_id'.
 *     @param string      $order        Sort order. Accepts 'ASC' or 'DESC'. Default: 'ASC'.
 * }
 * @return array Array of matching group memberships, keyed by group ID.
 */
function bp_get_user_groups($user_id, $args = array())
{
    $r = bp_parse_args($args, array('is_confirmed' => true, 'is_banned' => false, 'is_admin' => false, 'is_mod' => false, 'invite_sent' => null, 'orderby' => 'group_id', 'order' => 'ASC'), 'get_user_groups');
    $user_id = intval($user_id);
    $membership_ids = wp_cache_get($user_id, 'bp_groups_memberships_for_user');
    if (false === $membership_ids) {
        $membership_ids = BP_Groups_Member::get_membership_ids_for_user($user_id);
        wp_cache_set($user_id, $membership_ids, 'bp_groups_memberships_for_user');
    }
    // Prime the membership cache.
    $uncached_membership_ids = bp_get_non_cached_ids($membership_ids, 'bp_groups_memberships');
    if (!empty($uncached_membership_ids)) {
        $uncached_memberships = BP_Groups_Member::get_memberships_by_id($uncached_membership_ids);
        foreach ($uncached_memberships as $uncached_membership) {
            wp_cache_set($uncached_membership->id, $uncached_membership, 'bp_groups_memberships');
        }
    }
    // Assemble filter array for use in `wp_list_filter()`.
    $filters = wp_array_slice_assoc($r, array('is_confirmed', 'is_banned', 'is_admin', 'is_mod', 'invite_sent'));
    foreach ($filters as $filter_name => $filter_value) {
        if (is_null($filter_value)) {
            unset($filters[$filter_name]);
        }
    }
    // Populate group membership array from cache, and normalize.
    $groups = array();
    $int_keys = array('id', 'group_id', 'user_id', 'inviter_id');
    $bool_keys = array('is_admin', 'is_mod', 'is_confirmed', 'is_banned', 'invite_sent');
    foreach ($membership_ids as $membership_id) {
        $membership = wp_cache_get($membership_id, 'bp_groups_memberships');
        // Sanity check.
        if (!isset($membership->group_id)) {
            continue;
        }
        // Integer values.
        foreach ($int_keys as $index) {
            $membership->{$index} = intval($membership->{$index});
        }
        // Boolean values.
        foreach ($bool_keys as $index) {
            $membership->{$index} = (bool) $membership->{$index};
        }
        foreach ($filters as $filter_name => $filter_value) {
            if (!isset($membership->{$filter_name}) || $filter_value != $membership->{$filter_name}) {
                continue 2;
            }
        }
        $group_id = (int) $membership->group_id;
        $groups[$group_id] = $membership;
    }
    // By default, results are ordered by membership id.
    if ('group_id' === $r['orderby']) {
        ksort($groups);
    } elseif (in_array($r['orderby'], array('id', 'date_modified'))) {
        $groups = bp_sort_by_key($groups, $r['orderby']);
    }
    // By default, results are ordered ASC.
    if ('DESC' === strtoupper($r['order'])) {
        // `true` to preserve keys.
        $groups = array_reverse($groups, true);
    }
    return $groups;
}
Ejemplo n.º 11
0
/**
 * Slurp up xprofilemeta for a specified set of profile objects.
 *
 * We do not use bp_update_meta_cache() for the xprofile component. This is
 * because the xprofile component has three separate object types (group,
 * field, and data) and three corresponding cache groups. Using the technique
 * in bp_update_meta_cache(), pre-fetching would take three separate database
 * queries. By grouping them together, we can reduce the required queries to
 * one.
 *
 * This function is called within a bp_has_profile() loop.
 *
 * @since BuddyPress (2.0.0)
 *
 * @param array $object_ids Multi-dimensional array of object_ids, keyed by
 *        object type ('group', 'field', 'data')
 */
function bp_xprofile_update_meta_cache($object_ids = array(), $user_id = 0)
{
    global $wpdb;
    if (empty($object_ids)) {
        return false;
    }
    // $object_ids is a multi-dimensional array
    $uncached_object_ids = array('group' => array(), 'field' => array(), 'data' => array());
    $cache_groups = array('group' => 'xprofile_group_meta', 'field' => 'xprofile_field_meta', 'data' => 'xprofile_data_meta');
    $do_query = false;
    foreach ($uncached_object_ids as $object_type => $uncached_object_type_ids) {
        if (!empty($object_ids[$object_type])) {
            // Sanitize $object_ids passed to the function
            $object_type_ids = wp_parse_id_list($object_ids[$object_type]);
            // Get non-cached IDs for each object type
            $uncached_object_ids[$object_type] = bp_get_non_cached_ids($object_type_ids, $cache_groups[$object_type]);
            // Set the flag to do the meta query
            if (!empty($uncached_object_ids[$object_type]) && !$do_query) {
                $do_query = true;
            }
        }
    }
    // If there are uncached items, go ahead with the query
    if ($do_query) {
        $where = array();
        foreach ($uncached_object_ids as $otype => $oids) {
            if (empty($oids)) {
                continue;
            }
            $oids_sql = implode(',', wp_parse_id_list($oids));
            $where[] = $wpdb->prepare("( object_type = %s AND object_id IN ({$oids_sql}) )", $otype);
        }
        $where_sql = implode(" OR ", $where);
    }
    $bp = buddypress();
    $cache = array();
    $meta_list = $wpdb->get_results("SELECT object_id, object_type, meta_key, meta_value FROM {$bp->profile->table_name_meta} WHERE {$where_sql}");
    if (!empty($meta_list)) {
        foreach ($meta_list as $meta) {
            $oid = $meta->object_id;
            $otype = $meta->object_type;
            $okey = $meta->meta_key;
            $ovalue = $meta->meta_value;
            // Force subkeys to be array type
            if (!isset($cache[$otype][$oid]) || !is_array($cache[$otype][$oid])) {
                $cache[$otype][$oid] = array();
            }
            if (!isset($cache[$otype][$oid][$okey]) || !is_array($cache[$otype][$oid][$okey])) {
                $cache[$otype][$oid][$okey] = array();
            }
            // Add to the cache array
            $cache[$otype][$oid][$okey][] = maybe_unserialize($ovalue);
        }
        foreach ($cache as $object_type => $object_caches) {
            $cache_group = $cache_groups[$object_type];
            foreach ($object_caches as $object_id => $object_cache) {
                wp_cache_set($object_id, $object_cache, $cache_group);
            }
        }
    }
    return;
}
 /**
  * Prime the bp_group_admins cache for one or more groups.
  *
  * @since 2.7.0
  *
  * @param array $group_ids IDs of the groups.
  * @return bool True on success.
  */
 public static function prime_group_admins_mods_cache($group_ids)
 {
     global $wpdb;
     $uncached = bp_get_non_cached_ids($group_ids, 'bp_group_admins');
     if ($uncached) {
         $bp = buddypress();
         $uncached_sql = implode(',', array_map('intval', $uncached));
         $group_admin_mods = $wpdb->get_results("SELECT user_id, group_id, date_modified, is_admin, is_mod FROM {$bp->groups->table_name_members} WHERE group_id IN ({$uncached_sql}) AND ( is_admin = 1 OR is_mod = 1 ) AND is_banned = 0");
         $admins = $mods = array();
         if ($group_admin_mods) {
             foreach ($group_admin_mods as $group_admin_mod) {
                 $obj = new stdClass();
                 $obj->user_id = $group_admin_mod->user_id;
                 $obj->date_modified = $group_admin_mod->date_modified;
                 if ($group_admin_mod->is_admin) {
                     $admins[$group_admin_mod->group_id][] = $obj;
                 } else {
                     $mods[$group_admin_mod->group_id][] = $obj;
                 }
             }
         }
         // Prime cache for all groups, even those with no matches.
         foreach ($uncached as $group_id) {
             $group_admins = isset($admins[$group_id]) ? $admins[$group_id] : array();
             wp_cache_set($group_id, $group_admins, 'bp_group_admins');
             $group_mods = isset($mods[$group_id]) ? $mods[$group_id] : array();
             wp_cache_set($group_id, $group_mods, 'bp_group_mods');
         }
     }
 }
 /**
  * Query for groups.
  *
  * @see WP_Meta_Query::queries for a description of the 'meta_query'
  *      parameter format.
  *
  * @since 1.6.0
  * @since 2.6.0 Added `$group_type`, `$group_type__in`, and `$group_type__not_in` parameters.
  * @since 2.7.0 Added `$update_admin_cache` and `$parent_id` parameters.
  *
  * @param array $args {
  *     Array of parameters. All items are optional.
  *     @type string       $type               Optional. Shorthand for certain orderby/order combinations.
  *                                            'newest', 'active', 'popular', 'alphabetical', 'random'.
  *                                            When present, will override orderby and order params.
  *                                            Default: null.
  *     @type string       $orderby            Optional. Property to sort by. 'date_created', 'last_activity',
  *                                            'total_member_count', 'name', 'random'. Default: 'date_created'.
  *     @type string       $order              Optional. Sort order. 'ASC' or 'DESC'. Default: 'DESC'.
  *     @type int          $per_page           Optional. Number of items to return per page of results.
  *                                            Default: null (no limit).
  *     @type int          $page               Optional. Page offset of results to return.
  *                                            Default: null (no limit).
  *     @type int          $user_id            Optional. If provided, results will be limited to groups
  *                                            of which the specified user is a member. Default: null.
  *     @type string       $search_terms       Optional. If provided, only groups whose names or descriptions
  *                                            match the search terms will be returned. Default: false.
  *     @type array|string $group_type         Array or comma-separated list of group types to limit results to.
  *     @type array|string $group_type__in     Array or comma-separated list of group types to limit results to.
  *     @type array|string $group_type__not_in Array or comma-separated list of group types that will be
  *                                            excluded from results.
  *     @type array        $meta_query         Optional. An array of meta_query conditions.
  *                                            See {@link WP_Meta_Query::queries} for description.
  *     @type array|string $value              Optional. Array or comma-separated list of group IDs. Results
  *                                            will be limited to groups within the list. Default: false.
  *     @type array|string $parent_id          Optional. Array or comma-separated list of group IDs. Results
  *                                            will be limited to children of the specified groups. Default: null.
  *     @type array|string $exclude            Optional. Array or comma-separated list of group IDs.
  *                                            Results will exclude the listed groups. Default: false.
  *     @type bool         $update_meta_cache  Whether to pre-fetch groupmeta for the returned groups.
  *                                            Default: true.
  *     @type bool         $update_admin_cache Whether to pre-fetch administrator IDs for the returned
  *                                            groups. Default: false.
  *     @type bool         $show_hidden        Whether to include hidden groups in results. Default: false.
  * }
  * @return array {
  *     @type array $groups Array of group objects returned by the
  *                         paginated query.
  *     @type int   $total  Total count of all groups matching non-
  *                         paginated query params.
  * }
  */
 public static function get($args = array())
 {
     global $wpdb;
     // Backward compatibility with old method of passing arguments.
     if (!is_array($args) || func_num_args() > 1) {
         _deprecated_argument(__METHOD__, '1.7', sprintf(__('Arguments passed to %1$s should be in an associative array. See the inline documentation at %2$s for more details.', 'buddypress'), __METHOD__, __FILE__));
         $old_args_keys = array(0 => 'type', 1 => 'per_page', 2 => 'page', 3 => 'user_id', 4 => 'search_terms', 5 => 'include', 6 => 'populate_extras', 7 => 'exclude', 8 => 'show_hidden');
         $func_args = func_get_args();
         $args = bp_core_parse_args_array($old_args_keys, $func_args);
     }
     $defaults = array('type' => null, 'orderby' => 'date_created', 'order' => 'DESC', 'per_page' => null, 'page' => null, 'user_id' => 0, 'search_terms' => false, 'group_type' => '', 'group_type__in' => '', 'group_type__not_in' => '', 'meta_query' => false, 'include' => false, 'parent_id' => null, 'update_meta_cache' => true, 'update_admin_cache' => false, 'exclude' => false, 'show_hidden' => false);
     $r = wp_parse_args($args, $defaults);
     $bp = buddypress();
     $sql = array('select' => "SELECT DISTINCT g.id", 'from' => "{$bp->groups->table_name} g", 'where' => '', 'orderby' => '', 'pagination' => '');
     if (!empty($r['user_id'])) {
         $sql['from'] .= " JOIN {$bp->groups->table_name_members} m ON ( g.id = m.group_id )";
     }
     $where_conditions = array();
     if (empty($r['show_hidden'])) {
         $where_conditions['hidden'] = "g.status != 'hidden'";
     }
     if (!empty($r['search_terms'])) {
         $search_terms_like = '%' . bp_esc_like($r['search_terms']) . '%';
         $where_conditions['search'] = $wpdb->prepare("( g.name LIKE %s OR g.description LIKE %s )", $search_terms_like, $search_terms_like);
     }
     $meta_query_sql = self::get_meta_query_sql($r['meta_query']);
     if (!empty($meta_query_sql['join'])) {
         $sql['from'] .= $meta_query_sql['join'];
     }
     if (!empty($meta_query_sql['where'])) {
         $where_conditions['meta'] = $meta_query_sql['where'];
     }
     // Only use 'group_type__in', if 'group_type' is not set.
     if (empty($r['group_type']) && !empty($r['group_type__in'])) {
         $r['group_type'] = $r['group_type__in'];
     }
     // Group types to exclude. This has priority over inclusions.
     if (!empty($r['group_type__not_in'])) {
         $group_type_clause = self::get_sql_clause_for_group_types($r['group_type__not_in'], 'NOT IN');
         // Group types to include.
     } elseif (!empty($r['group_type'])) {
         $group_type_clause = self::get_sql_clause_for_group_types($r['group_type'], 'IN');
     }
     if (!empty($group_type_clause)) {
         $where_conditions['group_type'] = $group_type_clause;
     }
     if (!empty($r['user_id'])) {
         $where_conditions['user'] = $wpdb->prepare("m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $r['user_id']);
     }
     if (!empty($r['include'])) {
         $include = implode(',', wp_parse_id_list($r['include']));
         $where_conditions['include'] = "g.id IN ({$include})";
     }
     if (!is_null($r['parent_id'])) {
         // Note that `wp_parse_id_list()` converts `false` to 0.
         $parent_id = implode(',', wp_parse_id_list($r['parent_id']));
         $where_conditions['parent_id'] = "g.parent_id IN ({$parent_id})";
     }
     if (!empty($r['exclude'])) {
         $exclude = implode(',', wp_parse_id_list($r['exclude']));
         $where_conditions['exclude'] = "g.id NOT IN ({$exclude})";
     }
     /* Order/orderby ********************************************/
     $order = $r['order'];
     $orderby = $r['orderby'];
     // If a 'type' parameter was passed, parse it and overwrite
     // 'order' and 'orderby' params passed to the function.
     if (!empty($r['type'])) {
         /**
          * Filters the 'type' parameter used to overwrite 'order' and 'orderby' values.
          *
          * @since 2.1.0
          *
          * @param array  $value Converted 'type' value for order and orderby.
          * @param string $value Parsed 'type' value for the get method.
          */
         $order_orderby = apply_filters('bp_groups_get_orderby', self::convert_type_to_order_orderby($r['type']), $r['type']);
         // If an invalid type is passed, $order_orderby will be
         // an array with empty values. In this case, we stick
         // with the default values of $order and $orderby.
         if (!empty($order_orderby['order'])) {
             $order = $order_orderby['order'];
         }
         if (!empty($order_orderby['orderby'])) {
             $orderby = $order_orderby['orderby'];
         }
     }
     // 'total_member_count' and 'last_activity' sorts require additional table joins.
     if ('total_member_count' === $orderby) {
         $sql['from'] .= " JOIN {$bp->groups->table_name_groupmeta} gm_total_member_count ON ( g.id = gm_total_member_count.group_id )";
         $where_conditions['total_member_count'] = "gm_total_member_count.meta_key = 'total_member_count'";
     } elseif ('last_activity' === $orderby) {
         $sql['from'] .= " JOIN {$bp->groups->table_name_groupmeta} gm_last_activity on ( g.id = gm_last_activity.group_id )";
         $where_conditions['last_activity'] = "gm_last_activity.meta_key = 'last_activity'";
     }
     // Sanitize 'order'.
     $order = bp_esc_sql_order($order);
     /**
      * Filters the converted 'orderby' term.
      *
      * @since 2.1.0
      *
      * @param string $value   Converted 'orderby' term.
      * @param string $orderby Original orderby value.
      * @param string $value   Parsed 'type' value for the get method.
      */
     $orderby = apply_filters('bp_groups_get_orderby_converted_by_term', self::convert_orderby_to_order_by_term($orderby), $orderby, $r['type']);
     // Random order is a special case.
     if ('rand()' === $orderby) {
         $sql['orderby'] = "ORDER BY rand()";
     } else {
         $sql['orderby'] = "ORDER BY {$orderby} {$order}";
     }
     if (!empty($r['per_page']) && !empty($r['page']) && $r['per_page'] != -1) {
         $sql['pagination'] = $wpdb->prepare("LIMIT %d, %d", intval(($r['page'] - 1) * $r['per_page']), intval($r['per_page']));
     }
     $where = '';
     if (!empty($where_conditions)) {
         $sql['where'] = implode(' AND ', $where_conditions);
         $where = "WHERE {$sql['where']}";
     }
     $paged_groups_sql = "{$sql['select']} FROM {$sql['from']} {$where} {$sql['orderby']} {$sql['pagination']}";
     /**
      * Filters the pagination SQL statement.
      *
      * @since 1.5.0
      *
      * @param string $value Concatenated SQL statement.
      * @param array  $sql   Array of SQL parts before concatenation.
      * @param array  $r     Array of parsed arguments for the get method.
      */
     $paged_groups_sql = apply_filters('bp_groups_get_paged_groups_sql', $paged_groups_sql, $sql, $r);
     $cached = bp_core_get_incremented_cache($paged_groups_sql, 'bp_groups');
     if (false === $cached) {
         $paged_group_ids = $wpdb->get_col($paged_groups_sql);
         bp_core_set_incremented_cache($paged_groups_sql, 'bp_groups', $paged_group_ids);
     } else {
         $paged_group_ids = $cached;
     }
     $uncached_group_ids = bp_get_non_cached_ids($paged_group_ids, 'bp_groups');
     if ($uncached_group_ids) {
         $group_ids_sql = implode(',', array_map('intval', $uncached_group_ids));
         $group_data_objects = $wpdb->get_results("SELECT g.* FROM {$bp->groups->table_name} g WHERE g.id IN ({$group_ids_sql})");
         foreach ($group_data_objects as $group_data_object) {
             wp_cache_set($group_data_object->id, $group_data_object, 'bp_groups');
         }
     }
     $paged_groups = array();
     foreach ($paged_group_ids as $paged_group_id) {
         $paged_groups[] = new BP_Groups_Group($paged_group_id);
     }
     $total_groups_sql = "SELECT COUNT(DISTINCT g.id) FROM {$sql['from']} {$where}";
     /**
      * Filters the SQL used to retrieve total group results.
      *
      * @since 1.5.0
      *
      * @param string $t_sql     Concatenated SQL statement used for retrieving total group results.
      * @param array  $total_sql Array of SQL parts for the query.
      * @param array  $r         Array of parsed arguments for the get method.
      */
     $total_groups_sql = apply_filters('bp_groups_get_total_groups_sql', $total_groups_sql, $sql, $r);
     $cached = bp_core_get_incremented_cache($total_groups_sql, 'bp_groups');
     if (false === $cached) {
         $total_groups = (int) $wpdb->get_var($total_groups_sql);
         bp_core_set_incremented_cache($total_groups_sql, 'bp_groups', $total_groups);
     } else {
         $total_groups = (int) $cached;
     }
     $group_ids = array();
     foreach ((array) $paged_groups as $group) {
         $group_ids[] = $group->id;
     }
     // Grab all groupmeta.
     if (!empty($r['update_meta_cache'])) {
         bp_groups_update_meta_cache($group_ids);
     }
     // Prefetch all administrator IDs, if requested.
     if ($r['update_admin_cache']) {
         BP_Groups_Member::prime_group_admins_mods_cache($group_ids);
     }
     // Set up integer properties needing casting.
     $int_props = array('id', 'creator_id', 'enable_forum');
     // Integer casting.
     foreach ($paged_groups as $key => $g) {
         foreach ($int_props as $int_prop) {
             $paged_groups[$key]->{$int_prop} = (int) $paged_groups[$key]->{$int_prop};
         }
     }
     unset($sql, $total_sql);
     return array('groups' => $paged_groups, 'total' => $total_groups);
 }