192 lines
5.1 KiB
PHP
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,
|
|
]);
|
|
}
|
|
}
|