feat: route filter & improve search
This commit is contained in:
@@ -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'])
|
||||
|
||||
@@ -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']);
|
||||
|
||||
Reference in New Issue
Block a user