| @@ -989,8 +989,16 @@ | ||
| 989 | 989 | if ( \SRFM\Inc\Onboarding::get_instance()->get_onboarding_status() ) { |
| 990 | 990 | $onboarding_props = []; |
| 991 | 991 | $onboarding_analytics = Helper::get_srfm_option( 'onboarding_analytics', [] ); |
| 992 | 992 | |
| 993 | + // Which wizard produced the blob. Outside the non-empty guard and not | |
| 994 | + // isset()-gated like the flags below, because absence IS the answer: a | |
| 995 | + // blob from the old wizard, or no blob at all, must still report 'no'. | |
| 996 | + // Without this the two wizards share one event name and can only be | |
| 997 | + // told apart by which properties happen to be present -- and a v2 run | |
| 998 | + // on Pro with no caching plugin emits none of the new ones. | |
| 999 | + $onboarding_props['onboarding_v2'] = ! empty( $onboarding_analytics['onboardingV2'] ) ? 'yes' : 'no'; | |
| 1000 | + | |
| 993 | 1001 | if ( ! empty( $onboarding_analytics ) && is_array( $onboarding_analytics ) ) { |
| 994 | 1002 | if ( ! empty( $onboarding_analytics['skippedSteps'] ) && is_array( $onboarding_analytics['skippedSteps'] ) ) { |
| 995 | 1003 | $onboarding_props['skipped_steps'] = implode( ',', $onboarding_analytics['skippedSteps'] ); |
| 996 | 1004 | } |
| @@ -1010,17 +1018,40 @@ | ||
| 1010 | 1018 | if ( isset( $onboarding_analytics['exitedEarly'] ) ) { |
| 1011 | 1019 | $onboarding_props['exited_early'] = (bool) $onboarding_analytics['exitedEarly'] ? 'yes' : 'no'; |
| 1012 | 1020 | } |
| 1013 | 1021 | |
| 1014 | - if ( ! empty( $onboarding_analytics['premiumFeatures']['selectedFeatures'] ) && is_array( $onboarding_analytics['premiumFeatures']['selectedFeatures'] ) ) { | |
| 1015 | - $premium = array_filter( | |
| 1016 | - $onboarding_analytics['premiumFeatures']['selectedFeatures'], | |
| 1017 | - static function( $f ) { | |
| 1018 | - return 'ai-form-generation' !== $f && 'entries' !== $f; | |
| 1019 | - } | |
| 1022 | + // Add-ons step: the wizard shows one feature tab at a time | |
| 1023 | + // instead of a checkbox list, so we report which tabs were opened and | |
| 1024 | + // whether Upgrade was clicked. Blobs written by older wizards carry | |
| 1025 | + // neither key and emit neither property. | |
| 1026 | + if ( ! empty( $onboarding_analytics['premiumFeatures']['viewedTabs'] ) && is_array( $onboarding_analytics['premiumFeatures']['viewedTabs'] ) ) { | |
| 1027 | + // The blob is whatever the wizard POSTed. The tabs are a closed | |
| 1028 | + // set of four, so intersect against it rather than filtering on | |
| 1029 | + // type: that drops anything unrecognised and caps both the | |
| 1030 | + // content and the length of the property in one step. | |
| 1031 | + $viewed_tabs = array_values( | |
| 1032 | + array_intersect( | |
| 1033 | + array_map( 'strval', array_filter( (array) $onboarding_analytics['premiumFeatures']['viewedTabs'], 'is_scalar' ) ), | |
| 1034 | + [ 'multistep', 'conditional', 'calculation', 'conversational' ] | |
| 1035 | + ) | |
| 1020 | 1036 | ); |
| 1021 | - $onboarding_props['selected_premium_features'] = implode( ',', $premium ); | |
| 1022 | - $onboarding_props['premium_features_count'] = (string) count( $premium ); | |
| 1037 | + $onboarding_props['viewed_premium_tabs'] = implode( ',', $viewed_tabs ); | |
| 1038 | + } | |
| 1039 | + | |
| 1040 | + if ( isset( $onboarding_analytics['premiumFeatures']['upgradeClicked'] ) ) { | |
| 1041 | + $onboarding_props['premium_upgrade_clicked'] = (bool) $onboarding_analytics['premiumFeatures']['upgradeClicked'] ? 'yes' : 'no'; | |
| 1042 | + } | |
| 1043 | + | |
| 1044 | + // Cache-conflict step: shown only when a recognised caching plugin | |
| 1045 | + // is active; "yes" means the user pressed "I've fixed this". | |
| 1046 | + // | |
| 1047 | + // Read this as an abandonment signal, not as intent. Acknowledging | |
| 1048 | + // is the only way past the step, so everyone who completes the | |
| 1049 | + // wizard reports "yes" and "no" only ever appears next to | |
| 1050 | + // exited_early. It cannot answer "did people act on the warning" -- | |
| 1051 | + // only "did they stop here". | |
| 1052 | + if ( isset( $onboarding_analytics['cacheConflictAcknowledged'] ) ) { | |
| 1053 | + $onboarding_props['cache_conflict_acknowledged'] = (bool) $onboarding_analytics['cacheConflictAcknowledged'] ? 'yes' : 'no'; | |
| 1023 | 1054 | } |
| 1024 | 1055 | } |
| 1025 | 1056 | |
| 1026 | 1057 | self::events()->track( 'onboarding_completed', '', $onboarding_props ); |