feat: add filter media

This commit is contained in:
2026-06-15 14:06:17 +03:30
parent a7e3f2cbd8
commit 6293c7aa6e
+46 -67
View File
@@ -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(),
]);
}