I need to query wordpress posts returning results that could be matched either by the category OR custom field. Using the below code only returns results if they are matched by the category AND custom field. I need to find matches where it could be matched by either query, so an "OR" result but doesn't seem to work.
Can anyone help?
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'OR',
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'arts','food' ),
'operator' => 'IN'
)
),
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'birth_city',
'value' => 'London',
'compare' => 'IN',
),
)
);
WP_Meta_Query is a helper that allows primary query classes, such as WP_Query and WP_User_Query, to filter their results by object metadata, by generating JOIN and WHERE subclauses to be attached to the primary SQL query string.
The meta_value argument queries post that have the value you define. The meta_value argument is used for string values. This example will query any posts with a custom meta field that has the value “data1”. $args = array( 'meta_value' => 'data1' ); You can also combine the two.
First, you need to edit the post or page where you want to add the custom field and go to the custom fields meta box. Next, you need to provide a name for your custom field and then enter its value. Click on the Add Custom Field button to save it.
Here's a simplification of my previous answer - I hope you don't mind me adding it as a new answer, to avoid confusion with my previous one.
Here I use the WordPress functions get_meta_sql()
and get_tax_sql()
, to modify the WHERE
part of the SQL generated by WP_Query()
:
/**
* Class WPSE_OR_Query
*
* Add a support for (tax_query OR meta_query)
*
* @version 0.2
* @link http://stackoverflow.com/a/22633399/2078474
*
*/
class WPSE_OR_Query extends WP_Query
{
protected $meta_or_tax = FALSE;
protected $tax_args = NULL;
protected $meta_args = NULL;
public function __construct( $args = array() )
{
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 999 );
add_filter( 'posts_where', array( $this, 'posts_where' ), 999 );
parent::__construct( $args );
}
public function pre_get_posts( $qry )
{
remove_action( current_filter(), array( $this, __FUNCTION__ ) );
// Get query vars
$this->meta_or_tax = ( isset( $qry->query_vars['meta_or_tax'] ) ) ? $qry->query_vars['meta_or_tax'] : FALSE;
if( $this->meta_or_tax )
{
$this->tax_args = ( isset( $qry->query_vars['tax_query'] ) ) ? $qry->query_vars['tax_query'] : NULL;
$this->meta_args = ( isset( $qry->query_vars['meta_query'] ) ) ? $qry->query_vars['meta_query'] : NULL;
}
}
public function posts_where( $where )
{
global $wpdb;
$field = 'ID';
remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
// Construct the "tax OR meta" query
if( $this->meta_or_tax && is_array( $this->tax_args ) && is_array( $this->meta_args ) )
{
// Tax query
$sql_tax = get_tax_sql( $this->tax_args, $wpdb->posts, $field );
// Meta query
$sql_meta = get_meta_sql( $this->meta_args, 'post', $wpdb->posts, $field );
// Modify the 'where' part
if( isset( $sql_meta['where'] ) && isset( $sql_tax['where'] ) )
{
$where = str_replace( array( $sql_meta['where'], $sql_tax['where'] ) , '', $where );
$where .= sprintf( ' AND ( %s OR %s ) ', substr( trim( $sql_meta['where'] ), 4 ), substr( trim( $sql_tax['where'] ), 4 ) );
}
}
return $where;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With