How to exclude attachments from search query?

Question

I have issue getting my code works to exclude attachments from the search query.

I am adapting the Search Query to handle _sku value from WooCommerce but it also search for posts.post_type attachment even if I ask to only search in post, page, product type.

The problem is that my attachment (images) linked to the product has the sku has their name.

Ex:

Product title : Skull Woven Shirt | Dark Custom™ | Long Sleeves | Slim Fit

Product sku : 96242-20VH

Attachment #1 title : 96242-20VH_01front

Attachment #2 title : 96242-20VH_01back

When I print the query for the the search, I am getting this :

SELECT SQL_CALC_FOUND_ROWS  bhd_posts.ID FROM bhd_posts  INNER JOIN bhd_postmeta ON ( bhd_posts.ID = bhd_postmeta.post_id ) WHERE 1=1  AND (((bhd_posts.post_title LIKE '%96242-20VH%') OR (bhd_posts.post_excerpt LIKE '%96242-20VH%') OR (bhd_posts.post_content LIKE '%96242-20VH%')))  AND (bhd_posts.post_password = '')  OR  ( 
  ( bhd_postmeta.meta_key = '_sku' AND bhd_postmeta.meta_value = '96242-20VH' )
) AND bhd_posts.post_type IN ('post', 'page', 'product') AND (bhd_posts.post_status = 'publish') GROUP BY bhd_posts.ID ORDER BY bhd_posts.post_title LIKE '%96242-20VH%' DESC, bhd_posts.post_date DESC LIMIT 0, 10

The result give me :

17581 <- Attachment
17580 <- Attachment
12506 <- Product

I have tried the current code from this tread (Exclude image url from search query)

// Exclude images from search results - WordPress
add_action( 'init', 'exclude_images_from_search_results' );
function exclude_images_from_search_results() {
 global $wp_post_types;

 $wp_post_types['attachment']->exclude_from_search = true;
}

But it does not remove the attachments from the results.

I understand that because the SQL searchs for post.title it find the two attachment, but looks like the AND bhd_posts.post_type IN ('post', 'page', 'product') is ignored.

Any clue?


Here is additional code I have in my function.php file to handle the request.

function me_search_query( $query ) {
  if ( $query->is_search ) {
    $meta_query_args = array(
      array(
        'key' => '_sku',
        'value' => $query->query_vars['s'],
        'compare' => '=',
      )
    );
    $query->set('meta_query', $meta_query_args);
    add_filter( 'get_meta_sql', 'me_replace_and_with_or' );
  };
}

function SearchFilter($query) {
  if ($query->is_search) {
      $query->set('post_type',array('post','page', 'product'));
  }
return $query;
}
add_filter('pre_get_posts','SearchFilter');


function me_replace_and_with_or( $sql ) {
    if ( 1 === strpos( $sql['where'], 'AND' ) ) {
        $sql['where'] = substr( $sql['where'], 4 );
        $sql['where'] = ' OR ' . $sql['where'];
    }

    //make sure that this filter will fire only once for the meta query
    remove_filter( 'get_meta_sql', 'me_replace_and_with_or' );
    return $sql;
}

add_filter( 'pre_get_posts', 'me_search_query');
0
Patrice Poliquin 3 months 0 Answers 49 views 0

Leave an answer