Skip to content

Instantly share code, notes, and snippets.

@xlplugins
Last active July 23, 2026 13:01
Show Gist options
  • Select an option

  • Save xlplugins/1a356f4508261b60bc64b97498cd335e to your computer and use it in GitHub Desktop.

Select an option

Save xlplugins/1a356f4508261b60bc64b97498cd335e to your computer and use it in GitHub Desktop.
Cart: Exclude reward from specific categories #102355178
<?php
/**
* FunnelKit Cart Rewards — ignore products from specific categories.
*
* Behaviour:
* - Products in the excluded categories are IGNORED when calculating Cart Rewards
* (their value does not count toward reward progress).
* - Products in the included categories always count, regardless of the order
* they were added to the cart.
* - The Cart Rewards progress bar stays visible even when excluded-category
* products are in the cart.
*
* How it works: instead of disabling rewards outright (old approach with
* `fkcart_reward_enabled`, which hid the bar), we subtract the excluded-category
* items from the total FunnelKit uses to measure reward progress
* (`fkcart_reward_total`). This single filter drives both the progress bar and the
* actual reward application (free shipping / coupons / free gifts).
*/
defined( 'ABSPATH' ) || exit;
/**
* Category term IDs to exclude from Cart Rewards.
* Add more comma separated, e.g. [ 31, 45 ]. Subcategories of these are also excluded.
*/
if ( ! function_exists( 'fkcart_reward_excluded_categories' ) ) {
function fkcart_reward_excluded_categories() {
return apply_filters( 'fkcart_reward_excluded_categories', [ 31 ] );
}
}
/**
* Is this cart item in one of the excluded categories (or a subcategory of one)?
*
* @param array $cart_item
*
* @return bool
*/
if ( ! function_exists( 'fkcart_reward_item_is_excluded' ) ) {
function fkcart_reward_item_is_excluded( $cart_item ) {
$excluded = fkcart_reward_excluded_categories();
if ( empty( $excluded ) ) {
return false;
}
$product_id = ! empty( $cart_item['product_id'] ) ? $cart_item['product_id'] : 0;
$product = $product_id ? wc_get_product( $product_id ) : false;
if ( ! $product ) {
return false;
}
$cat_ids = $product->get_category_ids();
foreach ( $cat_ids as $cat_id ) {
if ( in_array( $cat_id, $excluded, false ) ) {
return true;
}
// Also treat a product placed in a subcategory of an excluded category as excluded.
$ancestors = get_ancestors( $cat_id, 'product_cat' );
if ( array_intersect( $ancestors, $excluded ) ) {
return true;
}
}
return false;
}
}
/**
* Subtract excluded-category items from the total FunnelKit measures rewards against.
* Keeps the tax basis consistent with how FunnelKit built the total.
*/
add_filter( 'fkcart_reward_total', function ( $total, $calculation_mode, $front ) { // phpcs:ignore
if ( is_null( WC()->cart ) ) {
return $total;
}
$include_tax = WC()->cart->display_prices_including_tax();
$deduct = 0.0;
foreach ( WC()->cart->get_cart() as $cart_item ) {
if ( ! fkcart_reward_item_is_excluded( $cart_item ) ) {
continue;
}
if ( 'total' === $calculation_mode ) {
// Total mode uses line totals (after line discounts).
$deduct += (float) ( $cart_item['line_total'] ?? 0 );
if ( $include_tax ) {
$deduct += (float) ( $cart_item['line_tax'] ?? 0 );
}
} else {
// Subtotal mode uses line subtotals (before cart discounts).
$deduct += (float) ( $cart_item['line_subtotal'] ?? 0 );
if ( $include_tax ) {
$deduct += (float) ( $cart_item['line_subtotal_tax'] ?? 0 );
}
}
}
$adjusted = (float) $total - $deduct;
return max( 0, $adjusted );
}, 10, 3 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment