1

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

}

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 );
1

What i did:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.