Skip to content

Fix: FluentCart real-time orders ignore Selected Product filter#126

Open
AmitPaul-akp wants to merge 1 commit into
WPDevelopers:masterfrom
AmitPaul-akp:amit-fluentcartfix
Open

Fix: FluentCart real-time orders ignore Selected Product filter#126
AmitPaul-akp wants to merge 1 commit into
WPDevelopers:masterfrom
AmitPaul-akp:amit-fluentcartfix

Conversation

@AmitPaul-akp
Copy link
Copy Markdown

Summary

Real-time FluentCart orders trigger every enabled NotificationX sales campaign whose status matches the incoming order, regardless of the campaign's Show Purchase Of: Selected Product or Exclude Products settings. The product/category filter is only honored on the Regenerate path.

Reproduction

  1. Create two FluentCart sales campaigns:
    • Campaign A -> Show Purchase Of: Selected Product -> Product A
    • Campaign B -> Show Purchase Of: Selected Product -> Product B
  2. Click Regenerate on both - filter works correctly.
  3. Place a live order for Product A via FluentCart.
  4. Expected: only Campaign A fires.
    Actual: both Campaign A and Campaign B fire.

Root cause

FluentCart::nx_can_entry() - the only callback registered on nx_can_entry_fluentcart - checks order/payment/shipping/fulfillment status only. It does not apply _show_purchaseof() / _excludes_product().

Real-time orders flow through:

fluent_cart/order_paid_done -> save_new_records() -> parent::save() -> update_notification() -> apply_filters('nx_can_entry_fluentcart', ...)

...so live orders bypass the product filter entirely. The Regenerate path works because get_orders() calls _excludes_product() / _show_purchaseof() itself before constructing entries.

For comparison, the WooCommerce source registers two callbacks on the same filter - status check and the Conversions type's product filter - at WooCommerce.php:110-111. FluentCart only registered the status one.

Note: we can't just delegate to Conversions::nx_can_entry because that compares against post IDs, while FluentCart stores product list values as slugs (product_lists() keys by post_name). Reusing FluentCart's own _excludes_product() / _show_purchaseof() keeps slug semantics identical to Regenerate.

Fix

Extend FluentCart::nx_can_entry() to apply the same _excludes_product === _show_purchaseof condition that get_orders() already uses. Behavior is now consistent between Regenerate and real-time paths.

  • Scope: 1 file, 1 method (nx_can_entry), +25 / -2.
  • No new dependencies, no signature changes, no new files.
  • Pro inline source (fluentcart_inline) inherits the fix via FluentCart::get_instance() reference - no Pro-side changes required.

Safety

  • Status-only campaigns (no product_control, no product_exclude_by): _excludes_product returns false, _show_purchaseof returns true -> differ -> entry passes. No regression.
  • Explicit 'none' / 'none' configs: returns true / false -> still differ -> entry passes. No regression.
  • Pro inline entries without product_id: guarded with if ($product_id) -> falls through, original behavior preserved.
  • get_the_terms() result guarded with is_wp_error() + !empty().
  • php -l (PHP 8.2): clean.

Test plan

  • Create two FluentCart sales campaigns with different Selected Product values
  • Place a live order for the product selected in Campaign A -> only Campaign A fires
  • Place a live order for the product selected in Campaign B -> only Campaign B fires
  • Campaign with no product filter (status only) still fires for any matching order
  • Campaign with Exclude Products set: excluded product does not trigger; non-excluded does
  • Campaign with Product Category filter: orders for products in the selected category fire; others don't
  • Regenerate continues to behave identically (no double-filtering regressions)
  • FluentCart Pro inline source still renders correctly

Reported by client via Fluent Boards task #81314.

Real-time FluentCart orders trigger every enabled campaign whose
status matches, regardless of "Show Purchase Of: Selected Product"
or "Exclude Products" settings. The product/category filter was
only being applied inside get_orders() (Regenerate path), not in
the nx_can_entry filter chain used by live orders.

Extend FluentCart::nx_can_entry to apply the same
_excludes_product / _show_purchaseof check that get_orders() uses,
so the real-time path enforces product filtering consistently.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant