Files
2026-08-09 20:15:40 +03:00

192 lines
5.1 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\Recipe;
use App\Models\RecipeComment;
use App\Models\RecipeRating;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class RecipeController extends Controller
{
public function index(Request $request)
{
$query = Recipe::with(['tags', 'nutrition'])
->where('status', 1); // Only published recipes
// Search filter
if ($request->filled('search')) {
$search = $request->search;
$query->where(function($q) use ($search) {
$q->where('title', 'LIKE', "%{$search}%")
->orWhere('description', 'LIKE', "%{$search}%");
});
}
// Category filter
if ($request->filled('category')) {
$query->where('category', $request->category);
}
// Cuisine filter
if ($request->filled('cuisine')) {
$query->where('cuisine', $request->cuisine);
}
// Difficulty filter
if ($request->filled('difficulty')) {
$query->where('difficulty', $request->difficulty);
}
// Tag filter
if ($request->filled('tag')) {
$query->whereHas('tags', function($q) use ($request) {
$q->where('slug', $request->tag);
});
}
// Sorting
$sort = $request->get('sort', 'latest');
switch ($sort) {
case 'popular':
$query->orderBy('views_count', 'desc');
break;
case 'rated':
$query->orderBy('rating_avg', 'desc');
break;
case 'title':
$query->orderBy('title', 'asc');
break;
default:
$query->latest();
}
$recipes = $query->paginate(12);
// Get filter options
$categories = Recipe::where('status', 1)
->distinct()
->pluck('category')
->filter()
->sort();
$cuisines = Recipe::where('status', 1)
->distinct()
->pluck('cuisine')
->filter()
->sort();
$difficulties = Recipe::where('status', 1)
->distinct()
->pluck('difficulty')
->filter()
->sort();
return view('recipes.index', compact('recipes', 'categories', 'cuisines', 'difficulties'));
}
public function show(Request $request, string $slug)
{
$recipe = Recipe::with([
'ingredients',
'steps',
'images',
'nutrition',
'tags',
'comments.user',
'ratings'
])
->where('slug', $slug)
->where('status', 1)
->firstOrFail();
// Increment views
$recipe->increment('views_count');
// Get similar recipes (same category or cuisine)
$similarRecipes = Recipe::where('id', '!=', $recipe->id)
->where('status', 1)
->where(function($q) use ($recipe) {
$q->where('category', $recipe->category)
->orWhere('cuisine', $recipe->cuisine);
})
->limit(4)
->get();
return view('recipes.show', compact('recipe', 'similarRecipes'));
}
public function toggleFavorite(Request $request, Recipe $recipe)
{
$user = $request->user();
if ($user->favoriteRecipes()->where('recipe_id', $recipe->id)->exists()) {
$user->favoriteRecipes()->detach($recipe->id);
$isFavorited = false;
} else {
$user->favoriteRecipes()->attach($recipe->id);
$isFavorited = true;
}
return response()->json([
'success' => true,
'is_favorited' => $isFavorited,
]);
}
public function rate(Request $request, Recipe $recipe)
{
$request->validate([
'rating' => 'required|integer|min:1|max:5',
]);
$user = $request->user();
RecipeRating::updateOrCreate(
[
'user_id' => $user->id,
'recipe_id' => $recipe->id,
],
[
'rating' => $request->rating,
]
);
// Recalculate average rating
$avgRating = $recipe->ratings()->avg('rating');
$ratingCount = $recipe->ratings()->count();
$recipe->update([
'rating_avg' => $avgRating,
'rating_count' => $ratingCount,
]);
return response()->json([
'success' => true,
'rating_avg' => round($avgRating, 2),
'rating_count' => $ratingCount,
]);
}
public function comment(Request $request, Recipe $recipe)
{
$request->validate([
'comment' => 'required|string|min:3|max:1000',
]);
$comment = RecipeComment::create([
'user_id' => $request->user()->id,
'recipe_id' => $recipe->id,
'comment' => $request->comment,
]);
$comment->load('user');
return response()->json([
'success' => true,
'comment' => $comment,
]);
}
}