181 lines
5.8 KiB
PHP
181 lines
5.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* Simple offline translator: duplicates lang/en -> lang/de and applies a rule-based
|
|
* English->German translation for string values while preserving tokens/placeholders.
|
|
*
|
|
* Usage: php scripts/generate_de_lang.php
|
|
*
|
|
* Note: this is a heuristic translator (word-replacement). For high-quality
|
|
* translations use a translation provider and enable it in this script.
|
|
*/
|
|
|
|
function ensureDir(string $path)
|
|
{
|
|
if (!is_dir($path)) mkdir($path, 0755, true);
|
|
}
|
|
|
|
function loadPhpArray(string $file)
|
|
{
|
|
return require $file;
|
|
}
|
|
|
|
// Basic mapping (expand as needed)
|
|
$dictionary = [
|
|
'Settings' => 'Einstellungen',
|
|
'Setting' => 'Einstellung',
|
|
'Update' => 'Aktualisierung',
|
|
'Updates' => 'Aktualisierungen',
|
|
'Application' => 'Anwendung',
|
|
'app' => 'App',
|
|
'Backup' => 'Sicherung',
|
|
'Backups' => 'Sicherungen',
|
|
'Restore' => 'Wiederherstellung',
|
|
'File' => 'Datei',
|
|
'Files' => 'Dateien',
|
|
'Selected file' => 'Ausgewählte Datei',
|
|
'Selected file:' => 'Ausgewählte Datei:',
|
|
'Cancel' => 'Abbrechen',
|
|
'Save' => 'Speichern',
|
|
'Upload' => 'Hochladen',
|
|
'Uploading...' => 'Hochladen...',
|
|
'Name' => 'Name',
|
|
'Date' => 'Datum',
|
|
'Size' => 'Größe',
|
|
'Status' => 'Status',
|
|
'Actions' => 'Aktionen',
|
|
'History' => 'Verlauf',
|
|
'Configure' => 'Konfigurieren',
|
|
'Configure Zoom Server-to-Server OAuth Credentials' => 'Zoom Server-to-Server OAuth-Anmeldedaten konfigurieren',
|
|
'Language' => 'Sprache',
|
|
'Languages' => 'Sprachen',
|
|
'Language Settings' => 'Spracheinstellungen',
|
|
'Add Language' => 'Sprache hinzufügen',
|
|
'Translate Language Properties' => 'Spracheigenschaften übersetzen',
|
|
'Application Update' => 'Anwendungs-Aktualisierung',
|
|
'Update Application' => 'Anwendung aktualisieren',
|
|
'Please do not close this window' => 'Bitte schließe dieses Fenster nicht',
|
|
'Are you sure' => 'Bist du sicher',
|
|
'Are you sure you want to delete this backup? This action cannot be undone.' => 'Bist du sicher, dass du diese Sicherung löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden.',
|
|
'Confirm Application Update' => 'Anwendungsaktualisierung bestätigen',
|
|
'Process may take several minutes' => 'Der Vorgang kann einige Minuten dauern',
|
|
'Test Mode' => 'Testmodus',
|
|
'Using Test Environment' => 'Verwendet Testumgebung',
|
|
'Using Live Environment' => 'Verwendet Live-Umgebung',
|
|
'API Credentials' => 'API-Zugangsdaten',
|
|
'Copy' => 'Kopieren',
|
|
'Browse Files' => 'Dateien durchsuchen',
|
|
'No file selected' => 'Keine Datei ausgewählt',
|
|
'Select File (.zip only)' => 'Datei auswählen (.zip nur)',
|
|
'Uploading...' => 'Wird hochgeladen...',
|
|
];
|
|
|
|
// Token patterns to preserve
|
|
$tokenPatterns = [
|
|
'/:(\w+)/', // :seconds, :filename
|
|
'/\{\{.*?\}\}/', // {{ var }}
|
|
'/\{[^}]+\}/', // {variable}
|
|
'/%\w/', // %s %d
|
|
'/%\([^\)]+\)s/', // %(name)s
|
|
];
|
|
|
|
function maskTokens(string $s, array $patterns, array &$tokens)
|
|
{
|
|
$tokens = [];
|
|
foreach ($patterns as $p) {
|
|
$s = preg_replace_callback($p, function ($m) use (&$tokens) {
|
|
$key = '__TOKEN'.count($tokens).'__';
|
|
$tokens[$key] = $m[0];
|
|
return $key;
|
|
}, $s);
|
|
}
|
|
return $s;
|
|
}
|
|
|
|
function unmaskTokens(string $s, array $tokens)
|
|
{
|
|
if (!$tokens) return $s;
|
|
return strtr($s, $tokens);
|
|
}
|
|
|
|
function translateString(string $s, array $dictionary, array $tokenPatterns)
|
|
{
|
|
// preserve tokens
|
|
$tokens = [];
|
|
$masked = maskTokens($s, $tokenPatterns, $tokens);
|
|
|
|
// quick full-match dictionary
|
|
if (isset($dictionary[$masked])) {
|
|
$translated = $dictionary[$masked];
|
|
} else {
|
|
// word-by-word replace, case-sensitive and insensitive
|
|
$translated = $masked;
|
|
// longer keys first
|
|
uksort($dictionary, function($a, $b){ return strlen($b) - strlen($a); });
|
|
foreach ($dictionary as $eng => $ger) {
|
|
// replace whole words and phrases
|
|
$translated = str_ireplace($eng, $ger, $translated);
|
|
}
|
|
}
|
|
|
|
// restore tokens
|
|
$translated = unmaskTokens($translated, $tokens);
|
|
|
|
return $translated;
|
|
}
|
|
|
|
function translateRecursive($data, $dictionary, $tokenPatterns)
|
|
{
|
|
if (is_string($data)) {
|
|
return translateString($data, $dictionary, $tokenPatterns);
|
|
}
|
|
if (is_array($data)) {
|
|
$out = [];
|
|
foreach ($data as $k => $v) {
|
|
$out[$k] = translateRecursive($v, $dictionary, $tokenPatterns);
|
|
}
|
|
return $out;
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
$baseEn = __DIR__ . '/../lang/en';
|
|
$baseDe = __DIR__ . '/../lang/de';
|
|
|
|
ensureDir($baseDe);
|
|
|
|
$files = glob($baseEn.'/*.php');
|
|
foreach ($files as $file) {
|
|
$name = basename($file);
|
|
echo "Processing $name...\n";
|
|
$arr = require $file;
|
|
$translated = translateRecursive($arr, $dictionary, $tokenPatterns);
|
|
$out = "<?php\n\nreturn ".var_export($translated, true).";\n";
|
|
file_put_contents($baseDe.'/'.$name, $out);
|
|
}
|
|
|
|
// Also copy storage group files (complex structures)
|
|
$groupsEn = __DIR__ . '/../storage/app/lang/groups';
|
|
$groupsDe = __DIR__ . '/../storage/app/lang/groups/de';
|
|
if (is_dir($groupsEn)) {
|
|
ensureDir($groupsDe);
|
|
$gfiles = glob($groupsEn.'/*.php');
|
|
foreach ($gfiles as $gf) {
|
|
$name = basename($gf);
|
|
echo "Processing group $name...\n";
|
|
$arr = require $gf;
|
|
// arr is list of entries with properties arrays
|
|
$outArr = [];
|
|
foreach ($arr as $entry) {
|
|
if (isset($entry['properties']) && is_array($entry['properties'])) {
|
|
$entry['properties'] = translateRecursive($entry['properties'], $dictionary, $tokenPatterns);
|
|
}
|
|
$outArr[] = $entry;
|
|
}
|
|
$out = "<?php\n\nreturn ".var_export($outArr, true).";\n";
|
|
file_put_contents($groupsDe.'/'.$name, $out);
|
|
}
|
|
}
|
|
|
|
echo "Done. German lang files generated under lang/de and storage/app/lang/groups/de\n";
|