PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 3.13.3
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v3.13.3
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
← All changes | public/class-wpfnl-public.php +577 -286 2.8.16 → 3.13.3 View file →
@@ -1,10 +1,12 @@
1 1 <?php
2 +
2 3 /**
3 4 * WPFunnels public module
4 - *
5 + *
5 6 * @package WPFunnels\Frontend
6 7 */
8 +
7 9 namespace WPFunnels\Frontend;
8 10
9 11 use PLL_Model;
10 12 use PLL_Translated_Post;
@@ -49,62 +51,125 @@
49 51 * Initialize the class and set its properties.
50 52 *
51 53 * @param string $plugin_name The name of the plugin.
52 54 * @param string $version The version of this plugin.
53 - *
55 + *
54 56 * @since 1.0.0
55 57 */
56 58 public function __construct()
57 59 {
58 60 /**
59 - * This will trigger when funnel first start
60 - */
61 - add_action( 'wp', array($this, 'init_funnel'), 1 );
62 - add_action( 'wp', array($this, 'init_wp_actions'), 55 );
61 + * This will trigger when funnel first start
62 + */
63 + add_action('wp', array($this, 'init_funnel'), 1);
64 + add_action('wp', array($this, 'init_wp_actions'), 55);
63 65
64 - add_action( 'wp_enqueue_scripts', [$this, 'enqueue_styles'] );
65 - add_action( 'wp_enqueue_scripts', [$this, 'enqueue_scripts'] );
66 + add_action('wp_enqueue_scripts', [$this, 'enqueue_styles']);
67 + add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts']);
66 68
67 - add_action( 'init' , array($this, 'init_function') );
69 + add_action('init', array($this, 'init_function'));
68 70
69 - add_filter( 'wpfnl_offer_meta', array($this, 'wpfnl_offer_meta'), 10, 1 );
71 + add_filter('wpfnl_offer_meta', array($this, 'wpfnl_offer_meta'), 10, 1);
70 72
71 73 /**
72 74 * Modify the checkout order received url to next step
73 75 */
74 - add_filter( 'woocommerce_get_checkout_order_received_url', [$this, 'redirect_to_funnel_thankyou_page'], 10, 2 );
76 + add_filter('woocommerce_get_checkout_order_received_url', [$this, 'redirect_to_funnel_thankyou_page'], 1000, 2);
75 77
76 78 /*
77 79 * This hook will be triggered once the elementor data is saved.
78 80 * Will be placed this hook on another class in future.
79 81 */
80 - add_action( 'elementor/editor/after_save', array($this, 'elementor_data_after_save_action'), 10, 2 );
81 - add_filter( 'woocommerce_hidden_order_itemmeta', array($this, 'wpfnl_woocommerce_hidden_order_itemmeta'), 10, 1 );
82 + add_action('elementor/editor/after_save', array($this, 'elementor_data_after_save_action'), 10, 2);
83 + add_filter('woocommerce_hidden_order_itemmeta', array($this, 'wpfnl_woocommerce_hidden_order_itemmeta'), 10, 1);
82 84
83 - add_filter( 'woocommerce_order_item_display_meta_key', array($this, 'wpfnl_beautify_item_meta_on_order'), 10, 3 );
85 + add_filter('woocommerce_order_item_display_meta_key', array($this, 'wpfnl_beautify_item_meta_on_order'), 10, 3);
84 86
85 - add_filter( 'woocommerce_order_item_display_meta_value', array($this, 'wpfnl_update_order_item_display_meta_value'), 9999, 3 );
87 + add_filter('woocommerce_order_item_display_meta_value', array($this, 'wpfnl_update_order_item_display_meta_value'), 9999, 3);
86 88
87 89
88 90 /**
89 - * Trigger ajax if any user abandoned a funnel
90 - */
91 - add_action( 'wp_ajax_nopriv_maybe_abandoned_funnel', array($this, 'maybe_abandoned_funnel'), 10 );
92 - add_action( 'wp_ajax_maybe_abandoned_funnel', array($this, 'maybe_abandoned_funnel'), 10 );
91 + * Trigger ajax if any user abandoned a funnel
92 + */
93 + add_action('wp_ajax_nopriv_maybe_abandoned_funnel', array($this, 'maybe_abandoned_funnel'), 10);
94 + add_action('wp_ajax_maybe_abandoned_funnel', array($this, 'maybe_abandoned_funnel'), 10);
93 95
94 - add_action( 'wpfunnels/funnel_journey_end', array( $this, 'end_journey' ), 10, 2 );
96 + add_action('wpfunnels/funnel_journey_end', array($this, 'end_journey'), 10, 2);
95 97
96 - add_filter( 'woocommerce_add_cart_item_data', [$this,'namespace_force_individual_cart_items'], 10, 2 );
97 - add_filter( 'wpfunnels/funnel_order_placed', [$this,'add_order_details_to_logger'], 10, 3 );
98 - add_action( 'wpfunnels/after_optin_submit', array( $this, 'add_optin_data_to_logger' ), 10, 4 );
99 - add_action( 'wpfunnels/after_optin_submit', array( $this, 'get_optin_data' ), 10, 4 );
100 - add_action( 'wpfunnels/after_optin_submit', [ $this, 'register_optin_user' ], 10, 5 );
101 - add_action( 'wpfunnels/optin_submission_response', [ $this, 'regenerate_redirect_url' ], 10, 5 );
98 + add_filter('woocommerce_add_cart_item_data', [$this, 'namespace_force_individual_cart_items'], 10, 2);
99 + add_filter('woocommerce_cart_item_name', [$this, 'wpfnl_order_bump_cart_item_name'], 10, 3);
100 + add_filter('woocommerce_checkout_cart_item_quantity', [$this, 'wpfnl_order_bump_cart_item_quantity'], 10, 3);
101 + add_action('woocommerce_checkout_create_order_line_item', [$this, 'wpfnl_order_bump_order_line_item'], 10, 4);
102 + add_filter('wpfunnels/funnel_order_placed', [$this, 'add_order_details_to_logger'], 10, 3);
103 + add_action('wpfunnels/after_optin_submit', array($this, 'add_optin_data_to_logger'), 10, 4);
104 + add_action('wpfunnels/after_optin_submit', array($this, 'get_optin_data'), 10, 4);
105 + add_action('wpfunnels/after_optin_submit', [$this, 'register_optin_user'], 10, 5);
106 + add_action('wpfunnels/optin_submission_response', [$this, 'regenerate_redirect_url'], 10, 5);
102 107
103 - add_filter( 'posts_where', array( $this, 'posts_where' ), 99 );
108 + add_filter('posts_where', array($this, 'posts_where'), 99);
109 +
110 + /**
111 + * Add edit funnel menu at admin bar
112 + */
113 + add_action('admin_bar_menu', array($this, 'add_edit_funnel_menu'), 999);
114 +
115 + /**
116 + * Add custom script
117 + */
118 + add_action('wp_head', array($this, 'add_custom_script'));
119 + add_action('wp_head', array($this, 'add_custom_css'));
120 +
121 + // remove woodmart hook for funnel checkout
122 + add_action('wp', [$this, 'remove_woodmart_hook'], 150);
123 +
124 + add_action( 'wp_footer', array( $this, 'load_variable_product_modal' ) );
125 +
126 +
104 127 }
105 128
106 129 /**
130 + * Removes Woodmart theme related hooks from the checkout page.
131 + *
132 + * This function is called when the checkout page is loaded in the admin or frontend.
133 + * It checks if the Woodmart theme is active and if the current page is a checkout page.
134 + * If both conditions are met, it removes the 'woodmart_enqueue_base_styles' action
135 + * with a priority of 10000 and the 'woodmart_sticky_toolbar_template' action with a priority of 10000.
136 + *
137 + * @since 3.4.9
138 + */
139 + public function remove_woodmart_hook()
140 + {
141 + global $post;
142 +
143 + // Check if we are in the admin or if the post object is not set
144 + if (is_admin() || !$post) {
145 + return;
146 + }
147 +
148 + $checkout_id = '';
149 +
150 + // Check if we are doing an AJAX request
151 + if (wp_doing_ajax()) {
152 + // Get the checkout ID from the POST data
153 + $checkout_id = Wpfnl_functions::get_checkout_id_from_post($_POST);
154 + }
155 +
156 + // If the checkout ID is not set, use the current post ID
157 + $checkout_id = !$checkout_id ? $post->ID : $checkout_id;
158 + $funnel_id = Wpfnl_functions::get_funnel_id_from_step( $checkout_id );
159 + // Check if the Woodmart theme is active and if the current page is a checkout page
160 + if (Wpfnl_functions::maybe_woodmart_theme() && $checkout_id && $funnel_id) {
161 + // Remove the 'woodmart_enqueue_base_styles' action with a priority of 10000
162 + remove_action('wp_enqueue_scripts', 'woodmart_enqueue_base_styles', 10000);
163 +
164 + // Remove the 'woodmart_sticky_toolbar_template' action with a priority of 10000
165 + remove_action('wp_footer', 'woodmart_sticky_toolbar_template', 10000);
166 + }
167 + }
168 +
169 +
170 +
171 + /**
107 172 * Modify the SQL JOIN clause to exclude language-based filtering when querying posts.
108 173 *
109 174 * This function is a filter callback used in WordPress to customize the SQL query's JOIN clause
110 175 * when retrieving posts. It is specifically designed to work with the Polylang plugin to exclude
@@ -116,15 +181,16 @@
116 181 *
117 182 * @see https://polylang.pro/
118 183 * @since 2.8.6
119 184 */
120 - public function posts_join( $join ) {
121 - if( class_exists( 'PLL_Model' ) && class_exists( 'PLL_Translated_Post' ) ) {
122 - $pll_options = get_option( 'polylang', [] );
123 - $model = new PLL_Model( $pll_options );
124 - $post = new PLL_Translated_Post( $model );
185 + public function posts_join($join)
186 + {
187 + if (class_exists('PLL_Model') && class_exists('PLL_Translated_Post')) {
188 + $options = new \WP_Syntex\Polylang\Options\Options();
189 + $model = new PLL_Model($options);
190 + $post = new PLL_Translated_Post($model);
125 191 $custom_join = $post->join_clause();
126 - return str_replace( $custom_join, '', $join );
192 + return str_replace($custom_join, '', $join);
127 193 }
128 194 return $join;
129 195 }
130 196
@@ -142,13 +208,14 @@
142 208 *
143 209 * @see https://wordpress.org/
144 210 * @since 2.8.6
145 211 */
146 - public function posts_where( $where ) {
147 - if( preg_match( '/wpfunnel_steps/', $where ) ) {
148 - add_filter( 'posts_join', array( $this, 'posts_join' ), 99 );
212 + public function posts_where($where)
213 + {
214 + if (preg_match('/wpfunnel_steps/', $where)) {
215 + add_filter('posts_join', array($this, 'posts_join'), 99);
149 216 $lang = $this->get_pll_term_id();
150 - return str_replace( "AND pll_tr.term_taxonomy_id = {$lang}", '', $where );
217 + return str_replace("AND pll_tr.term_taxonomy_id = {$lang}", '', $where);
151 218 }
152 219 return $where;
153 220 }
154 221
@@ -164,12 +231,13 @@
164 231 *
165 232 * @see https://polylang.pro/
166 233 * @since 2.8.6
167 234 */
168 - private function get_pll_term_id() {
235 + private function get_pll_term_id()
236 + {
169 237 global $wpdb;
170 - $pll_options = get_option( 'polylang', [] );
171 - return $wpdb->get_var( $wpdb->prepare( "SELECT `term_id` FROM %i WHERE `slug`=%s", [ $wpdb->terms, $pll_options[ 'default_lang' ] ?? '' ] ) );
238 + $pll_options = get_option('polylang', []);
239 + return $wpdb->get_var($wpdb->prepare("SELECT `term_id` FROM %i WHERE `slug`=%s", [$wpdb->terms, $pll_options['default_lang'] ?? '']));
172 240 }
173 241
174 242 /**
175 243 * Add individual items in cart forcefully. It's implemented for indentifying orderbump items
@@ -178,27 +246,82 @@
178 246 * @param String
179 247 *
180 248 * @return Array
181 249 */
182 - public function namespace_force_individual_cart_items( $cart_item_data, $product_id ) {
250 + public function namespace_force_individual_cart_items($cart_item_data, $product_id)
251 + {
183 252
184 253 $post_action = filter_input_array(INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS);
185 - if( isset( $post_action['action'] ) && ( 'wpfnl_order_bump_ajax' === $post_action['action'] || 'wpfnl_order_bump_ajax' === $post_action['action'] ) ){
186 - $unique_cart_item_key = md5( microtime() . rand() );
254 + if (isset($post_action['action']) && ('wpfnl_order_bump_ajax' === $post_action['action'] || 'wpfnl_order_bump_ajax' === $post_action['action'])) {
255 + $unique_cart_item_key = md5(microtime() . rand());
187 256 $cart_item_data['unique_key'] = $unique_cart_item_key;
257 + }
258 + return $cart_item_data;
259 + }
188 260
261 +
262 +
263 + /**
264 + * Display custom product title for order bump items in cart
265 + *
266 + * @param string $product_name
267 + * @param array $cart_item
268 + * @param string $cart_item_key
269 + * @return string
270 + */
271 + public function wpfnl_order_bump_cart_item_name($product_name, $cart_item, $cart_item_key)
272 + {
273 + if (isset($cart_item['wpfnl_order_bump']) && $cart_item['wpfnl_order_bump'] && isset($cart_item['wpfnl_ob_title']) && !empty($cart_item['wpfnl_ob_title'])) {
274 + return $cart_item['wpfnl_ob_title'];
189 275 }
190 - return $cart_item_data;
276 + return $product_name;
191 277 }
192 278
279 + /**
280 + * Display custom quantity for order bump items in cart
281 + *
282 + * @param string $quantity
283 + * @param array $cart_item
284 + * @param string $cart_item_key
285 + * @return string
286 + */
287 + public function wpfnl_order_bump_cart_item_quantity($quantity, $cart_item, $cart_item_key)
288 + {
289 + if (isset($cart_item['wpfnl_order_bump']) && $cart_item['wpfnl_order_bump'] && isset($cart_item['wpfnl_ob_quantity'])) {
290 + // When the checkout step has quantity selection enabled, let the bump
291 + // item go through the same editable quantity control as every other
292 + // cart item instead of forcing a fixed, non-editable badge.
293 + $step_id = wp_doing_ajax() ? Wpfnl_functions::is_funnel_checkout_page()['id'] : get_the_ID();
294 + if ( 'yes' === get_post_meta( $step_id, '_wpfnl_quantity_support', true ) ) {
295 + return $quantity;
296 + }
297 + return ' <strong class="product-quantity">' . $cart_item['quantity'] . '</strong>';
298 + }
299 + return $quantity;
300 + }
193 301
302 + /**
303 + * Add custom product title to order line item meta
304 + *
305 + * @param \WC_Order_Item_Product $item
306 + * @param string $cart_item_key
307 + * @param array $values
308 + * @param \WC_Order $order
309 + */
310 + public function wpfnl_order_bump_order_line_item($item, $cart_item_key, $values, $order)
311 + {
312 + if (isset($values['wpfnl_order_bump']) && $values['wpfnl_order_bump'] && isset($values['wpfnl_ob_title']) && !empty($values['wpfnl_ob_title'])) {
313 + $item->set_name($values['wpfnl_ob_title']);
314 + }
315 + }
194 316
195 317 /**
196 318 * Initialize function
197 319 */
198 - public function init_function(){
320 + public function init_function()
321 + {
199 322 $offer_meta = ['_wpfunnels_order_bump'];
200 - return apply_filters( 'wpfnl_offer_meta', $offer_meta );
323 + return apply_filters('wpfnl_offer_meta', $offer_meta);
201 324 }
202 325
203 326 /**
204 327 * Init actions for a funnel
@@ -228,17 +351,21 @@
228 351 }
229 352 }
230 353
231 354
232 - public function init_wp_actions() {
233 - if (Wpfnl_functions::is_funnel_step_page('')) {
355 + public function init_wp_actions()
356 + {
357 + $is_ajax = wp_doing_ajax() || isset( $_GET['wc-ajax'] );
358 + if ( Wpfnl_functions::is_funnel_step_page('') || $is_ajax ) {
234 359 /**
235 - * Enqueue public styles
236 - */
237 - add_action( 'wp_enqueue_scripts', array($this, 'enqueue_styles') );
238 - add_action( 'wp_enqueue_scripts', array($this, 'enqueue_scripts') );
239 - add_action( 'wp_enqueue_scripts', array($this, 'remove_theme_styles') );
240 - add_filter( 'woocommerce_enqueue_styles', array( $this, 'enqueue_wc_styles' ), 9999 );
360 + * Enqueue public styles
361 + */
362 + if ( ! $is_ajax ) {
363 + add_action('wp_enqueue_scripts', array($this, 'enqueue_styles'));
364 + add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
365 + add_action('wp_enqueue_scripts', array($this, 'remove_theme_styles'));
366 + add_filter('woocommerce_enqueue_styles', array($this, 'enqueue_wc_styles'), 9999);
367 + }
241 368
242 369 add_filter('woocommerce_locate_template', array($this, 'wpfunnels_woocommerce_locate_template'), 20, 3);
243 370 }
244 371 }
@@ -263,11 +390,11 @@
263 390 * between the defined hooks and the functions defined in this
264 391 * class.
265 392 */
266 393
267 - if(Wpfnl_functions::is_funnel_step_page()) {
268 - add_filter( 'astra_theme_woocommerce_dynamic_css', '__return_empty_string' );
269 -
394 + if (Wpfnl_functions::is_funnel_step_page()) {
395 + add_filter('astra_theme_woocommerce_dynamic_css', '__return_empty_string');
396 +
270 397 wp_enqueue_style('wpfnl-public', plugin_dir_url(__FILE__) . 'assets/css/wpfnl-public.css', [], WPFNL_VERSION, 'all');
271 398 //$this->load_googlefonts();
272 399 }
273 400 }
@@ -290,17 +417,37 @@
290 417 * The Wpfnl_Loader will then create the relationship
291 418 * between the defined hooks and the functions defined in this
292 419 * class.
293 420 */
294 - if(Wpfnl_functions::is_funnel_step_page()) {
421 + if (Wpfnl_functions::is_funnel_step_page()) {
295 422
296 423 $compatibility = Wpfnl_Theme_Compatibility::getInstance();
297 424
298 425 wp_enqueue_script('wpfnl-public', plugin_dir_url(__FILE__) . 'assets/js/wpfnl-public.js', ['jquery'], WPFNL_VERSION, false);
299 - wp_localize_script('wpfnl-public', 'wpfnl_obj', [
426 + if ( Wpfnl_functions::is_funnel_step_page( 'checkout' ) ) {
427 + $checkout_id = get_the_ID();
428 + $order_bump_settings = get_post_meta( $checkout_id, 'order-bump-settings', true );
429 +
430 + if ( ! empty( $order_bump_settings ) ) {
431 + foreach ( $order_bump_settings as $key => $settings ) {
432 + if ( isset( $settings['product'] ) ) {
433 + $product = wc_get_product( $settings['product'] );
434 + if ( $product && $product->is_type( 'variable' ) ) {
435 + wp_enqueue_script( 'wc-single-product' );
436 + break;
437 + }
438 + }
439 + }
440 + }
441 + }
442 + wp_enqueue_script('wpfnl-order-bump-variable', plugin_dir_url(__FILE__) . 'assets/js/order-bump-variable.js', array( 'jquery', 'wc-add-to-cart-variation' ), WPFNL_VERSION, true);
443 + wp_localize_script(
444 + 'wpfnl-public',
445 + 'wpfnl_obj',
446 + [
300 447 'ajaxurl' => admin_url('admin-ajax.php'),
301 448 'is_builder_preview' => $compatibility->is_builder_preview(),
302 - 'funnel_id' => get_post_meta( get_the_ID(), '_funnel_id', true ),
449 + 'funnel_id' => get_post_meta(get_the_ID(), '_funnel_id', true),
303 450 'step_id' => get_the_ID(),
304 451 'ajax_nonce' => wp_create_nonce('wpfnl'),
305 452 'abandoned_ajax_nonce' => wp_create_nonce('abandoned_ajax_nonce'),
306 453 'optin_form_nonce' => wp_create_nonce('optin_form_nonce'),
@@ -305,11 +452,36 @@
305 452 'abandoned_ajax_nonce' => wp_create_nonce('abandoned_ajax_nonce'),
306 453 'optin_form_nonce' => wp_create_nonce('optin_form_nonce'),
307 454 'is_user_logged_in' => is_user_logged_in(),
308 455 'user_id' => get_current_user_id(),
309 - 'is_login_reminder' => get_option( 'woocommerce_enable_checkout_login_reminder' ),
456 + 'is_login_reminder' => get_option('woocommerce_enable_checkout_login_reminder'),
457 + 'express_checkout_enabled' => get_post_meta(get_the_ID(), '_wpfnl_express_checkout_enabled', true) ? get_post_meta(get_the_ID(), '_wpfnl_express_checkout_enabled', true) : 'no',
458 + 'field_validation_enabled' => get_post_meta(get_the_ID(), '_wpfnl_field_validation_enabled', true) ? get_post_meta(get_the_ID(), '_wpfnl_field_validation_enabled', true) : 'no',
459 + 'field_validation_message' => get_post_meta(get_the_ID(), '_wpfnl_field_validation_message', true) ? get_post_meta(get_the_ID(), '_wpfnl_field_validation_message', true) : '{field} is required',
460 + 'display_product_images' => get_post_meta(get_the_ID(), '_wpfnl_display_product_images', true) ? get_post_meta(get_the_ID(), '_wpfnl_display_product_images', true) : 'no',
461 + 'collapsible_order_summary_enabled' => get_post_meta(get_the_ID(), '_wpfnl_collapsible_order_summary_enabled', true) !== '' ? get_post_meta(get_the_ID(), '_wpfnl_collapsible_order_summary_enabled', true) : 'yes',
462 + 'enhanced_phone_field_enabled' => get_post_meta(get_the_ID(), '_wpfnl_enhanced_phone_field_enabled', true) ? get_post_meta(get_the_ID(), '_wpfnl_enhanced_phone_field_enabled', true) : 'no',
463 + 'validate_phone_number' => get_post_meta(get_the_ID(), '_wpfnl_validate_phone_number', true) ? get_post_meta(get_the_ID(), '_wpfnl_validate_phone_number', true) : 'no',
464 + 'save_phone_number_format' => get_post_meta(get_the_ID(), '_wpfnl_save_phone_number_format', true) ? get_post_meta(get_the_ID(), '_wpfnl_save_phone_number_format', true) : 'without_country_code',
465 + 'phone_help_text' => get_post_meta(get_the_ID(), '_wpfnl_phone_help_text', true) ? get_post_meta(get_the_ID(), '_wpfnl_phone_help_text', true) : '',
466 + 'phone_utils_url' => plugin_dir_url(__FILE__) . 'assets/phone/js/utils.js',
310 467 ]
311 468 );
469 +
470 + if ('yes' === (get_post_meta(get_the_ID(), '_wpfnl_enhanced_phone_field_enabled', true) ? get_post_meta(get_the_ID(), '_wpfnl_enhanced_phone_field_enabled', true) : 'no')) {
471 + wp_enqueue_style('intl-tel-input-style', plugin_dir_url(__FILE__) . 'assets/phone/css/intlTelInput.css', array(), WPFNL_VERSION);
472 + wp_enqueue_script('intl-tel-input-script', plugin_dir_url(__FILE__) . 'assets/phone/js/intlTelInput.min.js', array('jquery'), WPFNL_VERSION, true);
473 + wp_enqueue_script('intl-tel-input-utils', plugin_dir_url(__FILE__) . 'assets/phone/js/utils.js', array('intl-tel-input-script'), WPFNL_VERSION, true);
474 + }
475 +
476 + $post_id = get_the_ID();
477 + $custom_css = get_post_meta($post_id, 'rex_gutenberg_css', true);
478 +
479 + if ($custom_css) {
480 + wp_register_style('rex-gutenberg-css', false);
481 + wp_enqueue_style('rex-gutenberg-css');
482 + wp_add_inline_style('rex-gutenberg-css', $custom_css);
483 + }
312 484 }
313 485 }
314 486
315 487
@@ -315,16 +487,17 @@
315 487
316 488 /**
317 489 * This functions are from qubely.
318 490 */
319 - private function load_googlefonts() {
491 + private function load_googlefonts()
492 + {
320 493 global $blocks;
321 494 $contains_wpfnl_blocks = false;
322 495 $block_fonts = [];
323 - $load_google_fonts ='yes';
496 + $load_google_fonts = 'yes';
324 497
325 498 if ($load_google_fonts == 'yes') {
326 - $blocks=$this->parse_all_blocks();
499 + $blocks = $this->parse_all_blocks();
327 500 $contains_wpfnl_blocks = $this->has_wpfnl_blocks($blocks);
328 501
329 502 if ($contains_wpfnl_blocks) {
330 503 $block_fonts = $this->gather_block_fonts($blocks, $block_fonts);
@@ -384,9 +557,10 @@
384 557 * Parse all blocks
385 558 *
386 559 * @return array[]
387 560 */
388 - public function parse_all_blocks(){
561 + public function parse_all_blocks()
562 + {
389 563 $blocks;
390 564 if (is_single() || is_page() || is_404()) {
391 565 global $post;
392 566 if (is_object($post) && property_exists($post, 'post_content')) {
@@ -407,12 +581,13 @@
407 581 /**
408 582 * Check whether the contents has wpfnl blocks or not
409 583 *
410 584 * @param $blocks
411 - *
585 + *
412 586 * @return bool
413 587 */
414 - public function has_wpfnl_blocks($blocks){
588 + public function has_wpfnl_blocks($blocks)
589 + {
415 590 $is_wpfnl_block = false;
416 591 foreach ($blocks as $key => $block) {
417 592 if (strpos($block['blockName'], 'wpfnl') !== false) {
418 593 $is_wpfnl_block = true;
@@ -429,12 +604,13 @@
429 604 * Gather block google fonts
430 605 *
431 606 * @param $blocks
432 607 * @param $block_fonts
433 - *
608 + *
434 609 * @return array
435 610 */
436 - public function gather_block_fonts($blocks,$block_fonts){
611 + public function gather_block_fonts($blocks, $block_fonts)
612 + {
437 613 $google_fonts = $block_fonts;
438 614 foreach ($blocks as $key => $block) {
439 615 if (strpos($block['blockName'], 'wpfnl') !== false) {
440 616 foreach ($block['attrs'] as $key => $att) {
@@ -440,20 +616,20 @@
440 616 foreach ($block['attrs'] as $key => $att) {
441 617 if (gettype($att) == 'array' && isset($att['openTypography']) && isset($att['family'])) {
442 618 if (isset($block['attrs'][$key]['activeSource'])) {
443 619 if ($block['attrs'][$key]['activeSource'] == 'custom') {
444 - array_push($google_fonts,$block['attrs'][$key]['family']);
620 + array_push($google_fonts, $block['attrs'][$key]['family']);
445 621 }
446 622 } else {
447 - array_push($google_fonts,$block['attrs'][$key]['family']);
623 + array_push($google_fonts, $block['attrs'][$key]['family']);
448 624 }
449 625 }
450 626 }
451 627 }
452 - if(isset($block['innerBlocks']) && gettype($block['innerBlocks']) == 'array' && count($block['innerBlocks'])>0){
453 - $child_fonts=$this->gather_block_fonts($block['innerBlocks'],$google_fonts);
454 - if(count($child_fonts)>0){
455 - $google_fonts= array_merge($google_fonts,$child_fonts);
628 + if (isset($block['innerBlocks']) && gettype($block['innerBlocks']) == 'array' && count($block['innerBlocks']) > 0) {
629 + $child_fonts = $this->gather_block_fonts($block['innerBlocks'], $google_fonts);
630 + if (count($child_fonts) > 0) {
631 + $google_fonts = array_merge($google_fonts, $child_fonts);
456 632 }
457 633 }
458 634 }
459 635 return array_unique($google_fonts);
@@ -461,21 +637,22 @@
461 637
462 638
463 639 /**
464 640 * Columns from array
465 - *
641 + *
466 642 * @param array $array
467 643 * @param $keys
468 - *
644 + *
469 645 * @return array
470 646 */
471 - public function colsFromArray(array $array, $keys) {
647 + public function colsFromArray(array $array, $keys)
648 + {
472 649 if (!is_array($keys)) $keys = [$keys];
473 650 return array_map(function ($el) use ($keys) {
474 651 $o = [];
475 - foreach($keys as $key){
652 + foreach ($keys as $key) {
476 653 // if(isset($el[$key]))$o[$key] = $el[$key]; //you can do it this way if you don't want to set a default for missing keys.
477 - $o[$key] = isset($el[$key])?$el[$key]:false;
654 + $o[$key] = isset($el[$key]) ? $el[$key] : false;
478 655 }
479 656 return $o;
480 657 }, $array);
481 658 }
@@ -485,12 +662,13 @@
485 662 * Remove theme style
486 663 *
487 664 * @return bool
488 665 */
489 - public function remove_theme_styles() {
490 - if( Wpfnl_functions::is_funnel_step_page() ) {
666 + public function remove_theme_styles()
667 + {
668 + if (Wpfnl_functions::is_funnel_step_page()) {
491 669
492 - if ( Wpfnl_Theme_Compatibility::getInstance()->is_compatible_theme_enabled() ) {
670 + if (Wpfnl_Theme_Compatibility::getInstance()->is_compatible_theme_enabled()) {
493 671 return;
494 672 }
495 673
496 674 $general_settings = Wpfnl_functions::get_general_settings();
@@ -497,20 +675,19 @@
497 675
498 676 $wp_styles = wp_styles();
499 677 $themes_uri = get_theme_root_uri();
500 678
501 - if( $general_settings['disable_theme_style'] == 'on' ){
679 + if ($general_settings['disable_theme_style'] == 'on') {
502 680 $dequeue_theme_style = apply_filters('wpfunnels/dequeue_theme_style', true);
503 -
504 - }else {
681 + } else {
505 682 $dequeue_theme_style = apply_filters('wpfunnels/dequeue_theme_style', false);
506 683 }
507 684
508 - if($dequeue_theme_style) {
509 - foreach ( $wp_styles->registered as $wp_style ) {
510 - if ( strpos( $wp_style->src, $themes_uri ) !== false ) {
511 - wp_deregister_style( $wp_style->handle );
512 - wp_dequeue_style( $wp_style->handle );
685 + if ($dequeue_theme_style) {
686 + foreach ($wp_styles->registered as $wp_style) {
687 + if (strpos($wp_style->src, $themes_uri) !== false) {
688 + wp_deregister_style($wp_style->handle);
689 + wp_dequeue_style($wp_style->handle);
513 690 do_action('wpfunnels/enqueue_custom_scripts');
514 691 }
515 692 }
516 693 }
@@ -522,12 +699,13 @@
522 699 * Enqueue woocommerce styles
523 700 *
524 701 * @return array
525 702 */
526 - public function enqueue_wc_styles() {
703 + public function enqueue_wc_styles()
704 + {
527 705 $wc_styles = array(
528 706 'woocommerce-layout' => array(
529 - 'src' => plugins_url( 'assets/css/woocommerce-layout.css', WC_PLUGIN_FILE ),
707 + 'src' => plugins_url('assets/css/woocommerce-layout.css', WC_PLUGIN_FILE),
530 708 'deps' => '',
531 709 'version' => WC_VERSION,
532 710 'media' => 'all',
533 711 'has_rtl' => true,
@@ -532,16 +710,16 @@
532 710 'media' => 'all',
533 711 'has_rtl' => true,
534 712 ),
535 713 'woocommerce-smallscreen' => array(
536 - 'src' => plugins_url( 'assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE ),
714 + 'src' => plugins_url('assets/css/woocommerce-smallscreen.css', WC_PLUGIN_FILE),
537 715 'deps' => 'woocommerce-layout',
538 716 'version' => WC_VERSION,
539 - 'media' => 'only screen and (max-width: ' . apply_filters( 'woocommerce_style_smallscreen_breakpoint', '768px' ) . ')',
717 + 'media' => 'only screen and (max-width: ' . apply_filters('woocommerce_style_smallscreen_breakpoint', '768px') . ')',
540 718 'has_rtl' => true,
541 719 ),
542 720 'woocommerce-general' => array(
543 - 'src' => plugins_url( 'assets/css/woocommerce.css', WC_PLUGIN_FILE ),
721 + 'src' => plugins_url('assets/css/woocommerce.css', WC_PLUGIN_FILE),
544 722 'deps' => '',
545 723 'version' => WC_VERSION,
546 724 'media' => 'all',
547 725 'has_rtl' => true,
@@ -574,16 +752,14 @@
574 752
575 753 if ($checkout_widget || $lms_checkout_widget) {
576 754 $widget_settings = isset($checkout_widget['settings']) ? $checkout_widget['settings'] : $lms_checkout_widget['settings'];
577 755 $layout = isset($widget_settings['checkout_layout']) ? $widget_settings['checkout_layout'] : 'wpfnl-col-2';
578 - update_post_meta( $post_id, '_wpfnl_checkout_layout' , $layout);
756 + update_post_meta($post_id, '_wpfnl_checkout_layout', $layout);
579 757 $order_bump_status = get_post_meta($post_id, 'order-bump', true);
580 758 $order_bump_settings = get_post_meta($post_id, 'order-bump-settings', true);
581 759 $order_bump_enabled = 'no';
582 - $default_order_bump_data = [
760 + $default_order_bump_data = [];
583 761
584 - ];
585 -
586 762 if ($order_bump_status) {
587 763 $order_bump_enabled = $order_bump_status;
588 764 }
589 765
@@ -592,17 +768,17 @@
592 768 } else {
593 769 $order_bump_data = $default_order_bump_data;
594 770 }
595 771
596 - if( count($order_bump_data) > 0 ){
597 - foreach( $order_bump_data as $key=>$ob ){
598 - $order_bump_data[$key]['isEnabled'] = $this->set_order_bump_data('isEnabled', 'order_bump_'.$key, $widget_settings, $order_bump_data[$key], 'yes');
599 - $order_bump_data[$key]['selectedStyle'] = $this->set_order_bump_data('selectedStyle', 'order_bump_layout_'.$key, $widget_settings, $order_bump_data[$key], 'style1');
600 - $order_bump_data[$key]['position'] = $this->set_order_bump_data('position', 'order_bump_position_'.$key, $widget_settings, $order_bump_data[$key], 'after-order');
601 - $order_bump_data[$key]['checkBoxLabel'] = $this->set_order_bump_data('checkBoxLabel', 'order_bump_checkbox_label_'.$key, $widget_settings, $order_bump_data[$key], 'Grab this offer with one click!');
602 - $order_bump_data[$key]['highLightText'] = $this->set_order_bump_data('highLightText', 'order_bump_product_detail_header_'.$key, $widget_settings, $order_bump_data[$key], 'Special one time offer');
603 - $order_bump_data[$key]['productDescriptionText'] = $this->set_order_bump_data('productDescriptionText', 'order_bump_product_detail_'.$key, $widget_settings, $order_bump_data[$key], 'Get this scratch proof 6D Tempered Glass Screen Protector for your iPhone. Keep your phone safe and sound just like a new one.');
604 - $ob_image = $this->set_order_bump_data('productImage', 'order_bump_image_'.$key, $widget_settings, $order_bump_data[$key]);
772 + if (count($order_bump_data) > 0) {
773 + foreach ($order_bump_data as $key => $ob) {
774 + $order_bump_data[$key]['isEnabled'] = $this->set_order_bump_data('isEnabled', 'order_bump_' . $key, $widget_settings, $order_bump_data[$key], 'yes');
775 + $order_bump_data[$key]['selectedStyle'] = $this->set_order_bump_data('selectedStyle', 'order_bump_layout_' . $key, $widget_settings, $order_bump_data[$key], 'style1');
776 + $order_bump_data[$key]['position'] = $this->set_order_bump_data('position', 'order_bump_position_' . $key, $widget_settings, $order_bump_data[$key], 'after-order');
777 + $order_bump_data[$key]['checkBoxLabel'] = $this->set_order_bump_data('checkBoxLabel', 'order_bump_checkbox_label_' . $key, $widget_settings, $order_bump_data[$key], 'Grab this offer with one click!');
778 + $order_bump_data[$key]['highLightText'] = $this->set_order_bump_data('highLightText', 'order_bump_product_detail_header_' . $key, $widget_settings, $order_bump_data[$key], 'Special one time offer');
779 + $order_bump_data[$key]['productDescriptionText'] = $this->set_order_bump_data('productDescriptionText', 'order_bump_product_detail_' . $key, $widget_settings, $order_bump_data[$key], 'Get this scratch proof 6D Tempered Glass Screen Protector for your iPhone. Keep your phone safe and sound just like a new one.');
780 + $ob_image = $this->set_order_bump_data('productImage', 'order_bump_image_' . $key, $widget_settings, $order_bump_data[$key]);
605 781 $order_bump_data[$key]['productImage'] = array(
606 782 'id' => isset($ob_image['id']) ? $ob_image['id'] : 0,
607 783 'url' => isset($ob_image['url']) ? $ob_image['url'] : '',
608 784 );
@@ -620,78 +796,51 @@
620 796 * Redirect to next step
621 797 *
622 798 * @param $order_received_url
623 799 * @param $order
624 - *
800 + *
625 801 * @return string
626 802 *
627 803 * @since 1.0.0
628 804 */
629 - public function redirect_to_funnel_thankyou_page( $order_received_url, $order ) {
630 -
631 - if ( $order && Wpfnl_functions::check_if_funnel_order( $order )) {
632 -
805 + public function redirect_to_funnel_thankyou_page($order_received_url, $order)
806 + {
807 + if ($order && Wpfnl_functions::check_if_funnel_order($order)) {
633 808 $order_key = $order->get_order_key();
634 809 $order_id = $order->get_id();
635 810 $link = '#';
636 - $funnel_id = Wpfnl_functions::get_funnel_id_from_order( $order );
811 + $funnel_id = Wpfnl_functions::get_funnel_id_from_order($order);
637 812
638 - if ( !$funnel_id ) {
813 + if (!$funnel_id) {
639 814 return $link;
640 815 }
641 -
642 - $current_page_id = $order->get_meta('_wpfunnels_checkout_id');
643 - $next_step = Wpfnl_functions::get_next_step( $funnel_id, $current_page_id );
644 - $next_step = apply_filters( 'wpfunnels/next_step_data', $next_step );
645 - $next_step = apply_filters( 'wpfunnels/modify_next_step_based_on_order', $next_step, $order );
646 -
647 - if ($next_step && isset( $next_step['step_id'], $next_step['step_type'] )) {
648 - if ( 'conditional' !== $next_step['step_type'] ) {
649 - $next_step_id = $next_step['step_id'];
650 -
651 - if( isset($next_step['step_type']) && 'thankyou' === $next_step['step_type'] ){
652 - $custom_url = Wpfnl_functions::custom_url_for_thankyou_page( $next_step_id );
653 - if( $custom_url ){
654 - return $custom_url;
655 - }
656 - }
657 -
658 - $query_args = array(
659 - 'wpfnl-order' => $order_id,
660 - 'wpfnl-key' => $order_key,
661 - );
662 -
663 - $next_step_url = $this->get_thankyou_step_url( $funnel_id, $next_step_id, $order );
664 - if( $next_step_url ) {
665 - return add_query_arg( $query_args, $next_step_url );
666 - }
667 - return $order_received_url;
668 - } else {
669 - $condition = Wpfnl_Condition_Checker::getInstance();
670 - $condition_identifier = strval( $next_step['step_id'] );
671 - $condition_matched = $condition->check_condition( $funnel_id, $order, $condition_identifier, $current_page_id );
672 - $next_node = Wpfnl_functions::get_next_step( $funnel_id, $condition_identifier, $condition_matched );
673 - $next_node = apply_filters( 'wpfunnels/next_step_data', $next_node );
674 -
675 - if( isset($next_node['step_type']) && 'thankyou' === $next_node['step_type'] ){
676 - $custom_url = Wpfnl_functions::custom_url_for_thankyou_page( $next_node['step_id'] );
677 - if( $custom_url ){
678 - return $custom_url;
679 - }
680 - }
681 816
682 - $query_args = array(
683 - 'wpfnl-order' => $order_id,
684 - 'wpfnl-key' => $order_key,
685 - );
686 -
687 - $next_step_url = $this->get_thankyou_step_url( $funnel_id, $next_node['step_id'], $order );
688 - if( $next_step_url ) {
689 - return add_query_arg( $query_args, $next_step_url );
690 - }
691 - return $order_received_url;
817 + $current_page_id = apply_filters('wpfunnels/current_step_id', $order->get_meta('_wpfunnels_checkout_id'), $order);
818 + $parent_step_id = get_post_meta($current_page_id, '_parent_step_id', true);
819 + $current_page_id = $parent_step_id ? $parent_step_id : $current_page_id;
820 + $next_node = Wpfnl_functions::get_next_conditional_step($funnel_id, $current_page_id, $order);
821 + $next_node = apply_filters('wpfunnels/next_step_data', $next_node);
822 + $next_node = apply_filters('wpfunnels/modify_next_step_based_on_order', $next_node, $order);
823 +
824 + if (isset($next_node['step_type']) && 'thankyou' === $next_node['step_type']) {
825 + if( Wpfnl_functions::is_global_thank_you_page_enabled() ){
826 + return home_url() . '/checkout/order-received/' . $order_id . '/?key=' . $order_key;
692 827 }
828 + $custom_url = Wpfnl_functions::custom_url_for_thankyou_page($next_node['step_id']);
829 + if ($custom_url) {
830 + return $custom_url;
831 + }
693 832 }
833 +
834 + $query_args = array(
835 + 'wpfnl-order' => $order_id,
836 + 'wpfnl-key' => $order_key,
837 + );
838 + $query_args = apply_filters('wpfunnels/order_meta', $query_args, $order);
839 + $next_step_url = $this->get_thankyou_step_url($funnel_id, $next_node['step_id'], $order);
840 + if ($next_step_url) {
841 + return add_query_arg($query_args, $next_step_url);
842 + }
694 843 }
695 844 return $order_received_url;
696 845 }
697 846
@@ -701,12 +850,13 @@
701 850 *
702 851 * @param $funnel_id
703 852 * @param $step_id
704 853 * @param $order_received_url
705 - *
854 + *
706 855 * @return string
707 856 */
708 - private function get_thankyou_step_url( $funnel_id, $step_id, $order ) {
857 + private function get_thankyou_step_url($funnel_id, $step_id, $order)
858 + {
709 859 /**
710 860 * If pro plugin isn't installed, there is no need to redirect user to the
711 861 * offer page. So for the plugin we redirect the user to the funnel thankyou page
712 862 * forcefully. We have also placed a hook for next step url, which will be modified
@@ -711,31 +861,39 @@
711 861 * offer page. So for the plugin we redirect the user to the funnel thankyou page
712 862 * forcefully. We have also placed a hook for next step url, which will be modified
713 863 * on the pro plugin
714 864 */
715 - $next_step_url = get_permalink( $step_id );
865 +
866 + $next_step_url = get_permalink($step_id);
867 + $step_type = get_post_meta($step_id, '_step_type', true);
868 +
869 +
870 +
716 871 $thankyou_step_url = '';
717 - if ( Wpfnl_functions::check_if_this_is_step_type_by_id( $step_id, 'thankyou' ) ) {
718 - return apply_filters( 'wpfunnels/funnel_thankyou_page_url', $next_step_url, $order );
872 + if (Wpfnl_functions::check_if_this_is_step_type_by_id($step_id, 'thankyou')) {
873 + return apply_filters('wpfunnels/funnel_thankyou_page_url', $next_step_url, $order);
874 + } else {
875 + $thankyou_page_id = Wpfnl_functions::get_thankyou_page_id($funnel_id);
876 + if ($thankyou_page_id) {
877 + $thankyou_step_url = get_permalink($thankyou_page_id);
878 + }
719 879 }
720 - else {
721 - $thankyou_page_id = Wpfnl_functions::get_thankyou_page_id( $funnel_id );
722 - if( $thankyou_page_id ) {
723 - $thankyou_step_url = get_permalink( $thankyou_page_id );
724 - }
880 + if( ! defined( 'WPFNL_PRO_DIR' ) ){
881 + $thankyou_step_url = $next_step_url;
725 882 }
726 - return apply_filters( 'wpfunnels/next_step_url', $thankyou_step_url, $next_step_url, $order );
883 +
884 + return apply_filters('wpfunnels/next_step_url', $thankyou_step_url, $next_step_url, $order);
727 885 }
728 886
729 887
730 888 /**
731 889 * Set order bump data
732 - *
890 + *
733 891 * @param $settings_key
734 892 * @param $key
735 893 * @param $widget_settings
736 894 * @param string $default_value
737 - *
895 + *
738 896 * @return mixed|string
739 897 *
740 898 * @since 2.0.0
741 899 */
@@ -756,23 +914,31 @@
756 914 *
757 915 * @param $template
758 916 * @param $template_name
759 917 * @param $template_path
760 - *
918 + *
761 919 * @return string
762 920 *
763 921 * @since 2.0.3
764 922 */
765 - public function wpfunnels_woocommerce_locate_template( $template, $template_name, $template_path ) {
766 - $_template = $template;
767 - $plugin_path = WPFNL_DIR . 'woocommerce/templates/';
923 + public function wpfunnels_woocommerce_locate_template($template, $template_name, $template_path)
924 + {
925 + /***
926 + * Fires when change the wc template
927 + *
928 + * @since 2.8.21
929 + */
930 + if (apply_filters('wpfunnels/maybe_locate_template', true)) {
931 + $_template = $template;
932 + $plugin_path = WPFNL_DIR . 'woocommerce/templates/';
768 933
769 - if( file_exists( $plugin_path . $template_name ) ) {
770 - $template = $plugin_path . $template_name;
771 - }
934 + if (file_exists($plugin_path . $template_name)) {
935 + $template = $plugin_path . $template_name;
936 + }
772 937
773 - if( !$template ) {
774 - $template = $_template;
938 + if (!$template) {
939 + $template = $_template;
940 + }
775 941 }
776 942 return $template;
777 943 }
778 944
@@ -781,9 +947,10 @@
781 947 * Wpfnl offer meta
782 948 *
783 949 * Return offer meta
784 950 */
785 - public function wpfnl_offer_meta($offer_meta){
951 + public function wpfnl_offer_meta($offer_meta)
952 + {
786 953 $this->offer_metas = $offer_meta;
787 954 return $offer_meta;
788 955 }
789 956
@@ -793,10 +960,11 @@
793 960 * @param $meta
794 961 *
795 962 * @return $meta
796 963 */
797 - public function wpfnl_woocommerce_hidden_order_itemmeta($meta) {
798 - $meta = ['_wpfunnels_step_id','_wpfnl_upsell','_wpfnl_downsell','_wpfnl_step_id','_wpfunnels_offer_txn_id','_reduced_stock','_wpfunnels_offer_refunded'];
964 + public function wpfnl_woocommerce_hidden_order_itemmeta($meta)
965 + {
966 + $meta = ['_wpfunnels_step_id', '_wpfnl_upsell', '_wpfnl_downsell', '_wpfnl_step_id', '_wpfunnels_offer_txn_id', '_reduced_stock', '_wpfunnels_offer_refunded'];
799 967 return $meta;
800 968 }
801 969
802 970 /**
@@ -805,12 +973,13 @@
805 973 * @param $display_key, $meta, $item
806 974 *
807 975 * @return $display_key
808 976 */
809 - public function wpfnl_beautify_item_meta_on_order( $display_key, $meta, $item ){
977 + public function wpfnl_beautify_item_meta_on_order($display_key, $meta, $item)
978 + {
810 979 $offer_meta = '_wpfunnels_order_bump';
811 - if( is_admin() && $item->get_type() === 'line_item' && ( $meta->key === $offer_meta)) {
812 - $display_key = __("Offer Type", "wpfnl" );
980 + if (is_admin() && $item->get_type() === 'line_item' && ($meta->key === $offer_meta)) {
981 + $display_key = __("Offer Type", "wpfnl");
813 982 }
814 983 return $display_key;
815 984 }
816 985
@@ -820,38 +989,37 @@
820 989 * @param $display_key, $meta, $item
821 990 *
822 991 * @return $meta
823 992 */
824 - public function wpfnl_update_order_item_display_meta_value($display_key, $meta, $item){
825 - if( isset($item['order_id']) && $item['order_id'] ){
826 - $order = wc_get_order( $item['order_id'] );
827 - if ( $order && Wpfnl_functions::check_if_funnel_order($order) ) {
828 - if( is_admin() && $item->get_type() === 'line_item' && ( $meta->key === '_wpfunnels_order_bump')) {
829 - $meta = __("Order Bump", "wpfnl" );
993 + public function wpfnl_update_order_item_display_meta_value($display_key, $meta, $item)
994 + {
995 + if (isset($item['order_id']) && $item['order_id']) {
996 + $order = wc_get_order($item['order_id']);
997 + if ($order && Wpfnl_functions::check_if_funnel_order($order)) {
998 + if (is_admin() && $item->get_type() === 'line_item' && ($meta->key === '_wpfunnels_order_bump')) {
999 + $meta = __("Order Bump", "wpfnl");
830 1000 return $meta;
831 - }elseif( is_admin() && $item->get_type() === 'line_item' && ( $meta->key === '_wpfunnels_upsell')) {
832 - $meta = __("Upsell", "wpfnl" );
1001 + } elseif (is_admin() && $item->get_type() === 'line_item' && ($meta->key === '_wpfunnels_upsell')) {
1002 + $meta = __("Upsell", "wpfnl");
833 1003 return $meta;
834 - }elseif( is_admin() && $item->get_type() === 'line_item' && ( $meta->key === '_wpfunnels_downsell')) {
835 - $meta = __("Downsell", "wpfnl" );
1004 + } elseif (is_admin() && $item->get_type() === 'line_item' && ($meta->key === '_wpfunnels_downsell')) {
1005 + $meta = __("Downsell", "wpfnl");
836 1006 return $meta;
837 - }elseif( is_admin() && $item->get_type() === 'shipping' && $meta->key === 'Items') {
1007 + } elseif (is_admin() && $item->get_type() === 'shipping' && $meta->key === 'Items') {
838 1008 $meta = $item->get_meta('Items');
839 1009 return $meta;
840 - }else{
1010 + } else {
841 1011 $display_value = $meta->value;
842 1012 return $display_value;
843 1013 }
844 - }else{
1014 + } else {
845 1015 $display_value = $meta->value;
846 1016 return $display_value;
847 -
848 1017 }
849 - }else{
1018 + } else {
850 1019 $display_value = $meta->value;
851 1020 return $display_value;
852 1021 }
853 -
854 1022 }
855 1023
856 1024
857 1025 /**
@@ -856,29 +1024,30 @@
856 1024
857 1025 /**
858 1026 * May be user abandoned funnel
859 1027 */
860 - public function maybe_abandoned_funnel() {
861 - check_ajax_referer( 'abandoned_ajax_nonce', 'security' );
1028 + public function maybe_abandoned_funnel()
1029 + {
1030 + check_ajax_referer('abandoned_ajax_nonce', 'security');
862 1031 $step_id = $_POST['step_id'];
863 1032 $funnel_id = $_POST['funnel_id'];
864 1033 $cookie_name = 'wpfunnels_automation_data';
865 - $cookie = isset( $_COOKIE[$cookie_name] ) ? json_decode( wp_unslash( $_COOKIE[$cookie_name] ), true ) : array();
1034 + $cookie = isset($_COOKIE[$cookie_name]) ? json_decode(wp_unslash($_COOKIE[$cookie_name]), true) : array();
866 1035 $cookie['funnel_status'] = 'abandoned';
867 - if( PHP_SESSION_DISABLED == session_status() ) {
1036 + if (PHP_SESSION_DISABLED == session_status()) {
868 1037 session_start();
869 - if ( isset( $_SESSION ) || $_SESSION ) {
870 - if( isset($_SESSION['wpfnl_orders_'.get_current_user_id().'_'.$funnel_id]) ){
871 - unset($_SESSION['wpfnl_orders_'.get_current_user_id().'_'.$funnel_id]);
1038 + if (isset($_SESSION) || $_SESSION) {
1039 + if (isset($_SESSION['wpfnl_orders_' . get_current_user_id() . '_' . $funnel_id])) {
1040 + unset($_SESSION['wpfnl_orders_' . get_current_user_id() . '_' . $funnel_id]);
872 1041 }
873 1042 }
874 1043 }
875 - $step_type = get_post_meta( $step_id, '_step_type', true );
876 - if( 'upsell' == $step_type || 'downsell' == $step_type || 'thankyou' == $step_type ){
877 - delete_option( 'wpfunnels_dynamic_offer_data' );
1044 + $step_type = get_post_meta($step_id, '_step_type', true);
1045 + if ('upsell' == $step_type || 'downsell' == $step_type || 'thankyou' == $step_type) {
1046 + delete_option('wpfunnels_dynamic_offer_data');
878 1047 }
879 - delete_option( 'optin_data' );
880 - do_action( 'wpfunnels/maybe_user_abandoned_funnel', $step_id, $funnel_id, $cookie );
1048 + delete_option('optin_data');
1049 + do_action('wpfunnels/maybe_user_abandoned_funnel', $step_id, $funnel_id, $cookie);
881 1050 die();
882 1051 }
883 1052
884 1053
@@ -889,14 +1058,14 @@
889 1058 * @param mixed $funnel_id
890 1059 *
891 1060 * @return [type]
892 1061 */
893 - public function end_journey( $step_id, $funnel_id ){
1062 + public function end_journey($step_id, $funnel_id)
1063 + {
894 1064
895 - if( !Wpfnl_Theme_Compatibility::getInstance()->is_elementor_preview() ){
896 - Wpfnl_functions::custom_url_for_thankyou_page( $step_id );
1065 + if (!Wpfnl_Theme_Compatibility::getInstance()->is_elementor_preview()) {
1066 + Wpfnl_functions::custom_url_for_thankyou_page($step_id);
897 1067 }
898 -
899 1068 }
900 1069 /**
901 1070 * Redirects from LearnDash offer step templates if accessed
902 1071 * without completing previous steps or user is already enrolled
@@ -904,44 +1073,44 @@
904 1073 */
905 1074 public function redirect_learndash_template()
906 1075 {
907 1076 global $post;
908 - $step_id = isset( $post->ID ) ? $post->ID : false;
1077 + $step_id = isset($post->ID) ? $post->ID : false;
909 1078
910 - if( $step_id ) {
911 - $funnel_id = Wpfnl_functions::get_funnel_id_from_step( $step_id );
912 - $lms_funnel = get_post_meta( $funnel_id, 'is_lms', true );
1079 + if ($step_id) {
1080 + $funnel_id = Wpfnl_functions::get_funnel_id_from_step($step_id);
1081 + $lms_funnel = get_post_meta($funnel_id, 'is_lms', true);
913 1082
914 - if( $lms_funnel === 'yes' ) {
915 - $step_type = get_post_meta( $step_id, '_step_type', true );
916 - $course = Wpfnl_lms_learndash_functions::get_course_details( $step_id );
1083 + if ($lms_funnel === 'yes') {
1084 + $step_type = get_post_meta($step_id, '_step_type', true);
1085 + $course = Wpfnl_lms_learndash_functions::get_course_details($step_id);
917 1086 $redirect_url = '';
918 - if( $step_type === 'upsell' || $step_type === 'downsell' ) {
919 - if( !isset( $_GET[ 'wpfnl_ld_payment' ] ) ) {
920 - $redirect_url = Wpfnl_functions::get_funnel_link( $funnel_id );
921 - Wpfnl_lms_learndash_functions::learndash_template_safe_redirect( $redirect_url );
1087 + if ($step_type === 'upsell' || $step_type === 'downsell') {
1088 + if (!isset($_GET['wpfnl_ld_payment'])) {
1089 + $redirect_url = Wpfnl_functions::get_funnel_link($funnel_id);
1090 + Wpfnl_lms_learndash_functions::learndash_template_safe_redirect($redirect_url);
922 1091 }
923 - if( $course && !empty( $course ) ) {
924 - $course_id = isset( $course[ 'id' ] ) ? $course[ 'id' ] : '';
925 - $course_type = isset( $course[ 'type' ] ) ? $course[ 'type' ] : '';
926 - $next_step = Wpfnl_functions::get_next_step( $funnel_id, $step_id );
927 - $current_user_id = function_exists( 'get_current_user_id' ) ? get_current_user_id() : '';
1092 + if ($course && !empty($course)) {
1093 + $course_id = isset($course['id']) ? $course['id'] : '';
1094 + $course_type = isset($course['type']) ? $course['type'] : '';
1095 + $next_step = Wpfnl_functions::get_next_step($funnel_id, $step_id);
1096 + $current_user_id = function_exists('get_current_user_id') ? get_current_user_id() : '';
928 1097
929 - if( isset( $next_step[ 'step_id' ] ) ) {
930 - if( $next_step[ 'step_type' ] == 'conditional' ) {
931 - $next_step = Wpfnl_functions::get_next_step( $funnel_id, $next_step[ 'step_id' ] );
1098 + if (isset($next_step['step_id'])) {
1099 + if ($next_step['step_type'] == 'conditional') {
1100 + $next_step = Wpfnl_functions::get_next_step($funnel_id, $next_step['step_id']);
932 1101 }
933 - $redirect_url = get_permalink( $next_step[ 'step_id' ] );
1102 + $redirect_url = get_permalink($next_step['step_id']);
934 1103 }
935 1104
936 - if( $course_type === 'open' ) {
937 - Wpfnl_lms_learndash_functions::learndash_template_safe_redirect( $redirect_url, 'free' );
1105 + if ($course_type === 'open') {
1106 + Wpfnl_lms_learndash_functions::learndash_template_safe_redirect($redirect_url, 'free');
938 1107 }
939 - if( $course_id !== '' && $current_user_id && $current_user_id !== '' ) {
940 - $course_access = function_exists( 'sfwd_lms_has_access' ) ? sfwd_lms_has_access( $course_id, $current_user_id ) : false;
1108 + if ($course_id !== '' && $current_user_id && $current_user_id !== '') {
1109 + $course_access = function_exists('sfwd_lms_has_access') ? sfwd_lms_has_access($course_id, $current_user_id) : false;
941 1110
942 - if( $course_access ) {
943 - Wpfnl_lms_learndash_functions::learndash_template_safe_redirect( $redirect_url, 'free' );
1111 + if ($course_access) {
1112 + Wpfnl_lms_learndash_functions::learndash_template_safe_redirect($redirect_url, 'free');
944 1113 }
945 1114 }
946 1115 }
947 1116 }
@@ -949,15 +1118,16 @@
949 1118 }
950 1119 }
951 1120
952 1121
953 - private function create_lms_order( $order_details = [] ){
1122 + private function create_lms_order($order_details = [])
1123 + {
954 1124
955 1125 global $wpdb;
956 - $result = $wpdb->get_results( "SELECT * FROM wp_wpfnl_lms_order WHERE funnel_id = ".$order_details['funnel_id']." AND step_id = ".$order_details['funnel_id']." AND user_id = ".$order_details['user_id']." ");
1126 + $result = $wpdb->get_results("SELECT * FROM wp_wpfnl_lms_order WHERE funnel_id = " . $order_details['funnel_id'] . " AND step_id = " . $order_details['funnel_id'] . " AND user_id = " . $order_details['user_id'] . " ");
957 1127
958 - if( !empty($result) ){
959 - $wpdb->query($wpdb->prepare("UPDATE wp_wpfnl_lms_order SET meta='order' WHERE funnel_id = ".$order_details['funnel_id']." AND step_id = ".$order_details['funnel_id']." AND user_id = ".$order_details['user_id'].""));
1128 + if (!empty($result)) {
1129 + $wpdb->query($wpdb->prepare("UPDATE wp_wpfnl_lms_order SET meta='order' WHERE funnel_id = " . $order_details['funnel_id'] . " AND step_id = " . $order_details['funnel_id'] . " AND user_id = " . $order_details['user_id'] . ""));
960 1130 }
961 1131
962 1132
963 1133 $wpdb->insert('wp_wpfnl_lms_order', array(
@@ -968,27 +1138,28 @@
968 1138 'order_data' => serialize($order_details['course_details']),
969 1139 'date_created' => date("Y-m-d h:i:s")
970 1140 ));
971 1141 }
972 -
1142 +
973 1143 /**
974 1144 * After main order placed
975 - *
1145 + *
976 1146 * @param String $order_id
977 1147 * @param Number $funnel_id
978 - *
1148 + *
979 1149 * @since 2.5.9
980 1150 */
981 - public function add_order_details_to_logger( $order_id, $funnel_id, $step_id ){
982 - if( Wpfnl_functions::maybe_logger_enabled() && Wpfnl_functions::is_wc_active() ) {
983 - if( $order_id && $funnel_id ){
984 - $order = wc_get_order( $order_id );
985 - $order_items = $order->get_items();
1151 + public function add_order_details_to_logger($order_id, $funnel_id, $step_id)
1152 + {
1153 + if (Wpfnl_functions::maybe_logger_enabled() && Wpfnl_functions::is_wc_active()) {
1154 + if ($order_id && $funnel_id) {
1155 + $order = wc_get_order($order_id);
1156 + $order_items = $order->get_items();
986 1157 $product_array = [];
987 - foreach ($order_items as $item_id => $item ) {
1158 + foreach ($order_items as $item_id => $item) {
988 1159 $product_array[] = [
989 1160 'name' => $item['name'],
990 - 'price' => number_format($item['total'] + $item['total_tax'],2),
1161 + 'price' => number_format($item['total'] + $item['total_tax'], 2),
991 1162 ];
992 1163 }
993 1164
994 1165 ob_start();
@@ -994,10 +1165,10 @@
994 1165 ob_start();
995 1166 print_r($product_array);
996 1167 $textual_representation = ob_get_contents();
997 1168 ob_end_clean();
998 -
999 - Wpfnl_Logger::modify_log_file( 'event',$textual_representation,'Main Order Deatils' );
1169 +
1170 + Wpfnl_Logger::modify_log_file('event', $textual_representation, 'Main Order Deatils');
1000 1171 }
1001 1172 }
1002 1173 }
1003 1174
@@ -1002,42 +1173,43 @@
1002 1173 }
1003 1174
1004 1175 /**
1005 1176 * Add optin data to logger
1006 - *
1177 + *
1007 1178 * @param Integrer $step_id
1008 1179 * @param String $post_action
1009 1180 * @param String $action_type
1010 1181 * @param Object $record
1011 - *
1182 + *
1012 1183 * @return void
1013 1184 * @since 2.5.9
1014 1185 */
1015 - public function add_optin_data_to_logger( $step_id, $post_action, $action_type, $record ){
1016 - if( Wpfnl_functions::maybe_logger_enabled() ) {
1017 - $optin_data = ( isset($record->form_data['email']) && $record->form_data['email'] ) ? $record->form_data : [];
1186 + public function add_optin_data_to_logger($step_id, $post_action, $action_type, $record)
1187 + {
1188 + if (Wpfnl_functions::maybe_logger_enabled()) {
1189 + $optin_data = (isset($record->form_data['email']) && $record->form_data['email']) ? $record->form_data : [];
1018 1190 ob_start();
1019 1191 print_r($optin_data);
1020 1192 $textual_representation = ob_get_contents();
1021 1193 ob_end_clean();
1022 1194
1023 - Wpfnl_Logger::modify_log_file( 'event',$textual_representation,'Optin Submission Data' );
1195 + Wpfnl_Logger::modify_log_file('event', $textual_representation, 'Optin Submission Data');
1024 1196 }
1025 1197 }
1026 1198
1027 -
1199 +
1028 1200 /**
1029 1201 * Get optin data
1030 1202 */
1031 - public function get_optin_data( $step_id, $post_action, $action_type, $record ){
1032 -
1203 + public function get_optin_data($step_id, $post_action, $action_type, $record)
1204 + {
1205 +
1033 1206 $data = get_option('optin_data');
1034 1207 $data['optin_data'][] = [
1035 1208 'step_id' => $step_id,
1036 - 'step_type' => get_post_meta( $step_id, '_step_type', true )
1209 + 'step_type' => get_post_meta($step_id, '_step_type', true)
1037 1210 ];
1038 - update_option('optin_data', $data );
1039 -
1211 + update_option('optin_data', $data);
1040 1212 }
1041 1213
1042 1214 /**
1043 1215 * Registers an opt-in user and performs actions based on the submitted data.
@@ -1053,9 +1225,10 @@
1053 1225 *
1054 1226 * @return void
1055 1227 * @since 2.8.2
1056 1228 */
1057 - public function register_optin_user( $step_id, $post_action, $action_type, $record, $post_data ) {
1229 + public function register_optin_user($step_id, $post_action, $action_type, $record, $post_data)
1230 + {
1058 1231 // Extract user info from the record.
1059 1232 $user_info = $record->form_data ?? [];
1060 1233
1061 1234 // Extract user's email for potential login and registration.
@@ -1060,10 +1233,15 @@
1060 1233
1061 1234 // Extract user's email for potential login and registration.
1062 1235 $login = $user_info['email'] ? strstr($user_info['email'], '@', true) : '';
1063 1236
1237 + // Kept as an early-out next to the request-supplied flag; the
1238 + // authoritative check lives in create_user_optin_allow_registration(),
1239 + // which every registration path routes through.
1240 + $can_register = get_option('users_can_register');
1241 +
1064 1242 // Check if opt-in registration is allowed and perform related actions.
1065 - if (!empty($post_data['optin_allow_registration']) && $post_data['optin_allow_registration'] == 'yes') {
1243 + if ( $can_register && !empty($post_data['optin_allow_registration']) && $post_data['optin_allow_registration'] == 'yes') {
1066 1244 // Create user account based on the extracted login and post data.
1067 1245 Ajax_Handler::create_user_optin_allow_registration($login, $post_data);
1068 1246 }
1069 1247 }
@@ -1083,15 +1261,128 @@
1083 1261 *
1084 1262 * @return array The updated response data with the generated redirect URL.
1085 1263 * @since 2.8.2
1086 1264 */
1087 - public function regenerate_redirect_url( $response, $funnel_id, $step_id, $next_step, $query_params ) {
1265 + public function regenerate_redirect_url($response, $funnel_id, $step_id, $next_step, $query_params)
1266 + {
1088 1267 // Check if the next step type is conditional.
1089 - if( !empty( $next_step[ 'step_type' ] ) && 'conditional' === $next_step[ 'step_type' ] ) {
1268 + if (!empty($next_step['step_type']) && 'conditional' === $next_step['step_type']) {
1090 1269 // Match the conditional step and update the redirect URL.
1091 - $next_step = Ajax_Handler::match_conditional_step( $next_step, $funnel_id, $step_id );
1092 - $response[ 'redirect_url' ] = add_query_arg( $query_params, get_the_permalink( $next_step[ 'step_id' ] ) );
1270 + $next_step = Ajax_Handler::match_conditional_step($next_step, $funnel_id, $step_id);
1271 + $response['redirect_url'] = add_query_arg($query_params, get_the_permalink($next_step['step_id']));
1093 1272 }
1094 1273
1095 1274 return $response;
1275 + }
1276 +
1277 +
1278 + /**
1279 + * Add Edit Funnel menu on admin bar for admin users
1280 + *
1281 + * @param \WP_Admin_Bar $admin_bar
1282 + * @since 3.1.0
1283 + */
1284 + public function add_edit_funnel_menu(\WP_Admin_Bar $admin_bar)
1285 + {
1286 + if (Wpfnl_functions::is_funnel_step_page()) {
1287 + $funnel_id = Wpfnl_functions::get_funnel_id();
1288 +
1289 + if (!$funnel_id) {
1290 + return;
1291 + }
1292 +
1293 + $admin_bar->add_node(
1294 + array(
1295 + 'id' => 'edit-funnel',
1296 + 'title' => '<span class="ab-icon dashicons dashicons-edit"></span>' . esc_html__('Edit Funnel', 'wpfnl'),
1297 + 'href' => admin_url("admin.php?page=edit_funnel&id={$funnel_id}&step_id=0"),
1298 + 'meta' => array(
1299 + 'class' => 'wpf-admin-bar-edit-funnel-menu-item',
1300 + ),
1301 + )
1302 + );
1303 + }
1304 + }
1305 +
1306 +
1307 + /**
1308 + * Add custom script to header of funnel step
1309 + *
1310 + * @return void
1311 + * @since 3.1.0
1312 + */
1313 + public function add_custom_script()
1314 + {
1315 + global $post;
1316 +
1317 + if (!is_object($post) && !isset($post->ID)) {
1318 + return;
1319 + }
1320 +
1321 + $script = get_post_meta($post->ID, '_wpfnl_custom_script', true);
1322 + if ('' !== $script) {
1323 + if (false === strpos($script, htmlentities('<script'))) {
1324 + $script = '<script>' . $script . '</script>';
1325 + }
1326 + echo '<!-- Custom WPFunnels Script -->';
1327 + echo html_entity_decode($script); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1328 + echo '<!-- End Custom WPFunnels Script -->';
1329 + }
1330 + }
1331 +
1332 + /**
1333 + * Add custom css to header of funnel step
1334 + *
1335 + * @return void
1336 + * @since 3.1.0
1337 + */
1338 + public function add_custom_css()
1339 + {
1340 + global $post;
1341 +
1342 + if (!is_object($post) && !isset($post->ID)) {
1343 + return;
1344 + }
1345 +
1346 + $css = get_post_meta($post->ID, '_wpfnl_custom_css', true);
1347 + if ('' !== $css) {
1348 + if (false === strpos($css, htmlentities('<style'))) {
1349 + $css = '<style>' . $css . '</style>';
1350 + }
1351 + echo "\n<!-- Custom WPFunnels CSS -->\n";
1352 + echo html_entity_decode($css); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
1353 + echo "\n<!-- End Custom WPFunnels CSS -->\n";
1354 + }
1355 + }
1356 +
1357 +
1358 +
1359 + /**
1360 + * Load variable product modal
1361 + *
1362 + * @return void
1363 + */
1364 + public function load_variable_product_modal() {
1365 + if ( Wpfnl_functions::is_funnel_step_page( 'checkout' ) ) {
1366 + $checkout_id = get_the_ID();
1367 + $order_bump_settings = get_post_meta( $checkout_id, 'order-bump-settings', true );
1368 + if ( ! empty( $order_bump_settings ) ) {
1369 + foreach ( $order_bump_settings as $key => $settings ) {
1370 + if ( isset( $settings['product'] ) ) {
1371 + $product = wc_get_product( $settings['product'] );
1372 + if ( $product && $product->is_type( 'variable' ) ) {
1373 + wc_get_template(
1374 + 'variable-product-modal.php',
1375 + array(
1376 + 'product' => $product,
1377 + 'key' => $key,
1378 + ),
1379 + '',
1380 + WPFNL_DIR . 'public/modules/checkout/templates/'
1381 + );
1382 + }
1383 + }
1384 + }
1385 + }
1386 + }
1096 1387 }
1097 1388 }