Thank you (again). I’ve done some modifications. Now, the results will only show for public (non-admin) searches using the is_admin() function. It will also do a case-insensitive substring check to see if the search term is in the title (I’m not accounting for words spread through the product title, as it would be quite labor intensive) and I also check whether there’s in stock matches first.
This way, you will get:
First part of the results: in stock and matching search term
Second part of the results: out of stock and matching search term
Third part of the results: everthing else
Last part of the results: out of stock
Sharing the code here in case someone else can benefit from it:
add_filter( 'relevanssi_hits_filter', 'rlv_bucket_sorting' );
function rlv_bucket_sorting ( $hits ) {
if (is_admin()) return $hits;
$original_search = get_search_query();
$out_of_stock = array();
$everything_else = array();
$exact_match_stock = array();
$exact_match_nostock = array();
foreach ( $hits[0] as $_post ) {
$post_object = relevanssi_get_an_object( $_post )['object'];
$product = wc_get_product( $post_object );
if ((! $product->is_in_stock()) && (stristr($_post->post_title, $original_search) == TRUE)) {
array_push($exact_match_nostock, $_post);
} elseif (( $product->is_in_stock()) && (stristr($_post->post_title, $original_search) == TRUE)) {
array_push($exact_match_stock, $_post);
} elseif ($product->is_in_stock()) {
array_push($everything_else, $_post);
} else {
array_push($out_of_stock, $_post);
}
}
$hits[0] = array_merge( $exact_match_stock, $exact_match_nostock, $everything_else, $out_of_stock );
return $hits;
}
Thanks again for sticking with me and my continuous questions!