I’m extending the search functionality by adding custom query vars to the search query object via pre_get_posts
so that it’ll be able to include tax_query and meta_query as search conditions. Everything works except when the query var s
is empty, WordPress redirects to the archive page which is not ideal because I’d still want it to search posts based on the other query vars(tax_query & meta_query). I’m thinking maybe it has something to do with setting is_search
boolean. So I tried to manually set it to true
but it gets overridden and reverted back to false
. Is there a way to force it so it’ll always be true and therefore WordPress stays in the search page even though the query var s
is empty? Or am I doing this the wrong way? Here’s my class for that:
class Custom_Query {
private $_get;
private static $_instance;
public function __construct() {
$this->_get = $_GET;
add_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ), 9999 );
add_filter( 'wp', array( $this, 'remove_product_query' ) );
}
/**
* Hook into pre_get_posts to do the main product query
*
* @access public
* @param mixed $q query object
* @return void
*/
function pre_get_posts( $q ) {
// We only want to affect the main query
if ( !$q->is_main_query() || is_admin() )
return;
$meta_query[] = $this->date_meta_query();
$q->set( 'meta_query', $meta_query );
$tax_query[] = $this->category_tax_query();
$q->set( 'tax_query', $tax_query );
$q->set( 'is_search', true );
}
/**
* Returns date meta query
*
* @return array $meta_query
*/
function date_meta_query() {
$meta_query = array();
$compare = '=';
$value = $this->to_date( $this->_get['ptp_date'] );
if ( isset( $this->_get['ptp_date_start'] ) && isset( $this->_get['ptp_date_end'] ) ) {
$compare = 'BETWEEN';
$value = array( $this->to_date( $this->_get['ptp_date_start'] ), $this->to_date( $this->_get['ptp_date_end'] ) );
}
$meta_query = array(
'key' => '_event_date',
'value' => $value,
'compare' => $compare
);
return $meta_query;
}
/**
* Returns category taxonomy query
*
* @return array $tax_query
*/
function category_tax_query() {
$tax_query = array();
$terms = array( (int) $this->_get['ptp_term_id'] );
$operator = 'IN';
$tax_query = array(
'taxonomy' => 'product_cat',
'field' => 'id',
'terms' => $terms,
'operator' => $operator
);
return $tax_query;
}
/**
* Converts date string into supported DATE format
*
* @param $date
* @return string $date
*/
function to_date( $date ) {
return date( 'Y-m-d H:i:s', strtotime( $date ) );
}
/**
* Remove the query
*
* @access public
* @return void
*/
function remove_product_query() {
remove_filter( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
}
}
You can force WordPress to load search.php template when you need it by using the following code:
instead of
What i did: