Files
dafuweng-saiadmin6.x/server/app/api/util/ApiLang.php

93 lines
3.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\api\util;
use support\Request;
/**
* API 多语言(兼容 Webman 多语言配置)
* 根据请求头 langzh=中文en=英文)返回对应文案;
* 无 lang 请求头时使用 config('translation.locale') 推断zh_CN/zh→中文en→英文
*/
class ApiLang
{
private const LANG_HEADER = 'lang';
private const LANG_EN = 'en';
private const LANG_ZH = 'zh';
/** @var array<string, array<string, string>> locale => [ 中文 => 译文 ] */
private static array $messages = [];
/**
* 从请求中获取语言:优先读 header lang否则按 Webman config('translation.locale') 推断
*/
public static function getLang(?Request $request = null): string
{
$request = $request ?? (function_exists('request') ? request() : null);
if ($request !== null) {
$lang = $request->header(self::LANG_HEADER);
if ($lang !== null && $lang !== '') {
$lang = strtolower(trim((string) $lang));
if ($lang === self::LANG_EN) {
return self::LANG_EN;
}
if ($lang === self::LANG_ZH || $lang === 'chs') {
return self::LANG_ZH;
}
}
}
$locale = (string) (function_exists('config') ? config('translation.locale', 'zh_CN') : 'zh_CN');
return stripos($locale, 'en') !== false ? self::LANG_EN : self::LANG_ZH;
}
/**
* 翻译文案lang=zh 返回原文中文lang=en 返回英文映射
* 语言文件优先从 Webman resource/translations/api/{locale}.php 加载,否则从 app/api/lang 加载
*/
public static function translate(string $message, ?Request $request = null): string
{
$lang = self::getLang($request);
if ($lang !== self::LANG_EN) {
return $message;
}
$map = self::loadMessages(self::LANG_EN);
return $map[$message] ?? $message;
}
/**
* 加载某语言的 API 文案key=中文value=译文)
*/
private static function loadMessages(string $locale): array
{
if (isset(self::$messages[$locale])) {
return self::$messages[$locale];
}
$path = null;
if (function_exists('config')) {
$base = rtrim((string) config('translation.path', ''), DIRECTORY_SEPARATOR);
if ($base !== '') {
$path = $base . DIRECTORY_SEPARATOR . 'api' . DIRECTORY_SEPARATOR . $locale . '.php';
}
}
if (($path === null || !is_file($path)) && $locale === self::LANG_EN) {
$path = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . 'en.php';
}
self::$messages[$locale] = ($path !== null && is_file($path)) ? (require $path) : [];
return self::$messages[$locale];
}
/**
* 带占位符的翻译,如 translateParams('当前玩家余额%s小于%s无法继续游戏', [$coin, $minCoin])
* 先翻译再替换en 文案使用 %s 占位)
*/
public static function translateParams(string $message, array $params = [], ?Request $request = null): string
{
$translated = self::translate($message, $request);
if ($params !== []) {
$translated = sprintf($translated, ...$params);
}
return $translated;
}
}