query('q', '')); $bodypart = (string) $request->query('bodypart', ''); $muscle = (string) $request->query('muscle', ''); $equipment = (string) $request->query('equipment', ''); $perPage = (int) ($request->query('per_page', 12)); if ($perPage < 6 || $perPage > 60) { $perPage = 12; } $query = Exercise::query() ->with(['bodyParts:id,name,slug', 'targetMuscles:id,name,slug', 'secondaryMuscles:id,name,slug', 'equipments:id,name,slug']) ->when($q !== '', function ($qBuilder) use ($q) { $qBuilder->where(function ($sub) use ($q) { $sub->where('name', 'like', "%{$q}%") ->orWhere('instructions', 'like', "%{$q}%"); }); }) ->when($bodypart !== '', function ($qBuilder) use ($bodypart) { $qBuilder->whereHas('bodyParts', function ($rel) use ($bodypart) { $rel->where('slug', $bodypart); }); }) ->when($muscle !== '', function ($qBuilder) use ($muscle) { $qBuilder->where(function ($sub) use ($muscle) { $sub->whereHas('targetMuscles', function ($rel) use ($muscle) { $rel->where('slug', $muscle); }) ->orWhereHas('secondaryMuscles', function ($rel) use ($muscle) { $rel->where('slug', $muscle); }); }); }) ->when($equipment !== '', function ($qBuilder) use ($equipment) { $qBuilder->whereHas('equipments', function ($rel) use ($equipment) { $rel->where('slug', $equipment); }); }) ->orderBy('name'); $exercises = $query->paginate($perPage)->withQueryString(); $bodyParts = BodyPart::query()->orderBy('name')->get(['id','name','slug']); $muscles = Muscle::query()->orderBy('name')->get(['id','name','slug']); $equipments = Equipment::query()->orderBy('name')->get(['id','name','slug']); return view('exercises.index', [ 'exercises' => $exercises, 'filters' => [ 'q' => $q, 'bodypart' => $bodypart, 'muscle' => $muscle, 'equipment' => $equipment, 'per_page' => $perPage, ], 'bodyParts' => $bodyParts, 'muscles' => $muscles, 'equipments' => $equipments, ]); } public function show(Exercise $exercise) { $exercise->load(['bodyParts:id,name,slug', 'targetMuscles:id,name,slug', 'secondaryMuscles:id,name,slug', 'equipments:id,name,slug']); // Find similar exercises by shared target muscles, body parts, or equipment $targetIds = $exercise->targetMuscles->pluck('id')->all(); $bodyPartIds = $exercise->bodyParts->pluck('id')->all(); $equipmentIds = $exercise->equipments->pluck('id')->all(); $similarQuery = Exercise::query() ->with(['bodyParts:id,name,slug', 'targetMuscles:id,name,slug', 'equipments:id,name,slug']) ->where('id', '!=', $exercise->id) ->where(function ($q) use ($targetIds, $bodyPartIds, $equipmentIds) { if (!empty($targetIds)) { $q->orWhereHas('targetMuscles', function ($rel) use ($targetIds) { $rel->whereIn('id', $targetIds); }); } if (!empty($bodyPartIds)) { $q->orWhereHas('bodyParts', function ($rel) use ($bodyPartIds) { $rel->whereIn('id', $bodyPartIds); }); } if (!empty($equipmentIds)) { $q->orWhereHas('equipments', function ($rel) use ($equipmentIds) { $rel->whereIn('id', $equipmentIds); }); } }) ->orderBy('name') ->limit(9); $similarExercises = $similarQuery->get(); return view('exercises.show', [ 'exercise' => $exercise, 'similarExercises' => $similarExercises, ]); } }