Force is_search to always TRUE

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' ) );
}

}

Related posts

Leave a Reply

2 comments

  1. You can force WordPress to load search.php template when you need it by using the following code:

    add_filter( 'template_include', 'get_search_template' );
    

    instead of

    $q->set( 'is_search', true );
    
  2. What i did:

    add_action( 'parse_query', 'search_even_empty' );
    function search_even_empty($query)
    {
        if( isset($_GET['s']) ):
            $query->is_search = true;
        endif;
    }