From 6293c7aa6ed73a1094be265571b4718f0d9b1971 Mon Sep 17 00:00:00 2001 From: AmirmahdiNourkazemi Date: Mon, 15 Jun 2026 14:06:17 +0330 Subject: [PATCH] feat: add filter media --- app/Http/Controllers/MediaController.php | 113 +++++++++-------------- 1 file changed, 46 insertions(+), 67 deletions(-) diff --git a/app/Http/Controllers/MediaController.php b/app/Http/Controllers/MediaController.php index a83f179..ad73db8 100644 --- a/app/Http/Controllers/MediaController.php +++ b/app/Http/Controllers/MediaController.php @@ -95,12 +95,22 @@ public function index(Request $request) ->orWhere('user_id', auth()->id()); }); - /* - |-------------------------------------------------------------------------- - | 1️⃣ Multi Category - |-------------------------------------------------------------------------- - */ + $this->applyMediaFilters($query, $request); + $query->orderBy('created_at', 'desc'); + + // Optional cap: ?count=10 returns only the first 10 items. + if ($request->filled('count')) { + $query->limit(max(1, (int) $request->input('count'))); + } + + return response()->json($query->get()); +} + +// Apply the category / subcategory / duration / tag / search filters shared by +// the media list (index) and the filters screen. +private function applyMediaFilters($query, Request $request) +{ if ($request->filled('categories')) { $categories = explode(',', $request->categories); $query->whereHas('categories', function ($q) use ($categories) { @@ -115,77 +125,32 @@ public function index(Request $request) }); } - /* - |-------------------------------------------------------------------------- - | 2️⃣ Multi Duration Ranges - |-------------------------------------------------------------------------- - | duration stored in minutes (integer) - |-------------------------------------------------------------------------- - */ - + // Duration ranges (duration stored in minutes). 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); - } + 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) { $q->whereIn('name', $tags); }); } - /* - |-------------------------------------------------------------------------- - | 4️⃣ Search - |-------------------------------------------------------------------------- - */ - if ($request->filled('search')) { - $search = $request->search; - $query->where(function ($q) use ($search) { - $q->where('title', 'LIKE', "%$search%") ->orWhere('caption', 'LIKE', "%$search%") ->orWhereHas('categories', function ($c) use ($search) { @@ -197,18 +162,10 @@ public function index(Request $request) ->orWhereHas('tags', function ($t) use ($search) { $t->where('name', 'LIKE', "%$search%"); }); - }); } - $query->orderBy('created_at', 'desc'); - - // Optional cap: ?count=10 returns only the first 10 items. - if ($request->filled('count')) { - $query->limit(max(1, (int) $request->input('count'))); - } - - return response()->json($query->get()); + return $query; } // NEWEST media, paginated (?per_page=, ?page=). Same visibility scope as index. @@ -369,10 +326,32 @@ public function filters(Request $request) ->groupBy('duration_range') ->get(); + /* + |-------------------------------------------------------------------------- + | 3️⃣ The media matching the chosen filters (so one call returns both the + | filter options and the result list the user asked for). + |-------------------------------------------------------------------------- + */ + + $mediaQuery = Media::with(['image', 'detailImage', 'categories', 'subCategories', 'myNote', 'tags']) + ->where(function ($q) { + $q->where('visibility', 'public') + ->orWhere('user_id', auth()->id()); + }); + + $this->applyMediaFilters($mediaQuery, $request); + + $mediaQuery->orderBy('created_at', 'desc'); + + if ($request->filled('count')) { + $mediaQuery->limit(max(1, (int) $request->input('count'))); + } + return response()->json([ 'categories' => $categories, 'subcategories' => $subcategories, 'durations' => $durations, + 'media' => $mediaQuery->get(), ]); }