FHM31052601IBL - FPDF controllers: decrypt PII via Ibl_patient_decrypt library
- Ibl_patient_decrypt: helper populate/delete patient_print_cache + decrypt_row - Inform_consent, Medical_checkup_report: decrypt langsung dari _enc (direct SQL) - Kartu_kontrol, Rpt_t_002, Rpt_t_002_eng: populate cache sebelum call SP, delete cache setelah SP selesai Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ class Inform_consent extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -68,16 +69,12 @@ class Inform_consent extends MY_Controller
|
||||
DATE_FORMAT(h.T_OrderHeaderDate, '%d-%m-%Y') as tanggal,
|
||||
DATE_FORMAT(h.T_OrderHeaderDate, '%H:%i') as jam,
|
||||
p.M_PatientID,
|
||||
p.M_PatientNoReg,
|
||||
CONCAT(
|
||||
IF(TRIM(IFNULL(t.M_TitleName,''))='', '', CONCAT(TRIM(IFNULL(t.M_TitleName,'')), '. ')),
|
||||
TRIM(IFNULL(p.M_PatientPrefix,'')), ' ', TRIM(IFNULL(p.M_PatientName,'')), ' ', TRIM(IFNULL(p.M_PatientSuffix,''))
|
||||
) AS patient_name,
|
||||
p.M_PatientNoReg, p.M_PatientPrefix, p.M_PatientSuffix,
|
||||
t.M_TitleName,
|
||||
s.M_SexCode,
|
||||
IFNULL(p.M_PatientPOB,'') as pob,
|
||||
DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y') as dob,
|
||||
IFNULL(pa.M_PatientAddressDescription,'') as alamat,
|
||||
IFNULL(p.M_PatientHP,'') as phone,
|
||||
p.M_PatientName_enc, p.M_PatientDOB_enc, p.M_PatientPOB_enc,
|
||||
p.M_PatientDOB, p.M_PatientHP_enc,
|
||||
pa.M_PatientAddressDescription_enc,
|
||||
IFNULL(c.M_CompanyName,'') as company_name,
|
||||
(
|
||||
SELECT ps.Patient_SignatureUrl
|
||||
@@ -98,10 +95,23 @@ class Inform_consent extends MY_Controller
|
||||
WHERE h.T_OrderHeaderID = ?
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$orderHeaderId]);
|
||||
if (!$qry) {
|
||||
return false;
|
||||
}
|
||||
return $qry->row_array();
|
||||
if (!$qry) return false;
|
||||
$row = $qry->row_array();
|
||||
if (!$row) return false;
|
||||
|
||||
$row = $this->ibl_patient_decrypt->decrypt_row($row);
|
||||
$title = trim($row['M_TitleName'] ?? '');
|
||||
$row['patient_name'] = trim(
|
||||
($title ? $title . '. ' : '') .
|
||||
trim($row['M_PatientPrefix'] ?? '') . ' ' .
|
||||
trim($row['M_PatientName'] ?? '') . ' ' .
|
||||
trim($row['M_PatientSuffix'] ?? '')
|
||||
);
|
||||
$row['dob'] = $row['M_PatientDOB'];
|
||||
$row['pob'] = $row['M_PatientPOB'] ?? '';
|
||||
$row['phone'] = $row['M_PatientHP'] ?? '';
|
||||
$row['alamat'] = $row['M_PatientAddressDescription'] ?? '';
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function get_consent_content()
|
||||
|
||||
@@ -9,6 +9,7 @@ class Kartu_kontrol extends MY_Controller
|
||||
{
|
||||
parent::__construct();
|
||||
$this->db_lab = $this->load->database('onedev', true);
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -53,10 +54,15 @@ class Kartu_kontrol extends MY_Controller
|
||||
|
||||
private function get_data($pid)
|
||||
{
|
||||
// Populate decrypt cache sebelum call SP
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($pid);
|
||||
|
||||
$qry = $this->db_lab->query("CALL sp_rpt_fo_001(?, 'fpdf')", [$pid]);
|
||||
if (!$qry) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Hapus cache setelah SP selesai
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
|
||||
if (!$qry) return [];
|
||||
return $qry->result_array();
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ class Medical_checkup_report extends MY_Controller
|
||||
parent::__construct();
|
||||
$this->db_onedev = $this->load->database('onedev', true);
|
||||
$this->load->library('Generateqrreport');
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -221,18 +222,10 @@ class Medical_checkup_report extends MY_Controller
|
||||
IFNULL(NULLIF(TRIM(IFNULL(p.M_PatientDivisi, '')), ''), '-')
|
||||
) AS departemen_npk,
|
||||
IFNULL(s.M_SexName, '-') AS jenis_kelamin,
|
||||
CONCAT(
|
||||
IF(TRIM(IFNULL(t.M_TitleName, '')) = '', '', CONCAT(TRIM(t.M_TitleName), '. ')),
|
||||
TRIM(IFNULL(p.M_PatientPrefix, '')), ' ',
|
||||
TRIM(IFNULL(p.M_PatientName, '')), ' ',
|
||||
TRIM(IFNULL(p.M_PatientSuffix, ''))
|
||||
) AS nama_pasien,
|
||||
CONCAT(
|
||||
IFNULL(DATE_FORMAT(p.M_PatientDOB, '%d-%m-%Y'), '-'),
|
||||
' / ',
|
||||
IFNULL(NULLIF(TRIM(IFNULL(h.T_OrderHeaderM_PatientAge, '')), ''), '-')
|
||||
) AS tgl_lahir_usia,
|
||||
IFNULL(pa.M_PatientAddressDescription, '-') AS alamat_pasien
|
||||
p.M_PatientPrefix, p.M_PatientSuffix, t.M_TitleName,
|
||||
p.M_PatientName_enc, p.M_PatientDOB_enc,
|
||||
p.M_PatientDOB, h.T_OrderHeaderM_PatientAge,
|
||||
pa.M_PatientAddressDescription_enc
|
||||
FROM t_orderheader h
|
||||
JOIN m_patient p ON p.M_PatientID = h.T_OrderHeaderM_PatientID
|
||||
LEFT JOIN m_title t ON t.M_TitleID = p.M_PatientM_TitleID
|
||||
@@ -244,10 +237,22 @@ class Medical_checkup_report extends MY_Controller
|
||||
WHERE h.T_OrderHeaderID = ?
|
||||
LIMIT 1";
|
||||
$qry = $this->db_onedev->query($sql, [$orderHeaderId]);
|
||||
if (!$qry) {
|
||||
return false;
|
||||
}
|
||||
return $qry->row_array();
|
||||
if (!$qry) return false;
|
||||
$row = $qry->row_array();
|
||||
if (!$row) return false;
|
||||
|
||||
$row = $this->ibl_patient_decrypt->decrypt_row($row);
|
||||
$title = trim($row['M_TitleName'] ?? '');
|
||||
$row['nama_pasien'] = trim(
|
||||
($title ? $title . '. ' : '') .
|
||||
trim($row['M_PatientPrefix'] ?? '') . ' ' .
|
||||
trim($row['M_PatientName'] ?? '') . ' ' .
|
||||
trim($row['M_PatientSuffix'] ?? '')
|
||||
);
|
||||
$row['tgl_lahir_usia'] = trim($row['M_PatientDOB'] ?? '-') . ' / ' .
|
||||
trim($row['T_OrderHeaderM_PatientAge'] ?? '-');
|
||||
$row['alamat_pasien'] = $row['M_PatientAddressDescription'] ?? '-';
|
||||
return $row;
|
||||
}
|
||||
|
||||
private function get_result_rows($orderHeaderId)
|
||||
|
||||
@@ -4,6 +4,7 @@ class Rpt_t_002 extends MY_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -34,8 +35,10 @@ class Rpt_t_002 extends MY_Controller
|
||||
if ($an === null) {
|
||||
$an = '';
|
||||
}
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$lastQry = $this->db->last_query();
|
||||
|
||||
if (!$qry) {
|
||||
@@ -75,8 +78,10 @@ class Rpt_t_002 extends MY_Controller
|
||||
if ($an === null) {
|
||||
$an = '';
|
||||
}
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$lastQry = $this->db->last_query();
|
||||
if (!$qry) {
|
||||
$this->sys_error_db([
|
||||
|
||||
@@ -4,6 +4,7 @@ class Rpt_t_002_eng extends MY_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->library('ibl_patient_decrypt');
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -35,8 +36,10 @@ class Rpt_t_002_eng extends MY_Controller
|
||||
$an = '';
|
||||
}
|
||||
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002_eng(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$this->ibl_patient_decrypt->delete_cache($cache_id);
|
||||
$lastQry = $this->db->last_query();
|
||||
|
||||
if (!$qry) {
|
||||
@@ -77,6 +80,7 @@ class Rpt_t_002_eng extends MY_Controller
|
||||
$an = '';
|
||||
}
|
||||
|
||||
$cache_id = $this->ibl_patient_decrypt->populate_cache_by_order($orderHeaderId);
|
||||
$sql = 'CALL sp_rpt_t_002_eng(?, ?, ?)';
|
||||
$qry = $this->db->query($sql, [$orderHeaderId, $an, $username]);
|
||||
$lastQry = $this->db->last_query();
|
||||
|
||||
100
application/libraries/Ibl_patient_decrypt.php
Normal file
100
application/libraries/Ibl_patient_decrypt.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?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");
|
||||
}
|
||||
|
||||
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]
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user