Skip to content

Commit

Permalink
include file name in translation key
Browse files Browse the repository at this point in the history
  • Loading branch information
benaja committed Jan 15, 2024
1 parent fbed735 commit f9e2ce0
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 28 deletions.
2 changes: 2 additions & 0 deletions config/translations.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,6 @@
|
*/
'database_connection' => env('TRANSLATIONS_DB_CONNECTION', null),

'include_file_in_key' => env('TRANSLATIONS_INCLUDE_FILE_IN_KEY', false),
];
1 change: 1 addition & 0 deletions database/factories/TranslationFileFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public function definition(): array
return [
'name' => $this->faker->randomElement(['app', 'auth', 'pagination', 'passwords', 'validation']),
'extension' => $this->faker->randomElement(['json', 'php']),
'is_root' => false,
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class () extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('ltu_translation_files', function (Blueprint $table) {
$table->boolean('is_root')->default(false)->after('extension');
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('ltu_translation_files', function (Blueprint $table) {
$table->dropColumn('is_root');
});
}
};
23 changes: 18 additions & 5 deletions src/Console/Commands/ImportTranslationsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Console\Command;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Str;
use Outhebox\LaravelTranslations\Models\Language;
use Outhebox\LaravelTranslations\Models\Phrase;
use Outhebox\LaravelTranslations\Models\Translation;
Expand Down Expand Up @@ -40,14 +41,14 @@ public function handle(): void
$this->importLanguages();

if ($this->option('fresh') && $this->confirm('Are you sure you want to truncate all translations and phrases?')) {
$this->info('Truncating translations and phrases...'.PHP_EOL);
$this->info('Truncating translations and phrases...' . PHP_EOL);

$this->truncateTables();
}

$translation = $this->createOrGetSourceLanguage();

$this->info('Importing translations...'.PHP_EOL);
$this->info('Importing translations...' . PHP_EOL);

$this->withProgressBar($this->manager->getLocales(), function ($locale) use ($translation) {
$this->syncTranslations($translation, $locale);
Expand All @@ -59,7 +60,7 @@ public function createOrGetSourceLanguage(): Translation
$language = Language::where('code', config('translations.source_language'))->first();

if (! $language) {
$this->error('Language with code '.config('translations.source_language').' not found'.PHP_EOL);
$this->error('Language with code ' . config('translations.source_language') . ' not found' . PHP_EOL);

exit;
}
Expand Down Expand Up @@ -111,7 +112,15 @@ public function syncMissingTranslations(Translation $source, string $locale): vo

$source->phrases->each(function ($phrase) use ($translation, $locale) {
if (! $translation->phrases()->where('key', $phrase->key)->first()) {
$this->syncPhrases($phrase->translation, $phrase->key, '', $locale, $phrase->file->name.'.'.$phrase->file->extension);
$fileName = $phrase->file->name . '.' . $phrase->file->extension;

if ($phrase->file->name === config('translations.source_language')) {
$fileName = Str::replaceStart(config('translations.source_language') . '.', "{$locale}.", $fileName);
} else {
$fileName = Str::replaceStart(config('translations.source_language') . '/', "{$locale}/", $fileName);
}

$this->syncPhrases($phrase->translation, $phrase->key, '', $locale, $fileName);
}
});
}
Expand All @@ -125,7 +134,7 @@ public function syncPhrases(Translation $source, $key, $value, $locale, $file):
$language = Language::where('code', $locale)->first();

if (! $language) {
$this->error(PHP_EOL."Language with code {$locale} not found");
$this->error(PHP_EOL . "Language with code {$locale} not found");

exit;
}
Expand All @@ -135,11 +144,15 @@ public function syncPhrases(Translation $source, $key, $value, $locale, $file):
'source' => config('translations.source_language') === $locale,
]);

$isRoot = $file === $locale . '.json' || $file === $locale . '.php';
$translationFile = TranslationFile::firstOrCreate([
'name' => pathinfo($file, PATHINFO_FILENAME),
'extension' => pathinfo($file, PATHINFO_EXTENSION),
'is_root' => $isRoot,
]);

$key = config('translations.include_file_in_key') && ! $isRoot ? "{$translationFile->name}.{$key}" : $key;

