6 * @link http://www.open-emr.org
7 * @author Brady Miller <brady.g.miller@gmail.com>
8 * @copyright Copyright (c) 2017-2018 Brady Miller <brady.g.miller@gmail.com>
9 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
13 require_once("../globals.php");
14 require_once("$srcdir/log.inc");
15 require_once("$srcdir/crypto.php");
16 require_once("$srcdir/acl.inc");
18 if (!acl_check('admin', 'users')) {
19 die(xlt("Not Authorized"));
23 if (!verifyCsrfToken($_GET["csrf_token_form"])) {
24 die(xlt('Authentication Error'));
31 <?php
html_header_show();?
>
33 <link rel
="stylesheet" href
="<?php echo $css_header;?>" type
="text/css">
34 <link rel
="stylesheet" href
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker/build/jquery.datetimepicker.min.css">
42 border
-collapse
: collapse
;
45 background
-color
: #cccccc;
46 cursor
: pointer
; cursor
: hand
;
53 background
-color
: #ffffff;
54 border
-bottom
: 1px solid
#808080;
60 background
-color
: #336699;
65 <script type
="text/javascript" src
="<?php echo $GLOBALS['webroot'] ?>/library/dialog.js?v=<?php echo $v_js_includes; ?>"></script
>
66 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery/dist/jquery.min.js"></script
>
67 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker/build/jquery.datetimepicker.full.min.js"></script
>
70 //function to disable the event type field if the event name is disclosure
71 function eventTypeChange(eventname
)
73 if (eventname
== "disclosure") {
74 document
.theform
.type_event
.disabled
= true;
77 document
.theform
.type_event
.disabled
= false;
81 // VicarePlus :: This invokes the find-patient popup.
82 function sel_patient() {
83 dlgopen('../main/calendar/find_patient_popup.php?pflag=0', '_blank', 500, 400);
86 // VicarePlus :: This is for callback by the find-patient popup.
87 function setpatient(pid
, lname
, fname
, dob
) {
88 var f
= document
.theform
;
89 f
.form_patient
.value
= lname +
', ' + fname
;
90 f
.form_pid
.value
= pid
;
95 <body
class="body_top">
96 <font
class="title"><?php
echo xlt('Logs Viewer'); ?
></font
>
101 $start_date = (!empty($_GET["start_date"])) ?
DateTimeToYYYYMMDDHHMMSS($_GET["start_date"]) : date("Y-m-d") . " 00:00";
102 $end_date = (!empty($_GET["end_date"])) ?
DateTimeToYYYYMMDDHHMMSS($_GET["end_date"]) : date("Y-m-d") . " 23:59";
104 * Start date should not be greater than end date - Date Validation
106 if ($start_date > $end_date) {
107 echo "<table><tr class='alert'><td colspan=7>";
108 echo xlt('Start Date should not be greater than End Date');
109 echo "</td></tr></table>";
113 if ($_GET["form_patient"]) {
114 $form_patient = isset($_GET["form_patient"]) ?
$_GET["form_patient"] : "";
119 $form_user = isset($_REQUEST['form_user']) ?
$_REQUEST['form_user'] : '';
120 $form_pid = isset($_REQUEST['form_pid']) ?
$_REQUEST['form_pid'] : '';
122 if ($form_patient == '') {
126 $res = sqlStatement("select distinct LEFT(date,10) as date from log order by date desc limit 30");
127 for ($iter=0; $row=sqlFetchArray($res); $iter++
) {
131 // Get the users list.
132 $sqlQuery = "SELECT username, fname, lname FROM users " .
133 "WHERE active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) ";
135 $ures = sqlStatement($sqlQuery);
139 <FORM METHOD
="GET" name
="theform" id
="theform">
141 $sortby = isset($_GET['sortby']) ?
$_GET['sortby'] : '';
142 $direction = isset($_GET['direction']) ?
$_GET['direction'] : '';
145 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(collectCsrfToken()); ?>" />
146 <input type
="hidden" name
="direction" id
="direction" value
="<?php echo !empty($direction) ? attr($direction) : 'asc'; ?>">
147 <input type
="hidden" name
="sortby" id
="sortby" value
="<?php echo attr($sortby); ?>">
148 <input type
=hidden name
=csum value
="">
151 <span
class="text"><?php
echo xlt('Start Date'); ?
>: </span
>
153 <input
class="datetimepicker" type
="text" size
="18" name
="start_date" id
="start_date" value
="<?php echo attr(oeFormatDateTime($start_date, 0)); ?>" title
="<?php echo xla('Start Date'); ?>" />
156 <span
class="text"><?php
xl('End Date', 'e'); ?
>: </span
>
158 <input
class="datetimepicker" type
="text" size
="18" name
="end_date" id
="end_date" value
="<?php echo attr(oeFormatDateTime($end_date, 0)); ?>" title
="<?php echo xla('End Date'); ?>" />
160 <!--VicarePlus
:: Feature
For Generating Log
For The Selected Patient
--!>
162  
; 
;<span
class='text'><?php
echo xlt('Patient'); ?
>: </span
>
165 <input type
='text' size
='20' name
='form_patient' style
='width:100%;cursor:pointer;cursor:hand' value
='<?php echo $form_patient ? attr($form_patient) : xla('Click To Select
'); ?>' onclick
='sel_patient()' title
='<?php echo xla('Click to select patient
'); ?>' />
166 <input type
='hidden' name
='form_pid' value
='<?php echo attr($form_pid); ?>' />
170 <span
class='text'><?php
echo xlt('User'); ?
>: </span
>
174 echo "<select name='form_user'>\n";
175 echo " <option value=''>" . xlt('All') . "</option>\n";
176 while ($urow = sqlFetchArray($ures)) {
177 if (!trim($urow['username'])) {
181 echo " <option value='" . attr($urow['username']) . "'";
182 if ($urow['username'] == $form_user) {
186 echo ">" . text($urow['lname']);
187 if ($urow['fname']) {
188 echo ", " . text($urow['fname']);
198 <!-- list of events name
-->
199 <span
class='text'><?php
echo xlt('Name of Events'); ?
>: </span
>
203 $eventname = isset($_GET['eventname']) ?
$_GET['eventname'] : '';
204 $res = sqlStatement("select distinct event from log order by event ASC");
207 while ($erow = sqlFetchArray($res)) {
208 if (!trim($erow['event'])) {
212 $data = explode('-', $erow['event']);
213 $data_c = count($data);
215 for ($i=1; $i<($data_c-1); $i++
) {
216 $ename.="-".$data[$i];
219 $ename_list[$j]=$ename;
223 $res1 = sqlStatement("select distinct event from extended_log order by event ASC");
224 // $j=0; // This can't be right! -- Rod 2013-08-23
225 while ($row = sqlFetchArray($res1)) {
226 if (!trim($row['event'])) {
230 $new_event = explode('-', $row['event']);
231 $no = count($new_event);
232 $events=$new_event[0];
233 for ($i=1; $i<($no-1); $i++
) {
234 $events.="-".$new_event[$i];
237 if ($events=="disclosure") {
238 $ename_list[$j]=$events;
244 $ename_list=array_unique($ename_list);
245 $ename_list=array_merge($ename_list);
246 $ecount=count($ename_list);
247 echo "<select name='eventname' onchange='eventTypeChange(this.options[this.selectedIndex].value);'>\n";
248 echo " <option value=''>" . xlt('All') . "</option>\n";
249 for ($k=0; $k<$ecount; $k++
) {
250 echo " <option value='" . attr($ename_list[$k]) . "'";
251 if ($ename_list[$k] == $eventname && $ename_list[$k]!= "") {
255 echo ">" . text($ename_list[$k]);
262 <!-- type of events ends
-->
264  
; 
;<span
class='text'><?php
echo xlt('Type of Events'); ?
>: </span
>
267 $type_event = isset($_GET['type_event']) ?
$_GET['type_event'] : '';
268 $event_types = array("select", "update", "insert", "delete", "replace");
269 $lcount = count($event_types);
270 if ($eventname=="disclosure") {
271 echo "<select name='type_event' disabled='disabled'>\n";
272 echo " <option value=''>" . xlt('All') . "</option>\n";
275 echo "<select name='type_event'>\n";
278 echo " <option value=''>" . xlt('All') . "</option>\n";
279 for ($k=0; $k<$lcount; $k++
) {
280 echo " <option value='" .attr($event_types[$k]). "'";
281 if ($event_types[$k] == $type_event && $event_types[$k]!= "") {
285 echo ">" . text(preg_replace('/^select$/', 'Query', $event_types[$k])); // Convert select to Query for MU2 requirement
293 <span
class='text'><?php
echo xlt('Include Checksum'); ?
>: </span
>
296 $check_sum = isset($_GET['check_sum']) ?
$_GET['check_sum'] : '';
298 <input type
="checkbox" name
="check_sum" <?php
echo ($check_sum == 'on') ?
"checked" : ""; ?
>></input
>
301 <input type
=hidden name
="event" value
="<?php echo attr($event); ?>">
302 <a href
="javascript:document.theform.submit();" class='link_submit'>[<?php
echo xlt('Refresh'); ?
>]</a
>
305 <div id
='valid_button'>
306 <input type
=button id
='validate_log' onclick
='validatelog();' value
='<?php echo xla('Validate Log
'); ?>'></input
>
308 <div id
='log_loading' style
="display: none">
309 <img src
='../../images/loading.gif'/>
317 <?php
if ($start_date && $end_date && $err_message!=1) { ?
>
321 <!-- <TH
><?php
echo xlt('Date'); ?
><TD
> -->
322 <th id
="sortby_date" class="text sortby" title
="<?php echo xla('Sort by date/time'); ?>"><?php
echo xlt('Date'); ?
></th
>
323 <th id
="sortby_event" class="text sortby" title
="<?php echo xla('Sort by Event'); ?>"><?php
echo xlt('Event'); ?
></th
>
324 <th id
="sortby_category" class="text sortby" title
="<?php echo xla('Sort by Category'); ?>"><?php
echo xlt('Category'); ?
></th
>
325 <th id
="sortby_user" class="text sortby" title
="<?php echo xla('Sort by User'); ?>"><?php
echo xlt('User'); ?
></th
>
326 <th id
="sortby_cuser" class="text sortby" title
="<?php echo xla('Sort by Crt User'); ?>"><?php
echo xlt('Certificate User'); ?
></th
>
327 <th id
="sortby_group" class="text sortby" title
="<?php echo xla('Sort by Group'); ?>"><?php
echo xlt('Group'); ?
></th
>
328 <th id
="sortby_pid" class="text sortby" title
="<?php echo xla('Sort by PatientID'); ?>"><?php
echo xlt('PatientID'); ?
></th
>
329 <th id
="sortby_success" class="text sortby" title
="<?php echo xla('Sort by Success'); ?>"><?php
echo xlt('Success'); ?
></th
>
330 <th id
="sortby_comments" class="text sortby" title
="<?php echo xla('Sort by Comments'); ?>"><?php
echo xlt('Comments'); ?
></th
>
331 <?php
if ($check_sum) {?
>
332 <th id
="sortby_checksum" class="text sortby" title
="<?php echo xla('Sort by Checksum'); ?>"><?php
echo xlt('Checksum'); ?
></th
>
337 <input type
="hidden" name
="event" value
="<?php echo attr($eventname) . "-" . attr($type_event) ?>">
342 if ($eventname != "" && $type_event != "") {
343 $getevent=$eventname."-".$type_event;
346 if (($eventname == "") && ($type_event != "")) {
348 } else if ($type_event =="" && $eventname != "") {
350 } else if ($eventname == "") {
356 if ($ret = getEvents(array('sdate' => $start_date,'edate' => $end_date, 'user' => $form_user, 'patient' => $form_pid, 'sortby' => $_GET['sortby'], 'levent' =>$gev, 'tevent' =>$tevent,'direction' => $_GET['direction']))) {
357 foreach ($ret as $iter) {
359 $patterns = array ('/^success/','/^failure/','/ encounter/');
360 $replace = array ( xl('success'), xl('failure'), xl('encounter', '', ' '));
362 $log_id = $iter['id'];
363 $commentEncrStatus = "No";
365 $logEncryptData = logCommentEncryptData($log_id);
366 if (count($logEncryptData) > 0) {
367 $commentEncrStatus = $logEncryptData['encrypt'];
368 $encryptVersion = $logEncryptData['version'];
371 //July 1, 2014: Ensoftek: Decrypt comment data if encrypted
372 if ($commentEncrStatus == "Yes") {
373 if ($encryptVersion == 1) {
374 // Use new openssl method
375 if (extension_loaded('openssl')) {
376 $trans_comments = preg_replace($patterns, $replace, aes256Decrypt($iter["comments"]));
378 $trans_comments = xl("Unable to decrypt these comments since the PHP openssl module is not installed.");
380 } else { //$encryptVersion == 0
381 // Use old mcrypt method
382 if (extension_loaded('mcrypt')) {
383 $trans_comments = preg_replace($patterns, $replace, aes256Decrypt_mycrypt($iter["comments"]));
385 $trans_comments = xl("Unable to decrypt these comments since the PHP mycrypt module is not installed.");
389 $trans_comments = preg_replace($patterns, $replace, $iter["comments"]);
392 <TR
class="oneresult">
393 <TD
class="text"><?php
echo text(oeFormatDateTime($iter["date"])); ?
></TD
>
394 <TD
class="text"><?php
echo text(preg_replace('/select$/', 'Query', $iter["event"])); //Convert select term to Query for MU2 requirements ?></TD>
395 <TD
class="text"><?php
echo text($iter["category"]); ?
></TD
>
396 <TD
class="text"><?php
echo text($iter["user"]); ?
></TD
>
397 <TD
class="text"><?php
echo text($iter["crt_user"]); ?
></TD
>
398 <TD
class="text"><?php
echo text($iter["groupname"]); ?
></TD
>
399 <TD
class="text"><?php
echo text($iter["patient_id"]); ?
></TD
>
400 <TD
class="text"><?php
echo text($iter["success"]); ?
></TD
>
401 <TD
class="text"><?php
echo nl2br(text(preg_replace('/^select/i', 'Query', $trans_comments))); //Convert select term to Query for MU2 requirements ?></TD>
402 <?php
if ($check_sum) { ?
>
403 <TD
class="text"><?php
echo text($iter["checksum"]); ?
></TD
>
411 if (($eventname=="disclosure") ||
($gev == "")) {
412 $eventname="disclosure";
413 if ($ret = getEvents(array('sdate' => $start_date,'edate' => $end_date, 'user' => $form_user, 'patient' => $form_pid, 'sortby' => $_GET['sortby'], 'event' =>$eventname))) {
414 foreach ($ret as $iter) {
415 $comments=xl('Recipient Name').":".$iter["recipient"].";".xl('Disclosure Info').":".$iter["description"];
417 <TR
class="oneresult">
418 <TD
class="text"><?php
echo text(oeFormatDateTime($iter["date"])); ?
></TD
>
419 <TD
class="text"><?php
echo xlt($iter["event"]); ?
></TD
>
420 <TD
class="text"><?php
echo xlt($iter["category"]); ?
></TD
>
421 <TD
class="text"><?php
echo text($iter["user"]); ?
></TD
>
422 <TD
class="text"><?php
echo text($iter["crt_user"]); ?
></TD
>
423 <TD
class="text"><?php
echo text($iter["groupname"]); ?
></TD
>
424 <TD
class="text"><?php
echo text($iter["patient_id"]); ?
></TD
>
425 <TD
class="text"><?php
echo text($iter["success"]); ?
></TD
>
426 <TD
class="text"><?php
echo text($comments); ?
></TD
>
427 <?php
if ($check_sum) { ?
>
428 <TD
class="text"><?php
echo text($iter["checksum"]); ?
></TD
>
443 <script language
="javascript">
445 // jQuery stuff to make the page a little easier to use
446 $
(document
).ready(function(){
447 // funny thing here... good learning experience
448 // the TR has TD children which have their own background and text color
449 // toggling the TR color doesn't change the TD color
450 // so we need to change all the TR's children (the TD's) just as we did the TR
451 // thus we have two calls to toggleClass:
452 // 1 - for the parent (the TR)
453 // 2 - for each of the children (the TDs)
454 $
(".oneresult").mouseover(function() { $
(this
).toggleClass("highlight"); $
(this
).children().toggleClass("highlight"); });
455 $
(".oneresult").mouseout(function() { $
(this
).toggleClass("highlight"); $
(this
).children().toggleClass("highlight"); });
457 // click-able column headers to sort the list
459 $
("#sortby_date").click(function() { set_sort_direction(); $
("#sortby").val("date"); $
("#theform").submit(); });
460 $
("#sortby_event").click(function() { set_sort_direction(); $
("#sortby").val("event"); $
("#theform").submit(); });
461 $
("#sortby_category").click(function() { set_sort_direction(); $
("#sortby").val("category"); $
("#theform").submit(); });
462 $
("#sortby_user").click(function() { set_sort_direction(); $
("#sortby").val("user"); $
("#theform").submit(); });
463 $
("#sortby_cuser").click(function() { set_sort_direction(); $
("#sortby").val("user"); $
("#theform").submit(); });
464 $
("#sortby_group").click(function() { set_sort_direction(); $
("#sortby").val("groupname"); $
("#theform").submit(); });
465 $
("#sortby_pid").click(function() { set_sort_direction(); $
("#sortby").val("patient_id"); $
("#theform").submit(); });
466 $
("#sortby_success").click(function() { set_sort_direction(); $
("#sortby").val("success"); $
("#theform").submit(); });
467 $
("#sortby_comments").click(function() { set_sort_direction(); $
("#sortby").val("comments"); $
("#theform").submit(); });
468 $
("#sortby_checksum").click(function() { set_sort_direction(); $
("#sortby").val("checksum"); $
("#theform").submit(); });
470 $
('.datetimepicker').datetimepicker({
471 <?php
$datetimepicker_timepicker = true; ?
>
472 <?php
$datetimepicker_showseconds = false; ?
>
473 <?php
$datetimepicker_formatInput = true; ?
>
474 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
475 <?php
// can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
479 function set_sort_direction(){
480 if($
('#direction').val() == 'asc')
481 $
('#direction').val('desc');
483 $
('#direction').val('asc');
486 function validatelog(){
487 var img
= document
.getElementById('log_loading');
488 var btn
= document
.getElementById('valid_button');
490 if(img
.style
.display
== "block"){
493 img
.style
.display
= "block";
494 if(btn
){btn
.style
.display
= "none"}
497 url
:"../../library/log_validation.php",
499 csrf_token_form
: '<?php echo attr(collectCsrfToken()); ?>'
503 success
:function(response
){
505 img
.style
.display
="none";
506 if(btn
){btn
.style
.display
="block";}
512 img
.style
.display
="none";
513 if(btn
){btn
.style
.display
="block";}
515 alert('<?php echo xls("Audit Log Validation Failed"); ?>');