<?php
/**
* An opposite/negative/excluding index for taxonomies
* For example if recipes are tagged "gluten" to indicate an allergy, this will index everything
* not tagged gluten so that selecting a facet choice gluten allergen would display all recipes without gluten
* Only for taxonomies
* Ignores hierarchy, ignores modifier settings in facet
* Re-index after adding this code
*/
add_filter( 'facetwp_indexer_post_facet', function( $bypass, $params ) {
if ( 'my_categories' == $params['facet']['name'] ) { // 'my_categories' change to name of facet
$post_id = $params['defaults']['post_id'];
/** checks post type, otherwise post types that don't have this taxonomy would get indexed for all terms */
if ( 'product' !== get_post_type( $post_id ) ) { // change 'product' to your post type
return true; // skip indexes this facet
}
/** this assumes the datasource is a taxonomy, it can just be hardcoded instead of checking the facet setting and extracting the name */
$taxonomy = substr( $params['defaults']['facet_source'], 4 );
$terms = get_terms( [ 'taxonomy' => $taxonomy, 'hide_empty' => false ] );
$post_terms = get_the_terms( $post_id, $taxonomy );
$post_terms = wp_list_pluck( $post_terms, 'term_id' ); // gets all term ids for this post
foreach ( $terms as $term ) {
if ( !in_array( $term->term_id, $post_terms ) ) { // only index terms not set for this post.
$row = $params['defaults'];
$row['facet_value'] = $term->slug;
/** since this is the opposite, for example, you might change the name "Gluten" to "Gluten Free" like this:
* $row['facet_display_value'] = $term->name . " Free";
*/
$row['facet_display_value'] = $term->name;
$row['term_id'] = $term->term_id;
FWP()->indexer->index_row( $row );
}
}
$bypass = true; // skip normal indexing
}
return $bypass;
}, 10, 2 );