1

I have a search field that's searching in my custom post type bwps with a hidden input:

<form class="search-form form-inline" action="<?php echo site_url('/'); ?>" method="get" role="search">
  <label class="sr-only"></label>
  <input class="searchInput" type="search" required="" placeholder="<?php _e('Search for event', 'mhe') ?>" name="s" value=""></input>
  <input type="hidden" name="post_type" value="bwps" />
  <button class="searchButton" type="submit"><span class="glyphicon glyphicon-search" aria-hidden="true"></span> <span class="searchButtonText"><?php _e('Search', 'mhe') ?></span></button>
</form>

However, the customer now also wants that it searches within all pages, but only pages with a specific category.

How can I make this search form search EVERYTHING in the custom post type, but also ONLY pages with a specific category? Is this even possible?

1 Answer 1

0

You may have already solved this months ago, but I here's my 2 cents as I thought this was an interesting question.

I don't think the standard WP search query can be used to search for posts with either (post type A) or (post type B and category C). But you could pass a custom where clause to the query with posts_where filter to handle this kind of case.

I think something like this should work,

add_filter( 'posts_where' , 'my_posts_where', 10, 2 );
function my_posts_where( $where, $query ) {

    if ( is_admin() || ! is_search() || ! is_main_query() ) {
        return $where;
    }

    // check that requred $_GET parameters are set
    if ( ! empty( $_GET['post_type'] ) || 'bwps' !== $_GET['post_type'] ) {
        return $where;
    }

    if ( empty( $_GET['s'] ) ) {
        return $where;
    }

    // return custom where clause
    global $wpdb;
    $sql = "
        AND (
            {$wpdb->posts}.post_title LIKE '%%%s%%' OR
            {$wpdb->posts}.post_name LIKE '%%%s%%'
        )
        AND
            {$wpdb->posts}.post_status = 'publish'
        AND
            (
                (
                    {$wpdb->posts}.post_type = 'bwps'
                ) OR
                (
                    {$wpdb->posts}.post_type = 'page'
                    AND
                    {$wpdb->posts}.ID IN (
                        SELECT {$wpdb->posts}.ID FROM {$wpdb->posts} AS p
                        INNER JOIN {$wpdb->term_relationships} AS tr ON (p.ID = tr.object_id)
                        INNER JOIN {$wpdb->term_taxonomy} AS tt ON (tr.term_taxonomy_id = tt.term_taxonomy_id)
                        INNER JOIN {$wpdb->terms} AS t ON (t.term_id = tt.term_id)
                        WHERE
                            p.post_status = 'publish'
                            AND t.term_id = %d
                            AND tt.taxonomy = 'category'
                    )
                )
            )
    ";

    $search_phrase = '%' . $_GET['s'] . '%';
    $term_id = 1;

    return $wpdb->prepare(
        $sql,
        $search_phrase,
        $search_phrase,
        $term_id
    );
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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