fix: duration fix
This commit is contained in:
@@ -125,21 +125,28 @@ private function applyMediaFilters($query, Request $request)
|
||||
});
|
||||
}
|
||||
|
||||
// Duration ranges (duration stored in minutes).
|
||||
// Duration ranges (duration stored in minutes). Keys come from durationRanges().
|
||||
if ($request->filled('durations')) {
|
||||
$ranges = explode(',', $request->durations);
|
||||
$query->where(function ($q) use ($ranges) {
|
||||
$defs = $this->durationRanges();
|
||||
// Keep only known range keys so an unknown value can't produce an empty
|
||||
// (match-everything) WHERE group.
|
||||
$ranges = array_filter(
|
||||
explode(',', $request->durations),
|
||||
fn ($r) => $r === '120-' || isset($defs[$r])
|
||||
);
|
||||
|
||||
if (!empty($ranges)) {
|
||||
$query->where(function ($q) use ($ranges, $defs) {
|
||||
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 === '120-') {
|
||||
$q->orWhere('duration', '>', $this->durationOtherMin());
|
||||
} else {
|
||||
$q->orWhereBetween('duration', $defs[$range]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('tags')) {
|
||||
$tags = explode(',', $request->tags);
|
||||
@@ -168,6 +175,26 @@ private function applyMediaFilters($query, Request $request)
|
||||
return $query;
|
||||
}
|
||||
|
||||
// Single source of truth for duration buckets (minutes), used by both the
|
||||
// filter facet (/media/filters) and the search filter. Non-overlapping.
|
||||
// Anything above durationOtherMin() falls into the 'other' bucket.
|
||||
private function durationRanges(): array
|
||||
{
|
||||
return [
|
||||
'1-2' => [1, 2],
|
||||
'2-5' => [3, 5],
|
||||
'5-10' => [6, 10],
|
||||
'10-30' => [11, 30],
|
||||
'30-60' => [31, 60],
|
||||
'60-120' => [61, 120],
|
||||
];
|
||||
}
|
||||
|
||||
private function durationOtherMin(): int
|
||||
{
|
||||
return 120;
|
||||
}
|
||||
|
||||
// NEWEST media, paginated (?per_page=, ?page=). Same visibility scope as index.
|
||||
public function newest(Request $request)
|
||||
{
|
||||
@@ -304,18 +331,16 @@ public function filters(Request $request)
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
// Build the CASE from the same range definitions the search filter uses,
|
||||
// so the facet keys (e.g. "10-30") always match what /media/search accepts.
|
||||
$caseSql = 'CASE ';
|
||||
foreach ($this->durationRanges() as $key => [$min, $max]) {
|
||||
$caseSql .= "WHEN duration BETWEEN {$min} AND {$max} THEN '{$key}' ";
|
||||
}
|
||||
$caseSql .= "WHEN duration > {$this->durationOtherMin()} THEN '120-' END";
|
||||
|
||||
$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 '120-'
|
||||
END as duration_range
|
||||
"),
|
||||
DB::raw("{$caseSql} as duration_range"),
|
||||
DB::raw('COUNT(*) as total')
|
||||
)
|
||||
->whereNotNull('duration')
|
||||
@@ -324,6 +349,7 @@ public function filters(Request $request)
|
||||
->orWhere('user_id', auth()->id());
|
||||
})
|
||||
->groupBy('duration_range')
|
||||
->havingRaw('duration_range IS NOT NULL')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
|
||||
Reference in New Issue
Block a user