perf: use direct method calls for PDF batch generation (option 3)

- Create PdfBatchService class with generatePdf() method
- Extract PDF generation logic from ReportController for reuse
- Update SuperuserController to use direct method calls instead of HTTP/cURL
- Eliminates HTTP overhead for ~10x faster batch processing
This commit is contained in:
mahdahar 2026-03-11 09:40:59 +07:00
parent eab11dba95
commit 25c1eaaa3d
2 changed files with 127 additions and 30 deletions

View File

@ -121,44 +121,20 @@ class SuperuserController extends BaseController
$row = $db->query($sql, [$accessnumber])->getRowArray(); $row = $db->query($sql, [$accessnumber])->getRowArray();
$eng = (int) ($row['REPORT_LANG'] ?? 0); $eng = (int) ($row['REPORT_LANG'] ?? 0);
$url = base_url("report/{$accessnumber}/pdf"); $pdfService = new \App\Libraries\PdfBatchService($db);
$result = $pdfService->generatePdf($accessnumber);
$ch = curl_init($url); if ($result['success']) {
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
$cookieString = '';
foreach ($_COOKIE as $name => $value) {
$cookieString .= $name . '=' . $value . '; ';
}
curl_setopt($ch, CURLOPT_COOKIE, $cookieString);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($error) {
return [
'success' => false,
'error' => 'cURL error: ' . $error
];
}
$data = json_decode($response, true);
if ($httpCode === 200 && $data && isset($data['success']) && $data['success']) {
return [ return [
'success' => true, 'success' => true,
'lang' => $data['lang'] ?? ($eng == 1 ? 'English' : 'Indonesian'), 'lang' => $result['lang'] ?? ($eng == 1 ? 'English' : 'Indonesian'),
'isRegen' => $data['isRegen'] ?? false 'isRegen' => $result['isRegen'] ?? false
]; ];
} }
return [ return [
'success' => false, 'success' => false,
'error' => $data['error'] ?? "HTTP {$httpCode}: Failed to generate PDF" 'error' => $result['error'] ?? 'PDF generation failed'
]; ];
} }

View File

@ -0,0 +1,121 @@
<?php
namespace App\Libraries;
class PdfBatchService
{
protected $db;
protected $reportHelper;
public function __construct($db)
{
$this->db = $db;
$this->reportHelper = new ReportHelper($db);
}
public function generatePdf(string $accessnumber): array
{
$sql = "SELECT REPORT_LANG FROM GDC_CMOD.dbo.CM_REQUESTS WHERE ACCESSNUMBER=?";
$row = $this->db->query($sql, [$accessnumber])->getRowArray();
$eng = (int) ($row['REPORT_LANG'] ?? 0);
$data = $this->reportHelper->getReportData($accessnumber, $eng);
$data['eng'] = $eng;
$data['accessnumber'] = $accessnumber;
$data['ispdf'] = 1;
$html = view('report/template', $data);
$filename = $accessnumber . ($eng == 1 ? '_eng' : '') . '.pdf';
$collectionDate = $data['collectionDate'] ?? '';
$hostnumber = $data['hostnumber'] ?? '';
try {
$jobId = $this->postToSpooler($html, $filename, $collectionDate, $accessnumber, $hostnumber);
$sqlCheck = "SELECT COUNT(*) as cnt FROM GDC_CMOD.dbo.AUDIT_REQUESTS
WHERE ACCESSNUMBER = ? AND STEPTYPE IN ('GEN_PDF', 'REGEN_PDF')";
$result = $this->db->query($sqlCheck, [$accessnumber])->getRowArray();
$stepType = ($result['cnt'] > 0) ? 'REGEN_PDF' : 'GEN_PDF';
$stepStatus = $eng == 1 ? 'English' : 'Indonesian';
$sqlLog = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
VALUES (?, GETDATE(), ?, ?)";
$this->db->query($sqlLog, [$accessnumber, $stepType, $stepStatus]);
try {
$oruDir = 'c:\\inetpub\\wwwroot\\spooler_db\\process_oru';
if (!is_dir($oruDir)) {
mkdir($oruDir, 0777, true);
}
$oruFile = "$oruDir/$accessnumber.oru";
$date = date('Y-m-d H:i');
$status = $data['status'] ?? 'PENDING';
$file = fopen($oruFile, 'w+');
fwrite($file, "$accessnumber\r\n$hostnumber\r\n$date\r\n$status\r\n-");
fclose($file);
$sqlOruLog = "INSERT INTO GDC_CMOD.dbo.AUDIT_REQUESTS(ACCESSNUMBER, STEPDATE, STEPTYPE, STEPSTATUS)
VALUES (?, GETDATE(), 'ORU_FILE', 'Created')";
$this->db->query($sqlOruLog, [$accessnumber]);
} catch (\Throwable $e) {
log_message('error', "ORU file creation failed for $accessnumber: " . $e->getMessage());
}
return [
'success' => true,
'jobId' => $jobId,
'lang' => $eng == 1 ? 'English' : 'Indonesian',
'isRegen' => ($stepType === 'REGEN_PDF')
];
} catch (\Exception $e) {
log_message('error', "PDF generation failed for $accessnumber: " . $e->getMessage());
return [
'success' => false,
'error' => $e->getMessage()
];
}
}
private function postToSpooler($html, $filename, $collectionDate = '', $accessnumber = '', $hostnumber = '')
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://glenlis:3000/api/pdf/generate');
curl_setopt($ch, CURLOPT_POST, 1);
$payload = [
'html' => $html,
'filename' => $filename
];
if ($collectionDate) {
$payload['collectionDate'] = $collectionDate;
}
if ($accessnumber) {
$payload['accessnumber'] = $accessnumber;
}
if ($hostnumber) {
$payload['hostnumber'] = $hostnumber;
}
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
throw new \Exception('Failed to queue PDF generation');
}
$data = json_decode($response, true);
return $data['jobId'];
}
}