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 <noreply@anthropic.com>
This commit is contained in:
@@ -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}";
|
$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);
|
$this->sys_ok($url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ class Hasil extends MY_Controller
|
|||||||
{
|
{
|
||||||
function __construct() {
|
function __construct() {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
$this->load->library('ibl_patient_decrypt');
|
||||||
}
|
}
|
||||||
/* WA ------ */
|
/* WA ------ */
|
||||||
function update_track() {
|
function update_track() {
|
||||||
@@ -524,14 +525,13 @@ class Hasil extends MY_Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
function dl_report($prm, $name) {
|
function dl_report($prm, $name) {
|
||||||
$url = "http://localhost/birt/frameset?" ;
|
$qry = "";
|
||||||
$qry = "";
|
|
||||||
foreach($prm as $k => $v) {
|
foreach($prm as $k => $v) {
|
||||||
if ($qry != "" ) $qry .= "&";
|
if ($qry != "") $qry .= "&";
|
||||||
$qry .= $k . "=" . urlencode($v);
|
$qry .= $k . "=" . urlencode($v);
|
||||||
}
|
}
|
||||||
$url .= $qry ;
|
$relative_url = "/birt/frameset?" . $qry;
|
||||||
$data = file_get_contents($url);
|
$data = $this->ibl_patient_decrypt->fetch_birt_pdf($relative_url);
|
||||||
header('Content-Type: application/octet-stream');
|
header('Content-Type: application/octet-stream');
|
||||||
header('Content-Disposition: attachment; filename=' . $name);
|
header('Content-Disposition: attachment; filename=' . $name);
|
||||||
header('Content-Transfer-Encoding: binary');
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ class Qr_report_uploader extends MY_Controller
|
|||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
$this->load->library('ibl_patient_decrypt');
|
||||||
$this->db_onedev = $this->load->database('onedev', true);
|
$this->db_onedev = $this->load->database('onedev', true);
|
||||||
$this->db_log = $this->load->database('one_lab_log', 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'];
|
$orderHeaderID = (int)$row['QR_PrintOutT_OrderHeaderID'];
|
||||||
$reportUrl = $row['QR_PrintOutReportURL'];
|
$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);
|
$pdfContent = $this->download_file($reportUrl);
|
||||||
|
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||||
|
|
||||||
if ($pdfContent === false) {
|
if ($pdfContent === false) {
|
||||||
return $this->mark_failed($row, $orderHeaderID, '', 'DOWNLOAD_FAILED');
|
return $this->mark_failed($row, $orderHeaderID, '', 'DOWNLOAD_FAILED');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class Ibl_merge_report_gateway
|
|||||||
{
|
{
|
||||||
$this->CI = &get_instance();
|
$this->CI = &get_instance();
|
||||||
$this->db_onedev = $this->CI->load->database('onedev', true);
|
$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 = '')
|
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.');
|
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(
|
$payload = array(
|
||||||
'name' => 'merge-' . (int) $orderHeaderId . '.pdf',
|
'name' => 'merge-' . (int) $orderHeaderId . '.pdf',
|
||||||
'urls' => $urls,
|
'urls' => $urls,
|
||||||
@@ -600,7 +604,12 @@ class Ibl_merge_report_gateway
|
|||||||
'T_OrderHeaderID' => (int) $orderHeaderId,
|
'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)
|
protected function call_merge_service(array $payload)
|
||||||
|
|||||||
@@ -85,6 +85,38 @@ class Ibl_patient_decrypt
|
|||||||
$this->db->query("DELETE FROM patient_print_cache WHERE ppc_created < NOW() - INTERVAL 5 MINUTE");
|
$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)
|
private function _insert_cache($order_id, $patient_id, $name, $dob, $hp, $email, $address)
|
||||||
{
|
{
|
||||||
$this->db->query(
|
$this->db->query(
|
||||||
|
|||||||
@@ -55,20 +55,18 @@ class Reporturl
|
|||||||
$final_url = str_replace($param_key, $replacement_value, $final_url);
|
$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'){
|
if($show == 'N'){
|
||||||
return array(true, $final_url);
|
return array(true, $final_url);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
$final_url = 'http'.($_SERVER['HTTPS'] == 'on' ? 's' : '').'://'.$_SERVER['HTTP_HOST'].$final_url;
|
$pdf = $CI->ibl_patient_decrypt->fetch_birt_pdf($final_url);
|
||||||
|
|
||||||
$response = file_get_contents($final_url);
|
|
||||||
header("Content-type: application/pdf");
|
header("Content-type: application/pdf");
|
||||||
header(
|
header('Content-Disposition: inline; filename="' . ($output_file_name ?? 'report.pdf') . '"');
|
||||||
'Content-Disposition: inline; filename="' .
|
echo $pdf;
|
||||||
$output_file_name .
|
|
||||||
'"'
|
|
||||||
);
|
|
||||||
echo ($response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,58 @@ function download_pdf(string $url)
|
|||||||
return $data;
|
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)
|
function encrypt_pdf(string $input_path, string $password)
|
||||||
{
|
{
|
||||||
$output_path = $input_path . '_enc.pdf';
|
$output_path = $input_path . '_enc.pdf';
|
||||||
@@ -308,7 +360,9 @@ foreach ($rows as $row) {
|
|||||||
|
|
||||||
log_msg(" Downloading attachment " . ($idx + 1) . " [{$result}]: {$url}");
|
log_msg(" Downloading attachment " . ($idx + 1) . " [{$result}]: {$url}");
|
||||||
|
|
||||||
|
$cache_id = populate_birt_cache($pdo, $GLOBALS['_enc'], $url);
|
||||||
$pdf = download_pdf($url);
|
$pdf = download_pdf($url);
|
||||||
|
delete_birt_cache($pdo, $cache_id);
|
||||||
if ($pdf === false) {
|
if ($pdf === false) {
|
||||||
log_msg(" Download failed, skipping");
|
log_msg(" Download failed, skipping");
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user