/** * Theme mod keys that should be available to multilingual string plugins. * * @return string[] */ function kedani_safari_translatable_theme_mod_keys() { return array( 'topbar_text', 'address', 'response_expectation', 'primary_cta_label', 'primary_cta_link', 'secondary_cta_label', 'secondary_cta_link', 'hero_eyebrow', 'hero_title', 'hero_text', 'hero_metric_one', 'hero_metric_two', 'hero_metric_three', 'company_blurb', 'footer_newsletter_title', 'footer_newsletter_text', ); } /** * Build a stable multilingual string identifier for a theme mod. * * @param string $key Theme mod key. * @return string */ function kedani_safari_theme_mod_string_name( $key ) { return 'theme_mod_' . sanitize_key( (string) $key ); } /** * Translate theme mod values via active multilingual plugins when available. * * @param string $key Theme mod key. * @param string $value Raw theme mod value. * @return string */ function kedani_safari_translate_theme_mod_value( $key, $value ) { $value = (string) $value; if ( '' === trim( $value ) || ! in_array( $key, kedani_safari_translatable_theme_mod_keys(), true ) ) { return $value; } if ( defined( 'ICL_SITEPRESS_VERSION' ) || has_filter( 'wpml_translate_single_string' ) ) { $translated = apply_filters( 'wpml_translate_single_string', $value, 'kedani-safari', kedani_safari_theme_mod_string_name( $key ) ); if ( is_string( $translated ) && '' !== trim( $translated ) ) { $value = $translated; } } elseif ( function_exists( 'pll__' ) ) { $translated = pll__( $value ); if ( is_string( $translated ) && '' !== trim( $translated ) ) { $value = $translated; } } return $value; } /** * Register translatable theme settings with supported multilingual plugins. * * @return void */ function kedani_safari_register_multilingual_strings() { $defaults = kedani_safari_default_settings(); foreach ( kedani_safari_translatable_theme_mod_keys() as $key ) { $value = (string) get_theme_mod( $key, $defaults[ $key ] ?? '' ); if ( '' === trim( $value ) ) { continue; } if ( function_exists( 'pll_register_string' ) ) { pll_register_string( kedani_safari_theme_mod_string_name( $key ), $value, 'Kedani Safari', false !== strpos( $value, "\n" ) ); } if ( defined( 'ICL_SITEPRESS_VERSION' ) || has_action( 'wpml_register_single_string' ) ) { do_action( 'wpml_register_single_string', 'kedani-safari', kedani_safari_theme_mod_string_name( $key ), $value ); } } } /** * Resolve the current language code from active multilingual plugins. * * @return string */ function kedani_safari_current_language_code() { $language = ''; if ( defined( 'ICL_SITEPRESS_VERSION' ) || has_filter( 'wpml_current_language' ) ) { $language = (string) apply_filters( 'wpml_current_language', null ); } if ( ! $language && function_exists( 'pll_current_language' ) ) { $language = (string) pll_current_language( 'slug' ); } if ( ! $language ) { $locale = strtolower( (string) get_locale() ); $language = substr( $locale, 0, 2 ); } return sanitize_key( $language ? $language : 'en' ); } /** * Map language codes to readable labels. * * @param string $code Language code. * @return string */ function kedani_safari_language_label_from_code( $code ) { $labels = array( 'en' => __( 'English', 'kedani-safari' ), 'sw' => __( 'Swahili', 'kedani-safari' ), 'de' => __( 'German', 'kedani-safari' ), 'it' => __( 'Italian', 'kedani-safari' ), 'zh' => __( 'Chinese', 'kedani-safari' ), 'fr' => __( 'French', 'kedani-safari' ), ); $code = sanitize_key( strtolower( (string) $code ) ); return $labels[ $code ] ?? strtoupper( $code ); } /** * Build language switcher items for the header utility menus. * * @return array> */ function kedani_safari_language_switcher_items() { $current_language = kedani_safari_current_language_code(); $items = array(); $filtered_items = apply_filters( 'kedani_safari_language_switcher_items', array(), $current_language ); if ( ! empty( $filtered_items ) && is_array( $filtered_items ) ) { $items = $filtered_items; } elseif ( function_exists( 'pll_the_languages' ) ) { $languages = pll_the_languages( array( 'raw' => 1, 'hide_if_empty' => 0, 'hide_if_no_translation' => 0, ) ); if ( is_array( $languages ) ) { foreach ( $languages as $language ) { if ( ! is_array( $language ) ) { continue; } $items[] = array( 'code' => (string) ( $language['slug'] ?? '' ), 'label' => (string) ( $language['name'] ?? '' ), 'url' => (string) ( $language['url'] ?? '' ), 'current' => ! empty( $language['current_lang'] ), ); } } } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) || has_filter( 'wpml_active_languages' ) ) { $languages = apply_filters( 'wpml_active_languages', null, array( 'skip_missing' => 0, ) ); if ( is_array( $languages ) ) { foreach ( $languages as $language ) { if ( ! is_array( $language ) ) { continue; } $items[] = array( 'code' => (string) ( $language['language_code'] ?? $language['code'] ?? '' ), 'label' => (string) ( $language['native_name'] ?? $language['translated_name'] ?? $language['display_name'] ?? '' ), 'url' => (string) ( $language['url'] ?? '' ), 'current' => ! empty( $language['active'] ), ); } } } if ( empty( $items ) ) { $fallback_languages = array( 'en', 'sw', 'de', 'it', 'zh' ); foreach ( $fallback_languages as $language_code ) { $items[] = array( 'code' => $language_code, 'label' => kedani_safari_language_label_from_code( $language_code ), 'url' => '', 'current' => $language_code === $current_language, ); } } $normalized = array(); foreach ( $items as $item ) { if ( ! is_array( $item ) ) { continue; } $code = sanitize_key( (string) ( $item['code'] ?? '' ) ); $label = trim( (string) ( $item['label'] ?? '' ) ); $url = trim( (string) ( $item['url'] ?? '' ) ); $current = ! empty( $item['current'] ) || ( $code && $code === $current_language ); if ( '' === $label ) { $label = kedani_safari_language_label_from_code( $code ); } if ( '' === $label ) { continue; } $normalized[] = array( 'code' => $code, 'label' => $label, 'url' => $url, 'current' => $current, ); } return $normalized; } /** * Resolve the current language label. * * @return string */ function kedani_safari_current_language_label() { foreach ( kedani_safari_language_switcher_items() as $item ) { if ( ! empty( $item['current'] ) && ! empty( $item['label'] ) ) { return (string) $item['label']; } } return kedani_safari_language_label_from_code( kedani_safari_current_language_code() ); } /** * Resolve the current storefront currency code. * * @return string */ function kedani_safari_current_currency_code() { $currency = function_exists( 'get_woocommerce_currency' ) ? (string) get_woocommerce_currency() : 'USD'; if ( class_exists( 'WCML\\MultiCurrency\\Settings' ) || has_filter( 'wcml_get_client_currency' ) ) { $currency = (string) apply_filters( 'wcml_get_client_currency', $currency ); } return strtoupper( trim( $currency ? $currency : 'USD' ) ); } /** * Build currency switcher items for the header utility menus. * * @return array> */ function kedani_safari_currency_switcher_items() { $current_currency = kedani_safari_current_currency_code(); $items = array(); $filtered_items = apply_filters( 'kedani_safari_currency_switcher_items', array(), $current_currency ); // Check for WCML MultiCurrency class with the required static methods. $has_wcml_class = class_exists( 'WCML\\MultiCurrency\\Settings' ) && method_exists( 'WCML\\MultiCurrency\\Settings', 'getOrderedCurrencyCodes' ) && function_exists( 'get_woocommerce_currencies' ); $has_wcml_source = $has_wcml_class; if ( ! empty( $filtered_items ) && is_array( $filtered_items ) ) { $items = $filtered_items; } elseif ( $has_wcml_source ) { try { $currency_codes = \WCML\MultiCurrency\Settings::getOrderedCurrencyCodes(); $currencies = get_woocommerce_currencies(); if ( method_exists( 'WCML\\MultiCurrency\\Settings', 'isModeByLanguage' ) && \WCML\MultiCurrency\Settings::isModeByLanguage() ) { $current_language = kedani_safari_current_language_code(); $filtered_codes = array_values( array_filter( $currency_codes, static function ( $code ) use ( $current_language ) { return method_exists( 'WCML\\MultiCurrency\\Settings', 'isValidCurrencyForLang' ) && \WCML\MultiCurrency\Settings::isValidCurrencyForLang( $code, $current_language ); } ) ); if ( ! empty( $filtered_codes ) ) { $currency_codes = $filtered_codes; } } elseif ( method_exists( 'WCML\\MultiCurrency\\Settings', 'isModeByLocation' ) && \WCML\MultiCurrency\Settings::isModeByLocation() && class_exists( 'WCML\\MultiCurrency\\Geolocation' ) && method_exists( 'WCML\\MultiCurrency\\Geolocation', 'getUserCountry' ) ) { $user_country = \WCML\MultiCurrency\Geolocation::getUserCountry(); $filtered_codes = array_values( array_filter( $currency_codes, static function ( $code ) use ( $user_country ) { return method_exists( 'WCML\\MultiCurrency\\Settings', 'isValidCurrencyByCountry' ) && \WCML\MultiCurrency\Settings::isValidCurrencyByCountry( $code, $user_country ); } ) ); if ( ! empty( $filtered_codes ) ) { $currency_codes = $filtered_codes; } } foreach ( $currency_codes as $code ) { $code = strtoupper( trim( (string) $code ) ); $name = isset( $currencies[ $code ] ) ? (string) $currencies[ $code ] : $code; $items[] = array( 'code' => $code, 'label' => trim( $code . ' – ' . $name ), 'current' => $code === $current_currency, 'url' => '', 'switcher' => 'wcml', ); } } catch ( \Throwable $e ) { // WCML class exists but threw an exception — fall through to the fallback below. $has_wcml_source = false; } } if ( empty( $items ) ) { $fallback_currencies = $has_wcml_source ? array( $current_currency => $current_currency, ) : array( 'USD' => __( 'USD US Dollar', 'kedani-safari' ), 'EUR' => __( 'EUR Euro', 'kedani-safari' ), 'TZS' => __( 'TZS Tanzanian Shilling', 'kedani-safari' ), ); foreach ( $fallback_currencies as $code => $label ) { $items[] = array( 'code' => $code, 'label' => $label, 'current' => $code === $current_currency, 'url' => '', 'switcher' => '', ); } } $normalized = array(); foreach ( $items as $item ) { if ( ! is_array( $item ) ) { continue; } $code = strtoupper( trim( (string) ( $item['code'] ?? '' ) ) ); $label = trim( (string) ( $item['label'] ?? '' ) ); $url = trim( (string) ( $item['url'] ?? '' ) ); $current = ! empty( $item['current'] ) || ( $code && $code === $current_currency ); $switcher = sanitize_key( (string) ( $item['switcher'] ?? '' ) ); if ( '' === $label ) { $label = $code; } if ( '' === $label ) { continue; } $normalized[] = array( 'code' => $code, 'label' => $label, 'url' => $url, 'current' => $current, 'switcher' => $switcher, ); } return $normalized; } /** * Resolve the current storefront currency label. * * @return string */ function kedani_safari_current_currency_label() { foreach ( kedani_safari_currency_switcher_items() as $item ) { if ( ! empty( $item['current'] ) ) { return ! empty( $item['code'] ) ? (string) $item['code'] : (string) $item['label']; } } return kedani_safari_current_currency_code(); } /** * Build the compact combined utility label shown in header pills. * * @return string */ function kedani_safari_language_currency_label() { $language_label = kedani_safari_current_language_label(); $currency_label = kedani_safari_current_currency_label(); if ( empty( $language_label ) || empty( $currency_label ) ) { return $language_label ? $language_label : $currency_label; } return sprintf( /* translators: 1: current language label, 2: current currency code. */ __( '%1$s | %2$s', 'kedani-safari' ), $language_label, $currency_label ); } /** * Resolve a translated equivalent for a post or page ID when available. * * @param int $post_id Original post ID. * @return int */ // Hook multilingual string registration so WPML/Polylang pick up theme strings. add_action( 'init', 'kedani_safari_register_multilingual_strings', 25 ); /** * Translate a post or page ID to its equivalent in the current language. * * @param int $post_id Original post ID. * @return int */ function kedani_safari_translate_post_id( $post_id ) { $post_id = (int) $post_id; if ( $post_id <= 0 ) { return 0; } if ( defined( 'ICL_SITEPRESS_VERSION' ) || has_filter( 'wpml_object_id' ) ) { $translated_id = (int) apply_filters( 'wpml_object_id', $post_id, get_post_type( $post_id ), true ); if ( $translated_id > 0 ) { return $translated_id; } } if ( function_exists( 'pll_get_post' ) ) { $translated_id = (int) pll_get_post( $post_id, kedani_safari_current_language_code() ); if ( $translated_id > 0 ) { return $translated_id; } } return $post_id; }