get_component( 'language_switcher' ); echo wp_kses( (string) $language_switcher->language_switcher(), translangated_kses_language_switcher_allowed_html() ); } /** * Wrapper function for json_encode to eliminate possible UTF8 special character errors * @param $value * @return mixed|string|void */ function translangated_safe_json_encode($value){ if (version_compare(PHP_VERSION, '5.4.0') >= 0 && apply_filters('translangated_safe_json_encode_pretty_print', true )) { $encoded = wp_json_encode($value, JSON_PRETTY_PRINT); } else { $encoded = wp_json_encode($value); } switch (json_last_error()) { case JSON_ERROR_NONE: return $encoded; case JSON_ERROR_DEPTH: return 'Maximum stack depth exceeded'; // or trigger_error() or throw new Exception() case JSON_ERROR_STATE_MISMATCH: return 'Underflow or the modes mismatch'; // or trigger_error() or throw new Exception() case JSON_ERROR_CTRL_CHAR: return 'Unexpected control character found'; case JSON_ERROR_SYNTAX: return 'Syntax error, malformed JSON'; // or trigger_error() or throw new Exception() case JSON_ERROR_UTF8: $clean = translangated_utf8ize($value); return translangated_safe_json_encode($clean); default: return 'Unknown error'; // or trigger_error() or throw new Exception() } } /** * Helper function for translangated_safe_json_encode that helps eliminate utf8 json encode errors * @param $mixed * @return array|string */ function translangated_utf8ize($mixed) { if (is_array($mixed)) { foreach ($mixed as $key => $value) { $mixed[$key] = translangated_utf8ize($value); } } else if (is_string ($mixed)) { // Replace only the invalid byte sequences with U+FFFD; valid UTF-8 is kept as is (core since WP 6.9). return wp_scrub_utf8( $mixed ); } return $mixed; } /** * function that gets the translation for a string with context directly from a .mo file * @TODO this was developped firstly for woocommerce so it maybe needs further development. */ function translangated_x( $text, $context, $domain, $language ) { $original_text = $text; $cache_key = 'translangated_x_' . md5( $text . $context . $domain . $language ); $new_text = wp_cache_get( $cache_key ); if ( $new_text !== false ) { return $new_text; } /* try to find the correct path for the textdomain */ $path_cache_key = 'translangated_x_path_' . md5( $domain . $language ); $path = wp_cache_get( $path_cache_key ); if ( $path === false ) { $path = translangated_find_translation_location_for_domain( $domain, $language ); wp_cache_set( $path_cache_key, $path ); } if ( !empty( $path ) ) { $mo_file = translangated_cache_get( 'translangated_x_' . $domain . '_' . $language ); if ( false === $mo_file ) { $mo_file = new MO(); $mo_file->import_from_file( $path ); wp_cache_set( 'translangated_x_' . $domain . '_' . $language, $mo_file ); } if ( !$mo_file ) { $return = apply_filters( 'translangated_x', $text, $original_text, $context, $domain, $language ); wp_cache_set( $cache_key, $return ); return $return; } if ( !empty( $mo_file->entries[ $context . '' . $text ] ) ) { $text = $mo_file->entries[ $context . '' . $text ]->translations[0]; } } $return = apply_filters( 'translangated_x', $text, $original_text, $context, $domain, $language ); wp_cache_set( $cache_key, $return ); return $return; } /** * Function that tries to find the path for a translation file defined by textdomain and language * @param $domain the textdomain of the string that you want the translation for * @param $language the language in which you want the translation * @return string the path of the mo file if it is found else an empty string */ function translangated_find_translation_location_for_domain( $domain, $language ){ global $translangated_template_directory; if ( !isset($translangated_template_directory)){ // "caching" this because it sometimes leads to increased page load time due to many calls $translangated_template_directory = get_template_directory(); } $path = ''; if( file_exists( WP_LANG_DIR . '/plugins/'. $domain .'-' . $language . '.mo') ) { $path = WP_LANG_DIR . '/plugins/'. $domain .'-' . $language . '.mo'; } elseif ( file_exists( WP_LANG_DIR . '/themes/'. $domain .'-' . $language . '.mo') ){ $path = WP_LANG_DIR . '/themes/'. $domain .'-' . $language . '.mo'; } elseif( $domain === '' && file_exists( WP_LANG_DIR . '/' . $language . '.mo')){ $path = WP_LANG_DIR . '/' . $language . '.mo'; } else { $possible_translation_folders = array( '', 'languages/', 'language/', 'translations/', 'translation/', 'lang/' ); foreach( $possible_translation_folders as $possible_translation_folder ){ if (file_exists($translangated_template_directory . '/' . $possible_translation_folder . $domain . '-' . $language . '.mo')) { $path = $translangated_template_directory . '/' . $possible_translation_folder . $domain . '-' . $language . '.mo'; } elseif ( file_exists(dirname( TRANSLANGATED_DIR ) . '/' . $domain . '/' . $possible_translation_folder . $domain . '-' . $language . '.mo') ) { $path = dirname( TRANSLANGATED_DIR ) . '/' . $domain . '/' . $possible_translation_folder . $domain . '-' . $language . '.mo'; } } } return $path; } /** * Sanitizes data decoded from a JSON request field (json_decode() alone does not sanitize). * Strings go through $sanitize_string, numbers and booleans are kept, anything else becomes null. * Callers still sanitize each field for its own use (kses for translations, esc_url_raw for URLs, casts for ids). */ function translangated_sanitize_decoded_json( $data, $sanitize_string = 'translangated_sanitize_json_string' ) { return map_deep( $data, function ( $value ) use ( $sanitize_string ) { if ( is_string( $value ) ) { return call_user_func( $sanitize_string, $value ); } return ( is_int( $value ) || is_float( $value ) || is_bool( $value ) ) ? $value : null; } ); } /** * Default string pass for JSON input: drops invalid UTF-8 and