'English', 'es' => 'Spanish', 'fr' => 'French', 'de' => 'German', 'it' => 'Italian', 'pt' => 'Portuguese', 'nl' => 'Dutch', 'pl' => 'Polish', 'ro' => 'Romanian', 'cs' => 'Czech', 'sk' => 'Slovak', 'hu' => 'Hungarian', 'sv' => 'Swedish', 'da' => 'Danish', 'no' => 'Norwegian', 'fi' => 'Finnish', 'el' => 'Greek', 'tr' => 'Turkish', 'ru' => 'Russian', 'uk' => 'Ukrainian', 'ar' => 'Arabic', 'he' => 'Hebrew', 'fa' => 'Persian', 'ur' => 'Urdu', 'hi' => 'Hindi', 'bn' => 'Bengali', 'pa' => 'Punjabi', 'ta' => 'Tamil', 'te' => 'Telugu', 'mr' => 'Marathi', 'gu' => 'Gujarati', 'zh-cn' => 'Chinese (Simplified)', 'zh-tw' => 'Chinese (Traditional)', 'ja' => 'Japanese', 'ko' => 'Korean', 'th' => 'Thai', 'vi' => 'Vietnamese', 'id' => 'Indonesian', 'ms' => 'Malay', 'fil' => 'Filipino', ); } } if ( ! function_exists( 'matewa_is_supported_language' ) ) { function matewa_is_supported_language( $lang ) { $supported = matewa_get_supported_languages(); return isset( $supported[ $lang ] ); } } /* --------------------------------------------------------- Language alias map --------------------------------------------------------- */ if ( ! function_exists( 'matewa_get_language_aliases' ) ) { function matewa_get_language_aliases() { return array( 'en-gb' => 'en', 'en-us' => 'en', 'en-au' => 'en', 'en-ca' => 'en', 'en-ie' => 'en', 'es-es' => 'es', 'es-mx' => 'es', 'es-ar' => 'es', 'es-co' => 'es', 'fr-fr' => 'fr', 'fr-ca' => 'fr', 'de-de' => 'de', 'de-at' => 'de', 'de-ch' => 'de', 'it-it' => 'it', 'pt-pt' => 'pt', 'pt-br' => 'pt', 'nl-nl' => 'nl', 'nl-be' => 'nl', 'pl-pl' => 'pl', 'ro-ro' => 'ro', 'cs-cz' => 'cs', 'sk-sk' => 'sk', 'hu-hu' => 'hu', 'sv-se' => 'sv', 'da-dk' => 'da', 'nb-no' => 'no', 'nn-no' => 'no', 'no-no' => 'no', 'fi-fi' => 'fi', 'el-gr' => 'el', 'tr-tr' => 'tr', 'ru-ru' => 'ru', 'uk-ua' => 'uk', 'ar-sa' => 'ar', 'ar-ae' => 'ar', 'ar-eg' => 'ar', 'he-il' => 'he', 'fa-ir' => 'fa', 'ur-pk' => 'ur', 'hi-in' => 'hi', 'bn-bd' => 'bn', 'bn-in' => 'bn', 'pa-in' => 'pa', 'pa-pk' => 'pa', 'ta-in' => 'ta', 'ta-lk' => 'ta', 'te-in' => 'te', 'mr-in' => 'mr', 'gu-in' => 'gu', 'zh' => 'zh-cn', 'zh-cn' => 'zh-cn', 'zh-sg' => 'zh-cn', 'zh-hans' => 'zh-cn', 'zh-tw' => 'zh-tw', 'zh-hk' => 'zh-tw', 'zh-mo' => 'zh-tw', 'zh-hant' => 'zh-tw', 'ja-jp' => 'ja', 'ko-kr' => 'ko', 'th-th' => 'th', 'vi-vn' => 'vi', 'id-id' => 'id', 'ms-my' => 'ms', 'fil-ph' => 'fil', 'tl-ph' => 'fil', ); } } /* --------------------------------------------------------- Resolve active language (authoritative) --------------------------------------------------------- */ if ( ! function_exists( 'matewa_resolve_language' ) ) { function matewa_resolve_language() { // 1. Admin override (highest priority). $matewa_admin_lang = trim( (string) get_option( 'matewa_admin_language', '' ) ); if ( '' !== $matewa_admin_lang ) { return matewa_normalise_lang( $matewa_admin_lang ); } // 2. Widget override. $matewa_widget_lang = trim( (string) get_option( 'matewa_widget_language', '' ) ); if ( '' !== $matewa_widget_lang ) { return matewa_normalise_lang( $matewa_widget_lang ); } // 3. Visitor language (Accept-Language header). $matewa_accept_language = isset( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) ) : ''; if ( '' !== $matewa_accept_language ) { $matewa_parsed = matewa_parse_accept_language( $matewa_accept_language ); if ( $matewa_parsed ) { return matewa_normalise_lang( $matewa_parsed ); } } // 4. Site language. return matewa_normalise_lang( get_locale() ); } } /* --------------------------------------------------------- Parse Accept-Language header properly --------------------------------------------------------- */ if ( ! function_exists( 'matewa_parse_accept_language' ) ) { function matewa_parse_accept_language( $header ) { $matewa_langs = array(); foreach ( explode( ',', (string) $header ) as $matewa_part ) { if ( preg_match( '/^\s*([a-zA-Z-]+)(?:;q=([0-9.]+))?/', $matewa_part, $matewa_matches ) ) { $matewa_lang = strtolower( $matewa_matches[1] ); $matewa_q = isset( $matewa_matches[2] ) ? (float) $matewa_matches[2] : 1.0; $matewa_langs[ $matewa_lang ] = $matewa_q; } } if ( empty( $matewa_langs ) ) { return null; } arsort( $matewa_langs, SORT_NUMERIC ); return array_key_first( $matewa_langs ); } } /* --------------------------------------------------------- Normalise language codes --------------------------------------------------------- */ if ( ! function_exists( 'matewa_normalise_lang' ) ) { function matewa_normalise_lang( $lang ) { $matewa_lang = strtolower( trim( (string) $lang ) ); $matewa_lang = str_replace( '_', '-', $matewa_lang ); if ( '' === $matewa_lang ) { return 'en'; } $aliases = matewa_get_language_aliases(); if ( isset( $aliases[ $matewa_lang ] ) ) { return $aliases[ $matewa_lang ]; } if ( matewa_is_supported_language( $matewa_lang ) ) { return $matewa_lang; } if ( preg_match( '/^[a-z]{2}$/', $matewa_lang ) && matewa_is_supported_language( $matewa_lang ) ) { return $matewa_lang; } if ( preg_match( '/^([a-z]{2})-[a-z0-9]+$/', $matewa_lang, $matches ) ) { $matewa_base = $matches[1]; if ( matewa_is_supported_language( $matewa_base ) ) { return $matewa_base; } if ( isset( $aliases[ $matewa_base ] ) ) { return $aliases[ $matewa_base ]; } } return 'en'; } } /* --------------------------------------------------------- Load remote i18n JSON (cached, including failures) --------------------------------------------------------- */ if ( ! function_exists( 'matewa_get_remote_i18n' ) ) { function matewa_get_remote_i18n( $lang ) { $matewa_cache_key = 'matewa_remote_i18n_' . $lang; $matewa_cached = get_transient( $matewa_cache_key ); if ( is_array( $matewa_cached ) ) { return $matewa_cached; } $matewa_url = 'https://247trademate.com/247chatmate/i18n/' . rawurlencode( $lang ) . '.json'; $matewa_response = wp_remote_get( $matewa_url, array( 'timeout' => 5, 'headers' => array( 'Accept' => 'application/json', ), ) ); if ( is_wp_error( $matewa_response ) || 200 !== wp_remote_retrieve_response_code( $matewa_response ) ) { set_transient( $matewa_cache_key, array(), 5 * MINUTE_IN_SECONDS ); return array(); } $matewa_data = json_decode( wp_remote_retrieve_body( $matewa_response ), true ); if ( ! is_array( $matewa_data ) ) { set_transient( $matewa_cache_key, array(), 5 * MINUTE_IN_SECONDS ); return array(); } set_transient( $matewa_cache_key, $matewa_data, 6 * HOUR_IN_SECONDS ); return $matewa_data; } } /* --------------------------------------------------------- Load local UI i18n JSON (fallback only) --------------------------------------------------------- */ if ( ! function_exists( 'matewa_get_local_i18n' ) ) { function matewa_get_local_i18n( $lang ) { $matewa_path = plugin_dir_path( __FILE__ ) . '../public/i18n/' . $lang . '.json'; if ( ! file_exists( $matewa_path ) || ! is_readable( $matewa_path ) ) { return array(); } $matewa_raw = file_get_contents( $matewa_path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents $matewa_data = json_decode( $matewa_raw, true ); return is_array( $matewa_data ) ? $matewa_data : array(); } } /* --------------------------------------------------------- Chip label overrides (site-level, per vertical) --------------------------------------------------------- */ if ( ! function_exists( 'matewa_get_chip_label_overrides' ) ) { function matewa_get_chip_label_overrides() { $matewa_overrides = get_option( 'matewa_chip_label_overrides', array() ); return is_array( $matewa_overrides ) ? $matewa_overrides : array(); } } if ( ! function_exists( 'matewa_get_chip_display_label' ) ) { function matewa_get_chip_display_label( $vertical_key, $intent_key ) { $matewa_vertical_key = trim( (string) $vertical_key ); $matewa_intent_key = trim( (string) $intent_key ); if ( '' === $matewa_intent_key ) { return ''; } $matewa_overrides = matewa_get_chip_label_overrides(); if ( '' !== $matewa_vertical_key && isset( $matewa_overrides[ $matewa_vertical_key ] ) && is_array( $matewa_overrides[ $matewa_vertical_key ] ) && isset( $matewa_overrides[ $matewa_vertical_key ][ $matewa_intent_key ] ) ) { $matewa_override = trim( (string) $matewa_overrides[ $matewa_vertical_key ][ $matewa_intent_key ] ); if ( '' !== $matewa_override ) { return $matewa_override; } } return matewa_get_i18n_label( $matewa_intent_key ); } } /* --------------------------------------------------------- Public label resolver (THIS is what you call) --------------------------------------------------------- */ if ( ! function_exists( 'matewa_get_i18n_label' ) ) { function matewa_get_i18n_label( $key ) { $matewa_key = trim( (string) $key ); if ( '' === $matewa_key ) { return ''; } $matewa_lang = matewa_resolve_language(); $matewa_candidates = array( $matewa_lang ); if ( false !== strpos( $matewa_lang, '-' ) ) { $matewa_base = substr( $matewa_lang, 0, 2 ); if ( ! in_array( $matewa_base, $matewa_candidates, true ) ) { $matewa_candidates[] = $matewa_base; } } if ( ! in_array( 'en', $matewa_candidates, true ) ) { $matewa_candidates[] = 'en'; } /* INTROLOCKLOCALFIRST1: intro wording is locked to local JSON so stale remote/demo packs cannot change it. */ if ( in_array( $matewa_key, array( 'intro.line_1', 'intro.line_2', 'intro.line_3', 'system.intro', 'system.reassurance', 'system.instruction' ), true ) ) { foreach ( $matewa_candidates as $matewa_candidate ) { $matewa_local = matewa_get_local_i18n( $matewa_candidate ); if ( isset( $matewa_local[ $matewa_key ] ) ) { return (string) $matewa_local[ $matewa_key ]; } } } foreach ( $matewa_candidates as $matewa_candidate ) { $matewa_remote = matewa_get_remote_i18n( $matewa_candidate ); if ( isset( $matewa_remote[ $matewa_key ] ) ) { return (string) $matewa_remote[ $matewa_key ]; } $matewa_local = matewa_get_local_i18n( $matewa_candidate ); if ( isset( $matewa_local[ $matewa_key ] ) ) { return (string) $matewa_local[ $matewa_key ]; } } $matewa_safe_fallbacks = array( 'header.title' => 'Chat with us', 'branding.powered_by' => 'Powered by 247ChatMate', ); if ( isset( $matewa_safe_fallbacks[ $matewa_key ] ) ) { return $matewa_safe_fallbacks[ $matewa_key ]; } return ucwords( str_replace( array( 'intent.', 'vertical.', '.' ), array( '', '', ' ' ), $matewa_key ) ); } }