search($request->query('search')) ->when($request->query('body_part'), fn ($query, $bodyPart) => $query->where('body_part', $bodyPart)) ->when($request->query('equipment'), function ($query, $equipment) { // Accepte une valeur unique ou une liste séparée par des virgules ("dumbbell,barbell") // → filtre "mon matériel" (plusieurs équipements possédés). $values = array_values(array_filter(is_array($equipment) ? $equipment : explode(',', (string) $equipment))); $query->whereIn('equipment', $values); }) ->when($request->query('target'), fn ($query, $target) => $query->where('target', $target)) ->when($request->query('category'), fn ($query, $category) => $query->where('category', $category)) ->orderBy('name') ->paginate((int) $request->query('per_page', self::DEFAULT_PER_PAGE)); ExerciseListResource::$locale = $this->resolveLocale($request); return ExerciseListResource::collection($exercises); } /** GET /api/exercises/{exercise} — détail avec instructions dans la locale demandée. */ public function show(Request $request, Exercise $exercise): ExerciseResource { return new ExerciseResource($exercise, $this->resolveLocale($request)); } /** * GET /api/exercises/facets — valeurs distinctes pour les filtres. * Chaque valeur = { value: anglais (canonique, envoyé au filtre), label: traduit }. */ public function facets(Request $request): JsonResponse { $locale = $this->resolveLocale($request); $facet = fn (string $column) => Exercise::query() ->whereNotNull($column)->distinct()->orderBy($column)->pluck($column) ->map(fn ($v) => ['value' => $v, 'label' => Exercise::localizeTerm($v, $locale)]) ->values(); return response()->json([ 'body_parts' => $facet('body_part'), 'equipments' => $facet('equipment'), 'targets' => $facet('target'), 'categories' => $facet('category'), ]); } /** Résout la locale demandée : paramètre `locale`, sinon header Accept-Language, sinon 'fr'. */ private function resolveLocale(Request $request): string { $locale = $request->query('locale'); if ($locale) { return (string) $locale; } $acceptLanguage = $request->header('Accept-Language'); if (! $acceptLanguage) { return self::DEFAULT_LOCALE; } // Le header peut lister plusieurs langues pondérées ("fr-FR,fr;q=0.9,en;q=0.8") : on ne garde que la première. $firstLanguage = strtok($acceptLanguage, ','); $languageTag = strtok($firstLanguage, ';'); return $languageTag !== false ? $languageTag : self::DEFAULT_LOCALE; } }