'; AIFLT_UI::empty_state('store', __('WooCommerce is needed', 'ai-flash-tune'), __('The funnel follows shoppers through your WooCommerce store. Activate WooCommerce to start.', 'ai-flash-tune'), '' . esc_html($aiflt_wc['button_text']) . ''); echo ''; return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only filter. $aiflt_device = isset($_GET['device']) ? sanitize_key(wp_unslash($_GET['device'])) : 'all'; $aiflt_device = in_array($aiflt_device, ['all', 'desktop', 'mobile'], true) ? $aiflt_device : 'all'; // Side-by-side comparison is an AI Flash Tune Pro feature (it turns this filter on). $aiflt_can_compare = (bool) apply_filters('aiflt_funnel_compare_enabled', true); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only filter. $aiflt_compare = isset($_GET['compare']) ? sanitize_key(wp_unslash($_GET['compare'])) : ''; $aiflt_compare = ($aiflt_can_compare && in_array($aiflt_compare, ['device', 'customer', 'source'], true)) ? $aiflt_compare : ''; if ($aiflt_compare !== '') { $aiflt_device = 'all'; } $aiflt_period = AIFLT_UI::period(30); $aiflt_funnel = AIFLT_Funnel_Analyzer_Logic::get_funnel_data($aiflt_device, $aiflt_period['start'], $aiflt_period['end']); // The same length of time just before, for the change figures. $aiflt_prev_end = wp_date('Y-m-d', strtotime($aiflt_period['start'] . ' -1 day')); $aiflt_prev_start = wp_date('Y-m-d', strtotime($aiflt_prev_end . ' -' . ($aiflt_period['days'] - 1) . ' days')); $aiflt_prev = AIFLT_Funnel_Analyzer_Logic::get_funnel_data($aiflt_device, $aiflt_prev_start, $aiflt_prev_end); $aiflt_has_prev = empty($aiflt_prev['is_empty']) && (int) ($aiflt_prev['total_sessions'] ?? 0) > 0; $aiflt_change = static function ($key) use ($aiflt_funnel, $aiflt_prev, $aiflt_has_prev) { $before = (float) ($aiflt_prev[$key] ?? 0); return ($aiflt_has_prev && $before > 0) ? ((float) ($aiflt_funnel[$key] ?? 0) - $before) / $before * 100 : null; }; $aiflt_has_data = empty($aiflt_funnel['is_empty']) && (int) ($aiflt_funnel['total_sessions'] ?? 0) > 0; $aiflt_keep = ['page' => 'aiflt-funnel', 'device' => $aiflt_device, 'compare' => $aiflt_compare]; if ($aiflt_period['range'] === 'custom') { $aiflt_keep += ['range' => 'custom', 'start_date' => $aiflt_period['start'], 'end_date' => $aiflt_period['end']]; } else { $aiflt_keep['range'] = $aiflt_period['range']; } $aiflt_toolbar_right = ''; if ($aiflt_compare === '') { $aiflt_toolbar_right .= AIFLT_UI::segmented( ['all' => __('All devices', 'ai-flash-tune'), 'desktop' => __('Desktop', 'ai-flash-tune'), 'mobile' => __('Mobile', 'ai-flash-tune')], $aiflt_device, 'device', array_diff_key($aiflt_keep, ['device' => 1]), __('Device', 'ai-flash-tune') ); } if ($aiflt_can_compare) { $aiflt_toolbar_right .= '' . esc_html__('Compare', 'ai-flash-tune') . '' . AIFLT_UI::segmented( ['' => __('Off', 'ai-flash-tune'), 'device' => __('Devices', 'ai-flash-tune'), 'customer' => __('Customer type', 'ai-flash-tune'), 'source' => __('AI assistants', 'ai-flash-tune')], $aiflt_compare, 'compare', array_diff_key($aiflt_keep, ['compare' => 1, 'device' => 1]), __('Compare', 'ai-flash-tune') ); } else { $aiflt_toolbar_right .= '' . AIFLT_UI::icon('lock') . esc_html__('Compare', 'ai-flash-tune') . ''; } AIFLT_UI::period_toolbar( $aiflt_period, array_diff_key($aiflt_keep, ['range' => 1, 'start_date' => 1, 'end_date' => 1]), $aiflt_toolbar_right ); if (!$aiflt_has_data) { echo '
'; AIFLT_UI::empty_state( 'funnel', __('No shopper visits in this period', 'ai-flash-tune'), __('Try a longer period, or check tracking: open your store in a private window, view a product, add it to the cart and open checkout. The visit appears here within a minute.', 'ai-flash-tune'), '' . AIFLT_UI::icon('external') . esc_html__('Open my store', 'ai-flash-tune') . '' ); echo '
'; return; } $aiflt_sessions = (int) $aiflt_funnel['total_sessions']; $aiflt_sales = (int) ($aiflt_funnel['sales'] ?? $aiflt_funnel['completed_sessions'] ?? 0); $aiflt_abandoned = (int) ($aiflt_funnel['drop_off_sessions'] ?? 0); ?>
0 ? 'good' : ''); AIFLT_UI::stat(__('Conversion rate', 'ai-flash-tune'), esc_html(number_format_i18n((float) $aiflt_funnel['conversion_rate'], 1)) . '%', AIFLT_UI::delta($aiflt_change('conversion_rate'))); AIFLT_UI::stat( __('Left in abandoned carts', 'ai-flash-tune'), (string) $aiflt_funnel['lost_sales'], /* translators: %s: number of abandoned shopping sessions */ esc_html(sprintf(_n('%s abandoned session', '%s abandoned sessions', $aiflt_abandoned, 'ai-flash-tune'), number_format_i18n($aiflt_abandoned))), $aiflt_abandoned > 0 ? 'leak' : '' ); ?>
__('%1$s of visitors did not view any product (%2$s sessions).', 'ai-flash-tune'), /* translators: 1: percentage, 2: number of sessions */ 2 => __('%1$s of shoppers who viewed a product did not add it to the cart (%2$s sessions).', 'ai-flash-tune'), /* translators: 1: percentage, 2: number of sessions */ 3 => __('%1$s of shoppers with a cart did not open checkout (%2$s sessions).', 'ai-flash-tune'), /* translators: 1: percentage, 2: number of sessions */ 4 => __('%1$s of shoppers who reached checkout did not buy (%2$s sessions).', 'ai-flash-tune'), ]; $aiflt_worst = null; for ($aiflt_step_i = 1; $aiflt_step_i < count($aiflt_steps); $aiflt_step_i++) { $aiflt_from_count = $aiflt_steps[$aiflt_step_i - 1][1]; if ($aiflt_from_count < 5) { continue; } $aiflt_lost_share = 1 - min($aiflt_steps[$aiflt_step_i][1], $aiflt_from_count) / $aiflt_from_count; if ($aiflt_worst === null || $aiflt_lost_share > $aiflt_worst[1]) { $aiflt_worst = [$aiflt_step_i, $aiflt_lost_share, $aiflt_from_count - min($aiflt_steps[$aiflt_step_i][1], $aiflt_from_count)]; } } ?> [['device', 'desktop', __('Desktop', 'ai-flash-tune')], ['device', 'mobile', __('Mobile', 'ai-flash-tune')]], 'customer' => [['user_type', 'guest', __('Guests', 'ai-flash-tune')], ['user_type', 'registered', __('Customers with an account', 'ai-flash-tune')]], // Sent by ChatGPT, Gemini, Perplexity... against every other visit. 'source' => [['source', 'ai', __('From AI assistants', 'ai-flash-tune')], ['source', 'other', __('Everyone else', 'ai-flash-tune')]], ]; $aiflt_sides = $aiflt_sides_by[$aiflt_compare]; $aiflt_side_steps = []; foreach ($aiflt_sides as $aiflt_i => [$aiflt_type, $aiflt_value, $aiflt_label]) { $aiflt_side_funnel = AIFLT_Funnel_Analyzer_Logic::get_funnel_data('all', $aiflt_period['start'], $aiflt_period['end'], $aiflt_type, $aiflt_value); $aiflt_side_steps[$aiflt_i] = [$aiflt_label, $aiflt_steps_for($aiflt_side_funnel), (int) ($aiflt_side_funnel['segment_sessions'] ?? 0)]; } // The step where the two groups differ most in the share they keep. $aiflt_diff = null; for ($aiflt_step_i = 1; $aiflt_step_i < 5; $aiflt_step_i++) { $aiflt_rate_pair = []; foreach ($aiflt_side_steps as [$aiflt_label, $aiflt_s]) { $aiflt_rate_pair[] = $aiflt_s[$aiflt_step_i - 1][1] >= 5 ? $aiflt_s[$aiflt_step_i][1] / $aiflt_s[$aiflt_step_i - 1][1] * 100 : null; } if ($aiflt_rate_pair[0] !== null && $aiflt_rate_pair[1] !== null && ($aiflt_diff === null || abs($aiflt_rate_pair[0] - $aiflt_rate_pair[1]) > abs($aiflt_diff[1] - $aiflt_diff[2]))) { $aiflt_diff = [$aiflt_step_i, $aiflt_rate_pair[0], $aiflt_rate_pair[1]]; } } ?>

' . esc_html__('Biggest difference:', 'ai-flash-tune') . ' '; printf( /* translators: 1: step name, 2: first group, 3: its percentage, 4: second group, 5: its percentage */ esc_html__('%1$s: %2$s keep %3$s, %4$s keep %5$s.', 'ai-flash-tune'), esc_html($aiflt_side_steps[0][1][$aiflt_diff[0]][0]), esc_html($aiflt_side_steps[0][0]), '' . esc_html(number_format_i18n($aiflt_diff[1], 0)) . '%', esc_html(mb_strtolower($aiflt_side_steps[1][0])), '' . esc_html(number_format_i18n($aiflt_diff[2], 0)) . '%' ); ?>

0) : ?>

' . esc_html__('Biggest drop:', 'ai-flash-tune') . ' '; printf( esc_html($aiflt_drop_sentences[$aiflt_worst[0]]), '' . esc_html(number_format_i18n($aiflt_worst[1] * 100, 0)) . '%', esc_html(number_format_i18n($aiflt_worst[2])) ); ?>