Add subscribe notices for products without subscription (#51060)
- Add a new notice to the plugins list for products used without subscriptions reminding them to purchase. - Remove notices for expired and expiring subscriptions from WooCommerce settings screens. - Change link for subscribe and renew to add the product directly to cart. --------- Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
parent
d7ccebc004
commit
411d9ae78c
|
@ -197,6 +197,9 @@ export default function Content(): JSX.Element {
|
|||
{ selectedTab !== 'business-services' && (
|
||||
<SubscriptionsExpiredExpiringNotice type="expiring" />
|
||||
) }
|
||||
{ selectedTab !== 'business-services' && (
|
||||
<SubscriptionsExpiredExpiringNotice type="missing" />
|
||||
) }
|
||||
|
||||
{ renderContent() }
|
||||
</div>
|
||||
|
|
|
@ -39,6 +39,12 @@ export default function SubscriptionsExpiredExpiringNotice(
|
|||
dismissed:
|
||||
'woo_subscription_expiring_notice_in_marketplace_dismissed',
|
||||
},
|
||||
'woo-subscription-missing-notice': {
|
||||
shown: 'woo_subscription_missing_notice_in_marketplace_shown',
|
||||
clicked: 'woo_subscription_missing_notice_in_marketplace_clicked',
|
||||
dismissed:
|
||||
'woo_subscription_missing_notice_in_marketplace_dismissed',
|
||||
},
|
||||
};
|
||||
|
||||
let notice = null;
|
||||
|
@ -51,6 +57,9 @@ export default function SubscriptionsExpiredExpiringNotice(
|
|||
} else if ( type === 'expiring' ) {
|
||||
notice = wccomSettings?.subscription_expiring_notice || {};
|
||||
notice_id = 'woo-subscription-expiring-notice';
|
||||
} else if ( type === 'missing' ) {
|
||||
notice = wccomSettings?.subscription_missing_notice || {};
|
||||
notice_id = 'woo-subscription-missing-notice';
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import domReady from '@wordpress/dom-ready';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
domReady( () => {
|
||||
const purchaseSubscriptionLink = document.querySelectorAll(
|
||||
'.woocommerce-purchase-subscription'
|
||||
);
|
||||
|
||||
if ( purchaseSubscriptionLink.length > 0 ) {
|
||||
recordEvent( 'woo_purchase_subscription_in_plugins_shown' );
|
||||
purchaseSubscriptionLink.forEach( ( link ) => {
|
||||
link.addEventListener( 'click', function () {
|
||||
recordEvent( 'woo_purchase_subscription_in_plugins_clicked' );
|
||||
} );
|
||||
} );
|
||||
}
|
||||
} );
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Add a new notice to the plugins list for products used without subscriptions reminding them to purchase.
|
|
@ -85,6 +85,7 @@ class WC_Helper_Admin {
|
|||
if ( WC_Helper::is_site_connected() ) {
|
||||
$settings['wccomHelper']['subscription_expired_notice'] = PluginsHelper::get_expired_subscription_notice( false );
|
||||
$settings['wccomHelper']['subscription_expiring_notice'] = PluginsHelper::get_expiring_subscription_notice( false );
|
||||
$settings['wccomHelper']['subscription_missing_notice'] = PluginsHelper::get_missing_subscription_notice();
|
||||
}
|
||||
|
||||
return $settings;
|
||||
|
|
|
@ -40,11 +40,13 @@ class WC_Helper_Updater {
|
|||
}
|
||||
if ( WC_Helper::is_site_connected() ) {
|
||||
add_action( 'load-plugins.php', array( __CLASS__, 'setup_message_for_expired_and_expiring_subscriptions' ), 11 );
|
||||
add_action( 'load-plugins.php', array( __CLASS__, 'setup_message_for_plugins_without_subscription' ), 11 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the hook for modifying default WPCore update notices on the plugins management page.
|
||||
* This is for plugins with expired or expiring subscriptions.
|
||||
*/
|
||||
public static function setup_message_for_expired_and_expiring_subscriptions() {
|
||||
foreach ( WC_Helper::get_local_woo_plugins() as $plugin ) {
|
||||
|
@ -52,6 +54,16 @@ class WC_Helper_Updater {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the hook for modifying default WPCore update notices on the plugins management page.
|
||||
* This is for plugins without a subscription.
|
||||
*/
|
||||
public static function setup_message_for_plugins_without_subscription() {
|
||||
foreach ( WC_Helper::get_local_woo_plugins() as $plugin ) {
|
||||
add_action( 'in_plugin_update_message-' . $plugin['_filename'], array( __CLASS__, 'display_notice_for_plugins_without_subscription' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs in a cron thread, or in a visitor thread if triggered
|
||||
* by _maybe_update_plugins(), or in an auto-update thread.
|
||||
|
@ -294,10 +306,11 @@ class WC_Helper_Updater {
|
|||
|
||||
$renew_link = add_query_arg(
|
||||
array(
|
||||
'add-to-cart' => $product_id,
|
||||
'utm_source' => 'pu',
|
||||
'utm_campaign' => 'pu_plugin_screen_renew',
|
||||
),
|
||||
PluginsHelper::WOO_SUBSCRIPTION_PAGE_URL
|
||||
PluginsHelper::WOO_CART_PAGE_URL
|
||||
);
|
||||
|
||||
/* translators: 1: Product regular price */
|
||||
|
@ -340,6 +353,52 @@ class WC_Helper_Updater {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs on in_plugin_update_message-{file-name}, show a message if plugin is without a subscription.
|
||||
* Only Woo local plugins are passed to this function.
|
||||
*
|
||||
* @see setup_message_for_plugins_without_subscription
|
||||
* @param object $plugin_data An array of plugin metadata.
|
||||
* @param object $response An object of metadata about the available plugin update.
|
||||
*
|
||||
* @return void.
|
||||
*/
|
||||
public static function display_notice_for_plugins_without_subscription( $plugin_data, $response ) {
|
||||
// Extract product ID from the response.
|
||||
$product_id = preg_replace( '/[^0-9]/', '', $response->id );
|
||||
|
||||
if ( WC_Helper::has_product_subscription( $product_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare the expiry notice based on subscription status.
|
||||
$purchase_link = add_query_arg(
|
||||
array(
|
||||
'add-to-cart' => $product_id,
|
||||
'utm_source' => 'pu',
|
||||
'utm_campaign' => 'pu_plugin_screen_purchase',
|
||||
),
|
||||
PluginsHelper::WOO_CART_PAGE_URL,
|
||||
);
|
||||
|
||||
$notice = sprintf(
|
||||
/* translators: 1: URL to My Subscriptions page */
|
||||
__( ' You don\'t have a subscription, <a href="%1$s" class="woocommerce-purchase-subscription">subscribe</a> to update.', 'woocommerce' ),
|
||||
esc_url( $purchase_link ),
|
||||
);
|
||||
|
||||
// Display the expiry notice.
|
||||
echo wp_kses(
|
||||
$notice,
|
||||
array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'class' => array(),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get update data for all plugins.
|
||||
*
|
||||
|
|
|
@ -33,17 +33,24 @@ if ( ! function_exists( 'get_plugins' ) ) {
|
|||
class PluginsHelper {
|
||||
|
||||
/**
|
||||
* Indicates whether the expiration notice for subscriptions can be displayed.
|
||||
* Subscription notices in Woo screens are shown in clear priority order, first
|
||||
* expired, and if those don't exist, expiring, and finally if none of those exist,
|
||||
* then missing. This keeps track of whether we can show the next set of notices.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public static $can_show_expiring_subs_notice = true;
|
||||
public static $subscription_usage_notices_already_shown = false;
|
||||
|
||||
/**
|
||||
* The URL for the WooCommerce subscription page.
|
||||
*/
|
||||
const WOO_SUBSCRIPTION_PAGE_URL = 'https://woocommerce.com/my-account/my-subscriptions/';
|
||||
|
||||
/**
|
||||
* The URL for the WooCommerce.com cart page.
|
||||
*/
|
||||
const WOO_CART_PAGE_URL = 'https://woocommerce.com/cart/';
|
||||
|
||||
/**
|
||||
* The URL for the WooCommerce.com add payment method page.
|
||||
*/
|
||||
|
@ -59,6 +66,11 @@ class PluginsHelper {
|
|||
*/
|
||||
const DISMISS_EXPIRING_SUBS_NOTICE = 'woo_subscription_expiring_notice_dismiss';
|
||||
|
||||
/**
|
||||
* Meta key for dismissing missing subscription notices
|
||||
*/
|
||||
const DISMISS_MISSING_SUBS_NOTICE = 'woo_subscription_missing_notice_dismiss';
|
||||
|
||||
/**
|
||||
* Initialize hooks.
|
||||
*/
|
||||
|
@ -67,10 +79,7 @@ class PluginsHelper {
|
|||
add_action( 'woocommerce_plugins_install_and_activate_async_callback', array( __CLASS__, 'install_and_activate_plugins_async_callback' ), 10, 2 );
|
||||
add_action( 'woocommerce_plugins_activate_callback', array( __CLASS__, 'activate_plugins' ), 10, 2 );
|
||||
add_action( 'admin_notices', array( __CLASS__, 'maybe_show_connect_notice_in_plugin_list' ) );
|
||||
add_action( 'admin_notices', array( __CLASS__, 'maybe_show_expired_subscriptions_notice' ), 10 );
|
||||
add_action( 'admin_notices', array( __CLASS__, 'maybe_show_expiring_subscriptions_notice' ), 11 );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'maybe_enqueue_scripts_for_connect_notice' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'maybe_enqueue_scripts_for_subscription_notice' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'maybe_enqueue_scripts_for_notices_in_plugins' ) );
|
||||
}
|
||||
|
||||
|
@ -659,6 +668,7 @@ class PluginsHelper {
|
|||
wp_enqueue_script( 'woo-plugin-update-connect-notice' );
|
||||
wp_enqueue_script( 'woo-enable-autorenew' );
|
||||
wp_enqueue_script( 'woo-renew-subscription' );
|
||||
wp_enqueue_script( 'woo-purchase-subscription' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -733,11 +743,15 @@ class PluginsHelper {
|
|||
* @return array notice data to return. Contains type, parsed_message and product_id.
|
||||
*/
|
||||
public static function get_subscriptions_notice_data( array $all_subs, array $subs_to_show, int $total, array $messages, string $type ) {
|
||||
$utm_campaign = 'expired' === $type ?
|
||||
'pu_settings_screen_renew' :
|
||||
( 'missing' === $type ? 'pu_settings_screen_purchase' : 'pu_settings_screen_enable_autorenew' );
|
||||
|
||||
if ( 1 < $total ) {
|
||||
$hyperlink_url = add_query_arg(
|
||||
array(
|
||||
'utm_source' => 'pu',
|
||||
'utm_campaign' => 'expired' === $type ? 'pu_settings_screen_renew' : 'pu_settings_screen_enable_autorenew',
|
||||
'utm_campaign' => $utm_campaign,
|
||||
|
||||
),
|
||||
self::WOO_SUBSCRIPTION_PAGE_URL
|
||||
|
@ -750,10 +764,18 @@ class PluginsHelper {
|
|||
esc_attr( $total ),
|
||||
);
|
||||
|
||||
// All product ids.
|
||||
$product_ids = array_map(
|
||||
function ( $sub ) {
|
||||
return $sub['product_id'];
|
||||
},
|
||||
$subs_to_show
|
||||
);
|
||||
|
||||
return array(
|
||||
'type' => 'different_subscriptions',
|
||||
'parsed_message' => $parsed_message,
|
||||
'product_id' => '',
|
||||
'product_ids' => $product_ids,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -769,8 +791,9 @@ class PluginsHelper {
|
|||
)
|
||||
);
|
||||
|
||||
$message_key = $has_multiple_subs_for_product ? 'multiple_manage' : 'single_manage';
|
||||
$renew_string = __( 'Renew', 'woocommerce' );
|
||||
$message_key = $has_multiple_subs_for_product ? 'multiple_manage' : 'single_manage';
|
||||
$renew_string = __( 'Renew', 'woocommerce' );
|
||||
$subscribe_string = __( 'Subscribe', 'woocommerce' );
|
||||
if ( isset( $subscription['product_regular_price'] ) ) {
|
||||
/* translators: 1: Product price */
|
||||
$renew_string = sprintf( __( 'Renew for %1$s', 'woocommerce' ), $subscription['product_regular_price'] );
|
||||
|
@ -781,7 +804,7 @@ class PluginsHelper {
|
|||
'product_id' => $product_id,
|
||||
'type' => $type,
|
||||
'utm_source' => 'pu',
|
||||
'utm_campaign' => 'expired' === $type ? 'pu_settings_screen_renew' : 'pu_settings_screen_enable_autorenew',
|
||||
'utm_campaign' => $utm_campaign,
|
||||
|
||||
),
|
||||
self::WOO_SUBSCRIPTION_PAGE_URL
|
||||
|
@ -798,7 +821,8 @@ class PluginsHelper {
|
|||
esc_attr( $subscription['product_name'] ),
|
||||
esc_attr( $expiry_date ),
|
||||
esc_url( $hyperlink_url ),
|
||||
esc_attr( $renew_string ),
|
||||
// Show subscribe for missing subscriptions, renew otherwise.
|
||||
'missing' === $type ? esc_attr( $subscribe_string ) : esc_attr( $renew_string ),
|
||||
);
|
||||
|
||||
return array(
|
||||
|
@ -826,7 +850,7 @@ class PluginsHelper {
|
|||
return array();
|
||||
}
|
||||
|
||||
if ( ! self::$can_show_expiring_subs_notice ) {
|
||||
if ( self::$subscription_usage_notices_already_shown ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
|
@ -851,6 +875,9 @@ class PluginsHelper {
|
|||
|
||||
$total_expiring_subscriptions = count( $expiring_subscriptions );
|
||||
|
||||
// Don't show missing notice if there are expiring subscriptions.
|
||||
self::$subscription_usage_notices_already_shown = true;
|
||||
|
||||
// When payment method is missing on WooCommerce.com.
|
||||
$helper_notices = WC_Helper::get_notices();
|
||||
if ( ! empty( $helper_notices['missing_payment_method_notice'] ) ) {
|
||||
|
@ -927,8 +954,8 @@ class PluginsHelper {
|
|||
return array();
|
||||
}
|
||||
|
||||
$total_expired_subscriptions = count( $expired_subscriptions );
|
||||
self::$can_show_expiring_subs_notice = false;
|
||||
$total_expired_subscriptions = count( $expired_subscriptions );
|
||||
self::$subscription_usage_notices_already_shown = true;
|
||||
|
||||
$notice_data = self::get_subscriptions_notice_data(
|
||||
$subscriptions,
|
||||
|
@ -947,17 +974,17 @@ class PluginsHelper {
|
|||
|
||||
$button_link = add_query_arg(
|
||||
array(
|
||||
'add-to-cart' => $notice_data['product_ids'],
|
||||
'utm_source' => 'pu',
|
||||
'utm_campaign' => $allowed_link ? 'pu_settings_screen_renew' : 'pu_in_apps_screen_renew',
|
||||
),
|
||||
self::WOO_SUBSCRIPTION_PAGE_URL
|
||||
self::WOO_CART_PAGE_URL
|
||||
);
|
||||
|
||||
if ( in_array( $notice_data['type'], array( 'single_manage', 'multiple_manage' ), true ) ) {
|
||||
$button_link = add_query_arg(
|
||||
array(
|
||||
'product_id' => $notice_data['product_id'],
|
||||
'type' => 'expiring',
|
||||
'add-to-cart' => $notice_data['product_id'],
|
||||
),
|
||||
$button_link
|
||||
);
|
||||
|
@ -970,6 +997,86 @@ class PluginsHelper {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted notice information for missing subscription.
|
||||
*
|
||||
* @return array notice information.
|
||||
*/
|
||||
public static function get_missing_subscription_notice() {
|
||||
if ( ! WC_Helper::is_site_connected() ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( self::$subscription_usage_notices_already_shown ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( ! self::should_show_notice( self::DISMISS_MISSING_SUBS_NOTICE ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$subscriptions = WC_Helper::get_subscription_list_data();
|
||||
$missing_subscriptions = array_filter(
|
||||
$subscriptions,
|
||||
function ( $sub ) {
|
||||
return ( ! empty( $sub['local']['installed'] ) && empty( $sub['product_key'] ) );
|
||||
},
|
||||
);
|
||||
|
||||
// Remove WUM from missing subscriptions list.
|
||||
$missing_subscriptions = array_filter(
|
||||
$missing_subscriptions,
|
||||
function ( $sub ) {
|
||||
return 'woo-update-manager' !== $sub['zip_slug'];
|
||||
}
|
||||
);
|
||||
|
||||
if ( ! $missing_subscriptions ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$total_missing_subscriptions = count( $missing_subscriptions );
|
||||
|
||||
$notice_data = self::get_subscriptions_notice_data(
|
||||
$subscriptions,
|
||||
$missing_subscriptions,
|
||||
$total_missing_subscriptions,
|
||||
array(
|
||||
/* translators: 1) product name */
|
||||
'single_manage' => __( 'You don\'t have a subscription for <strong>%1$s</strong>. Subscribe to receive updates and streamlined support.', 'woocommerce' ),
|
||||
/* translators: 1) total expired subscriptions */
|
||||
'different_subscriptions' => __( 'You don\'t have subscriptions for <strong>%1$s Woo extensions</strong>. Subscribe to receive updates and streamlined support.', 'woocommerce' ),
|
||||
),
|
||||
'missing',
|
||||
);
|
||||
|
||||
$button_link = add_query_arg(
|
||||
array(
|
||||
'add-to-cart' => $notice_data['product_ids'],
|
||||
'utm_source' => 'pu',
|
||||
'utm_campaign' => 'pu_in_apps_screen_purchase',
|
||||
),
|
||||
self::WOO_CART_PAGE_URL
|
||||
);
|
||||
|
||||
if ( in_array( $notice_data['type'], array( 'single_manage', 'multiple_manage' ), true ) ) {
|
||||
$button_link = add_query_arg(
|
||||
array(
|
||||
'add-to-cart' => $notice_data['product_id'],
|
||||
),
|
||||
$button_link
|
||||
);
|
||||
}
|
||||
|
||||
$button_text = __( 'Subscribe', 'woocommerce' );
|
||||
|
||||
return array(
|
||||
'description' => $notice_data['parsed_message'],
|
||||
'button_text' => $button_text,
|
||||
'button_link' => $button_link,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether a specific notice should be shown to the current user.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue