Index: bp-groups/bp-groups-classes.php
===================================================================
--- bp-groups/bp-groups-classes.php
+++ bp-groups/bp-groups-classes.php
@@ -350,8 +350,7 @@ class BP_Groups_Group {
 
 		$r = wp_parse_args( $args, $defaults );
 
-		$sql       = array();
-		$total_sql = array();
+		$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,";
@@ -447,46 +446,18 @@ class BP_Groups_Group {
 		$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}%%' )";
-		}
+		// Get total groups
+		// Use $paged_groups_sql, but replace "g.*" with COUNT
+		$t_sql = str_replace( 'g.*', 'COUNT(DISTINCT g.id)', $paged_groups_sql );
 
-		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'] );
-		}
-
-		// 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'] );
-		}
+		// Do not use! This is passed as the second parameter in the
+		// 'bp_groups_get_total_groups_sql' filter for backpat only
+		$total_sql = self::get_deprecated_total_groups_sql( $sql, $r );
 
 		// Get total group results
-		$total_groups_sql = apply_filters( 'bp_groups_get_total_groups_sql', $t_sql, $total_sql );
+		// For the 'bp_groups_get_total_groups_sql' filter, plugin devs new to BP 1.8
+		// should do their checks against $sql and skip $total_sql (see above)
+		$total_groups_sql = apply_filters( 'bp_groups_get_total_groups_sql', $t_sql, $total_sql, $sql );
 		$total_groups     = $wpdb->get_var( $total_groups_sql );
 
 		$group_ids = array();
@@ -945,6 +916,74 @@ class BP_Groups_Group {
 
 		return $ids;
 	}
+
+	/**
+	 * Get older total groups SQL array.
+	 *
+	 * The new total groups SQL statement uses the paged groups SQL instead of
+	 * regenerating a separate SQL statement that will become inaccurate.
+	 *
+	 * This will be deprecated in a future release and is only used for backpat
+	 * for plugins already utilizing this older SQL statement in the
+	 * 'bp_groups_get_total_groups_sql' filter.
+	 *
+	 * @since BuddyPress (1.8)
+	 *
+	 * @param array $sql The paged groups SQL array
+	 * @param array $r The passed arguments from bp_has_groups()
+	 * @return array
+	 */
+	protected static function get_deprecated_total_groups_sql( $sql = array(), $r = array() ) {
+		global $wpdb;
+
+		$bp = buddypress();
+
+		$total_sql = array();
+
+		// Setup some variables again
+		$include = wp_parse_id_list( $r['include'] );
+		$include = $wpdb->escape( implode( ',', $include ) );
+
+		$exclude = wp_parse_id_list( $r['exclude'] );
+		$exclude = $wpdb->escape( implode( ',', $exclude ) );
+
+		// start $total_sql array
+
+		$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'] ) ) {
+			$search_terms = esc_sql( like_escape( $r['search_terms'] ) );
+			$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'] );
+		}
+
+		// 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'";
+
+		return $total_sql;
+	}
 }
 
 /**
