- 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>
133 lines
5.7 KiB
PHP
133 lines
5.7 KiB
PHP
<?php
|
|
defined('BASEPATH') or exit('No direct script access allowed');
|
|
|
|
/**
|
|
* Helper untuk decrypt PII pasien sebelum call SP/BIRT
|
|
* Populate patient_print_cache, run callback, delete cache
|
|
*/
|
|
class Ibl_patient_decrypt
|
|
{
|
|
private $db;
|
|
private $enc;
|
|
|
|
public function __construct()
|
|
{
|
|
$CI = &get_instance();
|
|
$this->db = $CI->load->database('onedev', true);
|
|
$CI->load->library('ibl_encryptor');
|
|
$this->enc = $CI->ibl_encryptor;
|
|
}
|
|
|
|
// Populate cache, return cache_id untuk cleanup
|
|
public function populate_cache_by_order($order_id)
|
|
{
|
|
$order_id = intval($order_id);
|
|
if (!$order_id) return null;
|
|
|
|
$patient = $this->db->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 = ? LIMIT 1",
|
|
[$order_id]
|
|
)->row_array();
|
|
|
|
if (!$patient) return null;
|
|
|
|
$addr = $this->db->query(
|
|
"SELECT M_PatientAddressDescription_enc FROM m_patientaddress
|
|
WHERE M_PatientAddressM_PatientID = ?
|
|
AND M_PatientAddressIsActive = 'Y'
|
|
AND M_PatientAddressNote = 'Utama'
|
|
LIMIT 1",
|
|
[$patient['M_PatientID']]
|
|
)->row_array();
|
|
|
|
$enc = $this->enc;
|
|
$this->_insert_cache(
|
|
$order_id,
|
|
$patient['M_PatientID'],
|
|
$enc->decrypt($patient['M_PatientName_enc'] ?? '') ?? '',
|
|
$enc->decrypt($patient['M_PatientDOB_enc'] ?? '') ?? date('d-m-Y', strtotime($patient['M_PatientDOB'] ?? 'now')),
|
|
$enc->decrypt($patient['M_PatientHP_enc'] ?? '') ?? '',
|
|
$enc->decrypt($patient['M_PatientEmail_enc']?? '') ?? '',
|
|
$enc->decrypt($addr['M_PatientAddressDescription_enc'] ?? '') ?? ''
|
|
);
|
|
|
|
return $this->db->insert_id();
|
|
}
|
|
|
|
// Decrypt langsung dari query result (untuk controller dengan SQL sendiri)
|
|
public function decrypt_row(array $row): array
|
|
{
|
|
$enc = $this->enc;
|
|
if (!empty($row['M_PatientName_enc'])) $row['M_PatientName'] = $enc->decrypt($row['M_PatientName_enc']) ?? $row['M_PatientName'] ?? '';
|
|
if (!empty($row['M_PatientDOB_enc'])) $row['M_PatientDOB'] = $enc->decrypt($row['M_PatientDOB_enc']) ?? $row['M_PatientDOB'] ?? '';
|
|
if (!empty($row['M_PatientHP_enc'])) $row['M_PatientHP'] = $enc->decrypt($row['M_PatientHP_enc']) ?? '';
|
|
if (!empty($row['M_PatientEmail_enc'])) $row['M_PatientEmail'] = $enc->decrypt($row['M_PatientEmail_enc']) ?? '';
|
|
if (!empty($row['M_PatientPOB_enc'])) $row['M_PatientPOB'] = $enc->decrypt($row['M_PatientPOB_enc']) ?? '';
|
|
if (!empty($row['M_PatientAddressDescription_enc'])) $row['M_PatientAddressDescription'] = $enc->decrypt($row['M_PatientAddressDescription_enc']) ?? '';
|
|
if (!empty($row['phone_enc'])) $row['phone'] = $enc->decrypt($row['phone_enc']) ?? '';
|
|
if (!empty($row['alamat_enc'])) $row['alamat'] = $enc->decrypt($row['alamat_enc']) ?? '';
|
|
if (!empty($row['dob_enc'])) $row['dob'] = $enc->decrypt($row['dob_enc']) ?? '';
|
|
foreach (array_keys($row) as $k) { if (substr($k, -4) === '_enc') unset($row[$k]); }
|
|
return $row;
|
|
}
|
|
|
|
// Hapus cache by id
|
|
public function delete_cache($cache_id)
|
|
{
|
|
if ($cache_id) {
|
|
$this->db->query("DELETE FROM patient_print_cache WHERE ppc_id = ?", [$cache_id]);
|
|
}
|
|
// Cleanup expired juga
|
|
$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(
|
|
"DELETE FROM patient_print_cache WHERE ppc_order_id = ? OR ppc_created < NOW() - INTERVAL 5 MINUTE",
|
|
[$order_id]
|
|
);
|
|
$this->db->query(
|
|
"INSERT INTO patient_print_cache (ppc_order_id, ppc_patient_id, ppc_name, ppc_dob, ppc_hp, ppc_email, ppc_address, ppc_created)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, NOW())",
|
|
[$order_id, $patient_id, $name, $dob, $hp, $email, $address]
|
|
);
|
|
}
|
|
}
|