fix(perf): resolve F-11 — cap PDF exports to 90-day date range to prevent memory exhaustion

All three PDF exports (rainfall, water level, siren) now default to
last 90 days. Accepts optional ?from=&to= query params, capped at
90-day max range. Shared applyDateRange helper in NotificationController.
This commit is contained in:
root
2026-06-03 01:03:31 +08:00
parent d6193f0e5b
commit 398e17f291
2 changed files with 63 additions and 31 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
// Add This For Import DOMPDF Library // Add This For Import DOMPDF Library
use Barryvdh\DomPDF\Facade\Pdf; use Barryvdh\DomPDF\Facade\Pdf;
@@ -88,34 +89,54 @@ class NotificationController extends Controller
} }
//Function Export PDF for Rainfall History //Function Export PDF for Rainfall History
public function exportHistoryRfPDF() public function exportHistoryRfPDF(Request $request)
{ {
$rfHistory = DB::table('station') $query = DB::table('station')
->join('notification','station.stationid','notification.stationid') ->join('notification', 'station.stationid', 'notification.stationid')
->select('station.*','notification.*') ->select('station.*', 'notification.*')
->where('notification.stationtype',1) ->where('notification.stationtype', 1);
->orderByDesc('notification.timestamp')->get();
$pdf = Pdf::loadView('pdf.rfhistory',compact('rfHistory')) $this->applyDateRange($query, $request, 'notification.timestamp');
->setPaper('a4','portrait');
$rfHistory = $query->orderByDesc('notification.timestamp')->get();
$pdf = Pdf::loadView('pdf.rfhistory', compact('rfHistory'))
->setPaper('a4', 'portrait');
return $pdf->download('Rainfall Alarm History.pdf'); return $pdf->download('Rainfall Alarm History.pdf');
} }
// Function Export PDF for Water Level History public function exportHistoryWlPDF(Request $request)
public function exportHistoryWlPDF()
{ {
$wlHistory = DB::table('station') $query = DB::table('station')
->join('notification','station.stationid','notification.stationid') ->join('notification', 'station.stationid', 'notification.stationid')
->select('station.*','notification.*') ->select('station.*', 'notification.*')
->where('notification.stationtype',2) ->where('notification.stationtype', 2);
->orderByDesc('notification.timestamp')->get();
$pdf = Pdf::loadView('pdf.wlhistory',compact('wlHistory')) $this->applyDateRange($query, $request, 'notification.timestamp');
->setPaper('a4','portrait');
$wlHistory = $query->orderByDesc('notification.timestamp')->get();
$pdf = Pdf::loadView('pdf.wlhistory', compact('wlHistory'))
->setPaper('a4', 'portrait');
return $pdf->download('Water Level Alarm History.pdf'); return $pdf->download('Water Level Alarm History.pdf');
}
private function applyDateRange($query, Request $request, string $column): void
{
$maxDays = 90;
if ($request->filled('from') && $request->filled('to')) {
$from = Carbon::parse($request->input('from'))->startOfDay();
$to = Carbon::parse($request->input('to'))->endOfDay();
$diff = $from->diffInDays($to);
if ($diff > $maxDays) {
$from = $to->copy()->subDays($maxDays);
}
$query->whereBetween($column, [$from, $to]);
} else {
$query->where($column, '>=', now()->subDays($maxDays));
}
} }
} }

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf; use Barryvdh\DomPDF\Facade\Pdf;
use Carbon\Carbon;
class SirenController extends Controller class SirenController extends Controller
@@ -54,26 +55,36 @@ class SirenController extends Controller
} }
// Function for download Siren History to PDF // Function for download Siren History to PDF
public function exportHistorySirenPDF() public function exportHistorySirenPDF(Request $request)
{ {
$sirenHistory = DB::table('station') $maxDays = 90;
->join('siren','station.stationid','siren.stationid') $query = DB::table('station')
->select('station.*','siren.*') ->join('siren', 'station.stationid', 'siren.stationid')
->select('station.*', 'siren.*')
->where('siren.level', '!=', 'N') ->where('siren.level', '!=', 'N')
->where('siren.level', '!=', '') ->where('siren.level', '!=', '')
->where('station.siren',1) ->where('station.siren', 1);
->orderByDesc('siren.active_time')
->get();
$pdf = Pdf::loadView('pdf.sirenhistory',compact('sirenHistory')) if ($request->filled('from') && $request->filled('to')) {
->setPaper('a4','portrait'); $from = Carbon::parse($request->input('from'))->startOfDay();
$to = Carbon::parse($request->input('to'))->endOfDay();
if ($from->diffInDays($to) > $maxDays) {
$from = $to->copy()->subDays($maxDays);
}
$query->whereBetween('siren.active_time', [$from, $to]);
} else {
$query->where('siren.active_time', '>=', now()->subDays($maxDays));
}
$sirenHistory = $query->orderByDesc('siren.active_time')->get();
$pdf = Pdf::loadView('pdf.sirenhistory', compact('sirenHistory'))
->setPaper('a4', 'portrait');
return $pdf->download( return $pdf->download(
'Station_Siren_History.pdf', 'Station_Siren_History.pdf',
[], [],
['Content-Type' => 'application/pdf'] ['Content-Type' => 'application/pdf']
); );
} }
} }