fix: duration fix

This commit is contained in:
2026-06-16 13:09:03 +03:30
parent 0ac28ea776
commit 1cf1ba1c67
+47 -21
View File
@@ -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')) { if ($request->filled('durations')) {
$ranges = explode(',', $request->durations); $defs = $this->durationRanges();
$query->where(function ($q) use ($ranges) { // 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) { foreach ($ranges as $range) {
if ($range === '1-2') $q->orWhereBetween('duration', [1, 2]); if ($range === '120-') {
if ($range === '2-5') $q->orWhereBetween('duration', [3, 5]); $q->orWhere('duration', '>', $this->durationOtherMin());
if ($range === '5-10') $q->orWhereBetween('duration', [6, 10]); } else {
if ($range === '10-30') $q->orWhereBetween('duration', [10, 30]); $q->orWhereBetween('duration', $defs[$range]);
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 ($request->filled('tags')) { if ($request->filled('tags')) {
$tags = explode(',', $request->tags); $tags = explode(',', $request->tags);
@@ -168,6 +175,26 @@ private function applyMediaFilters($query, Request $request)
return $query; 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. // NEWEST media, paginated (?per_page=, ?page=). Same visibility scope as index.
public function newest(Request $request) 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( $durations = Media::select(
DB::raw(" DB::raw("{$caseSql} as duration_range"),
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('COUNT(*) as total') DB::raw('COUNT(*) as total')
) )
->whereNotNull('duration') ->whereNotNull('duration')
@@ -324,6 +349,7 @@ public function filters(Request $request)
->orWhere('user_id', auth()->id()); ->orWhere('user_id', auth()->id());
}) })
->groupBy('duration_range') ->groupBy('duration_range')
->havingRaw('duration_range IS NOT NULL')
->get(); ->get();
return response()->json([ return response()->json([