Files
hotel/docker/apply-translations.php
DanielS 8434d950dd Add German front-office translations
The German language pack leaves ~180 shop strings in English (search
bar, cart, room cards, footer, account menu). docker/apply-translations.php
fills only missing keys from docker/translations-de-front.php and fixes
English values in the theme language file; docker/find-missing-translations.php
lists remaining gaps. Module/theme de.php files are git-ignored upstream
(downloaded on install), so the script is re-run after each install.
Also includes the language-pack updates the installer wrote to the
tracked module de.php files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 00:33:32 +01:00

75 lines
2.9 KiB
PHP

<?php
/**
* Writes missing front-office translations into modules/<module>/translations/<iso>.php.
* Usage: docker compose exec -u www-data app php docker/apply-translations.php [iso]
* Reads the dictionary docker/translations-<iso>-front.php (English => target language)
* and only fills keys that are missing; existing translations are never overwritten.
*/
if (PHP_SAPI !== 'cli') {
exit;
}
$iso = isset($argv[1]) ? $argv[1] : 'de';
$root = realpath(__DIR__.'/..');
$dict = require __DIR__.'/translations-'.$iso.'-front.php';
$json = shell_exec('php '.escapeshellarg(__DIR__.'/find-missing-translations.php').' '.escapeshellarg($iso).' 2>/dev/null');
$missing = json_decode($json, true);
if (!is_array($missing)) {
fwrite(STDERR, "Could not read missing translations\n");
exit(1);
}
$added = 0;
$untranslated = array();
foreach ($missing['modules'] as $mod => $entries) {
$lines = array();
foreach ($entries as $key => $english) {
if (!isset($dict[$english])) {
$untranslated[$mod][] = $english;
continue;
}
$lines[] = '$_MODULE['.var_export($key, true).'] = '.var_export($dict[$english], true).';';
}
if (!$lines) {
continue;
}
$file = $root.'/modules/'.$mod.'/translations/'.$iso.'.php';
if (!is_file($file)) {
@mkdir(dirname($file), 0755, true);
file_put_contents($file, "<?php\n\nglobal \$_MODULE;\n\$_MODULE = array();\n");
}
$content = rtrim(file_get_contents($file));
if (substr($content, -2) === '?>') {
$content = rtrim(substr($content, 0, -2));
}
// Some language-pack files end with "return $_MODULE;" - new lines must go before it.
$hasReturn = (bool)preg_match('/\n\s*return \$_MODULE;\s*$/', $content);
if ($hasReturn) {
$content = rtrim(preg_replace('/\n\s*return \$_MODULE;\s*$/', '', $content));
}
$content .= "\n\n// Added by docker/apply-translations.php\n".implode("\n", $lines)."\n";
if ($hasReturn) {
$content .= "\nreturn \$_MODULE;\n";
}
file_put_contents($file, $content);
$added += count($lines);
echo sprintf(" %-26s +%d\n", $mod, count($lines));
}
// Theme strings the language pack "translates" with English text: replace those values.
$themeFixes = isset($dict['__theme_value_fixes']) ? $dict['__theme_value_fixes'] : array();
$themeFile = $root.'/themes/hotel-reservation-theme/lang/'.$iso.'.php';
if ($themeFixes && is_file($themeFile)) {
$c = file_get_contents($themeFile);
$n = 0;
foreach ($themeFixes as $from => $to) {
$c = str_replace('= '.var_export($from, true).';', '= '.var_export($to, true).';', $c, $count);
$n += $count;
}
file_put_contents($themeFile, $c);
echo " theme lang fixes $n\n";
}
echo "Added $added translations.\n";
$skip = array_sum(array_map('count', $untranslated));
echo "Not in dictionary: $skip (mostly back-office modules)\n";