is_woo_active ) { return; } wp_add_dashboard_widget( 'cartflows_funnel_performance', __( 'CartFlows โ€” Funnel Performance', 'cartflows' ), array( $this, 'render_widget' ) ); } /** * Render the dashboard widget body. * * @since 2.2.3 * @return void */ public function render_widget() { $stats = $this->get_stats(); $locked = $this->show_locked_cards(); // Decide message copy based on activity and licence state. if ( $locked ) { if ( 0 === (int) $stats['total_orders'] && (float) $stats['total_revenue_raw'] <= 0 ) { $message = __( 'Your funnels are ready to generate revenue. Start boosting sales instantly with order bumps and upsells in CartFlows Pro.', 'cartflows' ); } elseif ( (int) $stats['total_orders'] > 0 ) { /* translators: %s: Total revenue formatted as currency. */ $message = sprintf( __( "You've made %s โ€” now scale it with upsells & order bumps.", 'cartflows' ), wp_strip_all_tags( str_replace( ' ', ' ', wc_price( (float) $stats['total_revenue_raw'] ) ) ) ); } else { $message = __( 'Want to boost funnel revenue by 30%+? Unlock order bumps, upsells, and advanced funnel features with CartFlows Pro.', 'cartflows' ); } } else { /* translators: %s: Total revenue formatted as currency. */ $message = sprintf( __( "You've earned %s with CartFlows in the last 30 days.", 'cartflows' ), wp_strip_all_tags( str_replace( ' ', ' ', wc_price( (float) $stats['total_revenue_raw'] ) ) ) ); } $report_url = admin_url( 'admin.php?page=cartflows&path=home' ); $upgrade_url = $this->get_utm_url( 'https://cartflows.com/pricing/', 'dashboard-widget-card' ); ?>

' . esc_html__( 'last 30 days', 'cartflows' ) . '' ), array( 'strong' => array() ) ); ?>

→
render_card( __( 'Orders Generated', 'cartflows' ), $stats['total_orders'], false, false, false, $upgrade_url ); ?> render_card( __( 'Total Revenue', 'cartflows' ), $stats['total_revenue_raw'], true, false, false, $upgrade_url ); ?> render_card( __( 'Revenue from Order Bumps', 'cartflows' ), $stats['total_bump_revenue_raw'], true, $locked, true, $upgrade_url ); ?> render_card( __( 'Revenue from Upsells', 'cartflows' ), $stats['total_offers_revenue_raw'], true, $locked, true, $upgrade_url ); ?>
render_inline_styles(); ?>
(int) $cached['total_orders'], 'total_revenue_raw' => (float) $cached['total_revenue_raw'], 'total_bump_revenue_raw' => (float) $cached['total_bump_revenue_raw'], 'total_offers_revenue_raw' => (float) $cached['total_offers_revenue_raw'], ); } $earnings = array(); if ( class_exists( '\CartflowsAdmin\AdminCore\Inc\AdminHelper' ) ) { $earnings = \CartflowsAdmin\AdminCore\Inc\AdminHelper::get_earnings( $start, $end, '', 'home', '' ); } if ( ! is_array( $earnings ) ) { $earnings = array(); } // Pro filter shape may omit the *_raw keys; fall back to numeric parse of formatted fields. $bump_raw = isset( $earnings['total_bump_revenue_raw'] ) ? (float) $earnings['total_bump_revenue_raw'] : ( isset( $earnings['total_bump_revenue'] ) && is_numeric( $earnings['total_bump_revenue'] ) ? (float) $earnings['total_bump_revenue'] : 0.0 ); $offers_raw = isset( $earnings['total_offers_revenue_raw'] ) ? (float) $earnings['total_offers_revenue_raw'] : ( isset( $earnings['total_offers_revenue'] ) && is_numeric( $earnings['total_offers_revenue'] ) ? (float) $earnings['total_offers_revenue'] : 0.0 ); $stats = array( 'total_orders' => isset( $earnings['total_orders'] ) ? (int) $earnings['total_orders'] : 0, 'total_revenue_raw' => isset( $earnings['total_revenue_raw'] ) ? (float) $earnings['total_revenue_raw'] : ( isset( $earnings['total_revenue'] ) && is_numeric( $earnings['total_revenue'] ) ? (float) $earnings['total_revenue'] : 0.0 ), 'total_bump_revenue_raw' => $bump_raw, 'total_offers_revenue_raw' => $offers_raw, ); set_transient( $cache_key, $stats, 6 * HOUR_IN_SECONDS ); return $stats; } /** * Decide whether the PRO upsell cards should appear locked. * * @since 2.2.3 * @return bool True when running on free or unlicensed Pro. */ private function show_locked_cards() { return ! ( _is_cartflows_pro() && is_wcf_pro_plan() ); } /** * Build a CartFlows.com URL with UTM parameters appended. * * @since 2.2.3 * @param string $base Destination base URL. * @param string $campaign UTM campaign slug. * @return string Full URL with UTM query parameters. */ private function get_utm_url( $base, $campaign ) { return add_query_arg( array( 'utm_source' => 'plugin-page', 'utm_medium' => 'free-cartflows', 'utm_campaign' => $campaign, ), $base ); } /** * Render a single stat card. * * @since 2.2.3 * @param string $label Card label. * @param int|float|string $raw_value Raw numeric value. * @param bool $is_currency Whether the value should be formatted as currency. * @param bool $is_locked Whether the card should display the locked state. * @param bool $is_pro Whether this metric is PRO-only. * @param string $upgrade_url Upgrade URL used when the card is locked. * @return void */ private function render_card( $label, $raw_value, $is_currency, $is_locked, $is_pro, $upgrade_url ) { $numeric = (float) ( is_numeric( $raw_value ) ? $raw_value : 0 ); $display = $is_currency ? wc_price( $numeric ) : number_format_i18n( $numeric ); $class = 'wcf-dash-card'; if ( $is_locked ) { $class .= ' is-locked'; } if ( $is_pro ) { $class .= ' is-pro'; } // Locked card is rendered as a clickable upgrade surface; unlocked is a plain div. if ( $is_locked ) { ?>
' : '
'; } /** * Render scoped inline styles for the widget. * * @since 2.2.3 * @return void */ private function render_inline_styles() { ?>