diff --git a/classes/Upsell.php b/classes/Upsell.php
index 7d7f59351..b356d4b87 100644
--- a/classes/Upsell.php
+++ b/classes/Upsell.php
@@ -35,7 +35,7 @@ public static function notice_bar_display() {
return;
}
- // Disable it on post.php edit screens for popup editor & popup theme editor. post.php?post=850&action=edit | post-new.php?post_type=popup
+ // Disable it on post.php edit screens for popup editor & popup theme editor. post.php?post=850&action=edit | post-new.php?post_type=popup.
$screen = get_current_screen();
if ( 'post' === $screen->base && ( 'popup' === $screen->post_type || 'popup_theme' === $screen->post_type ) ) {
return;
@@ -128,24 +128,24 @@ private static function detect_integrations() {
/**
* Generate appropriate upgrade message based on current license and plugin status.
*
+ * Uses priority-based trigger system for targeted, engaging upgrade messaging.
+ *
+ * @since 1.21.3 Refactored to use priority-based trigger system.
+ *
* @return string Upgrade message or empty string if no message should be shown.
*/
private static function generate_upgrade_message() {
$license_service = \PopupMaker\plugin( 'license' );
$license_tier = $license_service->get_license_tier();
$license_status = $license_service->get_license_status();
- $pro_is_active = \PopupMaker\plugin()->is_pro_active();
$active_extensions = pum_enabled_extensions();
$has_active_add_ons = ! empty( $active_extensions );
/**
* 1. Pro Plus users with valid license see nothing.
- * 2. Pro users with valid license get targeted integration messaging.
- * 3. Pro users with invalid license get general upgrade messaging.
- * 4. Free users or users with invalid license get general upgrade messaging.
- * 5. Extension users get no message for now.
- * 6. Extension users without valid license get no message for now.
+ * 2. Extension users get no message for now (regardless of license status).
+ * 3. All other users (Free, Pro with invalid license, Pro with valid license) use priority system.
*/
// 1. Pro Plus users with valid license see nothing.
@@ -153,183 +153,344 @@ private static function generate_upgrade_message() {
return '';
}
- // 2. Pro users with valid license get targeted integration messaging.
- if ( 'valid' === $license_status && 'pro' === $license_tier ) {
- return self::get_pro_integration_message();
- }
-
- // 3. Pro users with invalid license get general upgrade messaging.
- if ( $pro_is_active && 'valid' !== $license_status ) {
- return self::get_free_upgrade_message();
+ // 2. Extension users get no message for now.
+ if ( $has_active_add_ons ) {
+ return '';
}
- // 4. Free users get general upgrade messaging.
- if ( ! $pro_is_active && ! $has_active_add_ons ) {
- return self::get_free_upgrade_message();
- }
+ // 3. Use priority-based trigger system for all other users.
+ $trigger = self::get_current_notice_bar_trigger();
- // 5 & 6. Extension users get no message for now (regardless of license status).
- if ( $has_active_add_ons ) {
+ if ( empty( $trigger ) ) {
return '';
}
- // Fallback (should not reach here).
- return '';
+ return $trigger['message'];
}
/**
- * Generate targeted upgrade messages based on detected integrations.
+ * Get a random matching notice bar trigger.
+ *
+ * Collects all triggers whose conditions are met and returns one at random,
+ * so users see different messages across page loads.
*
- * @param string $user_tier Current user tier ('free', 'pro', 'pro_plus').
- * @return string Targeted upgrade message or empty string.
+ * @since 1.21.3
+ *
+ * @return array|false Trigger array or false if no trigger matches.
*/
- private static function get_integration_messages( $user_tier ) {
- $integrations = self::detect_integrations();
- $messages = [];
-
- // For Pro users, show Pro+ integration opportunities.
- if ( in_array( $user_tier, [ 'free', 'pro' ], true ) && ! empty( $integrations['pro_plus'] ) ) {
- foreach ( $integrations['pro_plus'] as $category => $platforms ) {
- if ( ! empty( $platforms ) ) {
- $platform_list = self::format_integration_list( $platforms );
-
- switch ( $category ) {
- case 'ecommerce':
- // Determine which ecommerce platform to link to.
- $has_woocommerce = in_array( 'WooCommerce', $platforms, true );
- $has_edd = in_array( 'Easy Digital Downloads', $platforms, true );
-
- // Route to specific integration page (WooCommerce preferred if both exist, though rare).
- if ( $has_woocommerce ) {
- $base_url = 'https://wppopupmaker.com/ecommerce-integrations/woocommerce/';
- } else {
- $base_url = 'https://wppopupmaker.com/ecommerce-integrations/easy-digital-downloads/';
- }
-
- $upgrade_link = add_query_arg(
- [
- 'utm_source' => 'plugin',
- 'utm_medium' => 'notice-bar',
- 'utm_campaign' => 'ecommerce-detected',
- ],
- $base_url
- );
- $messages[] = sprintf(
- /* translators: 1: Detected ecommerce platforms, 2: Opening link tag, 3: Closing link tag. */
- esc_html__( 'Automate %1$s campaigns with %2$sPopup Maker Pro+ Ecommerce%3$s - unlock cart actions, revenue attribution, and precision targeting.', 'popup-maker' ),
- $platform_list,
- '',
- ''
- );
- break;
-
- case 'lms':
- // Point to LifterLMS integration page with UTM tracking.
- $base_url = 'https://wppopupmaker.com/lms-integrations/lifterlms/';
- $upgrade_link = add_query_arg(
- [
- 'utm_source' => 'plugin',
- 'utm_medium' => 'notice-bar',
- 'utm_campaign' => 'lms-detected',
- ],
- $base_url
- );
- $messages[] = sprintf(
- /* translators: 1: Detected LMS platforms, 2: Opening link tag, 3: Closing link tag. */
- esc_html__( 'Deliver targeted funnels for %1$s with %2$sPopup Maker Pro+ LMS%3$s - track enrollments, issue rewards, and automate course journeys.', 'popup-maker' ),
- $platform_list,
- '',
- ''
- );
- break;
- }
+ private static function get_current_notice_bar_trigger() {
+ $triggers = self::get_notice_bar_triggers();
+
+ // Collect all matching triggers across all groups.
+ $matching = [];
+ foreach ( $triggers as $group ) {
+ foreach ( $group['triggers'] as $trigger ) {
+ if ( ! in_array( false, $trigger['conditions'], true ) ) {
+ $matching[] = $trigger;
}
}
}
- // For Free users, show Pro integration opportunities.
- if ( 'free' === $user_tier && ! empty( $integrations['pro'] ) ) {
- foreach ( $integrations['pro'] as $category => $platforms ) {
- if ( ! empty( $platforms ) ) {
- $platform_list = self::format_integration_list( $platforms );
-
- switch ( $category ) {
- case 'crm':
- // Point to FluentCRM integration page with UTM tracking.
- $base_url = 'https://wppopupmaker.com/crm-integrations/fluentcrm/';
- $upgrade_link = add_query_arg(
- [
- 'utm_source' => 'plugin',
- 'utm_medium' => 'notice-bar',
- 'utm_campaign' => 'crm-detected',
- ],
- $base_url
- );
- $messages[] = sprintf(
- /* translators: 1: Detected CRM platforms, 2: Opening link tag, 3: Closing link tag. */
- esc_html__( 'Unlock %1$s integration with %2$sPopup Maker Pro%3$s - connect popups to your CRM workflows and automate lead capture.', 'popup-maker' ),
- $platform_list,
- '',
- ''
- );
- break;
- }
- }
- }
- }
-
- // Randomly select one message if available.
- if ( ! empty( $messages ) ) {
- $random_index = array_rand( $messages );
- return $messages[ $random_index ];
+ if ( empty( $matching ) ) {
+ return false;
}
- return '';
+ // Randomize so users see different messages across page loads.
+ return $matching[ array_rand( $matching ) ];
}
/**
- * Get upgrade message for Pro users based on detected integrations.
+ * Get notice bar triggers organized by priority groups.
+ *
+ * Trigger groups are sorted by group priority (highest first).
+ * Triggers within each group are sorted by trigger priority (highest first).
*
- * @return string Targeted upgrade message.
+ * @since 1.21.3
+ *
+ * @return array}> Trigger groups.
*/
- private static function get_pro_integration_message() {
- $integration_message = self::get_integration_messages( 'pro' );
+ private static function get_notice_bar_triggers() {
+ static $triggers;
- if ( ! empty( $integration_message ) ) {
- return $integration_message;
+ if ( isset( $triggers ) ) {
+ return $triggers;
}
- // Generic Pro+ upgrade message fallback.
- $upgrade_link = \PopupMaker\generate_upgrade_url( 'notice-bar', 'pro-generic-upgrade' );
- return sprintf(
- /* translators: 1: Opening link tag to pricing page. 2: Closing link tag. */
- esc_html__( 'Level up with %1$sPopup Maker Pro+%2$s - unlock ecommerce automation, revenue attribution, and enhanced targeting.', 'popup-maker' ),
- '',
- ''
- );
+ $license_service = \PopupMaker\plugin( 'license' );
+ $license_tier = $license_service->get_license_tier();
+ $license_status = $license_service->get_license_status();
+ $integrations = self::detect_integrations();
+ $has_ecommerce = ! empty( $integrations['pro_plus']['ecommerce'] );
+ $has_lms = ! empty( $integrations['pro_plus']['lms'] );
+ $has_crm = ! empty( $integrations['pro']['crm'] );
+
+ // Get form conversion count (will be 0 if service not available).
+ $form_count = self::get_form_conversion_count();
+
+ // Get total popup views.
+ $popup_views = (int) get_option( 'pum_total_open_count', 0 );
+
+ // New installs (after form tracking shipped) get celebration messaging.
+ // Existing installs get "tracking is now live" messaging instead.
+ $installed_on = get_option( 'pum_installed_on', '' );
+ $is_new_install = ! empty( $installed_on ) && strtotime( $installed_on ) >= strtotime( '2026-03-25' );
+
+ $triggers = [
+
+ /*
+ * Group 1: Milestone Achievements (Highest Priority: 100)
+ * Celebration-based messaging for user success milestones.
+ */
+ 'milestone_achievements' => [
+ 'pri' => 100,
+ 'triggers' => [
+ 'first_form_conversion' => [
+ 'message' => $is_new_install
+ ? sprintf(
+ /* translators: 1: Opening link tag, 2: Closing link tag. */
+ esc_html__( '🎉 Congrats on your first form submission! %1$sUpgrade to Pro%2$s for exit intent triggers, conversion analytics, and advanced targeting.', 'popup-maker' ),
+ '',
+ ''
+ )
+ : sprintf(
+ /* translators: 1: Opening link tag, 2: Closing link tag. */
+ esc_html__( '📊 Form conversion tracking is now live! Your first submission has been captured. %1$sSee what\'s converting with Pro analytics%2$s.', 'popup-maker' ),
+ '',
+ ''
+ ),
+ 'conditions' => [
+ 1 === $form_count,
+ ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'first-form-milestone' ),
+ 'utm_campaign' => 'first-form-milestone',
+ 'pri' => 100,
+ ],
+ 'high_engagement_10k' => [
+ 'message' => sprintf(
+ /* translators: 1: Number of popup views, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( '🚀 Amazing! You\'ve had %1$s popup views! %2$sSee which ones convert best with Pro analytics%3$s.', 'popup-maker' ),
+ number_format( $popup_views ),
+ '',
+ ''
+ ),
+ 'conditions' => [
+ $popup_views >= 10000,
+ ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'high-engagement-10k' ),
+ 'utm_campaign' => 'high-engagement-10k',
+ 'pri' => 95,
+ ],
+ 'high_engagement_5k' => [
+ 'message' => sprintf(
+ /* translators: 1: Number of popup views, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( '📊 You\'ve had %1$s popup views! %2$sSee which ones convert best with Pro analytics%3$s.', 'popup-maker' ),
+ number_format( $popup_views ),
+ '',
+ ''
+ ),
+ 'conditions' => [
+ $popup_views >= 5000,
+ $popup_views < 10000,
+ ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'high-engagement-5k' ),
+ 'utm_campaign' => 'high-engagement-5k',
+ 'pri' => 90,
+ ],
+ 'high_engagement_1k' => [
+ 'message' => sprintf(
+ /* translators: 1: Number of popup views, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( '📈 You\'ve had %1$s popup views! %2$sSee which ones convert best with Pro analytics%3$s.', 'popup-maker' ),
+ number_format( $popup_views ),
+ '',
+ ''
+ ),
+ 'conditions' => [
+ $popup_views >= 1000,
+ $popup_views < 5000,
+ ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'high-engagement-1k' ),
+ 'utm_campaign' => 'high-engagement-1k',
+ 'pri' => 85,
+ ],
+ ],
+ ],
+
+ /*
+ * Group 2: Integration Detected (Priority: 60)
+ * Contextual messages based on detected plugins.
+ */
+ 'integration_detected' => [
+ 'pri' => 60,
+ 'triggers' => [],
+ ],
+
+ /*
+ * Group 4: Generic Upgrade (Priority: 40)
+ * Fallback messages for users without specific triggers.
+ */
+ 'generic_upgrade' => [
+ 'pri' => 40,
+ 'triggers' => [],
+ ],
+ ];
+
+ // Build integration-detected triggers dynamically.
+ if ( $has_ecommerce ) {
+ $platform_list = self::format_integration_list( $integrations['pro_plus']['ecommerce'] );
+ $triggers['integration_detected']['triggers']['ecommerce_carts'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected ecommerce platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( '%1$s detected — recover abandoned carts, trigger discount popups, and track revenue per popup with %2$sPro+ Ecommerce Popups%3$s.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'ecommerce-carts' ),
+ 'utm_campaign' => 'ecommerce-carts',
+ 'pri' => 100,
+ ];
+ $triggers['integration_detected']['triggers']['ecommerce_revenue'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected ecommerce platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( 'Track exactly which popups drive %1$s sales with %2$sPro+ Ecommerce Popups%3$s — revenue attribution, purchase targeting, and conversion analytics.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'ecommerce-revenue' ),
+ 'utm_campaign' => 'ecommerce-revenue',
+ 'pri' => 90,
+ ];
+ $triggers['integration_detected']['triggers']['ecommerce_upsell'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected ecommerce platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( 'Show personalized offers to %1$s customers based on cart contents and purchase history with %2$sPro+ Ecommerce Popups%3$s.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'ecommerce-upsell' ),
+ 'utm_campaign' => 'ecommerce-upsell',
+ 'pri' => 80,
+ ];
+ }
+
+ if ( $has_lms ) {
+ $platform_list = self::format_integration_list( $integrations['pro_plus']['lms'] );
+ $triggers['integration_detected']['triggers']['lms_enrollment'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected LMS platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( '%1$s detected — boost course enrollment, target students by progress, and track signups per popup with %2$sPro+ LMS Popups%3$s.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'lms-enrollment' ),
+ 'utm_campaign' => 'lms-enrollment',
+ 'pri' => 90,
+ ];
+ $triggers['integration_detected']['triggers']['lms_targeting'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected LMS platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( 'Show the right offer at the right time — target %1$s students by enrollment status, course progress, and membership with %2$sPro+ LMS Popups%3$s.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'lms-targeting' ),
+ 'utm_campaign' => 'lms-targeting',
+ 'pri' => 80,
+ ];
+ }
+
+ if ( $has_crm ) {
+ $platform_list = self::format_integration_list( $integrations['pro']['crm'] );
+ $triggers['integration_detected']['triggers']['crm_tagging'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected CRM platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( '%1$s detected — auto-tag subscribers, trigger email sequences from popups, and sync leads with %2$sPopup Maker Pro%3$s.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'crm-tagging' ),
+ 'utm_campaign' => 'crm-tagging',
+ 'pri' => 80,
+ ];
+ $triggers['integration_detected']['triggers']['crm_automation'] = [
+ 'message' => sprintf(
+ /* translators: 1: Detected CRM platforms, 2: Opening link tag, 3: Closing link tag. */
+ esc_html__( 'Connect popups to %1$s workflows — automatically add contacts, apply tags, and start automations when visitors convert with %2$sPopup Maker Pro%3$s.', 'popup-maker' ),
+ $platform_list,
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'crm-automation' ),
+ 'utm_campaign' => 'crm-automation',
+ 'pri' => 70,
+ ];
+ }
+
+ // Build generic upgrade triggers.
+ if ( 'valid' === $license_status && 'pro' === $license_tier ) {
+ // Pro users get Pro+ generic message.
+ $triggers['generic_upgrade']['triggers']['pro_generic'] = [
+ 'message' => sprintf(
+ /* translators: 1: Opening link tag, 2: Closing link tag. */
+ esc_html__( 'Level up with %1$sPopup Maker Pro+%2$s - unlock ecommerce automation, revenue attribution, and enhanced targeting.', 'popup-maker' ),
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'pro-generic-upgrade' ),
+ 'utm_campaign' => 'pro-generic-upgrade',
+ 'pri' => 100,
+ ];
+ } else {
+ // Free users or Pro with invalid license get free generic message.
+ $triggers['generic_upgrade']['triggers']['free_generic'] = [
+ 'message' => sprintf(
+ /* translators: 1: Opening link tag, 2: Closing link tag. */
+ esc_html__( 'Unlock advanced features with %1$sPopup Maker Pro & Pro+%2$s - Enhanced targeting, revenue tracking, live analytics, and more.', 'popup-maker' ),
+ '',
+ ''
+ ),
+ 'conditions' => [ true ],
+ 'link' => \PopupMaker\generate_upgrade_url( 'notice-bar', 'free-generic-upgrade' ),
+ 'utm_campaign' => 'free-generic-upgrade',
+ 'pri' => 90,
+ ];
+ }
+
+ return $triggers;
}
/**
- * Get upgrade message for free users.
+ * Get site-wide form conversion count.
*
- * @return string General upgrade message.
+ * @since 1.21.3
+ *
+ * @return int Form conversion count, or 0 if not available.
*/
- private static function get_free_upgrade_message() {
- // Try to get an integration-specific message first.
- $integration_message = self::get_integration_messages( 'free' );
-
- if ( ! empty( $integration_message ) ) {
- return $integration_message;
+ private static function get_form_conversion_count() {
+ try {
+ $form_tracking = \PopupMaker\plugin( 'form_conversion_tracking' );
+ if ( $form_tracking && method_exists( $form_tracking, 'get_site_count' ) ) {
+ return $form_tracking->get_site_count();
+ }
+ } catch ( \Throwable $e ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
+ // Service not available, graceful fallback.
+ unset( $e );
}
- // Generic upgrade message fallback.
- $upgrade_link = \PopupMaker\generate_upgrade_url( 'notice-bar', 'free-generic-upgrade' );
- return sprintf(
- /* translators: 1: Opening link tag to pricing page. 2: Closing link tag. */
- esc_html__( 'Unlock advanced features with %1$sPopup Maker Pro & Pro+%2$s - Enhanced targeting, revenue tracking, live analytics, and more.', 'popup-maker' ),
- '',
- ''
- );
+ return 0;
}
/**