From 1815a6140a8f58fcd03fc0c9cdea58e0fc18f476 Mon Sep 17 00:00:00 2001 From: Robin Rosiers <5263188+RosiersRobin@users.noreply.github.com> Date: Mon, 30 Jun 2025 13:27:12 +0200 Subject: [PATCH] Add multi-level directory support for translation files (#1718) --- php-templates/translations.php | 92 ++++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 37 deletions(-) diff --git a/php-templates/translations.php b/php-templates/translations.php index 16f176c..acfaf2b 100644 --- a/php-templates/translations.php +++ b/php-templates/translations.php @@ -1,56 +1,71 @@ getExtension() !== 'php') { + return null; } - $lang = collect(explode(DIRECTORY_SEPARATOR, str_replace($path, '', $file))) - ->filter() - ->first(); + $filePath = $file->getRealPath(); - $fileLines = Illuminate\Support\Facades\File::lines($file); + $relativePath = trim(str_replace($path, '', $file->getPath()), DIRECTORY_SEPARATOR); + $lang = explode(DIRECTORY_SEPARATOR, $relativePath)[0] ?? null; + + if (!$lang) { + return null; + } + + $keyPath = str_replace($path . DIRECTORY_SEPARATOR . $lang . DIRECTORY_SEPARATOR, '', $filePath); + $keyWithSlashes = str_replace('.php', '', $keyPath); + $baseKey = str_replace(DIRECTORY_SEPARATOR, '.', $keyWithSlashes); + + if ($namespace) { + $baseKey = "{$namespace}::{$baseKey}"; + } + + try { + $translations = require $filePath; + } catch (Throwable $e) { + return null; + } + + if (!is_array($translations)) { + return null; + } + + $fileLines = Illuminate\Support\Facades\File::lines($filePath); $lines = []; $inComment = false; foreach ($fileLines as $index => $line) { $trimmed = trim($line); - - if (substr($trimmed, 0, 2) === '/*') { + if (str_starts_with($trimmed, '/*')) { $inComment = true; - continue; } - if ($inComment) { - if (substr($trimmed, -2) !== '*/') { - continue; + if (str_ends_with($trimmed, '*/')) { + $inComment = false; } - - $inComment = false; - } - - if (substr($trimmed, 0, 2) === '//') { continue; } - + if (str_starts_with($trimmed, '//')) { + continue; + } $lines[] = [$index + 1, $trimmed]; } return [ - 'k' => $key, + 'k' => $baseKey, 'la' => $lang, - 'vs' => collect(Illuminate\Support\Arr::dot((Illuminate\Support\Arr::wrap(__($key, [], $lang))))) - ->map( - fn ($value, $key) => vsCodeTranslationValue( - $key, - $value, - str_replace(base_path(DIRECTORY_SEPARATOR), '', $file), - $lines - ) + 'vs' => collect(Illuminate\Support\Arr::dot($translations)) + ->map( + fn ($value, $dotKey) => vsCodeTranslationValue( + $dotKey, + $value, + str_replace(base_path(DIRECTORY_SEPARATOR), '', $filePath), + $lines ) + ) ->filter(), ]; } @@ -63,13 +78,12 @@ function vsCodeTranslationValue($key, $value, $file, $lines): ?array $lineNumber = 1; $keys = explode('.', $key); - $index = 0; $currentKey = array_shift($keys); - foreach ($lines as $index => $line) { + foreach ($lines as $line) { if ( - strpos($line[1], '"' . $currentKey . '"', 0) !== false || - strpos($line[1], "'" . $currentKey . "'", 0) !== false + strpos($line[1], '"' . $currentKey . '"') !== false || + strpos($line[1], "'" . $currentKey . "'") !== false ) { $lineNumber = $line[0]; $currentKey = array_shift($keys); @@ -98,9 +112,9 @@ function vscodeCollectTranslations(string $path, ?string $namespace = null) return collect(); } - return collect(Illuminate\Support\Facades\File::allFiles($realPath))->map( - fn ($file) => vsCodeGetTranslationsFromFile($file, $path, $namespace) - ); + return collect(Illuminate\Support\Facades\File::allFiles($realPath)) + ->map(fn ($file) => vsCodeGetTranslationsFromFile($file, $path, $namespace)) + ->filter(); } $loader = app('translator')->getLoader(); @@ -125,6 +139,10 @@ $namespaced = collect($namespaces)->flatMap( $final = []; foreach ($default->merge($namespaced) as $value) { + if (!isset($value['vs']) || !is_iterable($value['vs'])) { + continue; + } + foreach ($value['vs'] as $key => $v) { $dotKey = "{$value['k']}.{$key}";