From a41424da602fbc2aacc3849c20915c5a8a49c761 Mon Sep 17 00:00:00 2001 From: Ade Reksi Susanto <34746706+adereksisusanto@users.noreply.github.com> Date: Mon, 27 May 2024 06:24:50 +0700 Subject: [PATCH] various fixes (#117) * fix add new key to json file * fix exclude_files en/book/excluded.php * fix test DIRECTORY_SEPARATOR on WINDOWS * undo factory & add test * fix dropdown file only source translation --- CONTRIBUTING.md | 3 ++- .../CopySourceKeyToTranslationsAction.php | 7 +++++-- .../Controllers/SourcePhraseController.php | 15 +++++++++++++-- src/TranslationsManager.php | 4 ++-- .../SourcePhraseControllerTest.php | 19 ++++++++++++++++++- tests/TranslationsManagerTest.php | 14 +++++++------- 6 files changed, 47 insertions(+), 15 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c3f80ea..3f47ce0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,7 +87,8 @@ Example: `composer.json` "type": "path", "url": "/home/myuser/projects/laravel-translations" } - ] + ], + "minimum-stability": "dev" } ``` diff --git a/src/Actions/CopySourceKeyToTranslationsAction.php b/src/Actions/CopySourceKeyToTranslationsAction.php index 3e4ac73..dcb0df4 100644 --- a/src/Actions/CopySourceKeyToTranslationsAction.php +++ b/src/Actions/CopySourceKeyToTranslationsAction.php @@ -4,20 +4,23 @@ use Outhebox\TranslationsUI\Models\Phrase; use Outhebox\TranslationsUI\Models\Translation; +use Outhebox\TranslationsUI\Models\TranslationFile; class CopySourceKeyToTranslationsAction { public static function execute(Phrase $sourceKey): void { Translation::where('source', false)->get()->each(function ($translation) use ($sourceKey) { + $isRoot = TranslationFile::find($sourceKey->file->id)?->is_root; + $locale = $translation->language()->first()?->code; $translation->phrases()->create([ 'value' => null, 'uuid' => str()->uuid(), 'key' => $sourceKey->key, - 'group' => $sourceKey->group, + 'group' => ($isRoot ? $locale : $sourceKey->group), 'phrase_id' => $sourceKey->id, 'parameters' => $sourceKey->parameters, - 'translation_file_id' => $sourceKey->file->id, + 'translation_file_id' => ($isRoot ? TranslationFile::firstWhere('name', $locale)?->id : $sourceKey->file->id), ]); }); } diff --git a/src/Http/Controllers/SourcePhraseController.php b/src/Http/Controllers/SourcePhraseController.php index dbe95d1..3f3119d 100644 --- a/src/Http/Controllers/SourcePhraseController.php +++ b/src/Http/Controllers/SourcePhraseController.php @@ -77,8 +77,14 @@ public function create(): Modal public function store(Request $request): RedirectResponse { $connection = config('translations.database_connection'); + + $key = ['required', 'regex:/^[\w.]+$/u']; + if (TranslationFile::find($request->input('file'))?->extension === 'json') { + $key = ['required', 'string']; + } + $request->validate([ - 'key' => ['required', 'regex:/^[\w. ]+$/u'], + 'key' => $key, 'file' => ['required', 'integer', 'exists:'.($connection ? $connection.'.' : '').'ltu_translation_files,id'], 'content' => ['required', 'string'], ]); @@ -101,11 +107,16 @@ public function edit(Phrase $phrase): Response|RedirectResponse return redirect()->route('ltu.phrases.edit', $phrase->uuid); } + $files = []; + foreach (collect($phrase->where('translation_id', $phrase->translation->id)->get())->unique('translation_file_id') as $value) { + $files[] = TranslationFile::where('id', $value->translation_file_id)->first(); + } + return Inertia::render('source/edit', [ 'phrase' => PhraseResource::make($phrase), 'translation' => TranslationResource::make($phrase->translation), 'source' => TranslationResource::make($phrase->translation), - 'files' => TranslationFileResource::collection(TranslationFile::get()), + 'files' => TranslationFileResource::collection($files), 'similarPhrases' => PhraseResource::collection($phrase->similarPhrases()), ]); } diff --git a/src/TranslationsManager.php b/src/TranslationsManager.php index 94fcc92..125491b 100644 --- a/src/TranslationsManager.php +++ b/src/TranslationsManager.php @@ -79,14 +79,14 @@ public function getTranslations(string $locale): array return $collection->prepend($rootFileName); }) ->filter(function ($file) use ($locale) { - foreach (config('translations.exclude_files') as $excludeFile) { + foreach (Str::replace('/', DIRECTORY_SEPARATOR, config('translations.exclude_files')) as $excludeFile) { /** *

File exclusion by wildcard

*

$file is with language like en/book/create.php while $excludedFile contains only wildcards or path like book/create.php

*

So, we need to remove the language part from $file before comparing with $excludeFile

*/ - if (fnmatch($excludeFile, str_replace($locale.DIRECTORY_SEPARATOR, '', $file))) { + if (fnmatch($excludeFile, str_replace($locale.DIRECTORY_SEPARATOR, '', $file)) || Str::contains(str_replace($locale.DIRECTORY_SEPARATOR, '', $file), $excludeFile)) { return false; } } diff --git a/tests/Http/Controllers/SourcePhraseControllerTest.php b/tests/Http/Controllers/SourcePhraseControllerTest.php index 679eff4..708afcf 100644 --- a/tests/Http/Controllers/SourcePhraseControllerTest.php +++ b/tests/Http/Controllers/SourcePhraseControllerTest.php @@ -61,7 +61,7 @@ ]))->assertRedirect(route('ltu.source_translation')); }); -it('can add new source key', function () { +it('can add new source key to php file', function () { $file = TranslationFile::factory()->create(); $phrase = Phrase::factory()->make([ @@ -76,3 +76,20 @@ 'content' => $phrase->value, ])->assertRedirect(route('ltu.source_translation')); }); + +it('can add new source key to json file', function () { + $file = TranslationFile::factory()->json()->create(['name' => 'en']); + + $phrase = Phrase::factory()->make([ + 'key' => 'Hello :name', + 'translation_id' => $this->translation->id, + 'translation_file_id' => $file->id, + ]); + + $this->actingAs($this->owner, 'translations') + ->post(route('ltu.source_translation.store_source_key'), [ + 'file' => $file->id, + 'key' => $phrase->key, + 'content' => $phrase->value, + ])->assertRedirect(route('ltu.source_translation')); +}); diff --git a/tests/TranslationsManagerTest.php b/tests/TranslationsManagerTest.php index 35d37ab..940cdb4 100644 --- a/tests/TranslationsManagerTest.php +++ b/tests/TranslationsManagerTest.php @@ -61,15 +61,15 @@ $translations = $translationsManager->getTranslations('en'); expect($translations)->toBe([ 'en.json' => ['title' => 'My title'], - 'en/auth.php' => ['test' => 'Test'], - 'en/book/create.php' => ['nested' => 'Nested test'], + 'en'.DIRECTORY_SEPARATOR.'auth.php' => ['test' => 'Test'], + 'en'.DIRECTORY_SEPARATOR.'book'.DIRECTORY_SEPARATOR.'create.php' => ['nested' => 'Nested test'], ]); $translations = $translationsManager->getTranslations(''); expect($translations)->toBe([ 'en.json' => ['title' => 'My title'], - 'en/auth.php' => ['test' => 'Test'], - 'en/book/create.php' => ['nested' => 'Nested test'], + 'en'.DIRECTORY_SEPARATOR.'auth.php' => ['test' => 'Test'], + 'en'.DIRECTORY_SEPARATOR.'book'.DIRECTORY_SEPARATOR.'create.php' => ['nested' => 'Nested test'], ]); }); @@ -134,7 +134,7 @@ ])->has(Phrase::factory()->state([ 'phrase_id' => null, 'translation_file_id' => TranslationFile::factory([ - 'name' => 'book/create', + 'name' => 'book'.DIRECTORY_SEPARATOR.'create', 'extension' => 'php', ]), ]))->create(); @@ -142,8 +142,8 @@ $translationsManager = new TranslationsManager($filesystem); $translationsManager->export(); - $fileName = lang_path('en/'.$translation->phrases[0]->file->name.'.'.$translation->phrases[0]->file->extension); - $nestedFileName = lang_path('en/'.$nestedTranslation->phrases[0]->file->name.'.'.$nestedTranslation->phrases[0]->file->extension); + $fileName = lang_path('en'.DIRECTORY_SEPARATOR.$translation->phrases[0]->file->name.'.'.$translation->phrases[0]->file->extension); + $nestedFileName = lang_path('en'.DIRECTORY_SEPARATOR.$nestedTranslation->phrases[0]->file->name.'.'.$nestedTranslation->phrases[0]->file->extension); $fileNameInDisk = File::allFiles(lang_path($translation->language->code))[0]->getPathname(); $nestedFileNameInDisk = File::allFiles(lang_path($nestedTranslation->language->code))[1]->getPathname();