185 lines
5.7 KiB
PHP
185 lines
5.7 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* 批量把代码中的中文 message 替换为英文短句(显式英文,不是错误码):
|
||
* - return $this->success('中文...')
|
||
* - return $this->fail('中文...', ...)
|
||
* - throw new ApiException('中文...', ...)
|
||
*
|
||
* 英文短句来源:resource/translations/api/en.php 与 zh.php 中的 MSG_ 对照(crc32 中文生成 key)。
|
||
* 同时自动把“英文短句 => 英文/中文”写入 resource/translations/api/{en,zh}.php(Webman 标准路径)。
|
||
*
|
||
* 用法:
|
||
* php server/scripts/replace_cn_messages_with_en.php
|
||
*/
|
||
|
||
$root = dirname(__DIR__);
|
||
$serverDir = $root;
|
||
|
||
$enPath = $root . '/resource/translations/api/en.php';
|
||
$zhPath = $root . '/resource/translations/api/zh.php';
|
||
|
||
$enMap = is_file($enPath) ? (require $enPath) : [];
|
||
$zhMap = is_file($zhPath) ? (require $zhPath) : [];
|
||
|
||
/** @var array<string, string> $cnToEn */
|
||
$cnToEn = [];
|
||
foreach ($zhMap as $k => $cn) {
|
||
if (!is_string($k) || !is_string($cn)) {
|
||
continue;
|
||
}
|
||
if (strncmp($k, 'MSG_', 4) !== 0) {
|
||
continue;
|
||
}
|
||
$en = $enMap[$k] ?? null;
|
||
if (is_string($en) && $en !== '') {
|
||
$cnToEn[$cn] = $en;
|
||
}
|
||
}
|
||
|
||
$fallbackCn = [
|
||
'添加成功' => 'add success',
|
||
'修改成功' => 'update success',
|
||
'删除成功' => 'delete success',
|
||
'操作成功' => 'operation success',
|
||
'保存成功' => 'save success',
|
||
'执行成功' => 'execute success',
|
||
'安装成功' => 'install success',
|
||
'导入成功' => 'import success',
|
||
'发送成功' => 'send success',
|
||
'重载成功' => 'reload success',
|
||
'重置成功' => 'reset success',
|
||
'卸载插件成功' => 'uninstall plugin success',
|
||
'优化成功' => 'optimize success',
|
||
'清理成功' => 'clean success',
|
||
'清除缓存成功!' => 'clear cache success',
|
||
'已清空测试数据' => 'test data cleared',
|
||
'已清空所有测试数据' => 'all test data cleared',
|
||
'创建奖励对照成功' => 'create reward mapping success',
|
||
'导入成功,已刷新 DiceReward、DiceRewardConfig(BIGWIN)、奖池配置' => 'import success, refreshed DiceReward, DiceRewardConfig(BIGWIN), and pool config',
|
||
'下载成功,请在插件列表中安装' => 'download success, please install in plugin list',
|
||
];
|
||
|
||
$containsCn = static function (string $s): bool {
|
||
return preg_match('/[\x{4e00}-\x{9fff}]/u', $s) === 1;
|
||
};
|
||
|
||
$quote = static function (string $s): string {
|
||
return "'" . str_replace("'", "\\'", $s) . "'";
|
||
};
|
||
|
||
$dump = static function (array $arr): string {
|
||
ksort($arr);
|
||
$out = "<?php\ndeclare(strict_types=1);\n\nreturn [\n";
|
||
foreach ($arr as $k => $v) {
|
||
$k = str_replace("'", "\\'", (string) $k);
|
||
$v = str_replace("'", "\\'", (string) $v);
|
||
$out .= " '{$k}' => '{$v}',\n";
|
||
}
|
||
$out .= "];\n";
|
||
return $out;
|
||
};
|
||
|
||
$files = [];
|
||
$it = new RecursiveIteratorIterator(
|
||
new RecursiveDirectoryIterator($serverDir, FilesystemIterator::SKIP_DOTS)
|
||
);
|
||
foreach ($it as $file) {
|
||
/** @var SplFileInfo $file */
|
||
if (!$file->isFile()) {
|
||
continue;
|
||
}
|
||
$path = $file->getPathname();
|
||
if (substr($path, -4) !== '.php') {
|
||
continue;
|
||
}
|
||
// 跳过 translations 目录与 scripts 自己,避免自我替换
|
||
$norm = str_replace('\\', '/', $path);
|
||
if (str_contains($norm, '/resource/translations/')) {
|
||
continue;
|
||
}
|
||
if (str_contains($norm, '/scripts/replace_cn_messages_with_en.php')) {
|
||
continue;
|
||
}
|
||
$files[] = $path;
|
||
}
|
||
|
||
$totalReplaced = 0;
|
||
$touchedFiles = 0;
|
||
$addedKeys = 0;
|
||
|
||
foreach ($files as $path) {
|
||
$content = file_get_contents($path);
|
||
if (!is_string($content) || $content === '') {
|
||
continue;
|
||
}
|
||
|
||
$replacedInFile = 0;
|
||
$newContent = $content;
|
||
|
||
// 只处理单引号字符串:'...'
|
||
$patterns = [
|
||
// return $this->success('中文')
|
||
'/(\$this->success\(\s*)\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/' => 'success',
|
||
// return $this->success($data, '中文')
|
||
'/(\$this->success\([^\\)]*?,\s*)\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/' => 'success_msg',
|
||
// return $this->fail('中文', ...)
|
||
'/(\$this->fail\(\s*)\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/' => 'fail',
|
||
// throw new ApiException('中文', ...)
|
||
'/(throw\s+new\s+ApiException\(\s*)\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/' => 'exception',
|
||
];
|
||
|
||
foreach ($patterns as $regex => $type) {
|
||
$newContent = preg_replace_callback($regex, function (array $m) use (
|
||
$containsCn,
|
||
$quote,
|
||
&$cnToEn,
|
||
$fallbackCn,
|
||
&$enMap,
|
||
&$zhMap,
|
||
&$replacedInFile,
|
||
&$addedKeys,
|
||
$type
|
||
) {
|
||
$prefix = $m[1];
|
||
$raw = $m[2];
|
||
$cn = stripcslashes($raw);
|
||
if (!$containsCn($cn)) {
|
||
return $m[0];
|
||
}
|
||
$en = $cnToEn[$cn] ?? ($fallbackCn[$cn] ?? null);
|
||
if (!is_string($en) || $en === '') {
|
||
return $m[0];
|
||
}
|
||
|
||
// 写入翻译表:英文短句作为 key
|
||
if (!isset($enMap[$en])) {
|
||
$enMap[$en] = $en;
|
||
$addedKeys++;
|
||
}
|
||
if (!isset($zhMap[$en])) {
|
||
$zhMap[$en] = $cn;
|
||
$addedKeys++;
|
||
}
|
||
|
||
$replacedInFile++;
|
||
return $prefix . $quote($en);
|
||
}, $newContent) ?? $newContent;
|
||
}
|
||
|
||
if ($replacedInFile > 0 && $newContent !== $content) {
|
||
file_put_contents($path, $newContent);
|
||
$totalReplaced += $replacedInFile;
|
||
$touchedFiles++;
|
||
}
|
||
}
|
||
|
||
file_put_contents($enPath, $dump($enMap));
|
||
file_put_contents($zhPath, $dump($zhMap));
|
||
|
||
echo "touched_files={$touchedFiles}\n";
|
||
echo "replaced={$totalReplaced}\n";
|
||
echo "added_translation_pairs={$addedKeys}\n";
|
||
|