Created
December 10, 2025 08:31
-
-
Save xlplugins/8a3232e8a693935f1e3e4768936b98c8 to your computer and use it in GitHub Desktop.
Funnelkit Order Bump: Enables cascading/sequential order bumps functionality where selecting one order bump can trigger another bump to appear based on cart rules.
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
| if ( ! class_exists( 'WFOB_Cascading_Bumps_Handler' ) ) { | |
| class WFOB_Cascading_Bumps_Handler { | |
| /** | |
| * Flag to track if fragment unsetting should be processed | |
| * | |
| * @var bool | |
| */ | |
| private $process = false; | |
| /** | |
| * Constructor - Register all hooks | |
| */ | |
| public function __construct() { | |
| // Allow bump items to be counted in cart rules (enables cascading) | |
| add_filter( 'wfob_dont_allow_bump_item_in_rule', [ $this, 'allow_bump_items_in_rules' ], 10, 2 ); | |
| // Check for fragment unset flag during checkout update | |
| add_action( 'woocommerce_checkout_update_order_review', [ $this, 'check_fragment_unset_flag' ], 5 ); | |
| // Unset fragments to prevent conflicts during bump updates | |
| add_filter( 'woocommerce_update_order_review_fragments', [ $this, 'unset_fragments_on_bump_action' ], 900 ); | |
| // Add JavaScript to handle bump add/remove events | |
| add_action( 'wp_footer', [ $this, 'add_bump_control_script' ] ); | |
| } | |
| /** | |
| * Allow order bump items to be included in cart rule calculations | |
| * | |
| * By default, FunnelKit excludes bump items from rules. This filter | |
| * overrides that behavior to enable cascading bumps. | |
| * | |
| * @param bool $status Current status (true = exclude, false = include) | |
| * @param array $item Cart item data | |
| * @return bool False to include bump items in rules | |
| */ | |
| public function allow_bump_items_in_rules( $status, $item ) { | |
| if ( isset( $item['_wfob_product'] ) ) { | |
| // Return false to INCLUDE bump items in rule calculations | |
| // This allows Order Bump 1 to trigger Order Bump 2's rules | |
| $status = false; | |
| } | |
| return $status; | |
| } | |
| /** | |
| * Check for fragment unset flag in posted checkout data | |
| * | |
| * When a bump is added/removed, the JavaScript sets a flag that | |
| * tells this method to unset fragments on the next update. | |
| * | |
| * @param string $data Posted checkout data | |
| * @return void | |
| */ | |
| public function check_fragment_unset_flag( $data ) { | |
| if ( empty( $data ) ) { | |
| return; | |
| } | |
| // Parse the posted data string | |
| parse_str( $data, $post_data ); | |
| if ( empty( $post_data ) || empty( $post_data['wfob_input_hidden_data'] ) ) { | |
| return; | |
| } | |
| // Decode the bump action data | |
| $bump_action_data = json_decode( $post_data['wfob_input_hidden_data'], true ); | |
| if ( empty( $bump_action_data ) ) { | |
| return; | |
| } | |
| // Check if fragment unsetting was requested | |
| if ( isset( $bump_action_data['temp_unset_frg'] ) ) { | |
| $this->process = true; | |
| } | |
| } | |
| /** | |
| * Unset WFACP and WFOB fragments during bump actions | |
| * | |
| * Prevents fragment update conflicts when bumps are added/removed. | |
| * Allows checkout to fully refresh and re-evaluate all bump rules. | |
| * | |
| * @param array $fragments Checkout fragments to be updated | |
| * @return array Modified fragments array | |
| */ | |
| public function unset_fragments_on_bump_action( $fragments ) { | |
| // Only process if flag was set | |
| if ( false == $this->process ) { | |
| return $fragments; | |
| } | |
| // Remove WFACP and WFOB fragments to prevent conflicts | |
| foreach ( $fragments as $k => $fragment ) { | |
| if ( ( false !== strpos( $k, 'wfacp' ) || false !== strpos( $k, 'wfob' ) ) ) { | |
| unset( $fragments[ $k ] ); | |
| } | |
| } | |
| // Also remove cart total to force recalculation | |
| unset( $fragments['cart_total'] ); | |
| return $fragments; | |
| } | |
| /** | |
| * Add JavaScript to handle bump add/remove events | |
| * | |
| * This script: | |
| * 1. Sets a flag when bumps are added/removed | |
| * 2. Triggers checkout update to re-evaluate bump rules | |
| * 3. Enables cascading bumps to appear/disappear dynamically | |
| * | |
| * @return void | |
| */ | |
| public function add_bump_control_script() { | |
| // Only run on checkout page | |
| if ( ! is_checkout() ) { | |
| return; | |
| } | |
| ?> | |
| <script> | |
| window.addEventListener('load', function () { | |
| (function ($) { | |
| // Hook into FunnelKit's bump add/remove filters | |
| wfob_frontend.hooks.addFilter('wfob_before_ajax_data_add_order_bump', set_fragment_unset_flag); | |
| wfob_frontend.hooks.addFilter('wfob_before_ajax_data_remove_order_bump', set_fragment_unset_flag); | |
| // Trigger checkout update after bump actions | |
| wfob_frontend.hooks.addAction('wfob_ajax_add_order_bump', trigger_checkout_refresh); | |
| wfob_frontend.hooks.addAction('wfob_ajax_remove_order_bump', trigger_checkout_refresh); | |
| /** | |
| * Set flag to unset fragments during next checkout update | |
| */ | |
| function set_fragment_unset_flag(data) { | |
| data['temp_unset_frg'] = 'yes'; | |
| return data; | |
| } | |
| /** | |
| * Trigger checkout update to re-evaluate bump rules | |
| */ | |
| function trigger_checkout_refresh(rsp) { | |
| $(document.body).trigger('update_checkout'); | |
| } | |
| })(jQuery); | |
| }); | |
| </script> | |
| <?php | |
| } | |
| } | |
| // Initialize the cascading bumps handler | |
| new WFOB_Cascading_Bumps_Handler(); | |
| } // End class_exists check |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment