Dictionaryrepository - Source Excerpt 01
Summary
This source excerpt preserves a bounded section of Antichrist.net/wp-content/plugins/uaix-locale-router/src/DictionaryRepository.php so readers can inspect the evidence without opening the full source file.
**Source path:** Antichrist.net/wp-content/plugins/uaix-locale-router/src/DictionaryRepository.php
<?php
namespace UAIXLocaleRouter;
use UAIXLocaleRouter\Support\Json;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
final class DictionaryRepository {
/**
* Per-request dictionary cache keyed by locale and content hash.
*
* @var array
*/
private static $dictionary_cache = array();
/**
* Per-request file hash cache keyed by file path, mtime, and size.
*
* @var array
*/
private static $file_hash_cache = array();
/**
* Register translation filters.
*
* @return void
*/
public static function register() {
add_filter( 'the_content', array( __CLASS__, 'render_content_tokens' ), 9 );
add_filter( 'nav_menu_item_title', array( __CLASS__, 'translate_nav_menu_item_title' ), 20, 4 );
}
/**
* Translate a key in the active locale.
*
* @param string $key Dictionary key.
* @param string $fallback Fallback text.
* @return string
*/
public static function translate( $key, $fallback = '' ) {
$key = trim( (string) $key );
$active_tag = LocaleRepository::wp_locale_to_tag( determine_locale() );
if ( '' === $active_tag ) {
$active_tag = LocaleRepository::get_default_locale();
}
$dictionary = self::load_locale_dictionary( $active_tag );
if ( isset( $dictionary['strings'][ $key ] ) && is_string( $dictionary['strings'][ $key ] ) && '' !== $dictionary['strings'][ $key ] ) {
return $dictionary['strings'][ $key ];
}
$fallback_tag = self::resolve_fallback_locale( $active_tag, $dictionary );
if ( $fallback_tag && $fallback_tag !== $active_tag ) {
$fallback_dictionary = self::load_locale_dictionary( $fallback_tag );
if ( isset( $fallback_dictionary['strings'][ $key ] ) && is_string( $fallback_dictionary['strings'][ $key ] ) && '' !== $fallback_dictionary['strings'][ $key ] ) {
return $fallback_dictionary['strings'][ $key ];
}
}
$template = self::load_template_dictionary();
if ( isset( $template['strings'][ $key ] ) && is_string( $template['strings'][ $key ] ) && '' !== $template['strings'][ $key ] ) {
return $template['strings'][ $key ];
}
return (string) $fallback;
}
/**
* Translate and interpolate a key.
*
* @param string $key Dictionary key.
* @param array $replacements Placeholder replacements.
* @param string $fallback Fallback text.
* @return string
*/
public static function translate_format( $key, array $replacements = array(), $fallback = '' ) {
$value = self::translate( $key, $fallback );
foreach ( $replacements as $name => $replacement ) {
$value = str_replace( '{' . $name . '}', (string) $replacement, $value );
}
return $value;
}
/**
* Load a locale dictionary.
*
* @param string $locale_tag Locale tag.
* @return array
*/
public static function load_locale_dictionary( $locale_tag ) {
$locale_tag = LocaleValidator::canonicalize_tag( $locale_tag );
$manifest = self::dictionary_manifest();
$file_paths = self::dictionary_candidate_paths( $locale_tag );
$file_hash = self::dictionary_cache_hash( $file_paths, isset( $manifest[ $locale_tag ]['fileHash'] ) ? (string) $manifest[ $locale_tag ]['fileHash'] : 'missing' );
$cache_key = 'uaixlr_dict_' . md5( $locale_tag . ':' . $file_hash );
$cached = wp_cache_get( $cache_key, 'uaixlr' );
if ( isset( self::$dictionary_cache[ $cache_key ] ) ) {
return self::$dictionary_cache[ $cache_key ];
}
if ( is_array( $cached ) ) {
self::$dictionary_cache[ $cache_key ] = $cached;
return $cached;
}
$dictionary = self::empty_dictionary( $locale_tag );
$file_path = '';
foreach ( $file_paths as $candidate_path ) {
$candidate = self::read_runtime_dictionary( $candidate_path, $locale_tag );
if ( empty( $candidate['strings'] ) ) {
continue;
}
$dictionary = self::merge_runtime_dictionaries( $dictionary, $candidate );
$file_path = $candidate_path;
}
$dictionary = apply_filters( 'uaixlr_locale_dictionary', $dictionary, $locale_tag, $file_path );
if ( ! is_array( $dictionary ) || ! isset( $dictionary['strings'] ) || ! is_array( $dictionary['strings'] ) ) {
$dictionary = self::empty_dictionary( $locale_tag );
}
wp_cache_set( $cache_key, $dictionary, 'uaixlr' );
self::$dictionary_cache[ $cache_key ] = $dictionary;
return $dictionary;
}
/**
* Load the template dictionary.
*
* @return array
*/
public static function load_template_dictionary() {
return TranslationCatalog::build_runtime_dictionary();
}
/**
* Replace content tokens in post content.
*
* @param string $content Rendered content.
* @return string
*/
public static function render_content_tokens( $content ) {
if ( ! is_string( $content ) || '' === $content || false === strpos( $content, '{{' ) ) {
return $content;
}
return preg_replace_callback(
'/\{\{\s*([a-zA-Z0-9._-]+)\s*\}\}/',
static function ( $matches ) {
$key = isset( $matches[1] ) ? (string) $matches[1] : '';
return esc_html( self::translate( $key, $key ) );
},
$content
);
}
/**
* Translate saved WordPress menu titles when their URL maps to a known navigation key.
*
* @param string $title Menu item title.
* @param object $menu_item Menu item object.
* @param object $args Menu args.
* @param int $depth Menu depth.
* @return string
*/
public static function translate_nav_menu_item_title( $title, $menu_item = null, $args = null, $depth = 0 ) {
unset( $args, $depth );
if ( is_admin() ) {
return $title;
}
$fallback = trim( wp_strip_all_tags( (string) $title ) );
if ( '' === $fallback ) {
return $title;
}
$key = self::navigation_dictionary_key_for_menu_item( $menu_item, $fallback );
if ( '' === $key ) {
return $title;
}
return self::translate( $key, $fallback );
}
/**
* Resolve a menu item URL/title to a dictionary key.
*
* @param object $menu_item Menu item object.
* @param string $fallback Existing title.
* @return string
*/
private static function navigation_dictionary_key_for_menu_item( $menu_item, $fallback ) {
$path = '';
if ( is_object( $menu_item ) ) {
if ( isset( $menu_item->type, $menu_item->object, $menu_item->object_id ) && 'post_type' === $menu_item->type && 'page' === $menu_item->object ) {
$page = get_post( (int) $menu_item->object_id );
if ( $page instanceof \WP_Post ) {
$path = get_page_uri( $page );
}
}
if ( '' === $path && isset( $menu_item->url ) ) {
$path = self::navigation_path_from_url( (string) $menu_item->url );
}
}
$key = self::navigation_dictionary_key_for_path( $path );
if ( '' !== $key ) {
return $key;
}
return self::navigation_dictionary_key_for_title( $fallback );
}
/**
* Normalize a menu URL to a site path.
*
* @param string $url Menu URL.
* @return string
*/
private static function navigation_path_from_url( $url ) {
$parts = wp_parse_url( trim( (string) $url ) );
if ( ! is_array( $parts ) ) {
return '';
}
$home_host = strtolower( (string) wp_parse_url( home_url( '/' ), PHP_URL_HOST ) );
$url_host = strtolower( (string) ( isset( $parts['host'] ) ? $parts['host'] : $home_host ) );
if ( '' !== $home_host && '' !== $url_host && $home_host !== $url_host ) {
return '';
}
$path = isset( $parts['path'] ) ? (string) $parts['path'] : '/';
$path = '/' . trim( str_replace( '\\', '/', $path ), '/' );
$path = preg_replace( '#/+#', '/', $path );
$home_path = wp_parse_url( (string) get_option( 'home' ), PHP_URL_PATH );
$home_path = is_string( $home_path ) ? '/' . trim( $home_path, '/' ) : '/';
$home_path = '/' === $home_path ? '/' : untrailingslashit( $home_path );
if ( '/' !== $home_path ) {
if ( $path === $home_path ) {
$path = '/';
} elseif ( 0 === strpos( $path, $home_path . '/' ) ) {
$path = substr( $path, strlen( $home_path ) );
}
}
$segments = array_values( array_filter( explode( '/', trim( $path, '/' ) ), 'strlen' ) );
if ( ! empty( $segments ) && LocaleRepository::is_enabled_url_tag( $segments[0] ) ) {
array_shift( $segments );
}
return empty( $segments ) ? '' : implode( '/', $segments );
}