'; return $headers; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_vertical_label' ) ) { function matewa_pro_lead_routing_get_vertical_label() { $label = ''; if ( function_exists( 'matewa_get_active_vertical' ) ) { $vertical = matewa_get_active_vertical(); if ( is_array( $vertical ) && ! empty( $vertical['label'] ) ) { $label = matewa_pro_lead_routing_limit_text( $vertical['label'], 80 ); } } if ( '' === $label ) { $label = matewa_pro_lead_routing_limit_text( get_option( 'matewa_industry', '' ), 80 ); } return $label; } } if ( ! function_exists( 'matewa_pro_lead_routing_normalise_phone' ) ) { function matewa_pro_lead_routing_normalise_phone( $phone ) { return preg_replace( '/\D+/', '', (string) $phone ); } } if ( ! function_exists( 'matewa_pro_lead_routing_normalise_whatsapp_link_phone' ) ) { function matewa_pro_lead_routing_normalise_whatsapp_link_phone( $phone ) { $digits = matewa_pro_lead_routing_normalise_phone( $phone ); /* * Link-only UK default: keep the displayed customer number unchanged, * but convert a local UK leading zero to 44 for WhatsApp click-to-chat URLs. * This value is not stored, logged, or transmitted anywhere except inside the email links. */ if ( 0 === strpos( $digits, '0' ) ) { $digits = '44' . substr( $digits, 1 ); } return $digits; } } if ( ! function_exists( 'matewa_pro_lead_routing_is_safe_whatsapp_phone' ) ) { function matewa_pro_lead_routing_is_safe_whatsapp_phone( $phone ) { $digits = matewa_pro_lead_routing_normalise_whatsapp_link_phone( $phone ); $length = strlen( $digits ); return $length >= 7 && $length <= 15; } } if ( ! function_exists( 'matewa_pro_lead_routing_phone_duplicate_hash' ) ) { function matewa_pro_lead_routing_phone_duplicate_hash( $phone ) { $digits = matewa_pro_lead_routing_normalise_phone( $phone ); if ( strlen( $digits ) < 7 || strlen( $digits ) > 15 ) { return ''; } return hash_hmac( 'sha256', $digits, wp_salt( 'auth' ) ); } } if ( ! function_exists( 'matewa_pro_lead_routing_phone_duplicate_key' ) ) { function matewa_pro_lead_routing_phone_duplicate_key( $phone ) { $hash = matewa_pro_lead_routing_phone_duplicate_hash( $phone ); return '' !== $hash ? 'matewa_phone_lead_' . substr( $hash, 0, 32 ) : ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_recent_phone_lead_exists' ) ) { function matewa_pro_lead_routing_recent_phone_lead_exists( $phone ) { $key = matewa_pro_lead_routing_phone_duplicate_key( $phone ); return '' !== $key && false !== get_transient( $key ); } } if ( ! function_exists( 'matewa_pro_lead_routing_mark_recent_phone_lead' ) ) { function matewa_pro_lead_routing_mark_recent_phone_lead( $phone, $source = 'lead' ) { $key = matewa_pro_lead_routing_phone_duplicate_key( $phone ); if ( '' === $key ) { return false; } return set_transient( $key, sanitize_key( (string) $source ), 30 * MINUTE_IN_SECONDS ); } } if ( ! function_exists( 'matewa_pro_lead_routing_get_whatsapp_status' ) ) { function matewa_pro_lead_routing_get_whatsapp_status( $method ) { $method = sanitize_key( (string) $method ); if ( 'now' === $method ) { return 'Completed'; } if ( 'later' === $method ) { return 'Partial'; } return 'Not Started'; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_temperature' ) ) { function matewa_pro_lead_routing_get_temperature( $intent_label, $message, $phone, $email ) { $combined = strtolower( $intent_label . ' ' . $message ); $hot_terms = array( 'emergency', 'urgent', 'today', 'asap', 'leak', 'leaking', 'broken', 'repair' ); foreach ( $hot_terms as $term ) { if ( false !== strpos( $combined, $term ) ) { return 'Hot Lead'; } } if ( '' !== trim( (string) $phone ) || '' !== trim( (string) $email ) ) { return 'Warm Lead'; } return 'New Lead'; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_first_name' ) ) { function matewa_pro_lead_routing_get_first_name( $name ) { $name = matewa_pro_lead_routing_limit_text( $name, 80 ); if ( '' === $name ) { return ''; } $parts = preg_split( '/\s+/', $name ); return ! empty( $parts[0] ) ? $parts[0] : ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_build_reply_message' ) ) { function matewa_pro_lead_routing_build_reply_message( $lead, $business_name ) { if ( function_exists( 'matewa_pro_lead_response_suggestions_resolve' ) ) { return matewa_pro_lead_response_suggestions_resolve( $lead, $business_name ); } $first_name = matewa_pro_lead_routing_get_first_name( $lead['name'] ); $greeting = '' !== $first_name ? 'Hi ' . $first_name : 'Hi there'; $intent = '' !== $lead['intent_label'] ? $lead['intent_label'] : 'your enquiry'; return sprintf( '%1$s, thanks for contacting %2$s through our website regarding %3$s. Where are you based, and do you still need help? Happy to assist.', $greeting, $business_name, $intent ); } } if ( ! function_exists( 'matewa_pro_lead_routing_is_weak_other_intent_label' ) ) { function matewa_pro_lead_routing_is_weak_other_intent_label( $label ) { $label = strtolower( trim( preg_replace( '/\s+/', ' ', (string) $label ) ) ); return in_array( $label, array( '', 'other', 'something else', 'custom request', 'general enquiry', 'interested in other', "i'm interested in other", 'i am interested in other', ), true ); } } if ( ! function_exists( 'matewa_pro_lead_routing_build_custom_request_label' ) ) { function matewa_pro_lead_routing_build_custom_request_label( $message, $fallback = 'Custom request' ) { $message = matewa_pro_lead_routing_limit_text( $message, 110 ); if ( '' === $message ) { return $fallback; } return 'Custom request: ' . $message; } } if ( ! function_exists( 'matewa_pro_lead_routing_build_phone_only_reply_message' ) ) { function matewa_pro_lead_routing_build_phone_only_reply_message( $lead, $business_name ) { $first_name = matewa_pro_lead_routing_get_first_name( $lead['name'] ?? '' ); $greeting = '' !== $first_name ? 'Hi ' . $first_name : 'Hi there'; $intent = matewa_pro_lead_routing_limit_text( $lead['intent_label'] ?? '', 120 ); $intent = '' !== $intent && 'general enquiry' !== strtolower( $intent ) ? $intent : 'your enquiry'; /* * Phase 5-A-14G1A: customer-facing phone-only follow-up copy must feel * like a normal business check-in. Do not mention abandonment, tracking, * forms being watched, or the site noticing behaviour. */ return sprintf( '%1$s, this is %2$s. Just checking if you still need help with %3$s. Happy to help whenever suits.', $greeting, $business_name, $intent ); } } if ( ! function_exists( 'matewa_pro_lead_routing_build_whatsapp_links' ) ) { function matewa_pro_lead_routing_build_whatsapp_links( $phone, $reply_message = '' ) { $empty = array( 'phone' => '', 'app' => '', 'web' => '', 'browser' => '', 'native' => '', ); if ( ! matewa_pro_lead_routing_is_safe_whatsapp_phone( $phone ) ) { return $empty; } $digits = matewa_pro_lead_routing_normalise_whatsapp_link_phone( $phone ); $reply_message = trim( matewa_pro_lead_routing_limit_textarea( $reply_message, 700 ) ); $encoded_text = '' !== $reply_message ? rawurlencode( $reply_message ) : ''; $wa_text_query = '' !== $encoded_text ? '?text=' . $encoded_text : ''; $web_text_query = '' !== $encoded_text ? '&text=' . $encoded_text : ''; $app_text_query = '' !== $encoded_text ? '&text=' . $encoded_text : ''; $wa_me_url = 'https://wa.me/' . rawurlencode( $digits ) . $wa_text_query; return array( 'phone' => $digits, 'app' => $wa_me_url, 'web' => 'https://web.whatsapp.com/send?phone=' . rawurlencode( $digits ) . $web_text_query, 'browser' => $wa_me_url, 'native' => 'whatsapp://send?phone=' . rawurlencode( $digits ) . $app_text_query, ); } } if ( ! function_exists( 'matewa_pro_lead_routing_format_phone_digits_for_display' ) ) { function matewa_pro_lead_routing_format_phone_digits_for_display( $digits ) { $digits = preg_replace( '/\D+/', '', (string) $digits ); $length = strlen( $digits ); if ( 10 === $length ) { return substr( $digits, 0, 4 ) . ' ' . substr( $digits, 4 ); } if ( 9 === $length ) { return substr( $digits, 0, 3 ) . ' ' . substr( $digits, 3, 3 ) . ' ' . substr( $digits, 6 ); } if ( $length > 10 ) { return trim( preg_replace( '/(.{3})/', '$1 ', $digits ) ); } return $digits; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_phone_display_parts' ) ) { function matewa_pro_lead_routing_get_phone_display_parts( $lead, $whatsapp_links ) { $entered = matewa_pro_lead_routing_limit_text( $lead['phone_original'] ?? '', 40 ); if ( '' === $entered ) { $entered = matewa_pro_lead_routing_limit_text( $lead['phone'] ?? '', 40 ); } $digits = matewa_pro_lead_routing_normalise_phone( $whatsapp_links['phone'] ?? ( $lead['phone'] ?? '' ) ); $country = matewa_pro_lead_routing_get_phone_country_display_data( $lead ); $dial_prefix = matewa_pro_lead_routing_normalise_phone( $country['dial_prefix'] ?? '' ); $dial_display = matewa_pro_lead_routing_limit_text( $country['dial_display'] ?? '', 20 ); $country_name = matewa_pro_lead_routing_limit_text( $country['name'] ?? '', 80 ); $country_iso2 = strtolower( sanitize_key( (string) ( $country['iso2'] ?? '' ) ) ); $national = matewa_pro_lead_routing_normalise_phone( $lead['phone_national_display'] ?? '' ); if ( '' === $dial_prefix && 0 === strpos( $digits, '44' ) ) { $dial_prefix = '44'; } if ( '' === $dial_display && '' !== $dial_prefix ) { $dial_display = '+' . $dial_prefix; } if ( '' === $national && '' !== $digits && '' !== $dial_prefix && 0 === strpos( $digits, $dial_prefix ) && strlen( $digits ) > strlen( $dial_prefix ) ) { $national = substr( $digits, strlen( $dial_prefix ) ); } $entered_digits = matewa_pro_lead_routing_normalise_phone( $entered ); /* * Safety fallback for older/cached frontend submissions. * If the browser only posts the WhatsApp-safe international digits, keep the * email human-friendly by rebuilding a local display for known countries. */ $known_national_prefix = isset( $country['national_prefix'] ) ? matewa_pro_lead_routing_normalise_phone( $country['national_prefix'] ) : ''; if ( '' !== $national && '' !== $known_national_prefix && ( '' === $entered_digits || $entered_digits === $digits ) ) { $entered = $known_national_prefix . $national; } $national_display = '' !== $national ? matewa_pro_lead_routing_format_phone_digits_for_display( $national ) : ''; $international = trim( $dial_display . ' ' . $national_display ); if ( '' === $international && '' !== $digits ) { $international = '+' . $digits; } /* * Keep lead-email international phone displays compact for mobile email clients. * Full country names can force the number onto a second line in Gmail/iOS. */ $international_html = matewa_pro_lead_routing_country_badge_html( $country_iso2, $international ); if ( '' === $international_html && '' !== $international ) { $international_html = esc_html( $international ); } return array( 'entered' => $entered, 'international' => $international, 'international_html' => $international_html, ); } } if ( ! function_exists( 'matewa_pro_lead_routing_build_phone_copy_html' ) ) { function matewa_pro_lead_routing_build_phone_copy_html( $phone_parts ) { $entered = matewa_pro_lead_routing_safe_display( $phone_parts['entered'] ?? '' ); $international = matewa_pro_lead_routing_safe_display( $phone_parts['international'] ?? '' ); $international_html = ! empty( $phone_parts['international_html'] ) ? $phone_parts['international_html'] : esc_html( $international ); return '
' . '
📋 Copy customer number
' . '
' . '
Customer entered
' . '
' . esc_html( $entered ) . '
' . '
' . '
' . '
WhatsApp-ready copy
' . '
' . $international_html . '
' . '
' . '

Use the international version if the customer is outside your country or WhatsApp needs the country code.

' . '
'; } } if ( ! function_exists( 'matewa_pro_lead_routing_safe_display' ) ) { function matewa_pro_lead_routing_safe_display( $value, $fallback = 'Not provided' ) { $value = trim( (string) $value ); return '' !== $value ? $value : $fallback; } } if ( ! function_exists( 'matewa_pro_lead_routing_phone_value_html' ) ) { function matewa_pro_lead_routing_phone_value_html( $value ) { $value = matewa_pro_lead_routing_safe_display( $value ); return '' . esc_html( $value ) . ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_email_row' ) ) { function matewa_pro_lead_routing_email_row( $label, $value ) { return '' . esc_html( $label ) . '' . esc_html( $value ) . ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_email_row_html' ) ) { function matewa_pro_lead_routing_email_row_html( $label, $value_html ) { return '' . esc_html( $label ) . '' . $value_html . ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_country_badge_html' ) ) { function matewa_pro_lead_routing_country_badge_html( $iso2, $text ) { $iso2 = strtoupper( preg_replace( '/[^A-Z]/', '', strtoupper( (string) $iso2 ) ) ); $text = matewa_pro_lead_routing_limit_text( $text, 160 ); if ( '' === $iso2 && '' === $text ) { return ''; } if ( '' === $iso2 ) { return esc_html( $text ); } if ( strlen( $iso2 ) > 3 ) { $iso2 = substr( $iso2, 0, 3 ); } $badge = '' . esc_html( $iso2 ) . ''; if ( '' === $text ) { return $badge; } return '' . $badge . '' . esc_html( $text ) . ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_inline_flag_html' ) ) { function matewa_pro_lead_routing_inline_flag_html( $flag, $text ) { /* * Email clients render emoji flags inconsistently, sometimes as oversized * replacement images. Keep the helper for compatibility, but return text-only * output. Country-code badges are used for new email country displays. */ return esc_html( matewa_pro_lead_routing_limit_text( $text, 160 ) ); } } if ( ! function_exists( 'matewa_pro_lead_routing_email_label' ) ) { function matewa_pro_lead_routing_email_label( $key, $fallback, $lead = array() ) { $lookup_key = trim( (string) $key ); $filter_key = sanitize_key( str_replace( '.', '_', $lookup_key ) ); $fallback = matewa_pro_lead_routing_limit_text( $fallback, 120 ); $lead = is_array( $lead ) ? $lead : array(); $label = $fallback; /* * Global/static-pack ready label lookup for lead emails. * Uses local bundled i18n JSON only, then English fallback. * It does not call translation APIs, does not fetch remote labels, * and does not send lead data externally. */ if ( '' !== $lookup_key && function_exists( 'matewa_get_local_i18n' ) ) { $candidates = array( matewa_pro_lead_routing_normalise_context_lang( $lead['widget_language'] ?? '' ), matewa_pro_lead_routing_get_default_context_lang(), 'en', ); $candidates = array_values( array_unique( array_filter( $candidates ) ) ); foreach ( $candidates as $candidate ) { $local_labels = matewa_get_local_i18n( $candidate ); if ( isset( $local_labels[ $lookup_key ] ) && is_scalar( $local_labels[ $lookup_key ] ) ) { $label = matewa_pro_lead_routing_limit_text( $local_labels[ $lookup_key ], 120 ); break; } } } $label = apply_filters( 'matewa_pro_lead_routing_email_label', $label, $filter_key, $lead ); $label = is_scalar( $label ) ? matewa_pro_lead_routing_limit_text( $label, 120 ) : $fallback; return '' !== $label ? $label : $fallback; } } if ( ! function_exists( 'matewa_pro_lead_routing_normalise_context_lang' ) ) { function matewa_pro_lead_routing_normalise_context_lang( $lang ) { $lang = strtolower( trim( (string) $lang ) ); $lang = str_replace( '_', '-', $lang ); if ( '' === $lang ) { return ''; } if ( function_exists( 'matewa_normalise_lang' ) ) { return matewa_normalise_lang( $lang ); } if ( preg_match( '/^([a-z]{2})-[a-z0-9]+$/', $lang, $matches ) ) { return $matches[1]; } return preg_match( '/^[a-z]{2,3}(?:-[a-z0-9]+)?$/', $lang ) ? $lang : ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_default_context_lang' ) ) { function matewa_pro_lead_routing_get_default_context_lang() { return matewa_pro_lead_routing_normalise_context_lang( get_locale() ); } } if ( ! function_exists( 'matewa_pro_lead_routing_get_language_context_label' ) ) { function matewa_pro_lead_routing_get_language_context_label( $lang ) { $lang = matewa_pro_lead_routing_normalise_context_lang( $lang ); if ( '' === $lang ) { return ''; } if ( function_exists( 'matewa_get_supported_languages' ) ) { $supported = matewa_get_supported_languages(); if ( isset( $supported[ $lang ] ) ) { return matewa_pro_lead_routing_limit_text( $supported[ $lang ], 80 ); } } return strtoupper( $lang ); } } if ( ! function_exists( 'matewa_pro_lead_routing_get_default_context_country_iso2' ) ) { function matewa_pro_lead_routing_get_default_context_country_iso2() { $locale = strtoupper( trim( (string) get_locale() ) ); if ( preg_match( '/[_-]([A-Z]{2})$/', $locale, $matches ) ) { return strtolower( $matches[1] ); } $host = wp_parse_url( home_url(), PHP_URL_HOST ); $host = is_string( $host ) ? strtolower( preg_replace( '/^www\./i', '', $host ) ) : ''; $tld_map = array( '.co.uk' => 'gb', '.uk' => 'gb', '.ie' => 'ie', '.com.au' => 'au', '.au' => 'au', '.co.nz' => 'nz', '.nz' => 'nz', '.ca' => 'ca', '.us' => 'us', '.de' => 'de', '.fr' => 'fr', '.es' => 'es', '.it' => 'it', '.nl' => 'nl', ); foreach ( $tld_map as $suffix => $iso2 ) { if ( '' !== $host && substr( $host, -strlen( $suffix ) ) === $suffix ) { return $iso2; } } return 'gb'; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_known_phone_country_map' ) ) { function matewa_pro_lead_routing_get_known_phone_country_map() { return array( 'gb' => array( 'flag' => '🇬🇧', 'name' => 'United Kingdom', 'dial_display' => '+44', 'dial_prefix' => '44', 'national_prefix' => '0' ), 'ie' => array( 'flag' => '🇮🇪', 'name' => 'Ireland', 'dial_display' => '+353', 'dial_prefix' => '353', 'national_prefix' => '0' ), 'au' => array( 'flag' => '🇦🇺', 'name' => 'Australia', 'dial_display' => '+61', 'dial_prefix' => '61', 'national_prefix' => '0' ), 'us' => array( 'flag' => '🇺🇸', 'name' => 'United States', 'dial_display' => '+1', 'dial_prefix' => '1', 'national_prefix' => '' ), 'ca' => array( 'flag' => '🇨🇦', 'name' => 'Canada', 'dial_display' => '+1', 'dial_prefix' => '1', 'national_prefix' => '' ), 'nz' => array( 'flag' => '🇳🇿', 'name' => 'New Zealand', 'dial_display' => '+64', 'dial_prefix' => '64', 'national_prefix' => '0' ), 'fr' => array( 'flag' => '🇫🇷', 'name' => 'France', 'dial_display' => '+33', 'dial_prefix' => '33', 'national_prefix' => '0' ), 'de' => array( 'flag' => '🇩🇪', 'name' => 'Germany', 'dial_display' => '+49', 'dial_prefix' => '49', 'national_prefix' => '0' ), 'es' => array( 'flag' => '🇪🇸', 'name' => 'Spain', 'dial_display' => '+34', 'dial_prefix' => '34', 'national_prefix' => '0' ), 'it' => array( 'flag' => '🇮🇹', 'name' => 'Italy', 'dial_display' => '+39', 'dial_prefix' => '39', 'national_prefix' => '0' ), 'nl' => array( 'flag' => '🇳🇱', 'name' => 'Netherlands', 'dial_display' => '+31', 'dial_prefix' => '31', 'national_prefix' => '0' ), ); } } if ( ! function_exists( 'matewa_pro_lead_routing_get_known_phone_country' ) ) { function matewa_pro_lead_routing_get_known_phone_country( $iso2 ) { $iso2 = strtolower( sanitize_key( (string) $iso2 ) ); $known = matewa_pro_lead_routing_get_known_phone_country_map(); return isset( $known[ $iso2 ] ) ? $known[ $iso2 ] : array(); } } if ( ! function_exists( 'matewa_pro_lead_routing_get_phone_country_display_data' ) ) { function matewa_pro_lead_routing_get_phone_country_display_data( $lead ) { $lead = is_array( $lead ) ? $lead : array(); $iso2 = matewa_pro_lead_routing_infer_phone_country_iso2( $lead ); $known = matewa_pro_lead_routing_get_known_phone_country( $iso2 ); $name = matewa_pro_lead_routing_limit_text( $known['name'] ?? ( $lead['phone_country_name'] ?? '' ), 80 ); $dial_display = matewa_pro_lead_routing_limit_text( $known['dial_display'] ?? ( $lead['phone_dial_display'] ?? '' ), 20 ); $dial_prefix = matewa_pro_lead_routing_normalise_phone( $known['dial_prefix'] ?? ( $lead['phone_dial_prefix'] ?? '' ) ); $national_prefix = matewa_pro_lead_routing_normalise_phone( $known['national_prefix'] ?? '' ); if ( '' === $dial_display && '' !== $dial_prefix ) { $dial_display = '+' . $dial_prefix; } if ( '' === $name && '' !== $iso2 ) { $name = strtoupper( $iso2 ); } return array( 'iso2' => $iso2, 'name' => $name, 'dial_display' => $dial_display, 'dial_prefix' => $dial_prefix, 'national_prefix' => $national_prefix, ); } } if ( ! function_exists( 'matewa_pro_lead_routing_infer_phone_country_iso2' ) ) { function matewa_pro_lead_routing_infer_phone_country_iso2( $lead ) { $lead = is_array( $lead ) ? $lead : array(); $iso2 = strtolower( sanitize_key( (string) ( $lead['phone_country_iso2'] ?? '' ) ) ); $known = matewa_pro_lead_routing_get_known_phone_country_map(); if ( '' !== $iso2 && preg_match( '/^[a-z]{2}$/', $iso2 ) ) { return $iso2; } $dial_prefix = matewa_pro_lead_routing_normalise_phone( $lead['phone_dial_prefix'] ?? '' ); if ( '' !== $dial_prefix ) { foreach ( $known as $known_iso2 => $country ) { if ( $dial_prefix === ( $country['dial_prefix'] ?? '' ) ) { return $known_iso2; } } } $digits = matewa_pro_lead_routing_normalise_phone( $lead['phone'] ?? '' ); if ( '' === $digits ) { return ''; } uasort( $known, function ( $a, $b ) { return strlen( $b['dial_prefix'] ?? '' ) - strlen( $a['dial_prefix'] ?? '' ); } ); foreach ( $known as $known_iso2 => $country ) { $prefix = (string) ( $country['dial_prefix'] ?? '' ); /* +1 is shared by several countries; do not infer it without explicit metadata. */ if ( '' === $prefix || '1' === $prefix ) { continue; } if ( 0 === strpos( $digits, $prefix ) && strlen( $digits ) > strlen( $prefix ) + 3 ) { return $known_iso2; } } return ''; } } if ( ! function_exists( 'matewa_pro_lead_routing_get_phone_country_context_label' ) ) { function matewa_pro_lead_routing_get_phone_country_context_label( $lead ) { $country = matewa_pro_lead_routing_get_phone_country_display_data( $lead ); $name = matewa_pro_lead_routing_limit_text( $country['name'] ?? '', 80 ); $dial_display = matewa_pro_lead_routing_limit_text( $country['dial_display'] ?? '', 20 ); return trim( preg_replace( '/\s+/', ' ', trim( $name . ' ' . $dial_display ) ) ); } } if ( ! function_exists( 'matewa_pro_lead_routing_get_phone_country_context_html' ) ) { function matewa_pro_lead_routing_get_phone_country_context_html( $lead ) { $country = matewa_pro_lead_routing_get_phone_country_display_data( $lead ); $iso2 = strtolower( sanitize_key( (string) ( $country['iso2'] ?? '' ) ) ); $name = matewa_pro_lead_routing_limit_text( $country['name'] ?? '', 80 ); $dial_display = matewa_pro_lead_routing_limit_text( $country['dial_display'] ?? '', 20 ); return matewa_pro_lead_routing_country_badge_html( $iso2, trim( $name . ' ' . $dial_display ) ); } } if ( ! function_exists( 'matewa_pro_lead_routing_build_widget_context_html' ) ) { function matewa_pro_lead_routing_build_widget_context_html( $lead ) { $lead = is_array( $lead ) ? $lead : array(); $rows = array(); $country_iso2 = matewa_pro_lead_routing_infer_phone_country_iso2( $lead ); $country_user_selected = ! empty( $lead['phone_country_user_selected'] ); $default_country_iso2 = matewa_pro_lead_routing_get_default_context_country_iso2(); if ( '' !== $country_iso2 && ( $country_user_selected || $country_iso2 !== $default_country_iso2 ) ) { $country_label = matewa_pro_lead_routing_get_phone_country_context_label( $lead ); $country_html = matewa_pro_lead_routing_get_phone_country_context_html( $lead ); if ( '' !== $country_label && '' !== $country_html ) { $rows[] = matewa_pro_lead_routing_email_row_html( matewa_pro_lead_routing_email_label( 'lead_email.widget_context.phone_country_used', 'Phone country used', $lead ), $country_html ); } } $widget_language = matewa_pro_lead_routing_normalise_context_lang( $lead['widget_language'] ?? '' ); $default_language = matewa_pro_lead_routing_get_default_context_lang(); if ( '' !== $widget_language && '' !== $default_language && $widget_language !== $default_language ) { $language_label = matewa_pro_lead_routing_get_language_context_label( $widget_language ); if ( '' !== $language_label ) { $rows[] = matewa_pro_lead_routing_email_row( matewa_pro_lead_routing_email_label( 'lead_email.widget_context.widget_language_used', 'Widget language used', $lead ), $language_label ); } } if ( empty( $rows ) ) { return ''; } return '
' . '

' . esc_html( matewa_pro_lead_routing_email_label( 'lead_email.widget_context.heading', 'Widget context', $lead ) ) . '

' . '' . implode( '', $rows ) . '
' . '
'; } } if ( ! function_exists( 'matewa_pro_lead_routing_build_html_email' ) ) { function matewa_pro_lead_routing_build_html_email( $lead ) { $business_name = matewa_pro_lead_routing_get_business_name(); $site_label = matewa_pro_lead_routing_get_site_label(); $vertical_label = matewa_pro_lead_routing_get_vertical_label(); $received_time = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), current_time( 'timestamp' ) ); $heading_context = '' !== $vertical_label ? $vertical_label : 'Website'; $heading = 'New ' . $heading_context . ' Lead Received'; $whatsapp_status = matewa_pro_lead_routing_get_whatsapp_status( $lead['handoff_method'] ); $temperature = matewa_pro_lead_routing_get_temperature( $lead['intent_label'], $lead['message'], $lead['phone'], $lead['email'] ); $reply_message = matewa_pro_lead_routing_build_reply_message( $lead, $business_name ); $whatsapp_links = matewa_pro_lead_routing_build_whatsapp_links( $lead['phone'], $reply_message ); $has_wa_links = '' !== $whatsapp_links['browser']; $phone_parts = matewa_pro_lead_routing_get_phone_display_parts( $lead, $whatsapp_links ); $widget_context_html = matewa_pro_lead_routing_build_widget_context_html( $lead ); $intent_display = matewa_pro_lead_routing_safe_display( $lead['intent_label'], 'General enquiry' ); $message_display = matewa_pro_lead_routing_safe_display( $lead['message'], 'Not provided' ); $name_display = matewa_pro_lead_routing_safe_display( $lead['name'] ); $phone_display = matewa_pro_lead_routing_safe_display( $phone_parts['entered'] ?? $lead['phone'] ); $phone_int_display = matewa_pro_lead_routing_safe_display( $phone_parts['international'] ?? '' ); $phone_int_html = ! empty( $phone_parts['international_html'] ) ? $phone_parts['international_html'] : esc_html( $phone_int_display ); $email_display = matewa_pro_lead_routing_safe_display( $lead['email'] ); $plan_label = 'Pro'; $app_button_html = $has_wa_links ? 'Reply on WhatsApp' : ''; $web_button_html = $has_wa_links ? 'Open WhatsApp Web' : ''; $browser_fallback_html = $has_wa_links ? '

Fallback link: open via wa.me.

' : '

WhatsApp links are unavailable because the phone number could not be prepared for click-to-chat. Copy the number manually if it is usable.

'; return 'New Lead Received' . '' . '
' . '' . '' . '' . '
' . '
247ChatMate
' . '

' . esc_html( $heading ) . '

' . '

From ' . esc_html( $site_label ) . ' • ' . esc_html( $received_time ) . '

' . '
' . esc_html( $temperature ) . '' . 'WhatsApp Handoff: ' . esc_html( $whatsapp_status ) . '
' . '
' . '
' . '

Lead Summary

' . matewa_pro_lead_routing_email_row( 'Customer', $name_display ) . matewa_pro_lead_routing_email_row_html( 'Phone', matewa_pro_lead_routing_phone_value_html( $phone_display ) ) . matewa_pro_lead_routing_email_row_html( 'International', $phone_int_html ) . matewa_pro_lead_routing_email_row( 'Email', $email_display ) . '
' . '
Selected Intent
' . '
' . esc_html( $intent_display ) . '
' . '
' . '
Customer Message
' . '

' . nl2br( esc_html( $message_display ) ) . '

' . '
' . $widget_context_html . '
' . '
Quick WhatsApp Handoff
' . '

Reply to this lead now

' . matewa_pro_lead_routing_build_phone_copy_html( $phone_parts ) . $app_button_html . $web_button_html . $browser_fallback_html . '

Opening behaviour varies by device and email client. If neither button opens correctly, open WhatsApp manually and paste the copied number.

' . '
' . '
Suggested Reply
' . '

' . esc_html( $reply_message ) . '

' . '
' . '
' . '

Lead Guidance

' . '' . '' . '' . '
• Leads are warmest within the first 5 minutes.
• Prioritise urgent or problem-led enquiries first.
• Mobile visitors often convert faster after a quick WhatsApp reply.
' . '' . '' . '' . '
Lead Captured
Yes
WhatsApp Status
' . esc_html( $whatsapp_status ) . '
247ChatMate
Turning website visitors into WhatsApp leads.

Plan: ' . esc_html( $plan_label ) . '
'; } } if ( ! function_exists( 'matewa_pro_lead_routing_build_phone_only_html_email' ) ) { function matewa_pro_lead_routing_build_phone_only_html_email( $lead ) { $business_name = matewa_pro_lead_routing_get_business_name(); $site_label = matewa_pro_lead_routing_get_site_label(); $vertical_label = matewa_pro_lead_routing_get_vertical_label(); $received_time = date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), current_time( 'timestamp' ) ); $reply_message = matewa_pro_lead_routing_build_phone_only_reply_message( $lead, $business_name ); $whatsapp_links = matewa_pro_lead_routing_build_whatsapp_links( $lead['phone'], $reply_message ); $has_wa_links = '' !== $whatsapp_links['browser']; $phone_parts = matewa_pro_lead_routing_get_phone_display_parts( $lead, $whatsapp_links ); $widget_context_html = matewa_pro_lead_routing_build_widget_context_html( $lead ); $intent_display = matewa_pro_lead_routing_safe_display( $lead['intent_label'], 'Not selected yet' ); $name_display = matewa_pro_lead_routing_safe_display( $lead['name'] ); $phone_display = matewa_pro_lead_routing_safe_display( $phone_parts['entered'] ?? $lead['phone'] ); $phone_int_display = matewa_pro_lead_routing_safe_display( $phone_parts['international'] ?? '' ); $phone_int_html = ! empty( $phone_parts['international_html'] ) ? $phone_parts['international_html'] : esc_html( $phone_int_display ); $email_display = matewa_pro_lead_routing_safe_display( $lead['email'] ); $context_label = '' !== $vertical_label ? $vertical_label : 'Website'; $app_button_html = $has_wa_links ? 'Follow up on WhatsApp' : ''; $web_button_html = $has_wa_links ? 'Open WhatsApp Web' : ''; $browser_fallback_html = $has_wa_links ? '

Fallback link: open via wa.me.

' : '

WhatsApp links are unavailable because the phone number could not be prepared for click-to-chat. Copy the number manually if it is usable.

'; return 'New phone lead saved' . '' . '
' . '' . '' . '' . '
' . '
247ChatMate
' . '

New phone lead saved from your website

' . '

From ' . esc_html( $site_label ) . ' • ' . esc_html( $received_time ) . '

' . '
Warm phone lead' . 'WhatsApp follow-up ready
' . '
' . '
' . '

Mobile number captured for follow-up

' . '

A customer shared a mobile/cell number before opening WhatsApp. Use the suggested reply below to follow up while the enquiry is still warm.

' . '' . matewa_pro_lead_routing_email_row( 'Source', $context_label ) . matewa_pro_lead_routing_email_row( 'Customer', $name_display ) . matewa_pro_lead_routing_email_row_html( 'Phone', matewa_pro_lead_routing_phone_value_html( $phone_display ) ) . matewa_pro_lead_routing_email_row_html( 'International', $phone_int_html ) . matewa_pro_lead_routing_email_row( 'Email', $email_display ) . matewa_pro_lead_routing_email_row( 'Selected intent', $intent_display ) . '
' . $widget_context_html . '
' . '
Suggested next action
' . '

Send a quick WhatsApp follow-up

' . matewa_pro_lead_routing_build_phone_copy_html( $phone_parts ) . $app_button_html . $web_button_html . $browser_fallback_html . '
' . '
Suggested Reply
' . '

' . esc_html( $reply_message ) . '

' . '
' . '
' . '

Lead Guidance

' . '' . '' . '' . '
• Phone leads saved are still warm enquiries.
• Use a soft, normal follow-up. Do not mention forms, tracking or abandonment.
• If WhatsApp does not open, copy the number manually.
' . '
247ChatMate
Phone lead saved locally. No IPs, visitor IDs or raw chats are stored in lead history.
'; } } if ( ! function_exists( 'matewa_pro_lead_routing_sanitise_submission' ) ) { function matewa_pro_lead_routing_sanitise_submission( $source ) { $source = is_array( $source ) ? $source : array(); $name = matewa_pro_lead_routing_limit_text( $source['name'] ?? '', 120 ); $phone = matewa_pro_lead_routing_limit_text( $source['phone'] ?? '', 40 ); $email = sanitize_email( (string) ( $source['email'] ?? '' ) ); $email = is_email( $email ) ? $email : ''; $intent = matewa_pro_lead_routing_limit_text( $source['intent_label'] ?? '', 160 ); $intent_keys = matewa_pro_lead_routing_limit_text( $source['intent_keys'] ?? '', 220 ); $message = matewa_pro_lead_routing_limit_textarea( $source['message'] ?? '', 800 ); /* * 5-A-30 / 5-A14Q safety net: * if the frontend sends a weak Other/Something else label but the visitor * typed a custom request, preserve that typed request as the lead context. */ if ( '' !== $message && matewa_pro_lead_routing_is_weak_other_intent_label( $intent ) ) { $intent = matewa_pro_lead_routing_build_custom_request_label( $message ); } $lead = array( 'name' => $name, 'phone' => $phone, 'phone_original' => matewa_pro_lead_routing_limit_text( $source['phone_original'] ?? '', 40 ), 'phone_country_iso2' => strtolower( sanitize_key( (string) ( $source['phone_country_iso2'] ?? '' ) ) ), 'phone_country_flag' => matewa_pro_lead_routing_limit_text( $source['phone_country_flag'] ?? '', 8 ), 'phone_country_name' => matewa_pro_lead_routing_limit_text( $source['phone_country_name'] ?? '', 80 ), 'phone_dial_display' => matewa_pro_lead_routing_limit_text( $source['phone_dial_display'] ?? '', 20 ), 'phone_dial_prefix' => matewa_pro_lead_routing_limit_text( $source['phone_dial_prefix'] ?? '', 12 ), 'phone_national_display' => matewa_pro_lead_routing_limit_text( $source['phone_national_display'] ?? '', 40 ), 'phone_normalisation_status' => matewa_pro_lead_routing_limit_text( $source['phone_normalisation_status'] ?? '', 30 ), 'phone_country_user_selected' => ! empty( $source['phone_country_user_selected'] ) ? '1' : '', 'widget_language' => matewa_pro_lead_routing_normalise_context_lang( $source['widget_language'] ?? '' ), 'page_path' => function_exists( 'matewa_lead_history_sanitise_page_path' ) ? matewa_lead_history_sanitise_page_path( $source['page_path'] ?? '' ) : matewa_pro_lead_routing_limit_text( $source['page_path'] ?? '', 180 ), 'page_title' => function_exists( 'matewa_lead_history_sanitise_page_title' ) ? matewa_lead_history_sanitise_page_title( $source['page_title'] ?? '', $source['page_path'] ?? '' ) : matewa_pro_lead_routing_limit_text( $source['page_title'] ?? '', 120 ), 'email' => $email, 'location' => matewa_pro_lead_routing_limit_text( $source['location'] ?? '', 160 ), 'intent_label' => '' !== $intent ? $intent : 'General enquiry', 'intent_keys' => $intent_keys, 'message' => $message, 'handoff_method' => sanitize_key( (string) ( $source['handoff_method'] ?? '' ) ), ); $inferred_iso2 = matewa_pro_lead_routing_infer_phone_country_iso2( $lead ); if ( '' !== $inferred_iso2 ) { $lead['phone_country_iso2'] = $inferred_iso2; $known = matewa_pro_lead_routing_get_known_phone_country( $inferred_iso2 ); if ( ! empty( $known['flag'] ) ) { $lead['phone_country_flag'] = $known['flag']; } if ( ! empty( $known['name'] ) ) { $lead['phone_country_name'] = $known['name']; } if ( ! empty( $known['dial_display'] ) ) { $lead['phone_dial_display'] = $known['dial_display']; } if ( ! empty( $known['dial_prefix'] ) ) { $lead['phone_dial_prefix'] = $known['dial_prefix']; } } return $lead; } } if ( ! function_exists( 'matewa_pro_lead_routing_record_queued_lead_history' ) ) { function matewa_pro_lead_routing_record_queued_lead_history( array $lead = array(), $phone_only = false ) { $handoff_method = sanitize_key( (string) ( $lead['handoff_method'] ?? '' ) ); $has_whatsapp_handoff = in_array( $handoff_method, array( 'now', 'later', 'whatsapp', 'app', 'web', 'browser', 'native' ), true ); if ( function_exists( 'matewa_record_lead_history_event' ) ) { return matewa_record_lead_history_event( array( 'completed_leads' => 1, 'whatsapp_handoffs' => $has_whatsapp_handoff ? 1 : 0, 'lead_emails_sent' => 0, 'phone_only_leads' => $phone_only ? 1 : 0, 'page_path' => $lead['page_path'] ?? '', 'page_title' => $lead['page_title'] ?? '', ) ); } return false; } } if ( ! function_exists( 'matewa_pro_lead_routing_handle_widget_open_ajax' ) ) { function matewa_pro_lead_routing_handle_widget_open_ajax() { if ( ! check_ajax_referer( 'matewa_pro_lead_routing', 'nonce', false ) ) { wp_send_json_error( array( 'code' => 'invalid_nonce' ), 403 ); } if ( ! matewa_pro_lead_routing_user_can_send() ) { wp_send_json_error( array( 'code' => 'pro_required' ), 403 ); } $post = wp_unslash( $_POST ); if ( function_exists( 'matewa_record_lead_history_widget_open' ) ) { matewa_record_lead_history_widget_open( array( 'page_path' => $post['page_path'] ?? '', 'page_title' => $post['page_title'] ?? '', ) ); } wp_send_json_success( array( 'code' => 'widget_open_recorded' ) ); } } if ( ! function_exists( 'matewa_pro_lead_routing_handle_phone_only_ajax' ) ) { function matewa_pro_lead_routing_handle_phone_only_ajax() { if ( ! check_ajax_referer( 'matewa_pro_lead_routing', 'nonce', false ) ) { wp_send_json_error( array( 'code' => 'invalid_nonce' ), 403 ); } if ( ! matewa_pro_lead_routing_user_can_send() ) { wp_send_json_error( array( 'code' => 'pro_required' ), 403 ); } $recipient = matewa_pro_lead_routing_get_recipient(); if ( '' === $recipient ) { wp_send_json_error( array( 'code' => 'missing_recipient' ), 400 ); } $post = wp_unslash( $_POST ); $lead = matewa_pro_lead_routing_sanitise_submission( $post ); $lead['handoff_method'] = 'phone_only'; $phone_digits = matewa_pro_lead_routing_normalise_phone( $lead['phone'] ); if ( strlen( $phone_digits ) < 7 || strlen( $phone_digits ) > 15 ) { wp_send_json_error( array( 'code' => 'invalid_phone' ), 400 ); } if ( matewa_pro_lead_routing_recent_phone_lead_exists( $lead['phone'] ) ) { wp_send_json_success( array( 'code' => 'recent_phone_lead_suppressed' ) ); } $business_name = matewa_pro_lead_routing_get_business_name(); $subject = sprintf( 'New phone lead saved from %1$s', $business_name ); $subject = wp_specialchars_decode( matewa_pro_lead_routing_limit_text( $subject, 180 ), ENT_QUOTES ); $message = matewa_pro_lead_routing_build_phone_only_html_email( $lead ); $headers = matewa_pro_lead_routing_get_email_headers(); if ( function_exists( 'matewa_fallback_mail_send' ) ) { $mail_result = matewa_fallback_mail_send( 'phone_only_lead', $recipient, $subject, $message, $headers, array( 'lead_type' => 'phone_only', 'page_path' => $lead['page_path'] ?? '', ) ); $sent = ! empty( $mail_result['sent'] ); $queued = ! empty( $mail_result['queued'] ); } else { $sent = wp_mail( $recipient, $subject, $message, $headers ); $queued = false; } if ( ! $sent && ! $queued ) { wp_send_json_error( array( 'code' => 'mail_failed' ), 500 ); } matewa_pro_lead_routing_mark_recent_phone_lead( $lead['phone'], 'phone_only' ); if ( $sent && function_exists( 'matewa_record_lead_history_phone_only_lead' ) ) { matewa_record_lead_history_phone_only_lead( $lead ); } elseif ( $queued && function_exists( 'matewa_pro_lead_routing_record_queued_lead_history' ) ) { matewa_pro_lead_routing_record_queued_lead_history( $lead, true ); } wp_send_json_success( array( 'code' => $sent ? 'phone_only_lead_sent' : 'phone_only_lead_queued' ) ); } } if ( ! function_exists( 'matewa_pro_lead_routing_handle_ajax' ) ) { function matewa_pro_lead_routing_handle_ajax() { if ( ! check_ajax_referer( 'matewa_pro_lead_routing', 'nonce', false ) ) { wp_send_json_error( array( 'code' => 'invalid_nonce' ), 403 ); } if ( ! matewa_pro_lead_routing_user_can_send() ) { wp_send_json_error( array( 'code' => 'pro_required' ), 403 ); } $recipient = matewa_pro_lead_routing_get_recipient(); if ( '' === $recipient ) { wp_send_json_error( array( 'code' => 'missing_recipient' ), 400 ); } $post = wp_unslash( $_POST ); $lead = matewa_pro_lead_routing_sanitise_submission( $post ); $phone_digits = matewa_pro_lead_routing_normalise_phone( $lead['phone'] ); $has_contact = ( strlen( $phone_digits ) >= 7 ) || ( '' !== $lead['email'] ); if ( ! $has_contact ) { wp_send_json_error( array( 'code' => 'missing_contact' ), 400 ); } if ( '' !== $lead['phone'] && matewa_pro_lead_routing_recent_phone_lead_exists( $lead['phone'] ) ) { wp_send_json_success( array( 'code' => 'recent_phone_lead_suppressed' ) ); } $business_name = matewa_pro_lead_routing_get_business_name(); $subject_intent = '' !== $lead['intent_label'] ? $lead['intent_label'] : 'New enquiry'; $subject = sprintf( 'New website lead from %1$s — %2$s', $business_name, $subject_intent ); $subject = wp_specialchars_decode( matewa_pro_lead_routing_limit_text( $subject, 180 ), ENT_QUOTES ); $message = matewa_pro_lead_routing_build_html_email( $lead ); $headers = matewa_pro_lead_routing_get_email_headers(); if ( function_exists( 'matewa_fallback_mail_send' ) ) { $mail_result = matewa_fallback_mail_send( 'lead', $recipient, $subject, $message, $headers, array( 'lead_type' => 'completed', 'page_path' => $lead['page_path'] ?? '', ) ); $sent = ! empty( $mail_result['sent'] ); $queued = ! empty( $mail_result['queued'] ); } else { $sent = wp_mail( $recipient, $subject, $message, $headers ); $queued = false; } if ( ! $sent && ! $queued ) { wp_send_json_error( array( 'code' => 'mail_failed' ), 500 ); } /* * Local lead history is updated after the email is sent, or after the * email payload has been safely queued for retry. Queued leads do not * increment lead_emails_sent until the queued email is retried/sent. */ if ( '' !== $lead['phone'] ) { matewa_pro_lead_routing_mark_recent_phone_lead( $lead['phone'], 'completed' ); } if ( $sent && function_exists( 'matewa_record_lead_history_completed_lead' ) ) { matewa_record_lead_history_completed_lead( $lead ); } elseif ( $queued && function_exists( 'matewa_pro_lead_routing_record_queued_lead_history' ) ) { matewa_pro_lead_routing_record_queued_lead_history( $lead, false ); } wp_send_json_success( array( 'code' => $sent ? 'lead_email_sent' : 'lead_email_queued' ) ); } } add_action( 'wp_ajax_matewa_record_widget_open', 'matewa_pro_lead_routing_handle_widget_open_ajax' ); add_action( 'wp_ajax_nopriv_matewa_record_widget_open', 'matewa_pro_lead_routing_handle_widget_open_ajax' ); add_action( 'wp_ajax_matewa_send_pro_lead', 'matewa_pro_lead_routing_handle_ajax' ); add_action( 'wp_ajax_nopriv_matewa_send_pro_lead', 'matewa_pro_lead_routing_handle_ajax' ); add_action( 'wp_ajax_matewa_send_phone_only_lead', 'matewa_pro_lead_routing_handle_phone_only_ajax' ); add_action( 'wp_ajax_nopriv_matewa_send_phone_only_lead', 'matewa_pro_lead_routing_handle_phone_only_ajax' );