bug fix march continued (#1921)
[openemr.git] / interface / logview / logview.php
blob8a39bd4e6e5aaad79f41870da9b77872dd04cef3
1 <?php
2 /**
3 * Log Viewer.
5 * @package OpenEMR
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"));
22 if (!empty($_GET)) {
23 if (!verifyCsrfToken($_GET["csrf_token_form"])) {
24 csrfNotVerified();
29 <html>
30 <head>
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">
36 <style>
37 #logview {
38 width: 100%;
40 #logview table {
41 width:100%;
42 border-collapse: collapse;
44 #logview th {
45 background-color: #cccccc;
46 cursor: pointer; cursor: hand;
47 padding: 5px 5px;
48 align: left;
49 text-align: left;
52 #logview td {
53 background-color: #ffffff;
54 border-bottom: 1px solid #808080;
55 cursor: default;
56 padding: 5px 5px;
57 vertical-align: top;
59 .highlight {
60 background-color: #336699;
61 color: #336699;
63 </style>
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>
69 <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;
76 else {
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;
93 </script>
94 </head>
95 <body class="body_top">
96 <font class="title"><?php echo xlt('Logs Viewer'); ?></font>
97 <br>
98 <?php
99 $err_message=0;
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>";
110 $err_message=1;
113 if ($_GET["form_patient"]) {
114 $form_patient = isset($_GET["form_patient"]) ? $_GET["form_patient"] : "";
118 <?php
119 $form_user = isset($_REQUEST['form_user']) ? $_REQUEST['form_user'] : '';
120 $form_pid = isset($_REQUEST['form_pid']) ? $_REQUEST['form_pid'] : '';
122 if ($form_patient == '') {
123 $form_pid = '';
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++) {
128 $ret[$iter] = $row;
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);
138 <br>
139 <FORM METHOD="GET" name="theform" id="theform">
140 <?php
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="">
149 <table>
150 <tr><td>
151 <span class="text"><?php echo xlt('Start Date'); ?>: </span>
152 </td><td>
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'); ?>" />
154 </td>
155 <td>
156 <span class="text"><?php xl('End Date', 'e'); ?>: </span>
157 </td><td>
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'); ?>" />
159 </td>
160 <!--VicarePlus :: Feature For Generating Log For The Selected Patient --!>
161 <td>
162 &nbsp;&nbsp;<span class='text'><?php echo xlt('Patient'); ?>: </span>
163 </td>
164 <td>
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); ?>' />
167 </td>
168 </tr>
169 <tr><td>
170 <span class='text'><?php echo xlt('User'); ?>: </span>
171 </td>
172 <td>
173 <?php
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'])) {
178 continue;
181 echo " <option value='" . attr($urow['username']) . "'";
182 if ($urow['username'] == $form_user) {
183 echo " selected";
186 echo ">" . text($urow['lname']);
187 if ($urow['fname']) {
188 echo ", " . text($urow['fname']);
191 echo "</option>\n";
194 echo "</select>\n";
196 </td>
197 <td>
198 <!-- list of events name -->
199 <span class='text'><?php echo xlt('Name of Events'); ?>: </span>
200 </td>
201 <td>
202 <?php
203 $eventname = isset($_GET['eventname']) ? $_GET['eventname'] : '';
204 $res = sqlStatement("select distinct event from log order by event ASC");
205 $ename_list=array();
206 $j=0;
207 while ($erow = sqlFetchArray($res)) {
208 if (!trim($erow['event'])) {
209 continue;
212 $data = explode('-', $erow['event']);
213 $data_c = count($data);
214 $ename=$data[0];
215 for ($i=1; $i<($data_c-1); $i++) {
216 $ename.="-".$data[$i];
219 $ename_list[$j]=$ename;
220 $j=$j+1;
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'])) {
227 continue;
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;
241 $j=$j+1;
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]!= "") {
252 echo " selected";
255 echo ">" . text($ename_list[$k]);
256 echo "</option>\n";
259 echo "</select>\n";
261 </td>
262 <!-- type of events ends -->
263 <td>
264 &nbsp;&nbsp;<span class='text'><?php echo xlt('Type of Events'); ?>: </span>
265 </td><td>
266 <?php
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";
273 echo "</option>\n";
274 } else {
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]!= "") {
282 echo " selected";
285 echo ">" . text(preg_replace('/^select$/', 'Query', $event_types[$k])); // Convert select to Query for MU2 requirement
286 echo "</option>\n";
289 echo "</select>\n";
291 </td>
292 <tr><td>
293 <span class='text'><?php echo xlt('Include Checksum'); ?>: </span>
294 </td><td>
295 <?php
296 $check_sum = isset($_GET['check_sum']) ? $_GET['check_sum'] : '';
298 <input type="checkbox" name="check_sum" <?php echo ($check_sum == 'on') ? "checked" : ""; ?>></input>
299 </td>
300 <td>
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>
303 </td>
304 <td>
305 <div id='valid_button'>
306 <input type=button id='validate_log' onclick='validatelog();' value='<?php echo xla('Validate Log'); ?>'></input>
307 </div>
308 <div id='log_loading' style="display: none">
309 <img src='../../images/loading.gif'/>
310 </div>
311 </td>
312 </tr>
313 </table>
314 </FORM>
317 <?php if ($start_date && $end_date && $err_message!=1) { ?>
318 <div id="logview">
319 <table>
320 <tr>
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>
333 <?php } ?>
334 </tr>
335 <?php
337 <input type="hidden" name="event" value="<?php echo attr($eventname) . "-" . attr($type_event) ?>">
338 <?php
340 $tevent="";
341 $gev="";
342 if ($eventname != "" && $type_event != "") {
343 $getevent=$eventname."-".$type_event;
346 if (($eventname == "") && ($type_event != "")) {
347 $tevent=$type_event;
348 } else if ($type_event =="" && $eventname != "") {
349 $gev=$eventname;
350 } else if ($eventname == "") {
351 $gev = "";
352 } else {
353 $gev = $getevent;
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) {
358 //translate comments
359 $patterns = array ('/^success/','/^failure/','/ encounter/');
360 $replace = array ( xl('success'), xl('failure'), xl('encounter', '', ' '));
362 $log_id = $iter['id'];
363 $commentEncrStatus = "No";
364 $encryptVersion = 0;
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"]));
377 } else {
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"]));
384 } else {
385 $trans_comments = xl("Unable to decrypt these comments since the PHP mycrypt module is not installed.");
388 } else {
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>
404 <?php } ?>
405 </TR>
407 <?php
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>
429 <?php } ?>
430 </TR>
431 <?php
436 </table>
437 </div>
439 <?php } ?>
441 </body>
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
458 $('.sortby')
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');
482 else
483 $('#direction').val('asc');
486 function validatelog(){
487 var img = document.getElementById('log_loading');
488 var btn = document.getElementById('valid_button');
489 if(img){
490 if(img.style.display == "block"){
491 return false;
493 img.style.display = "block";
494 if(btn){btn.style.display = "none"}
496 $.ajax({
497 url:"../../library/log_validation.php",
498 data: {
499 csrf_token_form: '<?php echo attr(collectCsrfToken()); ?>'
501 asynchronous : true,
502 method: "post",
503 success :function(response){
504 if(img){
505 img.style.display="none";
506 if(btn){btn.style.display="block";}
508 alert(response);
510 failure :function(){
511 if(img){
512 img.style.display="none";
513 if(btn){btn.style.display="block";}
515 alert('<?php echo xls("Audit Log Validation Failed"); ?>');
520 </script>
522 </html>