AITMT_Settings::get('selector_style', 'dropdown'), ), is_array($atts) ? $atts : array(), 'aitmt_language_switcher' ); return self::render((string) $atts['style']); } public static function render_header_switcher() { if ('1' !== AITMT_Settings::get('selector_header', '0')) { return; } echo wp_kses('
' . self::render() . '
', self::allowed_html()); } public static function render_footer_switcher() { if ('1' !== AITMT_Settings::get('selector_footer', '0')) { return; } echo wp_kses('', self::allowed_html()); } public static function render(string $style = ''): string { $languages = AITMT_Languages::enabled_with_source(); if (count($languages) < 2) { return ''; } $style = $style ?: (string) AITMT_Settings::get('selector_style', 'dropdown'); $current = AITMT_Router::current_language(); if ('list' === $style) { return self::kses_switcher(self::render_list($languages, $current)); } return self::kses_switcher(self::render_dropdown($languages, $current)); } public static function kses_switcher(string $html): string { return wp_kses($html, self::allowed_html()); } public static function allowed_html(): array { $allowed = wp_kses_allowed_html('post'); $attrs = array( 'aria-current' => true, 'aria-hidden' => true, 'aria-label' => true, 'class' => true, 'data-aitmt-no-translate' => true, 'decoding' => true, 'href' => true, 'hreflang' => true, 'id' => true, 'lang' => true, 'loading' => true, 'role' => true, 'src' => true, 'translate' => true, ); foreach (array('a', 'details', 'div', 'img', 'nav', 'span', 'summary') as $tag) { $allowed[$tag] = isset($allowed[$tag]) ? array_merge($allowed[$tag], $attrs) : $attrs; } return $allowed; } private static function render_dropdown(array $languages, string $current): string { $id = 'aitmt-switcher-' . wp_rand(1000, 999999); $output = '
'; $output .= ''; $output .= self::language_html($current); $output .= ''; $output .= '
'; foreach ($languages as $language) { $classes = array('aitmt-switcher-dropdown-link'); if ($language === $current) { $classes[] = 'is-current'; } $output .= sprintf( '%6$s', esc_attr(implode(' ', $classes)), esc_url(AITMT_Router::language_url($language)), esc_attr($language), $language === $current ? 'aria-current="true"' : '', esc_attr(self::language_accessible_label($language)), self::language_html($language) ); } $output .= '
'; return $output; } private static function render_list(array $languages, string $current): string { $output = ''; return $output; } private static function language_text(string $language): string { $parts = array(); if ('1' === AITMT_Settings::get('selector_show_flags', '0')) { $parts[] = self::flag_entity($language); } if ('1' === AITMT_Settings::get('selector_show_names', '1')) { $parts[] = AITMT_Languages::label($language); } if ('1' === AITMT_Settings::get('selector_show_codes', '0')) { $parts[] = strtoupper($language); } if (empty($parts)) { $parts[] = strtoupper($language); } return trim(implode(' ', $parts)); } private static function language_html(string $language): string { $parts = array(); if ('1' === AITMT_Settings::get('selector_show_flags', '0')) { $parts[] = self::flag_html($language); } if ('1' === AITMT_Settings::get('selector_show_names', '1')) { $parts[] = '' . esc_html(AITMT_Languages::label($language)) . ''; } if ('1' === AITMT_Settings::get('selector_show_codes', '0')) { $parts[] = '' . esc_html(strtoupper($language)) . ''; } if (empty($parts)) { $parts[] = '' . esc_html(strtoupper($language)) . ''; } return implode(' ', $parts); } private static function language_accessible_label(string $language): string { return AITMT_Languages::label($language) . ' (' . strtoupper($language) . ')'; } private static function flag_html(string $language): string { $url = self::flag_url($language); if ('' === $url) { return ''; } return ''; } private static function flag_url(string $language): string { $country = strtolower(self::language_country($language)); $relative = 'assets/flags/flag-icons/4x3/' . sanitize_file_name($country) . '.svg'; if (!file_exists(AITMT_PLUGIN_DIR . $relative)) { return ''; } return AITMT_PLUGIN_URL . $relative; } private static function flag_entity(string $language): string { $country = self::language_country($language); $entity = ''; foreach (str_split(strtoupper($country)) as $letter) { $entity .= '&#' . (127397 + ord($letter)) . ';'; } return html_entity_decode($entity, ENT_QUOTES, 'UTF-8'); } private static function language_country(string $language): string { $map = array( 'af' => 'ZA', 'am' => 'ET', 'ar' => 'SA', 'az' => 'AZ', 'be' => 'BY', 'bg' => 'BG', 'bn' => 'BD', 'bs' => 'BA', 'ca' => 'ES', 'ceb' => 'PH', 'co' => 'FR', 'cs' => 'CZ', 'cy' => 'GB', 'da' => 'DK', 'de' => 'DE', 'el' => 'GR', 'en' => 'US', 'es' => 'ES', 'eo' => 'UN', 'et' => 'EE', 'eu' => 'ES', 'fa' => 'IR', 'fi' => 'FI', 'fr' => 'FR', 'ga' => 'IE', 'gd' => 'GB', 'gl' => 'ES', 'he' => 'IL', 'hi' => 'IN', 'hr' => 'HR', 'hu' => 'HU', 'hy' => 'AM', 'ht' => 'HT', 'haw' => 'US', 'hmn' => 'CN', 'ha' => 'NG', 'ig' => 'NG', 'id' => 'ID', 'is' => 'IS', 'it' => 'IT', 'ja' => 'JP', 'jv' => 'ID', 'ka' => 'GE', 'km' => 'KH', 'kk' => 'KZ', 'ko' => 'KR', 'kn' => 'IN', 'ku' => 'IQ', 'ky' => 'KG', 'la' => 'VA', 'lo' => 'LA', 'lb' => 'LU', 'lt' => 'LT', 'lv' => 'LV', 'mk' => 'MK', 'mg' => 'MG', 'ml' => 'IN', 'mn' => 'MN', 'mr' => 'IN', 'ms' => 'MY', 'mt' => 'MT', 'mi' => 'NZ', 'my' => 'MM', 'ne' => 'NP', 'no' => 'NO', 'ny' => 'MW', 'ps' => 'AF', 'nb' => 'NO', 'nl' => 'NL', 'pl' => 'PL', 'pt' => 'PT', 'pa' => 'IN', 'ro' => 'RO', 'ru' => 'RU', 'sd' => 'PK', 'si' => 'LK', 'sk' => 'SK', 'sl' => 'SI', 'sm' => 'WS', 'sn' => 'ZW', 'so' => 'SO', 'sq' => 'AL', 'sr' => 'RS', 'st' => 'LS', 'su' => 'ID', 'sv' => 'SE', 'sw' => 'TZ', 'ta' => 'IN', 'te' => 'IN', 'tg' => 'TJ', 'th' => 'TH', 'tl' => 'PH', 'tr' => 'TR', 'uk' => 'UA', 'ug' => 'CN', 'ur' => 'PK', 'uz' => 'UZ', 'vi' => 'VN', 'xh' => 'ZA', 'yi' => 'IL', 'yo' => 'NG', 'zh' => 'CN', 'zu' => 'ZA', ); return $map[AITMT_Languages::normalize_code($language)] ?? strtoupper(substr($language, 0, 2)); } }