exercises:import-translations + recherche sur noms traduits (name_i18n)
Build & Deploy / build (push) Successful in 26s
Build & Deploy / build (push) Successful in 26s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Functional\Exercises\Console\Commands;
|
||||
|
||||
use Functional\Exercises\Models\Exercise;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
/**
|
||||
* Importe les traductions d'exercices (noms fr/pt-BR + instructions pt-BR) depuis des fichiers
|
||||
* result_*.json produits hors-ligne : [{id, name_fr, name_ptBR, instr_ptBR:[...]}].
|
||||
* Met à jour exercises.name_i18n et fusionne instructions['pt-BR'].
|
||||
*/
|
||||
class ImportTranslationsCommand extends Command
|
||||
{
|
||||
protected $signature = 'exercises:import-translations {--dir= : dossier contenant les result_*.json}';
|
||||
|
||||
protected $description = 'Importe les traductions (noms fr/pt-BR + instructions pt-BR) des exercices.';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$dir = rtrim((string) $this->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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user