From 2c59a33a914db198b7784882ba9986b28e7c55f8 Mon Sep 17 00:00:00 2001
From: Fernando Espinosa
Date: Fri, 9 May 2025 16:22:12 +0200
Subject: [PATCH 01/11] Add contextual banners for WooCommerce Shipping & Tax
Enhance the NUX (New User Experience) system by adding contextual banners that show different content based on:
- Store country (US vs non-US)
- Whether the WooCommerce Shipping plugin is active
This creates a more personalized onboarding flow by:
1. Adding a new option flag for tracking contextual banner state
2. Improving the banner display logic with prioritized checks
3. Creating three different contextual banner types
4. Ensuring proper transition between traditional and contextual banners
The change maintains backward compatibility while providing more targeted guidance.
---
classes/class-wc-connect-nux.php | 157 +++++++++++++++++++++++++++----
1 file changed, 139 insertions(+), 18 deletions(-)
diff --git a/classes/class-wc-connect-nux.php b/classes/class-wc-connect-nux.php
index 908530907..b214f0195 100644
--- a/classes/class-wc-connect-nux.php
+++ b/classes/class-wc-connect-nux.php
@@ -16,7 +16,8 @@ class WC_Connect_Nux {
* Option name for dismissing success banner
* after the JP connection flow
*/
- const SHOULD_SHOW_AFTER_CXN_BANNER = 'should_display_nux_after_jp_cxn_banner';
+ const SHOULD_SHOW_AFTER_CXN_BANNER = 'should_display_nux_after_jp_cxn_banner';
+ const SHOULD_SHOW_CONTEXTUAL_BANNER = 'should_display_nux_contextual_banner';
/**
* @var WC_Connect_Tracks
@@ -241,23 +242,48 @@ public static function get_banner_type_to_display( $status = array() ) {
return 'before_jetpack_connection';
case self::JETPACK_CONNECTED:
case self::JETPACK_OFFLINE_MODE:
- // Has the user just gone through our NUX connection flow?
+ // Priority 1: Standard "after connection" banner (if pending from NUX flow).
+ // This banner also handles initial TOS acceptance if coming from the NUX connection flow.
if ( isset( $status['should_display_after_cxn_banner'] ) && $status['should_display_after_cxn_banner'] ) {
return 'after_jetpack_connection';
}
- // Has the user already accepted our TOS? Then do nothing.
- // Note: TOS is accepted during the after_connection banner
- if (
- isset( $status['tos_accepted'] )
- && ! $status['tos_accepted']
- && isset( $status['can_accept_tos'] )
- && $status['can_accept_tos']
- ) {
+ // Priority 2: TOS acceptance banner (if Jetpack connected, but TOS not yet accepted,
+ // and the standard "after connection" banner is not pending).
+ if ( isset( $status['tos_accepted'] ) && ! $status['tos_accepted'] &&
+ isset( $status['can_accept_tos'] ) && $status['can_accept_tos'] ) {
return 'tos_only_banner';
}
- return false;
+ // For existing users: if TOS accepted, after_cxn_banner done, but contextual_banner flag not yet set, set it now.
+ if ( isset( $status['tos_accepted'] ) && $status['tos_accepted'] &&
+ ( ! isset( $status['should_display_after_cxn_banner'] ) || ! $status['should_display_after_cxn_banner'] ) &&
+ ( ! isset( $status['should_display_contextual_banner'] ) || ! $status['should_display_contextual_banner'] )
+ ) {
+ // This user is eligible for contextual banners but the flag isn't set. Set it now.
+ WC_Connect_Options::update_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER, true );
+ // Update the status for the current execution path, so Priority 3 check below can pick it up.
+ $status['should_display_contextual_banner'] = true;
+ }
+
+ // Priority 3: Contextual banners (if standard "after connection" is done or was not applicable,
+ // TOS is accepted, and the contextual flag is set - either previously or by the block above).
+ if ( isset( $status['should_display_contextual_banner'] ) && $status['should_display_contextual_banner'] ) {
+ // Determine which specific contextual banner to show.
+ $is_us_store = ( isset( $status['store_country'] ) && 'US' === $status['store_country'] );
+
+ if ( $is_us_store ) {
+ if ( isset( $status['is_wcs_shipping_plugin_active'] ) && ! $status['is_wcs_shipping_plugin_active'] ) {
+ return 'after_cxn_us_no_wcs_plugin';
+ } else {
+ return 'after_cxn_us_with_wcs_plugin';
+ }
+ } else {
+ return 'after_cxn_non_us';
+ }
+ }
+
+ return false; // All NUX banners handled or no NUX banner needed for this state.
default:
return false;
}
@@ -372,12 +398,22 @@ public function set_up_nux_notices() {
// If this is the case, the admin can connect the site on their own, and should be able to use WCS as ususal
$jetpack_install_status = $this->get_jetpack_install_status();
+ // Ensure is_plugin_active() is available for WCS check
+ if ( ! function_exists( 'is_plugin_active' ) ) {
+ include_once ABSPATH . 'wp-admin/includes/plugin.php';
+ }
+ $is_wcs_shipping_plugin_active = is_plugin_active( 'woocommerce-shipping/woocommerce-shipping.php' );
+ $store_country = WC()->countries->get_base_country();
+
$banner_to_display = self::get_banner_type_to_display(
array(
- 'jetpack_connection_status' => $jetpack_install_status,
- 'tos_accepted' => WC_Connect_Options::get_option( 'tos_accepted' ),
- 'can_accept_tos' => WC_Connect_Jetpack::is_current_user_connection_owner() || WC_Connect_Jetpack::is_offline_mode(),
- 'should_display_after_cxn_banner' => WC_Connect_Options::get_option( self::SHOULD_SHOW_AFTER_CXN_BANNER ),
+ 'jetpack_connection_status' => $jetpack_install_status,
+ 'tos_accepted' => WC_Connect_Options::get_option( 'tos_accepted' ),
+ 'can_accept_tos' => WC_Connect_Jetpack::is_current_user_connection_owner() || WC_Connect_Jetpack::is_offline_mode(),
+ 'should_display_after_cxn_banner' => WC_Connect_Options::get_option( self::SHOULD_SHOW_AFTER_CXN_BANNER ),
+ 'should_display_contextual_banner' => WC_Connect_Options::get_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER ),
+ 'store_country' => $store_country,
+ 'is_wcs_shipping_plugin_active' => $is_wcs_shipping_plugin_active,
)
);
@@ -391,13 +427,25 @@ public function set_up_nux_notices() {
wp_enqueue_style( 'wc_connect_banner' );
add_action( 'admin_notices', array( $this, 'show_banner_before_connection' ), 9 );
break;
+ case 'after_jetpack_connection':
+ wp_enqueue_style( 'wc_connect_banner' );
+ add_action( 'admin_notices', array( $this, 'show_banner_after_connection' ) );
+ break;
case 'tos_only_banner':
wp_enqueue_style( 'wc_connect_banner' );
add_action( 'admin_notices', array( $this, 'show_tos_banner' ) );
break;
- case 'after_jetpack_connection':
+ case 'after_cxn_us_no_wcs_plugin':
+ case 'after_cxn_us_with_wcs_plugin':
+ case 'after_cxn_non_us':
wp_enqueue_style( 'wc_connect_banner' );
- add_action( 'admin_notices', array( $this, 'show_banner_after_connection' ) );
+ // Using a closure to correctly pass the argument to the new handler method.
+ add_action(
+ 'admin_notices',
+ function () use ( $banner_to_display ) {
+ $this->show_contextual_after_connection_banner( $banner_to_display );
+ }
+ );
break;
}
@@ -452,8 +500,10 @@ public function show_banner_after_connection() {
// Did the user just dismiss?
if ( isset( $_GET['wcs-nux-notice'] ) && 'dismiss' === $_GET['wcs-nux-notice'] ) {
- // No longer need to keep track of whether the before connection banner was displayed.
+ // Delete the flag for this banner
WC_Connect_Options::delete_option( self::SHOULD_SHOW_AFTER_CXN_BANNER );
+ // Set the flag for the next contextual banner
+ WC_Connect_Options::update_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER, true );
wp_safe_redirect( remove_query_arg( 'wcs-nux-notice' ) );
exit;
}
@@ -487,6 +537,73 @@ public function show_banner_after_connection() {
);
}
+ public function show_contextual_after_connection_banner( $banner_type ) {
+ $screen = get_current_screen();
+
+ // This specific banner should only appear on the plugins page.
+ if ( ! $screen || 'plugins' !== $screen->base ) {
+ return;
+ }
+
+ // Still respect the store locale check.
+ if ( ! $this->should_display_nux_notice_for_current_store_locale() ) {
+ return;
+ }
+
+ // Did the user just dismiss?
+ if ( isset( $_GET['wcs-nux-notice'] ) && 'dismiss' === $_GET['wcs-nux-notice'] ) {
+ // Delete the flag for this contextual banner
+ WC_Connect_Options::delete_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER );
+ wp_safe_redirect( remove_query_arg( 'wcs-nux-notice' ) );
+ exit;
+ }
+
+ // By going through the connection process, the user has accepted our TOS
+ WC_Connect_Options::update_option( 'tos_accepted', true );
+
+ // Using a generic tracks event, can be made more specific if needed.
+ $this->tracks->opted_in( 'contextual_connection_banner_viewed' );
+
+ $banner_title = '';
+ $banner_description = '';
+
+ switch ( $banner_type ) {
+ case 'after_cxn_us_no_wcs_plugin':
+ $banner_title = __( 'US Store: WooCommerce Shipping Plugin Not Active - Title', 'woocommerce-services' );
+ $banner_description = __( 'US Store: WooCommerce Shipping Plugin Not Active - Description.', 'woocommerce-services' );
+ break;
+ case 'after_cxn_us_with_wcs_plugin':
+ $banner_title = __( 'US Store: WooCommerce Shipping Plugin Active - Title', 'woocommerce-services' );
+ $banner_description = __( 'US Store: WooCommerce Shipping Plugin Active - Description.', 'woocommerce-services' );
+ break;
+ case 'after_cxn_non_us':
+ $banner_title = __( 'Non-US Store - Title', 'woocommerce-services' );
+ $banner_description = __( 'Non-US Store - Description.', 'woocommerce-services' );
+ break;
+ default:
+ // Fallback for an unknown banner type, though this shouldn't be reached with current logic.
+ return;
+ }
+
+ $this->show_nux_banner(
+ array(
+ 'title' => $banner_title,
+ 'description' => esc_html( $banner_description ),
+ 'button_text' => __( 'Got it, thanks!', 'woocommerce-services' ),
+ 'button_link' => add_query_arg(
+ array(
+ 'wcs-nux-notice' => 'dismiss',
+ )
+ ),
+ 'image_url' => plugins_url(
+ 'images/wcs-notice.png',
+ __DIR__
+ ),
+ 'should_show_terms' => false,
+ )
+ );
+ }
+
public function show_tos_banner() {
if ( ! $this->should_display_nux_notice_for_current_store_locale() ) {
return;
@@ -498,6 +615,8 @@ public function show_tos_banner() {
if ( isset( $_GET['wcs-nux-tos'] ) && 'accept' === $_GET['wcs-nux-tos'] ) {
WC_Connect_Options::update_option( 'tos_accepted', true );
+ // Signal that the contextual banner can now be shown
+ WC_Connect_Options::update_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER, true );
$this->tracks->opted_in( 'tos_banner' );
@@ -625,6 +744,8 @@ public function register_woocommerce_services_jetpack() {
// Make sure we always display the after-connection banner
// after the before_connection button is clicked
WC_Connect_Options::update_option( self::SHOULD_SHOW_AFTER_CXN_BANNER, true );
+ // Ensure the contextual banner flag is not set prematurely
+ WC_Connect_Options::delete_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER );
WC_Connect_Jetpack::connect_site( $redirect_url );
}
From 50e47453362ec48680cb06975c61173d48da6cf3 Mon Sep 17 00:00:00 2001
From: Fernando Espinosa
Date: Mon, 12 May 2025 16:14:07 +0200
Subject: [PATCH 02/11] Update migration banner copy
---
classes/class-wc-connect-nux.php | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)
diff --git a/classes/class-wc-connect-nux.php b/classes/class-wc-connect-nux.php
index b214f0195..7a6984cc8 100644
--- a/classes/class-wc-connect-nux.php
+++ b/classes/class-wc-connect-nux.php
@@ -566,19 +566,31 @@ public function show_contextual_after_connection_banner( $banner_type ) {
$banner_title = '';
$banner_description = '';
+ $banner_button_text = '';
+ $banner_button_link = null;
switch ( $banner_type ) {
case 'after_cxn_us_no_wcs_plugin':
- $banner_title = __( 'US Store: WooCommerce Shipping Plugin Not Active - Title', 'woocommerce-services' );
- $banner_description = __( 'US Store: WooCommerce Shipping Plugin Not Active - Description.', 'woocommerce-services' );
+ $banner_title = __( 'WooCommerce Shipping & Tax has been renamed to WooCommerce Tax', 'woocommerce-services' );
+ $banner_description = __( 'Your tax functionality will continue to work as expected. The shipping functionality in this plugin will be discontinued on September 1, 2025. Please migrate to the new WooCommerce Shipping extension to get discounted labels for UPS, USPS, DHL Express— and more coming soon!', 'woocommerce-services' );
+ $banner_button_text = __( 'Try WooCommerce Shipping ', 'woocommerce-services' );
+ $banner_button_link = '';
break;
case 'after_cxn_us_with_wcs_plugin':
- $banner_title = __( 'US Store: WooCommerce Shipping Plugin Active - Title', 'woocommerce-services' );
- $banner_description = __( 'US Store: WooCommerce Shipping Plugin Active - Description.', 'woocommerce-services' );
+ $banner_title = __( 'WooCommerce Shipping & Tax has been renamed to WooCommerce Tax', 'woocommerce-services' );
+ $banner_description = __( 'Your tax functionality will continue to work as expected. Use WooCommerce Shipping to access deeply discounted UPS, USPS, and DHL shipping labels, reliable shipments, and on-time delivery options.', 'woocommerce-services' );
+ $banner_button_text = __( 'Ship with UPS on WooCommerce', 'woocommerce-services' );
+ $banner_button_link = '';
break;
case 'after_cxn_non_us':
- $banner_title = __( 'Non-US Store - Title', 'woocommerce-services' );
- $banner_description = __( 'Non-US Store - Description.', 'woocommerce-services' );
+ $banner_title = __( 'WooCommerce Shipping & Tax has been renamed to WooCommerce Tax', 'woocommerce-services' );
+ $banner_description = __( 'Your tax functionality will continue to work as expected. No action is required.', 'woocommerce-services' );
+ $banner_button_text = __( 'Close', 'woocommerce-services' );
+ $banner_button_link = add_query_arg(
+ array(
+ 'wcs-nux-notice' => 'dismiss',
+ )
+ );
break;
default:
// Fallback for an unknown banner type, though this shouldn't be reached with current logic.
@@ -589,12 +601,8 @@ public function show_contextual_after_connection_banner( $banner_type ) {
array(
'title' => $banner_title,
'description' => esc_html( $banner_description ),
- 'button_text' => __( 'Got it, thanks!', 'woocommerce-services' ),
- 'button_link' => add_query_arg(
- array(
- 'wcs-nux-notice' => 'dismiss',
- )
- ),
+ 'button_text' => $banner_button_text,
+ 'button_link' => $banner_button_link,
'image_url' => plugins_url(
'images/wcs-notice.png',
__DIR__
From 3161463dccedd3ef2e7b767344d72d28d9cadbec Mon Sep 17 00:00:00 2001
From: Fernando Espinosa
Date: Tue, 13 May 2025 09:21:45 +0200
Subject: [PATCH 03/11] Add WooCommerce Shipping Migration modal and contextual
banner with dismissal control
- Extend WC_Connect_Nux to support new service settings and schemas stores.
- Add contextual after-connection banner for US users without WooCommerce Shipping plugin.
- Enqueue and localize migration modal scripts and styles; render React modal container in admin notices.
- Add dismissal logic with a shared option (`wcs_nux_any_banner_shown`) to prevent multiple simultaneous banners.
- Enhance feature announcement React component to support forced open state.
- Improve migration runner state handling for robustness.
- Add safety checks in admin notice dismiss button event listeners.
- Make `WC_Connect_Loader::get_wc_connect_base_url` public static for broader usage.
- Instantiate `WC_Connect_Nux` with new dependencies in loader.
- Add placeholder admin banner and modal manager classes.
---
classes/class-wc-connect-nux.php | 148 ++++++++++++++++--
.../migration/feature-announcement.jsx | 5 +-
.../components/migration/migration-runner.js | 9 +-
client/wcshipping-migration-admin-notice.js | 20 ++-
includes/admin/class-wc-connect-banner.php | 0
.../admin/class-wc-connect-modal-manager.php | 0
woocommerce-services.php | 4 +-
7 files changed, 161 insertions(+), 25 deletions(-)
create mode 100644 includes/admin/class-wc-connect-banner.php
create mode 100644 includes/admin/class-wc-connect-modal-manager.php
diff --git a/classes/class-wc-connect-nux.php b/classes/class-wc-connect-nux.php
index 7a6984cc8..c55520c26 100644
--- a/classes/class-wc-connect-nux.php
+++ b/classes/class-wc-connect-nux.php
@@ -29,9 +29,34 @@ class WC_Connect_Nux {
*/
private $shipping_label;
- function __construct( WC_Connect_Tracks $tracks, WC_Connect_Shipping_Label $shipping_label ) {
- $this->tracks = $tracks;
- $this->shipping_label = $shipping_label;
+ /**
+ * @var WC_Connect_Service_Settings_Store
+ */
+ protected $service_settings_store;
+
+ /**
+ * @var WC_Connect_Payment_Methods_Store
+ */
+ protected $payment_methods_store;
+
+ /**
+ * @var WC_Connect_Service_Schemas_Store
+ */
+ protected $service_schemas_store;
+
+
+ function __construct(
+ WC_Connect_Tracks $tracks,
+ WC_Connect_Shipping_Label $shipping_label,
+ WC_Connect_Service_Settings_Store $service_settings_store,
+ WC_Connect_Payment_Methods_Store $payment_methods_store,
+ WC_Connect_Service_Schemas_Store $service_schemas_store
+ ) {
+ $this->tracks = $tracks;
+ $this->shipping_label = $shipping_label;
+ $this->service_settings_store = $service_settings_store;
+ $this->payment_methods_store = $payment_methods_store;
+ $this->service_schemas_store = $service_schemas_store;
$this->init_pointers();
}
@@ -436,6 +461,68 @@ public function set_up_nux_notices() {
add_action( 'admin_notices', array( $this, 'show_tos_banner' ) );
break;
case 'after_cxn_us_no_wcs_plugin':
+ // Enqueue the migration modal assets specifically for this banner on the plugins page.
+ $plugin_version = WC_Connect_Loader::get_wcs_version();
+ // Use the public static method from WC_Connect_Loader
+ $base_url = WC_Connect_Loader::get_wc_connect_base_url(); // Assuming get_wc_connect_base_url is static
+
+ wp_register_style( 'wcst_wcshipping_migration_admin_notice', $base_url . 'woocommerce-services-wcshipping-migration-admin-notice-' . $plugin_version . '.css', array(), null ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
+ // Add 'wp-element' and 'wc_connect_admin' dependency for React and base script
+ wp_register_script( 'wcst_wcshipping_migration_admin_notice', $base_url . 'woocommerce-services-wcshipping-migration-admin-notice-' . $plugin_version . '.js', array( 'wc_connect_admin', 'wp-element' ), null, true ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
+
+ // Localize script data - MATCHING the original register_wcshipping_migration_modal
+ // Note: The modal primarily uses data-args, localization is minimal here.
+ wp_localize_script(
+ 'wcst_wcshipping_migration_admin_notice',
+ 'wcsPluginData', // Ensure this matches the expected object name in the script
+ array(
+ 'assetPath' => $base_url,
+ 'adminPluginPath' => admin_url( 'plugins.php' ),
+ )
+ );
+
+ // Enqueue scripts/styles needed for the banner and modal
+ wp_enqueue_script( 'wc_connect_admin' ); // Ensure base script is loaded first
+ wp_enqueue_script( 'wcst_wcshipping_migration_admin_notice' );
+ wp_enqueue_style( 'wcst_wcshipping_migration_admin_notice' );
+ wp_enqueue_style( 'wc_connect_banner' );
+
+ // Add the action to render the notice and container div
+ add_action(
+ 'admin_notices',
+ function () use ( $banner_to_display ) {
+ // Instantiate settings classes HERE, inside the closure, using stored dependencies
+ $account_settings = new WC_Connect_Account_Settings(
+ $this->service_settings_store,
+ $this->payment_methods_store
+ );
+ $packages_settings = new WC_Connect_Package_Settings(
+ $this->service_settings_store,
+ $this->service_schemas_store
+ );
+
+ // Prepare the data for the data-args attribute by calling get()
+ $container_data_args = array(
+ 'nonce' => wp_create_nonce( 'wp_rest' ),
+ 'baseURL' => get_rest_url(),
+ 'accountSettings' => $account_settings->get(), // Get REAL data
+ 'packagesSettings' => $packages_settings->get(), // Get REAL data
+ );
+ $encoded_container_args = wp_json_encode( $container_data_args );
+
+ // Echo the container div needed for the modal React component BEFORE the banner.
+ // Add 'display: none;' initially; the script should manage visibility.
+ printf(
+ '',
+ esc_attr( $encoded_container_args ) // Use the REAL encoded data
+ );
+
+ // Now show the banner itself
+ $this->show_contextual_after_connection_banner( $banner_to_display );
+ }
+ );
+ break; // End case 'after_cxn_us_no_wcs_plugin'
+
case 'after_cxn_us_with_wcs_plugin':
case 'after_cxn_non_us':
wp_enqueue_style( 'wc_connect_banner' );
@@ -453,6 +540,10 @@ function () use ( $banner_to_display ) {
}
public function show_banner_before_connection() {
+ if ( get_option( 'wcs_nux_any_banner_shown', false ) ) {
+ return;
+ }
+
if ( ! $this->should_display_nux_notice_for_current_store_locale() ) {
return;
}
@@ -486,10 +577,16 @@ public function show_banner_before_connection() {
'should_show_terms' => true,
);
+ update_option( 'wcs_nux_any_banner_shown', true );
+
$this->show_nux_banner( $banner_content );
}
public function show_banner_after_connection() {
+ if ( get_option( 'wcs_nux_any_banner_shown', false ) ) {
+ return;
+ }
+
if ( ! $this->should_display_nux_notice_for_current_store_locale() ) {
return;
}
@@ -504,6 +601,7 @@ public function show_banner_after_connection() {
WC_Connect_Options::delete_option( self::SHOULD_SHOW_AFTER_CXN_BANNER );
// Set the flag for the next contextual banner
WC_Connect_Options::update_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER, true );
+ delete_option( 'wcs_nux_any_banner_shown' );
wp_safe_redirect( remove_query_arg( 'wcs-nux-notice' ) );
exit;
}
@@ -518,6 +616,8 @@ public function show_banner_after_connection() {
$description_base = __( 'You can now enjoy %s.', 'woocommerce-services' );
$feature_list = $this->get_feature_list_for_country( $country );
+ update_option( 'wcs_nux_any_banner_shown', true );
+
$this->show_nux_banner(
array(
'title' => __( 'Setup complete.', 'woocommerce-services' ),
@@ -538,6 +638,10 @@ public function show_banner_after_connection() {
}
public function show_contextual_after_connection_banner( $banner_type ) {
+ if ( get_option( 'wcs_nux_any_banner_shown', false ) ) {
+ return;
+ }
+
$screen = get_current_screen();
// This specific banner should only appear on the plugins page.
@@ -554,6 +658,7 @@ public function show_contextual_after_connection_banner( $banner_type ) {
if ( isset( $_GET['wcs-nux-notice'] ) && 'dismiss' === $_GET['wcs-nux-notice'] ) {
// Delete the flag for this contextual banner
WC_Connect_Options::delete_option( self::SHOULD_SHOW_CONTEXTUAL_BANNER );
+ delete_option( 'wcs_nux_any_banner_shown' );
wp_safe_redirect( remove_query_arg( 'wcs-nux-notice' ) );
exit;
}
@@ -564,17 +669,21 @@ public function show_contextual_after_connection_banner( $banner_type ) {
// Using a generic tracks event, can be made more specific if needed.
$this->tracks->opted_in( 'contextual_connection_banner_viewed' );
+ update_option( 'wcs_nux_any_banner_shown', true );
+
$banner_title = '';
$banner_description = '';
$banner_button_text = '';
$banner_button_link = null;
+ update_option( 'wcshipping_migration_state', '0' );
switch ( $banner_type ) {
case 'after_cxn_us_no_wcs_plugin':
$banner_title = __( 'WooCommerce Shipping & Tax has been renamed to WooCommerce Tax', 'woocommerce-services' );
$banner_description = __( 'Your tax functionality will continue to work as expected. The shipping functionality in this plugin will be discontinued on September 1, 2025. Please migrate to the new WooCommerce Shipping extension to get discounted labels for UPS, USPS, DHL Express— and more coming soon!', 'woocommerce-services' );
$banner_button_text = __( 'Try WooCommerce Shipping ', 'woocommerce-services' );
- $banner_button_link = '';
+ // Ensure this line uses the special trigger value:
+ $banner_button_link = '#trigger-migration-modal';
break;
case 'after_cxn_us_with_wcs_plugin':
$banner_title = __( 'WooCommerce Shipping & Tax has been renamed to WooCommerce Tax', 'woocommerce-services' );
@@ -613,6 +722,10 @@ public function show_contextual_after_connection_banner( $banner_type ) {
}
public function show_tos_banner() {
+ if ( get_option( 'wcs_nux_any_banner_shown', false ) ) {
+ return;
+ }
+
if ( ! $this->should_display_nux_notice_for_current_store_locale() ) {
return;
}
@@ -628,6 +741,8 @@ public function show_tos_banner() {
$this->tracks->opted_in( 'tos_banner' );
+ delete_option( 'wcs_nux_any_banner_shown' );
+
wp_safe_redirect( remove_query_arg( 'wcs-nux-tos' ) );
exit;
}
@@ -637,6 +752,8 @@ public function show_tos_banner() {
$description_base = __( "WooCommerce Tax is almost ready to go! Once you connect your site to WordPress.com you'll have access to %s.", 'woocommerce-services' );
$feature_list = $this->get_feature_list_for_country( $country );
+ update_option( 'wcs_nux_any_banner_shown', true );
+
$this->show_nux_banner(
array(
'title' => __( 'Connect your site to activate WooCommerce Tax', 'woocommerce-services' ),
@@ -694,12 +811,23 @@ public function show_nux_banner( $content ) {
-
-
-
+
+
+
+
+
+
+
+