diff --git a/app/Http/Controllers/MediaController.php b/app/Http/Controllers/MediaController.php index 856e64e..f72cbb5 100644 --- a/app/Http/Controllers/MediaController.php +++ b/app/Http/Controllers/MediaController.php @@ -5,7 +5,7 @@ use App\Models\Media; use App\Models\Category; use App\Models\Tag; - +use Illuminate\Support\Facades\DB; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; @@ -75,45 +75,177 @@ public function store(Request $request) public function index(Request $request) { $query = Media::with(['image', 'category', 'myNote', 'tags']) - ->where(function($q) { + ->where(function ($q) { $q->where('visibility', 'public') ->orWhere('user_id', auth()->id()); }); - if ($request->filled('category')) { - $query->where('category_id', $request->category); + + /* + |-------------------------------------------------------------------------- + | 1️⃣ Multi Category + |-------------------------------------------------------------------------- + */ + + if ($request->filled('categories')) { + $categories = explode(',', $request->categories); + $query->whereIn('category_id', $categories); } + + /* + |-------------------------------------------------------------------------- + | 2️⃣ Multi Duration Ranges + |-------------------------------------------------------------------------- + | duration stored in minutes (integer) + |-------------------------------------------------------------------------- + */ + + if ($request->filled('durations')) { + + $ranges = explode(',', $request->durations); + + $query->where(function ($q) use ($ranges) { + + foreach ($ranges as $range) { + + if ($range === '1-2') { + $q->orWhereBetween('duration', [1, 2]); + } + + if ($range === '2-5') { + $q->orWhereBetween('duration', [3, 5]); + } + + if ($range === '5-10') { + $q->orWhereBetween('duration', [6, 10]); + } + if ($range === '10-30') { + $q->orWhereBetween('duration', [10, 30]); + } + if ($range === '30-60') { + $q->orWhereBetween('duration', [30, 60]); + } + if ($range === '60-120') { + $q->orWhereBetween('duration', [60, 120]); + } + + if ($range === 'other') { + $q->orWhere('duration', '>', 120); + } + } + + }); + } + + /* + |-------------------------------------------------------------------------- + | 3️⃣ Tags + |-------------------------------------------------------------------------- + */ + if ($request->filled('tags')) { $tags = explode(',', $request->tags); - $query->whereHas('tags', function($q) use ($tags) { + $query->whereHas('tags', function ($q) use ($tags) { $q->whereIn('name', $tags); }); } + + /* + |-------------------------------------------------------------------------- + | 4️⃣ Search + |-------------------------------------------------------------------------- + */ + if ($request->filled('search')) { + $search = $request->search; - $query->where(function($q) use ($search) { + $query->where(function ($q) use ($search) { - // title & caption $q->where('title', 'LIKE', "%$search%") - ->orWhere('caption', 'LIKE', "%$search%") + ->orWhere('caption', 'LIKE', "%$search%") + ->orWhereHas('category', function ($c) use ($search) { + $c->where('name', 'LIKE', "%$search%"); + }) + ->orWhereHas('tags', function ($t) use ($search) { + $t->where('name', 'LIKE', "%$search%"); + }); - // category (join) - ->orWhereHas('category', function($c) use ($search) { - $c->where('name', 'LIKE', "%$search%"); - }) - - // tags - ->orWhereHas('tags', function($t) use ($search) { - $t->where('name', 'LIKE', "%$search%"); - }); }); } + return response()->json( $query->orderBy('created_at', 'desc')->get() ); } +public function filters(Request $request) +{ + $baseQuery = Media::query() + ->where(function ($q) { + $q->where('visibility', 'public') + ->orWhere('user_id', auth()->id()); + }); + + /* + |-------------------------------------------------------------------------- + | 1️⃣ Categories with media count + |-------------------------------------------------------------------------- + */ + + $categories = Category::select( + 'categories.id', + 'categories.name', + DB::raw('COUNT(media.id) as media_count') + ) + ->leftJoin('media', function ($join) { + $join->on('categories.id', '=', 'media.category_id') + ->where(function ($q) { + $q->where('media.visibility', 'public') + ->orWhere('media.user_id', auth()->id()); + }); + }) + ->groupBy('categories.id', 'categories.name') + ->orderByDesc('media_count') + ->get(); + + + /* + |-------------------------------------------------------------------------- + | 2️⃣ Duration ranges + |-------------------------------------------------------------------------- + | duration is stored in seconds + |-------------------------------------------------------------------------- + */ + + $durations = Media::select( + DB::raw(" + CASE + WHEN duration BETWEEN 1 AND 2 THEN '1-2' + WHEN duration BETWEEN 3 AND 5 THEN '2-5' + WHEN duration BETWEEN 5 AND 10 THEN '5-10' + WHEN duration BETWEEN 10 AND 20 THEN '10-20' + WHEN duration BETWEEN 20 AND 30 THEN '20-30' + WHEN duration BETWEEN 60 AND 120 THEN '60-120' + ELSE 'other' + END as duration_range + "), + DB::raw('COUNT(*) as total') + ) + ->whereNotNull('duration') + ->where(function ($q) { + $q->where('visibility', 'public') + ->orWhere('user_id', auth()->id()); + }) + ->groupBy('duration_range') + ->get(); + + return response()->json([ + 'categories' => $categories, + 'durations' => $durations, + ]); +} + public function show($id) { $media = Media::with(['image', 'category', 'myNote', 'tags']) diff --git a/routes/api.php b/routes/api.php index 14ebe8e..0b25779 100644 --- a/routes/api.php +++ b/routes/api.php @@ -135,6 +135,7 @@ ///media + Route::get('/media/filters', [MediaController::class, 'filters']); Route::post('/media', [MediaController::class, 'store']); Route::get('/media', [MediaController::class, 'index']); Route::post('/media/{id}', [MediaController::class, 'update']); @@ -142,7 +143,7 @@ Route::delete('/media/{id}', [MediaController::class, 'destroy']); Route::get('/media/{id}', [MediaController::class, 'show']); Route::post('/media/{id}/save', [MediaController::class, 'toggleSaveMedia']); - + Route::post('/media/{id}/note', [MediaController::class, 'storeNote']); }); \ No newline at end of file