Skip to:
Content

BuddyPress.org

Changeset 7323


Ignore:
Timestamp:
07/27/2013 06:06:48 PM (11 years ago)
Author:
boonebgorges
Message:

Fixes groups meta_query for multiple clauses

The 1.8 implementation of meta_query for BP_Groups_Group::get() did not
properly handle multiple clauses, because of certain necessary
transformations of the SQL syntax to match the peculiar syntax in the
groups component. This changeset fixes the problem by improving the
logic used to parse the SQL returned from the WP_Meta_Query object.

A related included fix is that a DISTINCT keyword has been added to the
main SELECT clause of the groups total sql statement. This ensures that
multi-clause meta_query queries will not return duplicate values.

Also adds an automated test for the situation described above.

Fixes #5119

Props imath

Location:
branches/1.8
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/1.8/bp-groups/bp-groups-classes.php

    r7315 r7323  
    354354        $total_sql = array();
    355355
    356         $sql['select'] = "SELECT g.*, gm1.meta_value AS total_member_count, gm2.meta_value AS last_activity";
     356        $sql['select'] = "SELECT DISTINCT g.id, g.*, gm1.meta_value AS total_member_count, gm2.meta_value AS last_activity";
    357357        $sql['from']   = " FROM {$bp->groups->table_name_groupmeta} gm1, {$bp->groups->table_name_groupmeta} gm2,";
    358358
     
    469469        if ( ! empty( $meta_query_sql['where'] ) ) {
    470470            // Join the groupmeta table
    471             $total_sql['select'] .= ", {$bp->groups->table_name_groupmeta} gmmq";
     471            $total_sql['select'] .= ", ". substr( $meta_query_sql['join'], 0, -2 );
    472472
    473473            // Modify the meta_query clause from paged_sql for our syntax
    474474            $meta_query_clause = preg_replace( '/^\s*AND/', '', $meta_query_sql['where'] );
    475             $meta_query_clause = str_replace( $bp->groups->table_name_groupmeta, 'gmmq', $meta_query_clause );
    476475            $total_sql['where'][] = $meta_query_clause;
    477476        }
     
    561560            // the more general query syntax to accord better with
    562561            // BP/WP convention
    563             preg_match( '/INNER JOIN (.*) ON/', $meta_sql['join'], $matches_a );
    564             preg_match( '/ON \((.*)\)$/', $meta_sql['join'], $matches_b );
     562            preg_match_all( '/INNER JOIN (.*) ON/', $meta_sql['join'], $matches_a );
     563            preg_match_all( '/ON \((.*)\)/', $meta_sql['join'], $matches_b );
     564
    565565            if ( ! empty( $matches_a[1] ) && ! empty( $matches_b[1] ) ) {
    566                 $sql_array['join']  = $matches_a[1] . ', ';
    567                 $sql_array['where'] = preg_replace( '/^(\sAND\s+[\(\s]+)/', '$1' . $matches_b[1] . ' AND ', $meta_sql['where'] );
     566                $sql_array['join']  = implode( ',', $matches_a[1] ). ', ';
     567
     568                $sql_array['where'] = '';
     569
     570                $meta_query_where_clauses = explode( "\n", $meta_sql['where'] );
     571                foreach( $matches_b[1] as $key => $group_id_clause ) {
     572                    $sql_array['where'] .= ' ' . preg_replace( '/^(AND\s+[\(\s]+)/', '$1' . $group_id_clause . ' AND ', ltrim( $meta_query_where_clauses[ $key ] ) );
     573                }
     574
    568575            }
    569576        }
  • branches/1.8/tests/testcases/groups/class-bp-groups-group.php

    r7274 r7323  
    9999    /**
    100100     * @group get
     101     * @group group_meta_query
     102     */
     103    public function test_get_with_meta_query_multiple_clauses() {
     104        $now = time();
     105        $g1 = $this->factory->group->create( array(
     106            'last_activity' => date( 'Y-m-d H:i:s', $now - 60*60 ),
     107        ) );
     108        $g2 = $this->factory->group->create( array(
     109            'last_activity' => date( 'Y-m-d H:i:s', $now - 60*60*2 ),
     110        ) );
     111        $g3 = $this->factory->group->create( array(
     112            'last_activity' => date( 'Y-m-d H:i:s', $now - 60*60*3 ),
     113        ) );
     114        groups_update_groupmeta( $g1, 'foo', 'bar' );
     115        groups_update_groupmeta( $g2, 'foo', 'bar' );
     116        groups_update_groupmeta( $g1, 'bar', 'barry' );
     117
     118        $groups = BP_Groups_Group::get( array(
     119            'meta_query' => array(
     120                'relation' => 'AND',
     121                array(
     122                    'key' => 'foo',
     123                    'value' => 'bar',
     124                ),
     125                array(
     126                    'key' => 'bar',
     127                    'value' => 'barry',
     128                ),
     129            ),
     130        ) );
     131        $ids = wp_list_pluck( $groups['groups'], 'id' );
     132        $this->assertEquals( $ids, array( $g1 ) );
     133        $this->assertEquals( 1, $groups['total'] );
     134    }
     135
     136    /**
     137     * @group get
    101138     */
    102139    public function test_get_normal_search() {
Note: See TracChangeset for help on using the changeset viewer.