/**
  * Fetch signups based on parameters.
  *
  * @since 2.0.0
  *
  * @param array $args the argument to retrieve desired signups.
  * @return array {
  *     @type array $signups Located signups.
  *     @type int   $total   Total number of signups matching params.
  * }
  */
 public static function get($args = array())
 {
     global $wpdb;
     $r = bp_parse_args($args, array('offset' => 0, 'number' => 1, 'usersearch' => false, 'orderby' => 'signup_id', 'order' => 'DESC', 'include' => false, 'activation_key' => '', 'user_login' => ''), 'bp_core_signups_get_args');
     // @todo whitelist sanitization
     if ($r['orderby'] !== 'signup_id') {
         $r['orderby'] = 'user_' . $r['orderby'];
     }
     $r['orderby'] = sanitize_title($r['orderby']);
     $sql = array();
     $signups_table = buddypress()->members->table_name_signups;
     $sql['select'] = "SELECT * FROM {$signups_table}";
     $sql['where'] = array();
     $sql['where'][] = "active = 0";
     if (empty($r['include'])) {
         // Search terms.
         if (!empty($r['usersearch'])) {
             $search_terms_like = '%' . bp_esc_like($r['usersearch']) . '%';
             $sql['where'][] = $wpdb->prepare("( user_login LIKE %s OR user_email LIKE %s OR meta LIKE %s )", $search_terms_like, $search_terms_like, $search_terms_like);
         }
         // Activation key.
         if (!empty($r['activation_key'])) {
             $sql['where'][] = $wpdb->prepare("activation_key = %s", $r['activation_key']);
         }
         // User login.
         if (!empty($r['user_login'])) {
             $sql['where'][] = $wpdb->prepare("user_login = %s", $r['user_login']);
         }
         $sql['orderby'] = "ORDER BY {$r['orderby']}";
         $sql['order'] = bp_esc_sql_order($r['order']);
         $sql['limit'] = $wpdb->prepare("LIMIT %d, %d", $r['offset'], $r['number']);
     } else {
         $in = implode(',', wp_parse_id_list($r['include']));
         $sql['in'] = "AND signup_id IN ({$in})";
     }
     // Implode WHERE clauses.
     $sql['where'] = 'WHERE ' . implode(' AND ', $sql['where']);
     /**
      * Filters the Signups paged query.
      *
      * @since 2.0.0
      *
      * @param string $value SQL statement.
      * @param array  $sql   Array of SQL statement parts.
      * @param array  $args  Array of original arguments for get() method.
      * @param array  $r     Array of parsed arguments for get() method.
      */
     $paged_signups = $wpdb->get_results(apply_filters('bp_members_signups_paged_query', join(' ', $sql), $sql, $args, $r));
     if (empty($paged_signups)) {
         return array('signups' => false, 'total' => false);
     }
     // Used to calculate a diff between now & last
     // time an activation link has been resent.
     $now = current_time('timestamp', true);
     foreach ((array) $paged_signups as $key => $signup) {
         $signup->id = intval($signup->signup_id);
         $signup->meta = !empty($signup->meta) ? maybe_unserialize($signup->meta) : false;
         $signup->user_name = '';
         if (!empty($signup->meta['field_1'])) {
             $signup->user_name = wp_unslash($signup->meta['field_1']);
         }
         // Sent date defaults to date of registration.
         if (!empty($signup->meta['sent_date'])) {
             $signup->date_sent = $signup->meta['sent_date'];
         } else {
             $signup->date_sent = $signup->registered;
         }
         $sent_at = mysql2date('U', $signup->date_sent);
         $diff = $now - $sent_at;
         /**
          * Add a boolean in case the last time an activation link
          * has been sent happened less than a day ago.
          */
         if ($diff < 1 * DAY_IN_SECONDS) {
             $signup->recently_sent = true;
         }
         if (!empty($signup->meta['count_sent'])) {
             $signup->count_sent = absint($signup->meta['count_sent']);
         } else {
             $signup->count_sent = 1;
         }
         $paged_signups[$key] = $signup;
     }
     unset($sql['limit']);
     $sql['select'] = preg_replace("/SELECT.*?FROM/", "SELECT COUNT(*) FROM", $sql['select']);
     /**
      * Filters the Signups count query.
      *
      * @since 2.0.0
      *
      * @param string $value SQL statement.
      * @param array  $sql   Array of SQL statement parts.
      * @param array  $args  Array of original arguments for get() method.
      * @param array  $r     Array of parsed arguments for get() method.
      */
     $total_signups = $wpdb->get_var(apply_filters('bp_members_signups_count_query', join(' ', $sql), $sql, $args, $r));
     return array('signups' => $paged_signups, 'total' => $total_signups);
 }
 /**
  * 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);
 }
예제 #3
0
 /**
  * @group bp_esc_sql_order
  */
 public function test_bp_esc_sql_order_invalid()
 {
     $this->assertEquals('ASC', bp_esc_sql_order('In ur base killin ur d00dz'));
 }
 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.
  *
  * @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);
 }