';
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. | ' .
' | ' .
'' .
' | ' .
'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' );