posts_where Fails with More than One Custom Field in Query

Think about your query. You are asking that $wpdb->postmeta.meta_key be both “foo” and “bar”. That will never happen. If you ran this in a context where you’d get to read MySQL debugging data (PhpMyAdmin’s SQL console will do this) you would probably see a warning about an “impossible where clause”. You need to JOIN on the post meta table for one of the values, but as near as I can tell WP_Query will do this too.

$args = array(
  'post_type' => 'post',
  'meta_query' => array(
    array(
      'key' => 'foo',
      'value' => '1',
    ),
    array(
      'key' => 'bar',
      'value' => '1',
    )
  )
);
$query = new WP_Query( $args );

If you look at the SQL for that query– var_dump($qry->request);— you will see the JOIN I am talking about.

You can do the same with a filter on pre_get_posts.

function set_post_meta_wpse_111456($qry) {
  $qry->set(
    'meta_query',
    array(
      array(
        'key' => 'foo',
        'value' => '1',
     ),
     array(
       'key' => 'bar',
       'value' => '1',
     )
  );
}
add_action('pre_get_posts','set_post_meta_wpse_111456');

WARNING: As written above, that will effect every query on the site so you do need to add conditions to limit where that runs.