/** * @group bp_groups_update_meta_cache */ public function test_bp_groups_update_meta_cache() { $g1 = $this->factory->group->create(); $g2 = $this->factory->group->create(); $time = bp_core_current_time(); // Set up some data groups_update_groupmeta($g1, 'total_member_count', 4); groups_update_groupmeta($g1, 'last_activity', $time); groups_update_groupmeta($g1, 'foo', 'bar'); groups_update_groupmeta($g2, 'total_member_count', 81); groups_update_groupmeta($g2, 'last_activity', $time); groups_update_groupmeta($g2, 'foo', 'baz'); // Prime the cache for $g1 groups_update_groupmeta($g1, 'foo', 'bar'); groups_get_groupmeta($g1, 'foo'); // Ensure an empty cache for $g2 wp_cache_delete($g2, 'group_meta'); bp_groups_update_meta_cache(array($g1, $g2)); $expected = array($g1 => array('total_member_count' => array(4), 'last_activity' => array($time), 'foo' => array('bar')), $g2 => array('total_member_count' => array(81), 'last_activity' => array($time), 'foo' => array('baz'))); $found = array($g1 => wp_cache_get($g1, 'group_meta'), $g2 => wp_cache_get($g2, 'group_meta')); $this->assertEquals($expected, $found); }
function get($type = 'newest', $per_page = null, $page = null, $user_id = 0, $search_terms = false, $include = false, $populate_extras = true, $exclude = false, $show_hidden = false) { global $wpdb, $bp; $sql = array(); $total_sql = array(); $sql['select'] = "SELECT g.*, gm1.meta_value AS total_member_count, gm2.meta_value AS last_activity"; $sql['from'] = " FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2,"; if (!empty($user_id)) { $sql['members_from'] = " {$bp->groups->table_name_members} m,"; } $sql['group_from'] = " {$bp->groups->table_name} g WHERE"; if (!empty($user_id)) { $sql['user_where'] = " g.id = m.group_id AND"; } $sql['where'] = " g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count'"; if (empty($show_hidden)) { $sql['hidden'] = " AND g.status != 'hidden'"; } if (!empty($search_terms)) { $search_terms = like_escape($wpdb->escape($search_terms)); $sql['search'] = " AND ( g.name LIKE '%%{$search_terms}%%' OR g.description LIKE '%%{$search_terms}%%' )"; } if (!empty($user_id)) { $sql['user'] = $wpdb->prepare(" AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $user_id); } if (!empty($include)) { if (is_array($include)) { $include = implode(',', $include); } $include = $wpdb->escape($include); $sql['include'] = " AND g.id IN ({$include})"; } if (!empty($exclude)) { if (is_array($exclude)) { $exclude = implode(',', $exclude); } $exclude = $wpdb->escape($exclude); $sql['exclude'] = " AND g.id NOT IN ({$exclude})"; } switch ($type) { case 'newest': default: $sql['order'] = " ORDER BY g.date_created DESC"; break; case 'active': $sql[] = "ORDER BY last_activity DESC"; break; case 'popular': $sql[] = "ORDER BY CONVERT(gm1.meta_value, SIGNED) DESC"; break; case 'alphabetical': $sql[] = "ORDER BY g.name ASC"; break; case 'random': $sql[] = "ORDER BY rand()"; break; } if (!empty($per_page) && !empty($page)) { $sql['pagination'] = $wpdb->prepare("LIMIT %d, %d", intval(($page - 1) * $per_page), intval($per_page)); } // Get paginated results $paged_groups_sql = apply_filters('bp_groups_get_paged_groups_sql', join(' ', (array) $sql), $sql); $paged_groups = $wpdb->get_results($paged_groups_sql); $total_sql['select'] = "SELECT COUNT(DISTINCT g.id) FROM {$bp->groups->table_name} g, {$bp->groups->table_name_members} gm1, {$bp->groups->table_name_groupmeta} gm2"; if (!empty($user_id)) { $total_sql['select'] .= ", {$bp->groups->table_name_members} m"; } if (!empty($sql['hidden'])) { $total_sql['where'][] = "g.status != 'hidden'"; } if (!empty($sql['search'])) { $total_sql['where'][] = "( g.name LIKE '%%{$search_terms}%%' OR g.description LIKE '%%{$search_terms}%%' )"; } if (!empty($user_id)) { $total_sql['where'][] = "m.group_id = g.id AND m.user_id = {$user_id} AND m.is_confirmed = 1 AND m.is_banned = 0"; } // Already escaped in the paginated results block if (!empty($include)) { $total_sql['where'][] = "g.id IN ({$include})"; } // Already escaped in the paginated results block if (!empty($exclude)) { $total_sql['where'][] = "g.id NOT IN ({$exclude})"; } $total_sql['where'][] = "g.id = gm1.group_id"; $total_sql['where'][] = "g.id = gm2.group_id"; $total_sql['where'][] = "gm2.meta_key = 'last_activity'"; $t_sql = $total_sql['select']; if (!empty($total_sql['where'])) { $t_sql .= " WHERE " . join(' AND ', (array) $total_sql['where']); } // Get total group results $total_groups_sql = apply_filters('bp_groups_get_total_groups_sql', $t_sql, $total_sql); $total_groups = $wpdb->get_var($total_groups_sql); $group_ids = array(); foreach ((array) $paged_groups as $group) { $group_ids[] = $group->id; } // Populate some extra information instead of querying each time in the loop if (!empty($populate_extras)) { $group_ids = $wpdb->escape(join(',', (array) $group_ids)); $paged_groups = BP_Groups_Group::get_group_extras($paged_groups, $group_ids, $type); } // Grab all groupmeta bp_groups_update_meta_cache($group_ids); unset($sql, $total_sql); return array('groups' => $paged_groups, 'total' => $total_groups); }
function get($args = array()) { global $wpdb, $bp; // 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, 'meta_query' => false, 'include' => false, 'populate_extras' => true, 'exclude' => false, 'show_hidden' => false); $r = wp_parse_args($args, $defaults); $sql = array(); $total_sql = array(); $sql['select'] = "SELECT g.*, gm1.meta_value AS total_member_count, gm2.meta_value AS last_activity"; $sql['from'] = " FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2,"; if (!empty($r['user_id'])) { $sql['members_from'] = " {$bp->groups->table_name_members} m,"; } $sql['group_from'] = " {$bp->groups->table_name} g WHERE"; if (!empty($r['user_id'])) { $sql['user_where'] = " g.id = m.group_id AND"; } $sql['where'] = " g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count'"; if (empty($r['show_hidden'])) { $sql['hidden'] = " AND g.status != 'hidden'"; } if (!empty($r['search_terms'])) { $search_terms = esc_sql(like_escape($r['search_terms'])); $sql['search'] = " AND ( g.name LIKE '%%{$search_terms}%%' OR g.description LIKE '%%{$search_terms}%%' )"; } $meta_query_sql = self::get_meta_query_sql($r['meta_query']); if (!empty($meta_query_sql['join'])) { $sql['from'] .= $meta_query_sql['join']; $total_sql['select'] .= $meta_query_sql['join_total']; } if (!empty($meta_query_sql['where'])) { $sql['meta'] = $meta_query_sql['where']; } if (!empty($r['user_id'])) { $sql['user'] = $wpdb->prepare(" AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $r['user_id']); } if (!empty($r['include'])) { $include = wp_parse_id_list($r['include']); $include = $wpdb->escape(implode(',', $include)); $sql['include'] = " AND g.id IN ({$include})"; } if (!empty($r['exclude'])) { $exclude = wp_parse_id_list($r['exclude']); $exclude = $wpdb->escape(implode(',', $exclude)); $sql['exclude'] = " AND 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'])) { $order_orderby = self::convert_type_to_order_orderby($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']; } } // Sanitize 'order' $order = bp_esc_sql_order($order); // Convert 'orderby' into the proper ORDER BY term $orderby = self::convert_orderby_to_order_by_term($orderby); // Random order is a special case if ('rand()' === $orderby) { $sql[] = "ORDER BY rand()"; } else { $sql[] = "ORDER BY {$orderby} {$order}"; } if (!empty($r['per_page']) && !empty($r['page'])) { $sql['pagination'] = $wpdb->prepare("LIMIT %d, %d", intval(($r['page'] - 1) * $r['per_page']), intval($r['per_page'])); } // Get paginated results $paged_groups_sql = apply_filters('bp_groups_get_paged_groups_sql', join(' ', (array) $sql), $sql); $paged_groups = $wpdb->get_results($paged_groups_sql); $total_sql['select'] = "SELECT COUNT(DISTINCT g.id) FROM {$bp->groups->table_name} g, {$bp->groups->table_name_members} gm1, {$bp->groups->table_name_groupmeta} gm2"; if (!empty($r['user_id'])) { $total_sql['select'] .= ", {$bp->groups->table_name_members} m"; } if (!empty($sql['hidden'])) { $total_sql['where'][] = "g.status != 'hidden'"; } if (!empty($sql['search'])) { $total_sql['where'][] = "( g.name LIKE '%%{$search_terms}%%' OR g.description LIKE '%%{$search_terms}%%' )"; } if (!empty($r['user_id'])) { $total_sql['where'][] = $wpdb->prepare("m.group_id = g.id AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $r['user_id']); } // Temporary implementation of meta_query for total count // See #5099 if (!empty($meta_query_sql['where'])) { // Join the groupmeta table $total_sql['select'] .= ", {$bp->groups->table_name_groupmeta} gmmq"; // Modify the meta_query clause from paged_sql for our syntax $meta_query_clause = preg_replace('/^\\s*AND/', '', $meta_query_sql['where']); $meta_query_clause = str_replace($bp->groups->table_name_groupmeta, 'gmmq', $meta_query_clause); $total_sql['where'][] = $meta_query_clause; } // Already escaped in the paginated results block if (!empty($include)) { $total_sql['where'][] = "g.id IN ({$include})"; } // Already escaped in the paginated results block if (!empty($exclude)) { $total_sql['where'][] = "g.id NOT IN ({$exclude})"; } $total_sql['where'][] = "g.id = gm1.group_id"; $total_sql['where'][] = "g.id = gm2.group_id"; $total_sql['where'][] = "gm2.meta_key = 'last_activity'"; $t_sql = $total_sql['select']; if (!empty($total_sql['where'])) { $t_sql .= " WHERE " . join(' AND ', (array) $total_sql['where']); } // Get total group results $total_groups_sql = apply_filters('bp_groups_get_total_groups_sql', $t_sql, $total_sql); $total_groups = $wpdb->get_var($total_groups_sql); $group_ids = array(); foreach ((array) $paged_groups as $group) { $group_ids[] = $group->id; } // Populate some extra information instead of querying each time in the loop if (!empty($r['populate_extras'])) { $group_ids = $wpdb->escape(join(',', (array) $group_ids)); $paged_groups = BP_Groups_Group::get_group_extras($paged_groups, $group_ids, $r['type']); } // Grab all groupmeta bp_groups_update_meta_cache($group_ids); unset($sql, $total_sql); return array('groups' => $paged_groups, 'total' => $total_groups); }
/** * Query for groups. * * @see WP_Meta_Query::queries for a description of the 'meta_query' * parameter format. * * @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 $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 bool $populate_extras Whether to fetch additional information * (such as member count) about groups. Default: true. * @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 $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, 'meta_query' => false, 'include' => false, 'populate_extras' => true, 'update_meta_cache' => true, 'exclude' => false, 'show_hidden' => false); $r = wp_parse_args($args, $defaults); $bp = buddypress(); $sql = array(); $total_sql = array(); $sql['select'] = "SELECT DISTINCT g.id, g.*, gm1.meta_value AS total_member_count, gm2.meta_value AS last_activity"; $sql['from'] = " FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2,"; if (!empty($r['user_id'])) { $sql['members_from'] = " {$bp->groups->table_name_members} m,"; } $sql['group_from'] = " {$bp->groups->table_name} g WHERE"; if (!empty($r['user_id'])) { $sql['user_where'] = " g.id = m.group_id AND"; } $sql['where'] = " g.id = gm1.group_id AND g.id = gm2.group_id AND gm2.meta_key = 'last_activity' AND gm1.meta_key = 'total_member_count'"; if (empty($r['show_hidden'])) { $sql['hidden'] = " AND g.status != 'hidden'"; } if (!empty($r['search_terms'])) { $search_terms_like = '%' . bp_esc_like($r['search_terms']) . '%'; $sql['search'] = $wpdb->prepare(" AND ( 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'])) { $sql['meta'] = $meta_query_sql['where']; } if (!empty($r['user_id'])) { $sql['user'] = $wpdb->prepare(" AND 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'])); $sql['include'] = " AND g.id IN ({$include})"; } if (!empty($r['exclude'])) { $exclude = implode(',', wp_parse_id_list($r['exclude'])); $sql['exclude'] = " AND 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']; } } // 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[] = "ORDER BY rand()"; } else { $sql[] = "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'])); } /** * 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', join(' ', (array) $sql), $sql, $r); $paged_groups = $wpdb->get_results($paged_groups_sql); $total_sql['select'] = "SELECT COUNT(DISTINCT g.id) FROM {$bp->groups->table_name} g, {$bp->groups->table_name_groupmeta} gm"; if (!empty($r['user_id'])) { $total_sql['select'] .= ", {$bp->groups->table_name_members} m"; } if (!empty($sql['hidden'])) { $total_sql['where'][] = "g.status != 'hidden'"; } if (!empty($sql['search'])) { $total_sql['where'][] = $wpdb->prepare("( g.name LIKE %s OR g.description LIKE %s )", $search_terms_like, $search_terms_like); } if (!empty($r['user_id'])) { $total_sql['where'][] = $wpdb->prepare("m.group_id = g.id AND m.user_id = %d AND m.is_confirmed = 1 AND m.is_banned = 0", $r['user_id']); } // Temporary implementation of meta_query for total count // See #5099. if (!empty($meta_query_sql['where'])) { // Join the groupmeta table. $total_sql['select'] .= ", " . substr($meta_query_sql['join'], 0, -2); // Modify the meta_query clause from paged_sql for our syntax. $meta_query_clause = preg_replace('/^\\s*AND/', '', $meta_query_sql['where']); $total_sql['where'][] = $meta_query_clause; } // Already escaped in the paginated results block. if (!empty($include)) { $total_sql['where'][] = "g.id IN ({$include})"; } // Already escaped in the paginated results block. if (!empty($exclude)) { $total_sql['where'][] = "g.id NOT IN ({$exclude})"; } $total_sql['where'][] = "g.id = gm.group_id"; $total_sql['where'][] = "gm.meta_key = 'last_activity'"; $t_sql = $total_sql['select']; if (!empty($total_sql['where'])) { $t_sql .= " WHERE " . join(' AND ', (array) $total_sql['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', $t_sql, $total_sql, $r); $total_groups = $wpdb->get_var($total_groups_sql); $group_ids = array(); foreach ((array) $paged_groups as $group) { $group_ids[] = $group->id; } // Populate some extra information instead of querying each time in the loop. if (!empty($r['populate_extras'])) { $paged_groups = BP_Groups_Group::get_group_extras($paged_groups, $group_ids, $r['type']); } // Grab all groupmeta. if (!empty($r['update_meta_cache'])) { bp_groups_update_meta_cache($group_ids); } unset($sql, $total_sql); return array('groups' => $paged_groups, 'total' => $total_groups); }
/** * 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); }