WP_Query and name__in

The parameter is not supported by WordPress core, but you can implement it using a filter on 'posts_where':

// require PHP 5.3+
add_action( 'posts_where', function( $where, $query ) {
  if ( isset( $query->query['name__in'] ) && is_array( $query->query['name__in'] ) ) { 
    global $wpdb;
    $names = array_filter( array_map( function( $name ) use( $wpdb ) {
        $sane = sanitize_title( $name );
        return ! empty( $sane ) ? $wpdb->prepare( '%s', $sane ) : NULL;
    }, $query->query['name__in'] ) );
    if ( ! empty( $names ) ) {
      $where .= " AND {$wpdb->posts}.post_name IN (" . implode( ',', $names ) . ")";
    }
  }
  return $where;
}, PHP_INT_MAX, 2 );

Note that this will not work by default using get_posts because using that function sql filters are suppressed by default and you need to enable it using ‘suppress_filters’ argument:

This will work:

$args = array(
  'post_type'       => 'my-cpt',
  'name__in'        => array( 'foo', 'bar' )
);
$posts = new WP_Query( $args );

This will not work:

$args = array(
  'post_type'       => 'my-cpt',
  'name__in'        => array( 'foo', 'bar' )
);
$posts = get_posts( $args );

This will work too:

$args = array(
  'post_type'        => 'my-cpt',
  'name__in'         => array( 'foo', 'bar' ),
  'suppress_filters' => FALSE // <== enable filters
);
$posts = get_posts( $args );

Leave a Comment