PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.3.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.3.0
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
← All changes | wizard/ajax/wizard.php +29 -16 3.0.1 → 3.3.0 View file →
@@ -13,8 +13,9 @@
13 13 }
14 14
15 15 use CartflowsAdmin\Wizard\Ajax\AjaxBase;
16 16 use CartflowsAdmin\AdminCore\Ajax\Importer;
17 +use CartflowsAdmin\AdminCore\Inc\AdminHelper;
17 18 use CartflowsAdmin\Wizard\Inc\WizardCore;
18 19
19 20 /**
20 21 * Class Steps.
@@ -197,9 +198,9 @@
197 198 $response_body = array();
198 199
199 200 $email = isset( $_POST['user_email'] ) ? sanitize_email( wp_unslash( $_POST['user_email'] ) ) : '';
200 201 $user_name = isset( $_POST['user_fname'] ) ? sanitize_text_field( wp_unslash( $_POST['user_fname'] ) ) : '';
201 - $usage_tracking = isset( $_POST['usage_tracking'] ) ? sanitize_text_field( wp_unslash( $_POST['usage_tracking'] ) ) : '';
202 + $usage_tracking = isset( $_POST['usage_tracking'] ) ? sanitize_text_field( wp_unslash( $_POST['usage_tracking'] ) ) : 'no';
202 203
203 204 if ( empty( $email ) ) {
204 205 wp_send_json_error(
205 206 array(
@@ -209,9 +210,9 @@
209 210 );
210 211 }
211 212
212 213 // Enable the usage tracking for BSF Analytics.
213 - update_option( 'cf_usage_optin', $usage_tracking );
214 + AdminHelper::update_admin_settings_option( 'cf_usage_optin', $usage_tracking, true );
214 215
215 216 $api_args = array(
216 217 'timeout' => 90, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
217 218 'body' => array(
@@ -353,9 +354,11 @@
353 354 $response_data = array( 'message' => $this->get_error_msg( 'nonce' ) );
354 355 wp_send_json_error( $response_data );
355 356 }
356 357
357 - $page_builder = isset( $_POST['page_builder'] ) ? sanitize_text_field( wp_unslash( $_POST['page_builder'] ) ) : '';
358 + // sanitize_key() here as well as sanitize_text_field(): import_templates() writes the
359 + // cache under the sanitized slug, so reading with the raw one missed it permanently.
360 + $page_builder = isset( $_POST['page_builder'] ) ? sanitize_key( wp_unslash( $_POST['page_builder'] ) ) : '';
358 361
359 362 $page = 1;
360 363 $flows_list = array();
361 364
@@ -406,9 +409,11 @@
406 409 $api_args = array(
407 410 'timeout' => 30, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
408 411 );
409 412
410 - $sites_and_pages = array();
413 + // Always shaped like a successful response so the error paths below cannot return
414 + // null for 'flows' — the client reads .flows.length off it.
415 + $sites_and_pages = array( 'flows' => array() );
411 416 $site_url = wcf()->get_site_url();
412 417
413 418 $query_args = array(
414 419 'per_page' => 100,
@@ -421,27 +426,35 @@
421 426 $api_url = add_query_arg( $query_args, $site_url . 'wp-json/cartflows-server/v1/flows-and-steps/' );
422 427
423 428 $response = wp_remote_get( $api_url, $api_args );
424 429
425 - if ( ! is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) === 200 ) {
430 + if ( ! is_wp_error( $response ) && 200 === wp_remote_retrieve_response_code( $response ) ) {
426 431
427 - $sites_and_pages = json_decode( wp_remote_retrieve_body( $response ), true );
432 + // Decode into its own variable — assigning over $sites_and_pages let the error
433 + // branches below return a response with no 'flows' key at all.
434 + $decoded = json_decode( wp_remote_retrieve_body( $response ), true );
428 435
429 - if ( isset( $sites_and_pages['code'] ) ) {
430 - $message = isset( $sites_and_pages['message'] ) ? $sites_and_pages['message'] : '';
436 + if ( is_array( $decoded ) && isset( $decoded['code'] ) ) {
437 + $message = isset( $decoded['message'] ) ? $decoded['message'] : '';
431 438 if ( ! empty( $message ) ) {
432 439 wcf()->logger->sync_log( 'HTTP Request Error: ' . $message );
433 440 } else {
434 441 wcf()->logger->sync_log( 'HTTP Request Error!' );
435 442 }
436 - } elseif ( is_array( $sites_and_pages ) && isset( $sites_and_pages['flows'] ) && ! empty( $sites_and_pages['flows'] ) ) {
437 - $option_name = 'cartflows-store-checkout-' . sanitize_key( $page_builder ) . '-flows-and-steps-' . $page;
438 - update_site_option( $option_name, $sites_and_pages['flows'] );
439 - } else {
440 - $sites_and_pages['flows'] = array();
443 + } elseif ( is_array( $decoded ) && ! empty( $decoded['flows'] ) ) {
444 + $sites_and_pages['flows'] = $decoded['flows'];
445 +
446 + $option_name = 'cartflows-store-checkout-' . $page_builder . '-flows-and-steps-' . $page;
447 + update_site_option( $option_name, $decoded['flows'] );
441 448 }
442 449 } else {
443 - wcf()->logger->sync_log( 'API Error: ' . $response->get_error_message() );
450 + // A non-200 response is not necessarily a WP_Error, and get_error_message()
451 + // only exists on one — the previous `||` sent those into the branch above.
452 + $error_message = is_wp_error( $response )
453 + ? $response->get_error_message()
454 + : sprintf( 'HTTP %s', wp_remote_retrieve_response_code( $response ) );
455 +
456 + wcf()->logger->sync_log( 'API Error: ' . $error_message );
444 457 }
445 458
446 459 return $sites_and_pages['flows'];
447 460 }
@@ -512,9 +525,9 @@
512 525
513 526 if ( is_wp_error( $response['data'] ) ) {
514 527
515 528 /* translators: %1$s: html tag, %2$s: link html start %3$s: link html end */
516 - $btn = sprintf( __( 'Request timeout error. Please check if the firewall or any security plugin is blocking the outgoing HTTP/HTTPS requests to templates.cartflows.com or not. %1$sTo resolve this issue, please check this %2$sarticle%3$s.', 'cartflows' ), '<br><br>', '<a target="_blank" href="https://cartflows.com/docs/request-timeout-error-while-importing-the-flow-step-templates/?utm_source=dashboard&utm_medium=free-cartflows&utm_campaign=docs">', '</a>' );
529 + $btn = sprintf( __( 'Request timeout error. Please check if the firewall or any security plugin is blocking the outgoing HTTP/HTTPS requests to templates.cartflows.com or not. %1$sTo resolve this issue, please check this %2$sarticle%3$s.', 'cartflows' ), '<br><br>', '<a target="_blank" href="' . esc_url( \Cartflows_Helper::get_kb_doc_link( 'https://cartflows.com/docs/request-timeout-error-while-importing-the-flow-step-templates/' ) ) . '">', '</a>' );
517 530
518 531 wp_send_json_error(
519 532 array(
520 533 'message' => $response['data']->get_error_message(),
@@ -535,9 +548,9 @@
535 548 $title = '';
536 549 $msg = '';
537 550 if ( 'not-installed' === $cf_pro_status ) {
538 551 /* translators: %1$s: link html start, %2$s: link html end*/
539 - $msg = sprintf( __( 'To import this template, CartFlows Pro Required! %1$sUpgrade to CartFlows Pro%2$s', 'cartflows' ), '<a target="_blank" href="https://cartflows.com/?utm_source=dashboard&utm_medium=free-cartflows&utm_campaign=go-pro">', '</a>' );
552 + $msg = sprintf( __( 'To import this template, CartFlows Pro Required! %1$sUpgrade to CartFlows Pro%2$s', 'cartflows' ), '<a target="_blank" href="' . esc_url( \Cartflows_Helper::get_upgrade_to_pro_link( '', 'https://cartflows.com/' ) ) . '">', '</a>' );
540 553 $title = __( 'CartFlows Pro Required', 'cartflows' );
541 554 } elseif ( 'inactive' === $cf_pro_status ) {
542 555 $title = __( 'CartFlows Pro Required', 'cartflows' );
543 556 /* translators: %1$s: link html start, %2$s: link html end*/