From 3ec14f219b848ac39f5f2762171648e01f385fb2 Mon Sep 17 00:00:00 2001 From: neckfire Date: Sun, 19 Jul 2026 04:04:38 +0200 Subject: [PATCH] exercises:import-translations + recherche sur noms traduits (name_i18n) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Commands/ImportTranslationsCommand.php | 74 +++++++++++++++++++ functional/exercises/src/Models/Exercise.php | 1 + .../Providers/ExercisesServiceProvider.php | 3 +- 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 functional/exercises/src/Console/Commands/ImportTranslationsCommand.php diff --git a/functional/exercises/src/Console/Commands/ImportTranslationsCommand.php b/functional/exercises/src/Console/Commands/ImportTranslationsCommand.php new file mode 100644 index 0000000..1d8adfa --- /dev/null +++ b/functional/exercises/src/Console/Commands/ImportTranslationsCommand.php @@ -0,0 +1,74 @@ +option('dir'), '/'); + if (! $dir || ! is_dir($dir)) { + $this->error("Dossier introuvable : {$dir}"); + + return self::FAILURE; + } + + $files = glob($dir . '/result_*.json'); + if (! $files) { + $this->error('Aucun fichier result_*.json.'); + + return self::FAILURE; + } + + $updated = 0; + $missing = 0; + + foreach ($files as $file) { + $rows = json_decode((string) file_get_contents($file), true); + if (! is_array($rows)) { + $this->warn('Ignoré (JSON invalide) : ' . basename($file)); + + continue; + } + + foreach ($rows as $r) { + $exercise = Exercise::find($r['id'] ?? null); + if (! $exercise) { + $missing++; + + continue; + } + + $exercise->name_i18n = array_filter([ + 'fr' => $r['name_fr'] ?? null, + 'pt-BR' => $r['name_ptBR'] ?? null, + ]); + + if (! empty($r['instr_ptBR'])) { + $instructions = $exercise->instructions ?? []; + $instructions['pt-BR'] = array_values($r['instr_ptBR']); + $exercise->instructions = $instructions; + } + + $exercise->save(); + $updated++; + } + } + + $this->info("Traductions importées : {$updated} exercices" . ($missing ? " ({$missing} id introuvables)" : '')); + + return self::SUCCESS; + } +} diff --git a/functional/exercises/src/Models/Exercise.php b/functional/exercises/src/Models/Exercise.php index b36d756..bcf5739 100644 --- a/functional/exercises/src/Models/Exercise.php +++ b/functional/exercises/src/Models/Exercise.php @@ -120,6 +120,7 @@ class Exercise extends Model return $query->where(function (Builder $q) use ($like) { $q->where('name', 'like', $like) + ->orWhere('name_i18n', 'like', $like) // noms traduits (JSON stocké en texte) ->orWhere('target', 'like', $like) ->orWhere('equipment', 'like', $like) ->orWhere('body_part', 'like', $like); diff --git a/functional/exercises/src/Providers/ExercisesServiceProvider.php b/functional/exercises/src/Providers/ExercisesServiceProvider.php index e9c2452..bbb33df 100644 --- a/functional/exercises/src/Providers/ExercisesServiceProvider.php +++ b/functional/exercises/src/Providers/ExercisesServiceProvider.php @@ -3,6 +3,7 @@ namespace Functional\Exercises\Providers; use Functional\Exercises\Console\Commands\ImportExercisesCommand; +use Functional\Exercises\Console\Commands\ImportTranslationsCommand; use Functional\Exercises\Database\Seeders\ExercisesSeeder; use Xefi\LaravelOSDD\LayerServiceProvider; @@ -13,7 +14,7 @@ class ExercisesServiceProvider extends LayerServiceProvider if ($this->app->runningInConsole()) { $this->loadMigrationsFrom(__DIR__ . '/../../database/migrations'); $this->loadSeeders([ExercisesSeeder::class]); - $this->commands([ImportExercisesCommand::class]); + $this->commands([ImportExercisesCommand::class, ImportTranslationsCommand::class]); } $this->withRouting(