You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
370 lines
13 KiB
370 lines
13 KiB
<?php |
|
|
|
/** |
|
* Patient Portal |
|
* |
|
* @package OpenEMR |
|
* @link http://www.open-emr.org |
|
* @author Jerry Padgett <sjpadgett@gmail.com> |
|
* @copyright Copyright (c) 2016-2019 Jerry Padgett <sjpadgett@gmail.com> |
|
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3 |
|
*/ |
|
|
|
require_once(dirname(__FILE__) . '/../../interface/globals.php'); |
|
|
|
use OpenEMR\Common\Crypto\CryptoGen; |
|
use OpenEMR\Common\Logging\EventAuditLogger; |
|
|
|
class ApplicationTable |
|
{ |
|
public function __construct() |
|
{ |
|
} |
|
|
|
/** |
|
* Function zQuery |
|
* All DB Transactions take place |
|
* |
|
* @param String $sql |
|
* SQL Query Statment |
|
* @param array $params |
|
* SQL Parameters |
|
* @param boolean $log |
|
* Logging True / False |
|
* @param boolean $error |
|
* Error Display True / False |
|
* @return type |
|
*/ |
|
public function zQuery($sql, $params = '', $log = false, $error = true) |
|
{ |
|
$return = false; |
|
$result = false; |
|
|
|
try { |
|
$return = sqlStatement($sql, $params); |
|
$result = true; |
|
} catch (Exception $e) { |
|
if ($error) { |
|
$this->errorHandler($e, $sql, $params); |
|
} |
|
} |
|
|
|
if ($log) { |
|
EventAuditLogger::instance()->auditSQLEvent($sql, $result, $params); |
|
} |
|
|
|
return $return; |
|
} |
|
|
|
public function getPortalAuditRec($recid) |
|
{ |
|
$return = false; |
|
$result = false; |
|
try { |
|
$sql = "Select * From onsite_portal_activity Where id = ?"; |
|
$return = sqlStatementNoLog($sql, $recid); |
|
$result = true; |
|
} catch (Exception $e) { |
|
$this->errorHandler($e, $sql); |
|
} |
|
if ($result === true) { |
|
return sqlFetchArray($return); |
|
} else { |
|
return false; |
|
} |
|
} |
|
|
|
public function getPortalAudit($patientid, $action = 'review', $activity = 'profile', $status = 'waiting', $auditflg = 1, $rtn = 'last', $oelog = true, $error = true) |
|
{ |
|
$return = false; |
|
$result = false; |
|
$audit = array ( |
|
$patientid, |
|
$activity, |
|
$auditflg, |
|
$status, |
|
$action |
|
); |
|
try { |
|
$sql = "Select * From onsite_portal_activity As pa Where pa.patient_id = ? And pa.activity = ? And pa.require_audit = ? " . |
|
"And pa.status = ? And pa.pending_action = ? ORDER BY pa.date ASC LIMIT 1"; |
|
$return = sqlStatementNoLog($sql, $audit); |
|
$result = true; |
|
} catch (Exception $e) { |
|
if ($error) { |
|
$this->errorHandler($e, $sql, $audit); |
|
} |
|
} |
|
|
|
if ($oelog) { |
|
EventAuditLogger::instance()->auditSQLEvent($sql, $result, $audit); |
|
} |
|
|
|
if ($rtn == 'last') { |
|
return sqlFetchArray($return); |
|
} else { |
|
return $return; |
|
} |
|
} |
|
/** |
|
* Function portalAudit |
|
* All Portal audit Transactions log |
|
* Hoping to work both ends, patient and user, from one or most two tables |
|
* |
|
* @param String $sql |
|
* SQL Query Statment for actions will execute sql as normal for cases |
|
* user auth is not required. |
|
* @param array $params |
|
* Parameters for actions |
|
* @param array $auditvals |
|
* Parameters of audit |
|
* @param boolean $log |
|
* openemr Logging True / False |
|
* @param boolean $error |
|
* Error Display True / False |
|
* @param type audit array params for portal audits |
|
* $audit = Array(); |
|
* $audit['patient_id']=""; |
|
* $audit['activity']=""; |
|
* $audit['require_audit']=""; |
|
* $audit['pending_action']=""; |
|
* $audit['action_taken']=""; |
|
* $audit['status']=""; |
|
* $audit['narrative']=""; |
|
* $audit['table_action']=""; //auth user action sql to run after review |
|
* $audit['table_args']=""; //auth user action data to run after review |
|
* $audit['action_user']=""; |
|
* $audit['action_taken_time']=""; |
|
* $audit['checksum']=""; |
|
*/ |
|
public function portalAudit(string $type = null, string $rec = null, array $auditvals, $oelog = true, $error = true) |
|
{ |
|
$return = false; |
|
$result = false; |
|
$audit = array (); |
|
if (!$type) { |
|
$type = 'insert'; |
|
} |
|
if ($type != 'insert') { |
|
$audit['date'] = $auditvals['date'] ? $auditvals['date'] : date("Y-m-d H:i:s"); |
|
} |
|
|
|
$audit['patient_id'] = $auditvals['patient_id'] ? $auditvals['patient_id'] : $_SESSION['pid']; |
|
$audit['activity'] = $auditvals['activity'] ? $auditvals['activity'] : ""; |
|
$audit['require_audit'] = $auditvals['require_audit'] ? $auditvals['require_audit'] : ""; |
|
$audit['pending_action'] = $auditvals['pending_action'] ? $auditvals['pending_action'] : ""; |
|
$audit['action_taken'] = $auditvals['action_taken'] ? $auditvals['action_taken'] : ""; |
|
$audit['status'] = $auditvals['status'] ? $auditvals['status'] : "new"; |
|
$audit['narrative'] = $auditvals['narrative'] ? $auditvals['narrative'] : ""; |
|
$audit['table_action'] = $auditvals['table_action'] ? $auditvals['table_action'] : ""; |
|
if ($auditvals['activity'] == 'profile') { |
|
$audit['table_args'] = serialize($auditvals['table_args']); |
|
} else { |
|
$audit['table_args'] = $auditvals['table_args']; |
|
} |
|
|
|
$audit['action_user'] = $auditvals['action_user'] ? $auditvals['action_user'] : ""; |
|
$audit['action_taken_time'] = $auditvals['action_taken_time'] ? $auditvals['action_taken_time'] : ""; |
|
$audit['checksum'] = $auditvals['checksum'] ? $auditvals['checksum'] : ""; |
|
|
|
try { |
|
if ($type != 'update') { |
|
$logsql = "INSERT INTO onsite_portal_activity" . |
|
"( date, patient_id, activity, require_audit, pending_action, action_taken, status, narrative," . |
|
"table_action, table_args, action_user, action_taken_time, checksum) " . |
|
"VALUES (NOW(), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; |
|
} else { |
|
$logsql = "update onsite_portal_activity set date=?, patient_id=?, activity=?, require_audit=?," . |
|
" pending_action=?, action_taken=?,status=?, narrative=?, table_action=?, table_args=?," . |
|
"action_user=?, action_taken_time=?, checksum=? "; |
|
$logsql .= "where id='" . add_escape_custom($rec) . "' And patient_id='" . add_escape_custom($audit['patient_id']) . "'"; |
|
} |
|
|
|
$return = sqlStatementNoLog($logsql, $audit); |
|
$result = true; |
|
} catch (Exception $e) { |
|
if ($error) { |
|
$this->errorHandler($e, $logsql, $audit); |
|
} |
|
} |
|
|
|
if ($oelog) { |
|
$this->portalLog('profile audit transaction', $audit['patient_id'], $logsql, $audit, $result, 'See portal audit activity'); |
|
//auditSQLEvent( $logsql, $result, $audit ); |
|
} |
|
|
|
return $return; |
|
} |
|
|
|
public function portalLog($event = '', $patient_id = null, $comments = "", $binds = '', $success = '1', $user_notes = '', $ccda_doc_id = 0) |
|
{ |
|
$groupname = isset($GLOBALS['groupname']) ? $GLOBALS['groupname'] : 'none'; |
|
$user = isset($_SESSION['portal_username']) ? $_SESSION['portal_username'] : $_SESSION['authUser']; |
|
$log_from = isset($_SESSION['portal_username']) ? 'onsite-portal' : 'portal-dashboard'; |
|
if (!isset($_SESSION['portal_username']) && !isset($_SESSION['authUser'])) { |
|
$log_from = 'portal-login'; |
|
} |
|
|
|
$user_notes .= isset($_SESSION['whereto']) ? (' Module:' . $_SESSION['whereto']) : ""; |
|
|
|
$processed_binds = ""; |
|
if (is_array($binds)) { |
|
$first_loop = true; |
|
foreach ($binds as $value_bind) { |
|
if ($first_loop) { |
|
$processed_binds .= "'" . add_escape_custom($value_bind) . "'"; |
|
$first_loop = false; |
|
} else { |
|
$processed_binds .= ",'" . add_escape_custom($value_bind) . "'"; |
|
} |
|
} |
|
|
|
if (! empty($processed_binds)) { |
|
$processed_binds = "(" . $processed_binds . ")"; |
|
$comments .= " " . $processed_binds; |
|
} |
|
} |
|
|
|
$this->portalNewEvent($event, $user, $groupname, $success, $comments, $patient_id, $log_from, $user_notes, $ccda_doc_id); |
|
} |
|
/** |
|
* Function errorHandler |
|
* All error display and log |
|
* Display the Error, Line and File |
|
* Same behavior of HelpfulDie fuction in OpenEMR |
|
* Path /library/sql.inc |
|
* |
|
* @param type $e |
|
* @param string $sql |
|
* @param array $binds |
|
*/ |
|
public function errorHandler($e, $sql, $binds = '') |
|
{ |
|
$trace = $e->getTraceAsString(); |
|
$nLast = strpos($trace, '[internal function]'); |
|
$trace = substr($trace, 0, ( $nLast - 3 )); |
|
$logMsg = ''; |
|
do { |
|
$logMsg .= "\r Exception: " . self::escapeHtml($e->getMessage()); |
|
} while ($e = $e->getPrevious()); |
|
/** |
|
* List all Params |
|
*/ |
|
$processedBinds = ""; |
|
if (is_array($binds)) { |
|
$firstLoop = true; |
|
foreach ($binds as $valueBind) { |
|
if ($firstLoop) { |
|
$processedBinds .= "'" . $valueBind . "'"; |
|
$firstLoop = false; |
|
} else { |
|
$processedBinds .= ",'" . $valueBind . "'"; |
|
} |
|
} |
|
|
|
if (! empty($processedBinds)) { |
|
$processedBinds = "(" . $processedBinds . ")"; |
|
} |
|
} |
|
|
|
echo '<pre><span style="color: red;">'; |
|
echo 'ERROR : ' . $logMsg; |
|
echo "\r\n"; |
|
echo 'SQL statement : ' . self::escapeHtml($sql); |
|
echo self::escapeHtml($processedBinds); |
|
echo '</span></pre>'; |
|
echo '<pre>'; |
|
echo $trace; |
|
echo '</pre>'; |
|
/** |
|
* Error Logging |
|
*/ |
|
$logMsg .= "\n SQL statement : $sql" . $processedBinds; |
|
$logMsg .= "\n $trace"; |
|
error_log("ERROR: " . htmlspecialchars($logMsg, ENT_QUOTES), 0); |
|
} |
|
public function escapeHtml($string) |
|
{ |
|
return htmlspecialchars($string, ENT_QUOTES); |
|
} |
|
/* |
|
* Retrive the data format from GLOBALS |
|
* |
|
* @param Date format set in GLOBALS |
|
* @return Date format in PHP |
|
*/ |
|
public function dateFormat($format) |
|
{ |
|
if ($format == "0") { |
|
$date_format = 'yyyy/mm/dd'; |
|
} elseif ($format == 1) { |
|
$date_format = 'mm/dd/yyyy'; |
|
} elseif ($format == 2) { |
|
$date_format = 'dd/mm/yyyy'; |
|
} else { |
|
$date_format = $format; |
|
} |
|
|
|
return $date_format; |
|
} |
|
/** |
|
* fixDate - Date Conversion Between Different Formats |
|
* |
|
* @param String $input_date |
|
* Date to be converted |
|
* @param String $date_format |
|
* Target Date Format |
|
*/ |
|
public function fixDate($input_date, $output_format = null, $input_format = null) |
|
{ |
|
if (! $input_date) { |
|
return; |
|
} |
|
|
|
$input_date = preg_replace('/T|Z/', ' ', $input_date); |
|
|
|
$temp = explode(' ', $input_date); // split using space and consider the first portion, in case of date with time |
|
$input_date = $temp[0]; |
|
|
|
$output_format = ApplicationTable::dateFormat($output_format); |
|
$input_format = ApplicationTable::dateFormat($input_format); |
|
|
|
preg_match("/[^ymd]/", $output_format, $date_seperator_output); |
|
$seperator_output = $date_seperator_output[0]; |
|
$output_date_arr = explode($seperator_output, $output_format); |
|
|
|
preg_match("/[^ymd]/", $input_format, $date_seperator_input); |
|
$seperator_input = $date_seperator_input[0]; |
|
$input_date_array = explode($seperator_input, $input_format); |
|
|
|
preg_match("/[^1234567890]/", $input_date, $date_seperator_input); |
|
$seperator_input = $date_seperator_input[0]; |
|
$input_date_arr = explode($seperator_input, $input_date); |
|
|
|
foreach ($output_date_arr as $key => $format) { |
|
$index = array_search($format, $input_date_array); |
|
$output_date_arr[$key] = $input_date_arr[$index]; |
|
} |
|
|
|
$output_date = implode($seperator_output, $output_date_arr); |
|
|
|
$output_date = $temp[1] ? $output_date . " " . $temp[1] : $output_date; // append the time, if exists, with the new formatted date |
|
return $output_date; |
|
} |
|
|
|
/* |
|
* Using generate id function from OpenEMR sql.inc library file |
|
* @param string $seqname table name containing sequence (default is adodbseq) |
|
* @param integer $startID id to start with for a new sequence (default is 1) |
|
* @return integer returns the sequence integer |
|
*/ |
|
public function generateSequenceID() |
|
{ |
|
return generate_id(); |
|
} |
|
|
|
public function portalNewEvent($event, $user, $groupname, $success, $comments = "", $patient_id = null, $log_from = '', $user_notes = "", $ccda_doc_id = 0) |
|
{ |
|
EventAuditLogger::instance()->recordLogItem($success, $event, $user, $groupname, $comments, $patient_id, null, $log_from, null, $ccda_doc_id, $user_notes); |
|
} |
|
}// app query class
|
|
|