Update release reporting

This commit is contained in:
DariusIII
2026-06-08 16:42:06 +02:00
parent cb80f4f17e
commit 5a837e52af
7 changed files with 82 additions and 23 deletions
@@ -79,6 +79,12 @@ class DetailsController extends BasePageController
->get();
$reportCount = $reportData->count();
$reportReasons = ReleaseReport::reasonKeysToLabels($reportData->pluck('reason')->unique()->implode(', '));
$originalReportData = ReleaseReport::query()
->where('releases_id', $data['id'])
->orderByDesc('created_at')
->get();
$totalReportCount = $originalReportData->count();
$allReportReasons = ReleaseReport::reasonKeysToLabels($originalReportData->pluck('reason')->unique()->implode(', '));
$publicReportResponses = ReleaseReport::query()
->with('responder')
->where('releases_id', $data['id'])
@@ -185,6 +191,9 @@ class DetailsController extends BasePageController
'failed' => $failed,
'reportCount' => $reportCount,
'reportReasons' => $reportReasons,
'originalReportData' => $originalReportData,
'totalReportCount' => $totalReportCount,
'allReportReasons' => $allReportReasons,
'publicReportResponses' => $publicReportResponses,
'regex' => $releaseRegex,
'downloadedby' => $downloadedBy,
@@ -165,8 +165,12 @@ class ReleaseBrowseService
$outerSelect = "SELECT r.id, r.searchname, r.guid, r.postdate, r.categories_id, r.size, r.totalpart, r.fromname, r.grabs, r.comments, r.adddate, r.videos_id, r.haspreview, r.jpgstatus, r.nfostatus, r.group_name,
CONCAT(cp.title, ' > ', c.title) AS category_name,
df.failed AS failed_count,
rr.total_report_count AS total_report_count,
rr.report_count AS report_count,
rr.report_reasons AS report_reasons,
rr.all_report_reasons AS all_report_reasons,
rr.latest_report_reason AS latest_report_reason,
rr.latest_report_description AS latest_report_description,
rr.response_count AS report_response_count,
rr.latest_response_at AS latest_report_response_at,
rn.releases_id AS nfoid,
@@ -178,7 +182,7 @@ class ReleaseBrowseService
LEFT OUTER JOIN video_data re ON re.releases_id = r.id
LEFT OUTER JOIN release_nfos rn ON rn.releases_id = r.id
LEFT OUTER JOIN dnzb_failures df ON df.release_id = r.id
LEFT OUTER JOIN (SELECT releases_id, SUM(CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN 1 ELSE 0 END) AS report_count, GROUP_CONCAT(DISTINCT CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN reason ELSE NULL END SEPARATOR ', ') AS report_reasons, SUM(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN 1 ELSE 0 END) AS response_count, MAX(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN responded_at ELSE NULL END) AS latest_response_at FROM release_reports GROUP BY releases_id) rr ON rr.releases_id = r.id";
LEFT OUTER JOIN (SELECT releases_id, COUNT(*) AS total_report_count, SUM(CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN 1 ELSE 0 END) AS report_count, GROUP_CONCAT(DISTINCT CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN reason ELSE NULL END SEPARATOR ', ') AS report_reasons, GROUP_CONCAT(DISTINCT reason SEPARATOR ', ') AS all_report_reasons, SUBSTRING_INDEX(GROUP_CONCAT(reason ORDER BY created_at DESC SEPARATOR ','), ',', 1) AS latest_report_reason, SUBSTRING_INDEX(GROUP_CONCAT(COALESCE(NULLIF(description, ''), 'No additional report details were provided.') ORDER BY created_at DESC SEPARATOR ' || '), ' || ', 1) AS latest_report_description, SUM(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN 1 ELSE 0 END) AS response_count, MAX(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN responded_at ELSE NULL END) AS latest_response_at FROM release_reports GROUP BY releases_id) rr ON rr.releases_id = r.id";
$innerSelect = 'SELECT r.id, r.searchname, r.guid, r.postdate, r.groups_id, r.categories_id, r.size, r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, r.adddate, r.videos_id, r.haspreview, r.jpgstatus, r.nfostatus, g.name AS group_name, r.movieinfo_id';
}
@@ -1901,8 +1901,12 @@ class ReleaseSearchService
r.videos_id, r.haspreview, r.jpgstatus, r.nfostatus,
CONCAT(cp.title, ' > ', c.title) AS category_name,
df.failed AS failed_count,
rr.total_report_count AS total_report_count,
rr.report_count AS report_count,
rr.report_reasons AS report_reasons,
rr.all_report_reasons AS all_report_reasons,
rr.latest_report_reason AS latest_report_reason,
rr.latest_report_description AS latest_report_description,
rr.response_count AS report_response_count,
rr.latest_response_at AS latest_report_response_at,
g.name AS group_name,
@@ -1917,7 +1921,7 @@ class ReleaseSearchService
LEFT JOIN categories c ON c.id = r.categories_id
LEFT JOIN root_categories cp ON cp.id = c.root_categories_id
LEFT OUTER JOIN dnzb_failures df ON df.release_id = r.id
LEFT OUTER JOIN (SELECT releases_id, SUM(CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN 1 ELSE 0 END) AS report_count, GROUP_CONCAT(DISTINCT CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN reason ELSE NULL END SEPARATOR ', ') AS report_reasons, SUM(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN 1 ELSE 0 END) AS response_count, MAX(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN responded_at ELSE NULL END) AS latest_response_at FROM release_reports GROUP BY releases_id) rr ON rr.releases_id = r.id
LEFT OUTER JOIN (SELECT releases_id, COUNT(*) AS total_report_count, SUM(CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN 1 ELSE 0 END) AS report_count, GROUP_CONCAT(DISTINCT CASE WHEN status IN ('pending', 'reviewed', 'resolved') THEN reason ELSE NULL END SEPARATOR ', ') AS report_reasons, GROUP_CONCAT(DISTINCT reason SEPARATOR ', ') AS all_report_reasons, SUBSTRING_INDEX(GROUP_CONCAT(reason ORDER BY created_at DESC SEPARATOR ','), ',', 1) AS latest_report_reason, SUBSTRING_INDEX(GROUP_CONCAT(COALESCE(NULLIF(description, ''), 'No additional report details were provided.') ORDER BY created_at DESC SEPARATOR ' || '), ' || ', 1) AS latest_report_description, SUM(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN 1 ELSE 0 END) AS response_count, MAX(CASE WHEN response IS NOT NULL AND response != '' AND response_is_public = 1 THEN responded_at ELSE NULL END) AS latest_response_at FROM release_reports GROUP BY releases_id) rr ON rr.releases_id = r.id
%s",
$whereSql
);
+8 -8
View File
@@ -136,10 +136,10 @@
<div class="flex-1">
<div class="flex items-center gap-2 flex-wrap">
<a href="{{ url('/details/' . $result->guid) }}" class="text-primary-600 dark:text-primary-400 hover:text-primary-800 dark:hover:text-primary-300 font-medium wrap-break-word break-all">{{ $result->searchname }}</a>
@if(!empty($result->report_count) && $result->report_count > 0)
@if(!empty($result->total_report_count) && $result->total_report_count > 0)
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200"
title="Reported: {{ \App\Models\ReleaseReport::reasonKeysToLabels($result->report_reasons ?? '') }}">
<i class="fas fa-flag mr-1"></i> Reported ({{ $result->report_count }})
title="Reported: {{ $result->all_report_reasons ?? 'Unknown' }} | Original report: {{ $result->latest_report_reason ?? 'Unknown' }} - {{ $result->latest_report_description ?? 'No additional report details were provided.' }}">
<i class="fas fa-flag mr-1"></i> Reported ({{ $result->total_report_count }})
</span>
@endif
@if(!empty($result->report_response_count) && $result->report_response_count > 0)
@@ -261,7 +261,7 @@
<i class="fa fa-film"></i>
</a>
@endif
<x-report-button :release-id="$result->id" variant="icon" />
<x-report-button :release-id="$result->id" :reported-count="$result->total_report_count ?? 0" variant="icon" />
</div>
</td>
</tr>
@@ -290,10 +290,10 @@
{{ $result->searchname }}
</a>
<div class="flex flex-wrap items-center gap-2 mt-2">
@if(!empty($result->report_count) && $result->report_count > 0)
@if(!empty($result->total_report_count) && $result->total_report_count > 0)
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200"
title="Reported: {{ \App\Models\ReleaseReport::reasonKeysToLabels($result->report_reasons ?? '') }}">
<i class="fas fa-flag mr-1"></i> Reported ({{ $result->report_count }})
title="Reported: {{ $result->all_report_reasons ?? 'Unknown' }} | Original report: {{ $result->latest_report_reason ?? 'Unknown' }} - {{ $result->latest_report_description ?? 'No additional report details were provided.' }}">
<i class="fas fa-flag mr-1"></i> Reported ({{ $result->total_report_count }})
</span>
@endif
@if(!empty($result->report_response_count) && $result->report_response_count > 0)
@@ -322,7 +322,7 @@
<a href="#" class="add-to-cart px-3 py-1.5 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition text-sm" data-guid="{{ $result->guid }}" title="Add to Cart">
<i class="icon_cart fa fa-shopping-basket"></i>
</a>
<x-report-button :release-id="$result->id" variant="icon" />
<x-report-button :release-id="$result->id" :reported-count="$result->total_report_count ?? 0" variant="icon" />
</div>
</div>
</div>
@@ -5,37 +5,48 @@
'releaseGuid' => null,
'size' => 'sm', // sm, md, lg
'variant' => 'icon', // icon, button, button-lg, text
'reportedCount' => 0,
])
@php
$reportedCount = (int) $reportedCount;
$hasReports = $reportedCount > 0;
$reportTitle = $hasReports
? 'This release has already been reported. Click to submit another report.'
: 'Report this release';
@endphp
@auth
@if($variant === 'icon')
<button type="button"
data-report-release-id="{{ $releaseId }}"
class="report-trigger text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300 transition text-sm"
title="Report this release">
class="report-trigger {{ $hasReports ? 'text-orange-500 dark:text-orange-400 hover:text-orange-600 dark:hover:text-orange-300' : 'text-red-500 dark:text-red-400 hover:text-red-600 dark:hover:text-red-300' }} transition text-sm"
title="{{ $reportTitle }}">
<i class="fas fa-flag"></i>
</button>
@elseif($variant === 'button-lg')
<button type="button"
data-report-release-id="{{ $releaseId }}"
class="report-trigger px-4 py-2 bg-red-600 dark:bg-red-700 text-white rounded-lg hover:bg-red-700 dark:hover:bg-red-800 transition inline-flex items-center"
title="Report this release">
class="report-trigger px-4 py-2 {{ $hasReports ? 'bg-orange-600 dark:bg-orange-700 hover:bg-orange-700 dark:hover:bg-orange-800' : 'bg-red-600 dark:bg-red-700 hover:bg-red-700 dark:hover:bg-red-800' }} text-white rounded-lg transition inline-flex items-center"
title="{{ $reportTitle }}">
<i class="fas fa-flag mr-2"></i>
<span class="report-label">Report</span>
<span class="report-label">{{ $hasReports ? 'Reported' : 'Report' }}</span>
</button>
@elseif($variant === 'button')
<button type="button"
data-report-release-id="{{ $releaseId }}"
class="report-trigger px-3 py-1.5 text-{{ $size }} bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-red-100 dark:hover:bg-red-900 hover:text-red-700 dark:hover:text-red-300 transition inline-flex items-center">
class="report-trigger px-3 py-1.5 text-{{ $size }} {{ $hasReports ? 'bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200 hover:bg-orange-200 dark:hover:bg-orange-800' : 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-red-100 dark:hover:bg-red-900 hover:text-red-700 dark:hover:text-red-300' }} rounded-lg transition inline-flex items-center"
title="{{ $reportTitle }}">
<i class="fas fa-flag mr-1.5"></i>
<span class="report-label">Report</span>
<span class="report-label">{{ $hasReports ? 'Reported' : 'Report' }}</span>
</button>
@else
<button type="button"
data-report-release-id="{{ $releaseId }}"
class="report-trigger text-gray-600 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400 text-{{ $size }} transition">
class="report-trigger {{ $hasReports ? 'text-orange-600 dark:text-orange-400 hover:text-orange-700 dark:hover:text-orange-300' : 'text-gray-600 dark:text-gray-400 hover:text-red-600 dark:hover:text-red-400' }} text-{{ $size }} transition"
title="{{ $reportTitle }}">
<i class="fas fa-flag mr-1"></i>
<span class="report-label">Report Issue</span>
<span class="report-label">{{ $hasReports ? 'Reported' : 'Report Issue' }}</span>
</button>
@endif
@endauth
+28 -4
View File
@@ -34,11 +34,11 @@
<div class="mb-3">
<h2 class="text-xl font-bold text-gray-800 dark:text-gray-200 mb-2 wrap-break-word break-all">{{ $release->searchname }}</h2>
<div class="flex flex-wrap gap-2">
@if(!empty($reportCount) && $reportCount > 0)
@if(!empty($totalReportCount) && $totalReportCount > 0)
<div class="inline-flex items-center px-3 py-1.5 rounded-lg text-sm font-medium bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200 border border-orange-200 dark:border-orange-800"
title="Reported: {{ $reportReasons ?? 'Unknown' }}">
title="Reported: {{ $allReportReasons ?? 'Unknown' }}">
<i class="fas fa-flag mr-2"></i>
<span>{{ $reportCount }} report{{ $reportCount > 1 ? 's' : '' }}: {{ $reportReasons ?? 'Unknown' }}</span>
<span>Reported ({{ $totalReportCount }}): {{ $allReportReasons ?? 'Unknown' }}</span>
</div>
@endif
@if(!empty($failed) && $failed > 0)
@@ -68,8 +68,32 @@
</a>
@endif
@endauth
<x-report-button :release-id="$release->id" variant="button-lg" />
<x-report-button :release-id="$release->id" :reported-count="$totalReportCount ?? 0" variant="button-lg" />
</div>
@if(!empty($originalReportData) && $originalReportData->count() > 0)
<div class="mt-4 rounded-lg border border-orange-200 dark:border-orange-800 bg-orange-50 dark:bg-orange-900/20 p-4">
<h3 class="text-sm font-semibold text-orange-800 dark:text-orange-200 mb-3 flex items-center">
<i class="fas fa-flag mr-2"></i> Original report
</h3>
<div class="space-y-3">
@foreach($originalReportData as $originalReport)
<div class="text-sm text-orange-900 dark:text-orange-100">
<div class="flex flex-wrap items-center gap-2 mb-1">
<span class="inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-orange-100 dark:bg-orange-900 text-orange-800 dark:text-orange-200 border border-orange-200 dark:border-orange-800">
{{ $originalReport->reason_label }}
</span>
<span class="text-xs text-orange-700 dark:text-orange-300">
{{ ucfirst($originalReport->status) }} · Reported {{ $originalReport->created_at->format('M d, Y H:i') }}
</span>
</div>
<div class="whitespace-pre-wrap break-words">
{{ $originalReport->description ?: 'No additional report details were provided.' }}
</div>
</div>
@endforeach
</div>
</div>
@endif
@if(!empty($publicReportResponses) && $publicReportResponses->count() > 0)
<div class="mt-4 rounded-lg border border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-900/20 p-4">
<h3 class="text-sm font-semibold text-blue-800 dark:text-blue-200 mb-3 flex items-center">
@@ -320,10 +320,17 @@ class AdminReleaseReportControllerTest extends TestCase
$browseService = file_get_contents($browseServicePath);
$this->assertStringContainsString('publicReportResponses', $detailsController);
$this->assertStringContainsString('originalReportData', $detailsController);
$this->assertStringContainsString('totalReportCount', $detailsController);
$this->assertStringContainsString("where('response_is_public', true)", $detailsController);
$this->assertStringContainsString('Staff response', $detailsView);
$this->assertStringContainsString('Original report', $detailsView);
$this->assertStringContainsString('total_report_count', $browseService);
$this->assertStringContainsString('latest_report_description', $browseService);
$this->assertStringContainsString('all_report_reasons', $browseService);
$this->assertStringContainsString('report_response_count', $browseService);
$this->assertStringContainsString('response_is_public = 1', $browseService);
$this->assertStringContainsString('Original report:', $browseView);
$this->assertStringContainsString('Staff response available on release details', $browseView);
}
}