Here’s a little experiment:
You can try the following setup:
$args = array(
'wpse_search_or_tax_query' => true, // <-- New parameter!
's' => 'some search text',
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( 'some-category-slug' ),
'operator' => 'IN',
),
),
);
$query = new WP_Query( $args );
where we introduce the custom wpse_search_or_tax_query
parameter to activate the query modifications.
This is supported by the following demo plugin:
<?php
/**
* Plugin Name: Modify the WP_Query to use OR between the search and tax query parts.
* Description: Activation through the boolean 'wpse_search_or_tax_query' parameter.
* Plugin URI: http://wordpress.stackexchange.com/a/174221/26350
* Author: Birgir Erlendsson (birgire)
* Version: 0.0.2
*/
add_action( 'init', function()
{
if( ! is_admin() && class_exists( 'WPSE_Modify_Query' ) )
{
$o = new WPSE_Modify_Query;
$o->activate();
}
});
class WPSE_Modify_Query
{
private $search="";
public function activate()
{
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
}
public function pre_get_posts( WP_Query $q )
{
if( filter_var(
$q->get( 'wpse_search_or_tax_query' ),
FILTER_VALIDATE_BOOLEAN
)
&& $q->get( 'tax_query' )
&& $q->get( 's' )
)
{
add_filter( 'posts_clauses', array( $this, 'posts_clauses' ), 10, 2 );
add_filter( 'posts_search', array( $this, 'posts_search' ), 10, 2 );
}
}
public function posts_clauses( $clauses, \WP_Query $q )
{
remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
// Generate the tax query:
$tq = new WP_Tax_Query( $q->query_vars['tax_query'] );
// Get the generated taxonomy clauses:
global $wpdb;
$tc = $tq->get_sql( $wpdb->posts, 'ID' );
// Remove the search part:
$clauses['where'] = str_ireplace(
$this->search,
' ',
$clauses['where']
);
// Remove the taxonomy part:
$clauses['where'] = str_ireplace(
$tc['where'],
' ',
$clauses['where']
);
// Add the search OR taxonomy part:
$clauses['where'] .= sprintf(
" AND ( ( 1=1 %s ) OR ( 1=1 %s ) ) ",
$tc['where'],
$this->search
);
return $clauses;
}
public function posts_search( $search, \WP_Query $q )
{
remove_filter( current_filter(), array( $this, __FUNCTION__ ) );
$this->search = $search;
return $search;
}
} // end class
Hopefully you can adjust this further to your needs.