From d4ecd7f06df9a246f83e1e02f6f32f556cde911c Mon Sep 17 00:00:00 2001 From: "sas.fajri" Date: Sun, 31 May 2026 18:04:36 +0700 Subject: [PATCH] FHM31052601IBL - populate decrypt cache sebelum semua BIRT/PDF fetch - Ibl_patient_decrypt: tambah fetch_birt_pdf() + pre_cache_and_get_url() - Reporturl.php: auto pre-cache sebelum return URL atau fetch PDF - Rv_patient.php: pre_cache sebelum return URL ke frontend - tgram/Hasil.php: fetch_birt_pdf() via dl_report() - Qr_report_uploader.php: populate/delete cache wrapping download_file() - Ibl_merge_report_gateway.php: populate/delete cache wrapping Go merge service call - send_email.php: populate_birt_cache() + delete_birt_cache() untuk email attachment Co-Authored-By: Claude Sonnet 4.6 --- .../process/resultprintadm-v7/Rv_patient.php | 4 ++ application/controllers/tgram/Hasil.php | 12 ++--- .../controllers/tools/Qr_report_uploader.php | 5 ++ .../libraries/Ibl_merge_report_gateway.php | 11 +++- application/libraries/Ibl_patient_decrypt.php | 32 +++++++++++ application/libraries/Reporturl.php | 16 +++--- scripts/send_email.php | 54 +++++++++++++++++++ 7 files changed, 118 insertions(+), 16 deletions(-) diff --git a/application/controllers/mockup/process/resultprintadm-v7/Rv_patient.php b/application/controllers/mockup/process/resultprintadm-v7/Rv_patient.php index 3d1d02a2..81fb79c4 100644 --- a/application/controllers/mockup/process/resultprintadm-v7/Rv_patient.php +++ b/application/controllers/mockup/process/resultprintadm-v7/Rv_patient.php @@ -790,6 +790,10 @@ private function get_fallback_report($group_name, $type, $ready_print) $url = "/birt/{$mode}?__report=report/onelab/{$folder}/{$rpt_name}.rptdesign&__format=pdf&username={$username}&PID={$order_id}&tm={$tm}"; } + // Populate decrypt cache sebelum frontend buka URL ke BIRT + $this->load->library('ibl_patient_decrypt'); + $this->ibl_patient_decrypt->pre_cache_and_get_url($url); + $this->sys_ok($url); } diff --git a/application/controllers/tgram/Hasil.php b/application/controllers/tgram/Hasil.php index 386ffeea..724a6ace 100644 --- a/application/controllers/tgram/Hasil.php +++ b/application/controllers/tgram/Hasil.php @@ -6,6 +6,7 @@ class Hasil extends MY_Controller { function __construct() { parent::__construct(); + $this->load->library('ibl_patient_decrypt'); } /* WA ------ */ function update_track() { @@ -524,14 +525,13 @@ class Hasil extends MY_Controller } } function dl_report($prm, $name) { - $url = "http://localhost/birt/frameset?" ; - $qry = ""; + $qry = ""; foreach($prm as $k => $v) { - if ($qry != "" ) $qry .= "&"; + if ($qry != "") $qry .= "&"; $qry .= $k . "=" . urlencode($v); - } - $url .= $qry ; - $data = file_get_contents($url); + } + $relative_url = "/birt/frameset?" . $qry; + $data = $this->ibl_patient_decrypt->fetch_birt_pdf($relative_url); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . $name); header('Content-Transfer-Encoding: binary'); diff --git a/application/controllers/tools/Qr_report_uploader.php b/application/controllers/tools/Qr_report_uploader.php index d4170cdf..72bc57b9 100644 --- a/application/controllers/tools/Qr_report_uploader.php +++ b/application/controllers/tools/Qr_report_uploader.php @@ -8,6 +8,7 @@ class Qr_report_uploader extends MY_Controller public function __construct() { parent::__construct(); + $this->load->library('ibl_patient_decrypt'); $this->db_onedev = $this->load->database('onedev', true); $this->db_log = $this->load->database('one_lab_log', true); } @@ -120,7 +121,11 @@ class Qr_report_uploader extends MY_Controller $orderHeaderID = (int)$row['QR_PrintOutT_OrderHeaderID']; $reportUrl = $row['QR_PrintOutReportURL']; + // Populate cache sebelum fetch dari BIRT + $cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderID); $pdfContent = $this->download_file($reportUrl); + $this->ibl_patient_decrypt->delete_cache($cache_id); + if ($pdfContent === false) { return $this->mark_failed($row, $orderHeaderID, '', 'DOWNLOAD_FAILED'); } diff --git a/application/libraries/Ibl_merge_report_gateway.php b/application/libraries/Ibl_merge_report_gateway.php index ed83959f..922c8208 100644 --- a/application/libraries/Ibl_merge_report_gateway.php +++ b/application/libraries/Ibl_merge_report_gateway.php @@ -10,6 +10,7 @@ class Ibl_merge_report_gateway { $this->CI = &get_instance(); $this->db_onedev = $this->CI->load->database('onedev', true); + $this->CI->load->library('ibl_patient_decrypt'); } public function create_merge_request_from_lab_number($labNumber, $creatorUserId, $customName = '') @@ -593,6 +594,9 @@ class Ibl_merge_report_gateway return $this->error('QR_PRINTOUT_EMPTY', 'URL report kosong setelah normalisasi.'); } + // Populate decrypt cache sebelum Go merge service fetch PDF dari BIRT + $cache_id = $this->CI->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId); + $payload = array( 'name' => 'merge-' . (int) $orderHeaderId . '.pdf', 'urls' => $urls, @@ -600,7 +604,12 @@ class Ibl_merge_report_gateway 'T_OrderHeaderID' => (int) $orderHeaderId, ); - return $this->call_merge_service($payload); + $result = $this->call_merge_service($payload); + + // Hapus cache setelah merge service selesai + $this->CI->ibl_patient_decrypt->delete_cache($cache_id); + + return $result; } protected function call_merge_service(array $payload) diff --git a/application/libraries/Ibl_patient_decrypt.php b/application/libraries/Ibl_patient_decrypt.php index a74475e6..086bc7f4 100644 --- a/application/libraries/Ibl_patient_decrypt.php +++ b/application/libraries/Ibl_patient_decrypt.php @@ -85,6 +85,38 @@ class Ibl_patient_decrypt $this->db->query("DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE"); } + // Fetch PDF dari BIRT dengan auto decrypt cache + // Ganti semua file_get_contents($birt_url) dengan ini + public function fetch_birt_pdf($birt_relative_url) + { + // Parse PID dari URL query string + parse_str(parse_url($birt_relative_url, PHP_URL_QUERY) ?? '', $params); + $order_id = intval($params['PID'] ?? 0); + + $cache_id = $order_id ? $this->populate_cache_by_order($order_id) : null; + + // Build full internal URL ke BIRT server + $full_url = 'http://localhost:8080' . $birt_relative_url; + $context = stream_context_create(['http' => ['timeout' => 120]]); + $pdf = @file_get_contents($full_url, false, $context); + + $this->delete_cache($cache_id); + + return $pdf; + } + + // Populate cache lalu return URL (untuk controller yang return URL ke frontend) + // Cache hidup 5 menit — cukup untuk browser buka BIRT + public function pre_cache_and_get_url($birt_relative_url) + { + parse_str(parse_url($birt_relative_url, PHP_URL_QUERY) ?? '', $params); + $order_id = intval($params['PID'] ?? 0); + if ($order_id) { + $this->populate_cache_by_order($order_id); + } + return $birt_relative_url; + } + private function _insert_cache($order_id, $patient_id, $name, $dob, $hp, $email, $address) { $this->db->query( diff --git a/application/libraries/Reporturl.php b/application/libraries/Reporturl.php index 88459e66..b20f5019 100644 --- a/application/libraries/Reporturl.php +++ b/application/libraries/Reporturl.php @@ -55,20 +55,18 @@ class Reporturl $final_url = str_replace($param_key, $replacement_value, $final_url); } + // Populate decrypt cache sebelum return URL atau fetch PDF + $CI->load->library('ibl_patient_decrypt'); + $CI->ibl_patient_decrypt->pre_cache_and_get_url($final_url); + if($show == 'N'){ return array(true, $final_url); } else{ - $final_url = 'http'.($_SERVER['HTTPS'] == 'on' ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$final_url; - - $response = file_get_contents($final_url); + $pdf = $CI->ibl_patient_decrypt->fetch_birt_pdf($final_url); header("Content-type: application/pdf"); - header( - 'Content-Disposition: inline; filename="' . - $output_file_name . - '"' - ); - echo ($response); + header('Content-Disposition: inline; filename="' . ($output_file_name ?? 'report.pdf') . '"'); + echo $pdf; } } diff --git a/scripts/send_email.php b/scripts/send_email.php index c102e45d..6e2cde07 100755 --- a/scripts/send_email.php +++ b/scripts/send_email.php @@ -60,6 +60,58 @@ function download_pdf(string $url) return $data; } +// Load ibl_encryptor untuk decrypt PII sebelum fetch PDF dari BIRT +define('BASEPATH', true); +$_env_file = __DIR__ . '/../.env'; +if (file_exists($_env_file)) { + foreach (file($_env_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $_l) { + if (strpos(trim($_l), '#') === 0) continue; + [$_k, $_v] = array_map('trim', explode('=', $_l, 2)); + if ($_k !== '') $_ENV[$_k] = $_v; + } +} +require __DIR__ . '/../application/libraries/Ibl_encryptor.php'; +$_enc = new Ibl_encryptor(); + +// Populate patient_print_cache sebelum fetch PDF dari BIRT +function populate_birt_cache(PDO $pdo, $enc, string $birt_url): ?int +{ + parse_str(parse_url($birt_url, PHP_URL_QUERY) ?? '', $params); + $order_id = intval($params['PID'] ?? 0); + if (!$order_id) return null; + + $patient = $pdo->query( + "SELECT M_PatientID, M_PatientName_enc, M_PatientDOB_enc, + M_PatientHP_enc, M_PatientEmail_enc, M_PatientDOB + FROM t_orderheader + JOIN m_patient ON T_OrderHeaderM_PatientID = M_PatientID + WHERE T_OrderHeaderID = {$order_id} LIMIT 1" + )->fetch(PDO::FETCH_ASSOC); + if (!$patient) return null; + + $addr = $pdo->query( + "SELECT M_PatientAddressDescription_enc FROM m_patientaddress + WHERE M_PatientAddressM_PatientID = {$patient['M_PatientID']} + AND M_PatientAddressIsActive = 'Y' AND M_PatientAddressNote = 'Utama' LIMIT 1" + )->fetch(PDO::FETCH_ASSOC); + + $name = $enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? ''; + $dob = $enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now')); + $hp = $enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? ''; + $email = $enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? ''; + $address = $enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? ''; + + $pdo->exec("DELETE FROM patient_print_cache WHERE ppc_order_id = {$order_id} OR ppc_created < NOW() - INTERVAL 5 MINUTE"); + $stmt = $pdo->prepare("INSERT INTO patient_print_cache (ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address) VALUES (?,?,?,?,?,?,?)"); + $stmt->execute([$order_id, $patient['M_PatientID'], $name, $dob, $hp, $email, $address]); + return (int)$pdo->lastInsertId(); +} + +function delete_birt_cache(PDO $pdo, ?int $cache_id): void +{ + if ($cache_id) $pdo->exec("DELETE FROM patient_print_cache WHERE ppc_id = {$cache_id}"); +} + function encrypt_pdf(string $input_path, string $password) { $output_path = $input_path . '_enc.pdf'; @@ -308,7 +360,9 @@ foreach ($rows as $row) { log_msg(" Downloading attachment " . ($idx + 1) . " [{$result}]: {$url}"); + $cache_id = populate_birt_cache($pdo, $GLOBALS['_enc'], $url); $pdf = download_pdf($url); + delete_birt_cache($pdo, $cache_id); if ($pdf === false) { log_msg(" Download failed, skipping"); continue;