kurz
This commit is contained in:
@@ -21,353 +21,3 @@ declare(strict_types=1);
|
||||
|
||||
$baseDir = dirname(__DIR__);
|
||||
echo $deJson = $baseDir . '/public/assets/i18n/de.json';
|
||||
|
||||
// -------------------------------
|
||||
// 1) Bestehende de.json laden
|
||||
// -------------------------------
|
||||
if (!is_file($deJson)) {
|
||||
die("de.json nicht gefunden unter: $deJson\n");
|
||||
}
|
||||
|
||||
$raw = file_get_contents($deJson);
|
||||
if ($raw === false) {
|
||||
die("Konnte de.json nicht lesen: $deJson\n");
|
||||
}
|
||||
|
||||
$data = json_decode($raw, true);
|
||||
if (!is_array($data)) {
|
||||
die("Ungültiges JSON in de.json\n");
|
||||
}
|
||||
|
||||
if (!isset($data['meta']) || !is_array($data['meta'])) {
|
||||
$data['meta'] = [
|
||||
'code' => 'de',
|
||||
'label' => 'Deutsch',
|
||||
'flag' => '🇩🇪',
|
||||
];
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// 2) Verzeichnisse zum Scannen
|
||||
// -------------------------------
|
||||
$scanDirs = [
|
||||
$baseDir . '/public/landingpage',
|
||||
$baseDir . '/partials/landing',
|
||||
$baseDir . '/partials/structure',
|
||||
$baseDir . '/partials/partials', // nur, falls vorhanden
|
||||
];
|
||||
|
||||
$allowedExtensions = ['php', 'html', 'htm'];
|
||||
|
||||
// -------------------------------
|
||||
// 3) Helper-Funktionen
|
||||
// -------------------------------
|
||||
|
||||
function dotKeyExists(array $data, string $key): bool
|
||||
{
|
||||
$segments = explode('.', $key);
|
||||
$node = $data;
|
||||
|
||||
foreach ($segments as $seg) {
|
||||
if (!is_array($node) || !array_key_exists($seg, $node)) {
|
||||
return false;
|
||||
}
|
||||
$node = $node[$seg];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function addDotKey(array &$data, string $key, string $default = ''): void
|
||||
{
|
||||
if (dotKeyExists($data, $key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$segments = explode('.', $key);
|
||||
$node =& $data;
|
||||
|
||||
$last = array_pop($segments);
|
||||
foreach ($segments as $seg) {
|
||||
if (!isset($node[$seg]) || !is_array($node[$seg])) {
|
||||
$node[$seg] = [];
|
||||
}
|
||||
$node =& $node[$seg];
|
||||
}
|
||||
|
||||
if (!array_key_exists($last, $node)) {
|
||||
$node[$last] = $default;
|
||||
}
|
||||
}
|
||||
|
||||
function simpleKeyExistsRecursive(array $data, string $key): bool
|
||||
{
|
||||
foreach ($data as $k => $v) {
|
||||
if ($k === $key) {
|
||||
return true;
|
||||
}
|
||||
if (is_array($v) && simpleKeyExistsRecursive($v, $key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function addSimpleKey(array &$data, string $key, string $defaultValue = null): void
|
||||
{
|
||||
if (simpleKeyExistsRecursive($data, $key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($data['auto']) || !is_array($data['auto'])) {
|
||||
$data['auto'] = [];
|
||||
}
|
||||
|
||||
if ($defaultValue === null || $defaultValue === '') {
|
||||
$defaultValue = $key;
|
||||
}
|
||||
|
||||
if (!array_key_exists($key, $data['auto'])) {
|
||||
$data['auto'][$key] = $defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Key einfügen, mit optionalem Default-Text.
|
||||
* Dot-Notation → verschachtelt,
|
||||
* Simple-Key → unter "auto".
|
||||
*/
|
||||
function addKeyToData(array &$data, string $key, ?string $defaultValue = null): void
|
||||
{
|
||||
$key = trim($key);
|
||||
if ($key === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$default = ($defaultValue !== null && $defaultValue !== '')
|
||||
? $defaultValue
|
||||
: $key;
|
||||
|
||||
if (strpos($key, '.') !== false) {
|
||||
addDotKey($data, $key, $default);
|
||||
} else {
|
||||
addSimpleKey($data, $key, $default);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extrahiert den „aktuellen Inhalt“ eines data-i18n-Elements
|
||||
* ganz grob über Regex:
|
||||
* ... data-i18n="key"> Inhalt </...
|
||||
* Ist nur ein Best-Effort; bei komplexeren Strukturen fällt es auf null zurück.
|
||||
*/
|
||||
function extractInlineTextForDataI18n(string $content, int $matchOffset, int $matchLength): ?string
|
||||
{
|
||||
$start = $matchOffset + $matchLength;
|
||||
$gtPos = strpos($content, '>', $start);
|
||||
if ($gtPos === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$closePos = strpos($content, '<', $gtPos + 1);
|
||||
if ($closePos === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$inner = substr($content, $gtPos + 1, $closePos - $gtPos - 1);
|
||||
$inner = trim($inner);
|
||||
|
||||
if ($inner === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ganz grob Tags entfernen
|
||||
$inner = strip_tags($inner);
|
||||
$inner = trim($inner);
|
||||
|
||||
return $inner !== '' ? $inner : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scannt eine Datei nach i18n-Keys und möglichen Default-Texten.
|
||||
*
|
||||
* Rückgabe:
|
||||
* [ 'key1' => 'Default-Text oder null', 'key2' => null, ... ]
|
||||
*/
|
||||
function collectKeysFromFile(string $file): array
|
||||
{
|
||||
$content = file_get_contents($file);
|
||||
if ($content === false || $content === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
$keysWithDefaults = [];
|
||||
|
||||
// --- data-i18n="key" / 'key' ---
|
||||
if (preg_match_all('/data-i18n\s*=\s*(["\'])(.+?)\1/i', $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
|
||||
foreach ($matches as $m) {
|
||||
$fullMatch = $m[0][0];
|
||||
$fullOffset = $m[0][1];
|
||||
$key = trim($m[2][0]);
|
||||
|
||||
// Versuche, den Inline-Text zu extrahieren: >Text<
|
||||
$inlineText = extractInlineTextForDataI18n($content, $fullOffset, strlen($fullMatch));
|
||||
|
||||
if (!array_key_exists($key, $keysWithDefaults)) {
|
||||
$keysWithDefaults[$key] = $inlineText;
|
||||
} elseif ($keysWithDefaults[$key] === null && $inlineText !== null) {
|
||||
// Falls wir bisher keinen Default hatten, aber jetzt einen finden:
|
||||
$keysWithDefaults[$key] = $inlineText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- i18n_get('path.to.key', 'Default') ---
|
||||
if (preg_match_all(
|
||||
'/\bi18n_get\s*\(\s*(["\'])([^"\']+)\1\s*(,\s*(["\'])(.*?)\4)?/i',
|
||||
$content,
|
||||
$m2,
|
||||
PREG_SET_ORDER
|
||||
)) {
|
||||
foreach ($m2 as $match) {
|
||||
$key = trim($match[2]);
|
||||
$default = isset($match[5]) ? trim($match[5]) : null;
|
||||
|
||||
if ($default !== null && $default !== '') {
|
||||
// expliziter Default im PHP-Code → höchste Priorität
|
||||
$keysWithDefaults[$key] = $default;
|
||||
} else {
|
||||
if (!array_key_exists($key, $keysWithDefaults)) {
|
||||
$keysWithDefaults[$key] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- i18n_get_fmt("path.to.key", "Default", ...) ---
|
||||
if (preg_match_all(
|
||||
'/\bi18n_get_fmt\s*\(\s*(["\'])([^"\']+)\1\s*(,\s*(["\'])(.*?)\4)?/i',
|
||||
$content,
|
||||
$m3,
|
||||
PREG_SET_ORDER
|
||||
)) {
|
||||
foreach ($m3 as $match) {
|
||||
$key = trim($match[2]);
|
||||
$default = isset($match[5]) ? trim($match[5]) : null;
|
||||
|
||||
if ($default !== null && $default !== '') {
|
||||
$keysWithDefaults[$key] = $default;
|
||||
} else {
|
||||
if (!array_key_exists($key, $keysWithDefaults)) {
|
||||
$keysWithDefaults[$key] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $keysWithDefaults;
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// 4) Dateien durchlaufen & Keys sammeln
|
||||
// -------------------------------
|
||||
$foundKeys = []; // key => defaultText|null
|
||||
|
||||
foreach ($scanDirs as $dir) {
|
||||
if (!is_dir($dir)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$it = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
|
||||
foreach ($it as $fileInfo) {
|
||||
/** @var SplFileInfo $fileInfo */
|
||||
if (!$fileInfo->isFile()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ext = strtolower($fileInfo->getExtension());
|
||||
if (!in_array($ext, $allowedExtensions, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$filePath = $fileInfo->getPathname();
|
||||
$keysInFile = collectKeysFromFile($filePath);
|
||||
|
||||
foreach ($keysInFile as $key => $defaultText) {
|
||||
if (!array_key_exists($key, $foundKeys)) {
|
||||
$foundKeys[$key] = $defaultText;
|
||||
} else {
|
||||
// Wenn wir bisher keinen Default hatten, aber jetzt einen haben → übernehmen
|
||||
if (($foundKeys[$key] === null || $foundKeys[$key] === '')
|
||||
&& $defaultText !== null
|
||||
&& $defaultText !== ''
|
||||
) {
|
||||
$foundKeys[$key] = $defaultText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// 5) Gefundene Keys in de.json eintragen
|
||||
// -------------------------------
|
||||
$addedCount = 0;
|
||||
$skippedCount = 0;
|
||||
$newKeys = [];
|
||||
|
||||
foreach ($foundKeys as $key => $defaultText) {
|
||||
$before = json_encode($data);
|
||||
addKeyToData($data, $key, $defaultText);
|
||||
$after = json_encode($data);
|
||||
|
||||
if ($before === $after) {
|
||||
$skippedCount++;
|
||||
} else {
|
||||
$addedCount++;
|
||||
$newKeys[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// 6) de.json zurückschreiben
|
||||
// -------------------------------
|
||||
$newJson = json_encode(
|
||||
$data,
|
||||
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
|
||||
);
|
||||
|
||||
if ($newJson === false) {
|
||||
die("Fehler beim JSON-Encode von de.json\n");
|
||||
}
|
||||
|
||||
if (file_put_contents($deJson, $newJson) === false) {
|
||||
die("Konnte de.json nicht schreiben: $deJson\n");
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// 7) Ausgabe
|
||||
// -------------------------------
|
||||
$isCli = (php_sapi_name() === 'cli');
|
||||
|
||||
$output = "i18n-Collect abgeschlossen.\n";
|
||||
$output .= "Gefundene Keys gesamt: " . count($foundKeys) . "\n";
|
||||
$output .= "Neu hinzugefügt: " . $addedCount . "\n";
|
||||
$output .= "Übersprungen (bereits vorhanden): $skippedCount\n";
|
||||
$output .= "Datei aktualisiert: $deJson\n";
|
||||
|
||||
if (!empty($newKeys)) {
|
||||
$output .= "\nNeu angelegte Keys:\n";
|
||||
foreach ($newKeys as $k) {
|
||||
$output .= " - " . $k . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ($isCli) {
|
||||
echo $output;
|
||||
} else {
|
||||
header('Content-Type: text/plain; charset=utf-8');
|
||||
echo $output;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user