$translation->phrases()->updateOrCreate([
'key' => $key,
'group' => $translationFile->name,
Expand Down
15 changes: 13 additions & 2 deletions src/Livewire/Modals/CreateTranslation.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use LivewireUI\Modal\ModalComponent;
use Outhebox\LaravelTranslations\Models\Language;
use Outhebox\LaravelTranslations\Models\Translation;
use Outhebox\LaravelTranslations\Models\TranslationFile;
use WireUi\Traits\Actions;

class CreateTranslation extends ModalComponent
Expand Down Expand Up @@ -46,13 +47,23 @@ public function create(): void
$sourceTranslation = Translation::where('source', true)->first();

foreach ($sourceTranslation->phrases()->with('file')->get() as $sourcePhrase) {
$file = $sourcePhrase->file;

if ($file->is_root) {
$file = TranslationFile::firstOrCreate([
'name' => $translation->language->code,
'extension' => $file->extension,
'is_root' => true,
]);
}

$translation->phrases()->create([
'value' => null,
'key' => $sourcePhrase->key,
'group' => $sourcePhrase->group,
'group' => $file->name,
'phrase_id' => $sourcePhrase->id,
'parameters' => $sourcePhrase->parameters,
'translation_file_id' => $sourcePhrase->file->id,
'translation_file_id' => $file->id,
]);
}

Expand Down
4 changes: 4 additions & 0 deletions src/Models/TranslationFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class TranslationFile extends Model

public $timestamps = false;

protected $casts = [
'is_root' => 'boolean',
];

public function phrases(): HasMany
{
return $this->hasMany(Phrase::class);
Expand Down
28 changes: 23 additions & 5 deletions src/TranslationsManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,20 @@ public function getTranslations(string $locale): array
}

$translations = [];
$baseFileName = "{$locale}.json";
$rootFileName = "{$locale}.json";

collect($this->filesystem->allFiles(lang_path($locale)))
$files = [];

if ($this->filesystem->exists(lang_path($locale))) {
$files = $this->filesystem->allFiles(lang_path($locale));
}

collect($files)
->map(function ($file) use ($locale) {
return $locale . DIRECTORY_SEPARATOR . $file->getFilename();
})
->when($this->filesystem->exists(lang_path($baseFileName)), function ($collection) use ($baseFileName) {
return $collection->prepend($baseFileName);
->when($this->filesystem->exists(lang_path($rootFileName)), function ($collection) use ($rootFileName) {
return $collection->prepend($rootFileName);
})
->filter(function ($file) {
foreach (config('translations.exclude_files') as $excludeFile) {
Expand Down Expand Up @@ -142,7 +148,19 @@ protected function buildPhrasesTree($phrases, $locale): array
$tree = [];

foreach ($phrases as $phrase) {
Arr::set($tree[$locale][$phrase->file->file_name], $phrase->key, $phrase->value);
if ($phrase->file->is_root) {
$fileName = $phrase->file->file_name;
} else {
$fileName = "{$locale}/{$phrase->file->file_name}";
}

$key = $phrase->key;

if (config('translations.include_file_in_key') && !$phrase->file->is_root) {
$key = Str::replaceStart($phrase->file->name . '.', '', $key);
}

Arr::set($tree[$locale][$fileName], $key, $phrase->value);
}

return $tree;
Expand Down
4 changes: 4 additions & 0 deletions tests/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ function createDirectoryIfNotExits($path)

function createPhpLanguageFile($path, array $content)
{
$path = lang_path($path);

createDirectoryIfNotExits($path);

File::put($path, "<?php\n\nreturn " . VarExporter::export($content, VarExporter::TRAILING_COMMA_IN_ARRAY) . ';' . PHP_EOL);
}

function createJsonLangaueFile($path, array $content)
{
$path = lang_path($path);

createDirectoryIfNotExits($path);

File::put($path, json_encode($content, JSON_PRETTY_PRINT));
Expand Down
7 changes: 5 additions & 2 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ protected function setUp(): void
parent::setUp();

Factory::guessFactoryNamesUsing(
fn (string $modelName) => 'Outhebox\\LaravelTranslations\\Database\\Factories\\'.class_basename($modelName).'Factory'
fn(string $modelName) => 'Outhebox\\LaravelTranslations\\Database\\Factories\\' . class_basename($modelName) . 'Factory'
);
}

Expand All @@ -33,7 +33,10 @@ public function getEnvironmentSetUp($app): void
{
Schema::dropAllTables();

$migration = include __DIR__.'/../database/migrations/2018_08_08_100000_create_translations_tables.php';
$migration = include __DIR__ . '/../database/migrations/2018_08_08_100000_create_translations_tables.php';
$migration->up();

$migration = include __DIR__ . '/../database/migrations/2018_08_08_100001_add_is_root_to_translation_files_table.php';
$migration->up();
}
}
28 changes: 14 additions & 14 deletions tests/TranslationsManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
it('returns the correct list of locales', function () {
$filesystem = new Filesystem();
// Create the source language directory
createPhpLanguageFile(lang_path('en/auth.php'), []);
createJsonLangaueFile(lang_path('en.json'), []);
createPhpLanguageFile('en/auth.php', []);
createJsonLangaueFile('en.json', []);

createJsonLangaueFile(lang_path('fr.json'), []);
createJsonLangaueFile('fr.json', []);

createPhpLanguageFile(lang_path('de/validation.php'), []);
createPhpLanguageFile('de/validation.php', []);

$translationsManager = new TranslationsManager($filesystem);
$locales = $translationsManager->getLocales();
Expand All @@ -34,13 +34,13 @@
});

it('returns the correct translations for a given locale', function () {
createPhpLanguageFile(lang_path('en/auth.php'), [
createPhpLanguageFile('en/auth.php', [
'test' => 'Test',
]);
createPhpLanguageFile(lang_path('en/validation.php'), [
createPhpLanguageFile('en/validation.php', [
'test' => 'Test1',
]);
createJsonLangaueFile(lang_path('en.json'), [
createJsonLangaueFile('en.json', [
'title' => 'My title',
]);

Expand All @@ -63,13 +63,13 @@
});

it('it excludes the correct files', function () {
createPhpLanguageFile(lang_path('en/auth.php'), [
createPhpLanguageFile('en/auth.php', [
'test' => 'Test',
]);
createPhpLanguageFile(lang_path('en/validation.php'), [
createPhpLanguageFile('en/validation.php', [
'test' => 'Test1',
]);
createJsonLangaueFile(lang_path('en.json'), [
createJsonLangaueFile('en.json', [
'title' => 'My title',
]);

Expand Down Expand Up @@ -102,15 +102,15 @@
])->has(Phrase::factory()->state([
'phrase_id' => null,
'translation_file_id' => TranslationFile::factory([
'name' => 'en/auth',
'name' => 'auth',
'extension' => 'php',
]),
]))->create();

$translationsManager = new TranslationsManager($filesystem);
$translationsManager->export();

$fileName = lang_path($translation->phrases[0]->file->name . '.' . $translation->phrases[0]->file->extension);
$fileName = lang_path("en/" . $translation->phrases[0]->file->name . '.' . $translation->phrases[0]->file->extension);
$fileNameInDisk = File::allFiles(lang_path($translation->language->code))[0]->getPathname();

expect($fileName)->toBe($fileNameInDisk)
Expand All @@ -127,7 +127,7 @@

$translation = Translation::factory()
->has(Phrase::factory()
->for(TranslationFile::factory()->state(['name' => 'en/test', 'extension' => 'php']), 'file')
->for(TranslationFile::factory()->state(['name' => 'test', 'extension' => 'php']), 'file')
->state([
'key' => 'accepted',
'value' => 'The :attribute must be accepted.',
Expand All @@ -154,7 +154,7 @@

$translation = Translation::factory()
->has(Phrase::factory()
->for(TranslationFile::factory()->state(['name' => 'en/test', 'extension' => 'json']), 'file')
->for(TranslationFile::factory()->state(['name' => 'test', 'extension' => 'json']), 'file')
->state([
'key' => 'accepted',
'value' => 'The :attribute must be accepted.',
Expand Down

0 comments on commit f9e2ce0

Please sign in to comment.