Last active
July 23, 2026 13:01
-
-
Save xlplugins/1a356f4508261b60bc64b97498cd335e to your computer and use it in GitHub Desktop.
Cart: Exclude reward from specific categories #102355178
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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