WordPress custom search for custom post type

After creating a custom post type for an Inventory plugin the client needed also customized search for the columns.

Custom search for custom post type

First the pre_get_posts looked as a good candidate for hooking, but ended up with filtering via posts_clauses_request

add_filter('posts_clauses_request', 'customSearchClause');
function customSearchClause($query)
{
    global $wp_query;

    if (!is_search()) {
        return $query;
    }

    $term = $wp_query->query['s'];
    $query['join'] = 'INNER JOIN wp_postmeta ON (wp_posts.ID = wp_postmeta.post_id)';
    $query['where'] = "AND wp_posts.post_type = '$this->post_type'
    AND (
        (wp_posts.post_title LIKE '%{$term}%')
        OR (wp_postmeta.meta_key = 'product' AND wp_postmeta.meta_value LIKE '%{$term}%')
        OR (wp_postmeta.meta_key = 'product_code' AND wp_postmeta.meta_value LIKE '%{$term}%')
    )";

    return $query;
}

WooCommerce advanced (product attribute) search

I couldn’t find answers why Googling, how to make search work with product attributes of WooCommerce products.
Wrote the code, but it was always 404 page. URLs with /taxonomy/term_slug (example.com/radius/16/) were working, but example.com/?s=&post_type=product&pa_radius=TERM_ID&pa_width=TERM_ID&pa_manufacturer=TERM_ID wasn’t outputing any products.

header.php

 <form action="<?php echo site_url( '/' ); ?>" class="search2">
 <input type="hidden" name="s" value=""/>
 <input type="hidden" name="post_type" value="product"/>
 <img src="<?php echo get_template_directory_uri(); ?>/img/box_holder.png">

 <div class="search_box">
 <h3 class="search_title">Search by attribute</h3>
 <select class="selectBox" name="pa_season">
 <?php echo pf_get_filter_options( 'Season', 'pa_season' ); ?>
 </select>
 <select class="selectBox" name="pa_radius">
 <?php echo pf_get_filter_options( 'Radius', 'pa_radius' ); ?>
 </select>
 <select class="selectBox" name="pa_height">
 <?php echo pf_get_filter_options( 'Height', 'pa_height' ); ?>
 </select>
 <select class="selectBox" name="pa_width">
 <?php echo pf_get_filter_options( 'Width', 'pa_width' ); ?>
 </select>
 <select class="selectBox" name="pa_speedindex">
 <?php echo pf_get_filter_options( 'Speed index', 'pa_speedindex' ); ?>
 </select>
 <select class="selectBox" name="pa_manufacturer">
 <?php echo pf_get_filter_options( 'Manufacturer', 'pa_manufacturer' ); ?>
 </select>
 <button class="search-button" type="submit">Search ➤</button>
 </div>
 </form>

functions.php

/**
 * Output for specified taxonomy ( product attributee)
 *
 * @return string  list
 */
function pf_get_filter_options( $title, $taxonomy ) {

    global $wp_query;

    $options = '' . $title . '';

    $data = get_terms( $taxonomy );

    foreach ( $data as $term ) {

        // Skip some weird terms
        switch ( $taxonomy ) {
            case 'pa_radius':
                if ( in_array($term->slug, array('13c','14c','15c','1616c','16c')) )
                    continue( 2 );

                break;

            case 'pa_width':
                if ( in_array($term->slug, array('195205','255265')) )
                    continue( 2 );

                break;
        }

        $selected = isset( $wp_query->query_vars[$taxonomy] ) && $wp_query->query_vars[$taxonomy] == $term->term_id ? ' selected="selected"' : '';
        $options .= '<option value="' . $term->term_id . '"' . $selected . '>' . $term->name . '</option>';

    }

    return $options;

}

So I decided to watch https://www.youtube.com/watch?v=v7Uj3pLQseM to free my mind a bit.
In the talk Debug Bar was mentioned that I tried before, but I’m used
to watch errors in OSX Console.app so I wasn’t using Debug Bar.

What catched my attention was the SQL queries log so I added
define('SAVEQUERIES', true); to my wp-config.php and installed Debug Bar
to give it another try.

So I clicked Debug, went over the queries and found the solution.

Debug Bar Queries
Debug Bar Queries

Solution

The problem was that as value I was using $term->term_id instead $term->slug by which the queries search in code.