Skip to:
Content

BuddyPress.org

Changeset 7322


Ignore:
Timestamp:
07/27/2013 06:06:17 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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/bp-groups/bp-groups-classes.php

    r7316 r7322  
    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        }
  • trunk/tests/testcases/groups/class-bp-groups-group.php

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