Feat openemr fix 7480 7494 email prescription (#7495)
[openemr.git] / interface / main / messages / messages.php
blob9374d93d2a887f58b1971a9388e8e60aec54f1ce
1 <?php
3 /**
4 * Message and Reminder Center UI
6 * @Package OpenEMR
7 * @link http://www.open-emr.org
8 * @author OpenEMR Support LLC
9 * @author Roberto Vasquez <robertogagliotta@gmail.com>
10 * @author Rod Roark <rod@sunsetsystems.com>
11 * @author Brady Miller <brady.g.miller@gmail.com>
12 * @author Ray Magauran <magauran@medfetch.com>
13 * @author Tyler Wrenn <tyler@tylerwrenn.com>
14 * @copyright Copyright (c) 2010 OpenEMR Support LLC
15 * @copyright Copyright (c) 2017 MedEXBank.com
16 * @copyright Copyright (c) 2018-2019 Brady Miller <brady.g.miller@gmail.com>
17 * @copyright Copyright (c) 2020 Tyler Wrenn <tyler@tylerwrenn.com>
18 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
21 require_once("../../globals.php");
22 require_once("$srcdir/pnotes.inc.php");
23 require_once("$srcdir/patient.inc.php");
24 require_once("$srcdir/options.inc.php");
25 require_once("$srcdir/gprelations.inc.php");
26 require_once "$srcdir/user.inc.php";
27 require_once("$srcdir/MedEx/API.php");
29 use OpenEMR\Common\Acl\AclMain;
30 use OpenEMR\Common\Csrf\CsrfUtils;
31 use OpenEMR\Common\Logging\EventAuditLogger;
32 use OpenEMR\Core\Header;
33 use OpenEMR\OeUI\OemrUI;
35 //Gets validation rules from Page Validation list.
36 $collectthis = collectValidationPageRules("/interface/main/messages/messages.php");
37 if (empty($collectthis)) {
38 $collectthis = "{}";
39 } else {
40 $collectthis = json_sanitize($collectthis[array_keys($collectthis)[0]]["rules"]);
43 $MedEx = new MedExApi\MedEx('MedExBank.com');
45 if ($GLOBALS['medex_enable'] == '1') {
46 if ($_REQUEST['SMS_bot']) {
47 $result = $MedEx->login('');
48 $MedEx->display->SMS_bot($result);
49 exit();
51 $logged_in = $MedEx->login();
52 } else {
53 $logged_in = null;
56 $setting_bootstrap_submenu = prevSetting('', 'setting_bootstrap_submenu', 'setting_bootstrap_submenu', ' ');
57 //use $uspfx as the first variable for page/script specific user settings instead of '' (which is like a global but you have to request it).
58 $uspfx = substr(__FILE__, strlen($webserver_root)) . '.';
59 $rcb_selectors = prevSetting($uspfx, 'rcb_selectors', 'rcb_selectors', 'block');
60 $rcb_facility = prevSetting($uspfx, 'form_facility', 'form_facility', '');
61 $rcb_provider = prevSetting($uspfx, 'form_provider', 'form_provider', $_SESSION['authUserID']);
63 if (
64 (array_key_exists('setting_bootstrap_submenu', $_POST)) ||
65 (array_key_exists('rcb_selectors', $_POST))
66 ) {
67 // These are not form elements. We only ever change them via ajax, so exit now.
68 exit();
71 <!DOCTYPE html>
72 <html>
73 <head>
74 <?php
75 //validation library
76 $use_validate_js = 1;
77 require_once($GLOBALS['srcdir'] . "/validation/validation_script.js.php");
79 <meta charset="utf-8" />
80 <meta http-equiv="X-UA-Compatible" content="IE=edge" />
81 <meta name="description" content="MedEx Bank" />
82 <meta name="author" content="OpenEMR: MedExBank" />
83 <?php Header::setupHeader(['datetime-picker', 'opener', 'moment', 'select2']); ?>
84 <link rel="stylesheet" href="<?php echo $webroot; ?>/interface/main/messages/css/reminder_style.css?v=<?php echo $v_js_includes; ?>">
86 <script>
87 var xljs1 = '<?php echo xla('Preferences updated successfully'); ?>';
88 var format_date_moment_js = '<?php echo attr(DateFormatRead("validateJS")); ?>';
89 <?php require_once "$srcdir/restoreSession.php"; ?>
90 </script>
92 <script src="<?php echo $GLOBALS['web_root']; ?>/interface/main/messages/js/reminder_appts.js?v=<?php echo $v_js_includes; ?>"></script>
93 <style>
94 @media only screen and (max-width: 768px) {
95 [class*="col-"] {
96 width: 100%;
97 text-align: left !important;
100 .icon-bar {
101 background-color: var(--danger);
104 </style>
106 <?php
107 if (($GLOBALS['medex_enable'] == '1') && (empty($_REQUEST['nomenu'])) && ($GLOBALS['disable_rcb'] != '1')) {
108 $MedEx->display->navigation($logged_in);
109 echo "<br /><br /><br />";
112 if (!empty($_REQUEST['go'])) { ?>
113 <?php
114 if (($_REQUEST['go'] == "setup") && (!$logged_in)) {
115 echo "<title>" . xlt('MedEx Setup') . "</title>";
116 $stage = $_REQUEST['stage'];
117 if (!is_numeric($stage)) {
118 echo "<br /><span class='title'>" . text($stage) . " " . xlt('Warning') . ": " . xlt('This is not a valid request') . ".</span>";
119 } else {
120 $MedEx->setup->MedExBank($stage);
122 } elseif ($_REQUEST['go'] == "addRecall") {
123 echo "<title>" . xlt('New Recall') . "</title>";
124 $MedEx->display->display_add_recall();
125 } elseif ($_REQUEST['go'] == 'Recalls') {
126 echo "<title>" . xlt('Recall Board') . "</title>";
127 $MedEx->display->display_recalls($logged_in);
128 } elseif ((($_REQUEST['go'] == "setup") || ($_REQUEST['go'] == 'Preferences')) && ($logged_in)) {
129 echo "<title>MedEx: " . xlt('Preferences') . "</title>";
130 $MedEx->display->preferences();
131 } elseif ($_REQUEST['go'] == 'icons') {
132 echo "<title>MedEx: " . xlt('Icons') . "&#x24B8;</title>";
133 $MedEx->display->icon_template();
134 } elseif ($_REQUEST['go'] == 'SMS_bot') {
135 echo "<title>MedEx: SMS Bot&#x24B8;</title>";
136 $MedEx->display->SMS_bot($logged_in);
137 exit;
138 } else {
139 echo "<title>" . xlt('MedEx Setup') . "</title>";
140 echo xlt('Warning: Navigation error. Please refresh this page.');
142 } else {
143 //original message.php stuff
145 if ($GLOBALS['enable_help'] == 1) {
146 $help_icon = '<a class="float-right oe-help-redirect" data-target="#myModal" data-toggle="modal" href="#" id="help-href" name="help-href" style="color: var(--gray)" title="' . xla("Click to view Help") . '"><i class="fa fa-question-circle" aria-hidden="true"></i></a>';
147 } elseif ($GLOBALS['enable_help'] == 2) {
148 $help_icon = '<a class="float-right oe-help-redirect" data-target="#myModal" data-toggle="modal" href="#" id="help-href" name="help-href" style="color: var(--gray300) !important" title="' . xla("To enable help - Go to Administration > Globals > Features > Enable Help Modal") . '"><i class="fa fa-question-circle" aria-hidden="true"></i></a>';
149 } elseif ($GLOBALS['enable_help'] == 0) {
150 $help_icon = '';
152 $heading_caption = xlt('Messages') . ', ' . xlt('Reminders');
153 if ($GLOBALS['disable_rcb'] != '1') {
154 $heading_caption .= ', ' . xlt('Recalls');
157 $arrOeUiSettings = array(
158 'heading_title' => $heading_caption,
159 'include_patient_name' => false,// use only in appropriate pages
160 'expandable' => true,
161 'expandable_files' => array(""),//all file names need suffix _xpd
162 'action' => "",//conceal, reveal, search, reset, link or back
163 'action_title' => "",
164 'action_href' => "",//only for actions - reset, link or back
165 'show_help_icon' => true,
166 'help_file_name' => "message_center_help.php"
168 $oemr_ui = new OemrUI($arrOeUiSettings);
170 echo "<title>" . xlt('Message Center') . "</title>";
172 </head>
173 <body class='body_top'>
174 <div id="container_div" class="<?php echo attr($oemr_ui->oeContainer()); ?>">
175 <div class="row">
176 <div class="col-sm-12">
177 <div class="clearfix">
178 <?php echo $oemr_ui->pageHeading() . "\r\n"; ?>
179 </div>
180 </div>
181 </div>
182 <div class="row my-3">
183 <div class="col-sm-12">
184 <ul class="nav nav-pills bg-light" id="main-nav-pills" role="tablist">
185 <li class="nav-item" id='li-mess' role="presentation">
186 <a href='#messages-div' class="active nav-link" id='messages-li' data-toggle="pill" role="tab" aria-controls="<?php echo xla("Message");?>" aria-selected="true"><?php echo xlt('Messages'); ?></a>
187 </li>
188 <li class="nav-item" id='li-remi' role="presentation">
189 <a href='#reminders-div' id='reminders-li' class="nav-link" data-toggle="pill" role="tab" aria-controls="<?php echo xla("Reminders");?>" aria-selected="true"><?php echo xlt('Reminders'); ?></a>
190 </li>
191 <?php if ($GLOBALS['disable_rcb'] != '1') { ?>
192 <li class="nav-item" id='li-reca' role="presentation">
193 <a href='#recalls-div' id='recalls-li' class="nav-link" data-toggle="pill" role="tab" aria-controls="<?php echo xla("Recalls");?>" aria-selected="true"><?php echo xlt('Recalls'); ?></a>
194 </li>
195 <?php }?>
196 <?php if ($logged_in) { ?>
197 <li class="nav-item" id='li-sms' role="presentation">
198 <a href='#sms-div' id='sms-li' class="nav-link" data-toggle="pill" role="tab" aria-controls="<?php echo xla("SMS Zone");?>" aria-selected="true"><?php echo xlt('SMS Zone'); ?></a>
199 </li>
200 <?php }?>
201 </ul>
202 </div>
203 </div>
204 <div class="tab-content" id="content">
205 <div class="row tab-pane active" role="tabpanel" id="messages-div">
206 <div class="col-sm-12">
207 <?php
208 // Check to see if the user has Admin rights, and if so, allow access to See All.
209 $showall = isset($_GET['show_all']) ? $_GET['show_all'] : "";
210 if ($showall == "yes") {
211 $show_all = $showall;
212 } else {
213 $show_all = "no";
215 // Collect active variable and applicable html code for links
216 $form_active = (isset($_REQUEST['form_active']) ? $_REQUEST['form_active'] : false);
217 $form_inactive = (isset($_REQUEST['form_inactive']) ? $_REQUEST['form_inactive'] : false);
218 if ($form_active) {
219 $active = '1';
220 $activity_string_html = 'form_active=1';
221 } elseif ($form_inactive) {
222 $active = '0';
223 $activity_string_html = 'form_inactive=1';
224 } else {
225 $active = 'all';
226 $activity_string_html = '';
228 //collect the task setting
229 $task = isset($_REQUEST['task']) ? $_REQUEST['task'] : "";
230 if (AclMain::aclCheckCore('admin', 'super')) {
231 if ($show_all == 'yes') {
232 $showall = "yes";
233 $lnkvar = "messages.php?show_all=no&" . $activity_string_html;
234 $lnkattributes = "name='Just Mine' onclick='top.restoreSession()'";
235 $otherstuff = "<i id='just-mine-tooltip' class='fa fa-user fa-2x fa-fw text-body' aria-hidden='true'></i>";
236 $messages = xl('All Messages');
237 } else {
238 $showall = "no";
239 $lnkvar = "messages.php?show_all=yes&" . $activity_string_html;
240 $lnkattributes = "name='See All' onclick='top.restoreSession()'";
241 $otherstuff = "<i id='see-all-tooltip' class='fa fa-users fa-2x fa-fw text-body' aria-hidden='true'></i>";
242 $messages = xl('My Messages');
244 } else {
245 $messages = xlt('My Messages');
248 <div class="d-flex justify-content-around">
249 <h4 class="flex-grow-1">
250 <?php echo text($messages); ?>
251 <a class='more' href="<?php echo $lnkvar ?? ''; ?>" <?php echo $lnkattributes ?? ''; ?>><?php echo $otherstuff ?? ''; ?></a>
252 </h4>
253 <ul class="nav text-right">
254 <?php
255 //show the activity links
256 if (empty($task) || $task == "add" || $task == "delete") { ?>
257 <li class="nav-item">
258 <?php if ($active == "all") : ?>
259 <span class="nav-link disabled"><?php echo xlt('All Messages'); ?></span>
260 <?php else : ?>
261 <a href="messages.php?show_all=yes" class="nav-link active" onclick="top.restoreSession()"><?php echo xlt('Show All'); ?></a>
262 <?php endif; ?>
263 </li>
264 <li class="nav-item">
265 <?php if ($active == '1') { ?>
266 <span class="nav-link disabled"><?php echo xlt('Active Messages'); ?></span>
267 <?php } else { ?>
268 <a href="messages.php?form_active=1" class="nav-link" onclick="top.restoreSession()"><?php echo xlt('Show Active'); ?></a>
269 <?php } ?>
270 </li>
271 <li class="nav-item">
272 <?php if ($active == '0') { ?>
273 <span class="nav-link disabled"><?php echo xlt('Inactive Messages'); ?></span>
274 <?php } else { ?>
275 <a href="messages.php?form_inactive=1" class="nav-link" onclick="top.restoreSession()"><?php echo xlt('Show Inactive'); ?></a>
276 <?php } ?>
277 </li>
278 <?php } ?>
279 </ul>
280 </div>
281 <div>
282 </div>
283 <?php
284 $note = '';
285 $noteid = '';
286 $title = '';
287 $form_message_status = '';
288 $reply_to = '';
289 $patientname = '';
290 switch ($task) {
291 case "add":
292 // Add a new message for a specific patient; the message is documented in Patient Notes.
293 // Add a new message; it's treated as a new note in Patient Notes.
294 $note = $_POST['note'];
295 $noteid = $_POST['noteid'];
296 $form_note_type = $_POST['form_note_type'];
297 $form_message_status = $_POST['form_message_status'];
298 $reply_to = explode(';', rtrim($_POST['reply_to'], ';'));
299 $assigned_to_list = explode(';', $_POST['assigned_to']);
300 $datetime = isset($_POST['form_datetime']) ? DateTimeToYYYYMMDDHHMMSS($_POST['form_datetime']) : '';
301 foreach ($assigned_to_list as $assigned_to) {
302 if ($noteid && $assigned_to != '-patient-') {
303 if (checkPnotesNoteId($noteid, $_SESSION['authUser'])) {
304 updatePnote($noteid, $note, $form_note_type, $assigned_to, $form_message_status, $datetime);
305 $noteid = '';
306 } else {
307 die("Message is not assigned to you. Adding is disallowed.");
309 } else {
310 if ($noteid && $assigned_to == '-patient-') {
311 // When $assigned_to == '-patient-' we don't update the current note, but
312 // instead create a new one with the current note's body prepended and
313 // attributed to the patient. This seems to be all for the patient portal.
314 $row = getPnoteById($noteid);
315 if (!$row) {
316 die("getPnoteById() did not find id '" . text($noteid) . "'");
318 $pres = sqlQuery("SELECT lname, fname " .
319 "FROM patient_data WHERE pid = ?", array($reply_to[0]));
320 $patientname = $pres['lname'] . ", " . $pres['fname'];
321 $note .= "\n\n$patientname on " . $row['date'] . " wrote:\n\n";
322 $note .= $row['body'];
324 // There's no note ID, and/or it's assigned to the patient.
325 // In these cases a new note is created.
326 foreach ($reply_to as $patient) {
327 $note_id = addPnote($patient, $note, $userauthorized, '1', $form_note_type, $assigned_to, $datetime, $form_message_status);
328 if (!empty($_POST['attachment_id'] ?? null) && !empty($_POST['attachment_type'] ?? null)) {
329 setGpRelation($_POST['attachment_type'], $_POST['attachment_id'], 6, $note_id);
330 echo "<script>dlgclose();</script>";
335 break;
336 case "savePatient":
337 case "save":
338 // Update alert.
339 $noteid = $_POST['noteid'];
340 $form_message_status = $_POST['form_message_status'];
341 $reply_to = $_POST['reply_to'];
342 if ($task == "save") {
343 updatePnoteMessageStatus($noteid, $form_message_status);
344 } else {
345 updatePnotePatient($noteid, $reply_to);
347 $task = "edit";
348 $note = $_POST['note'];
349 $title = $_POST['form_note_type'];
350 break;
351 case "edit":
352 $noteid = (int) $_GET['noteid'];
353 if (empty($noteid)) {
354 die("There was an error processing your request.");
356 // Check to make sure the noteid is assigned to the user
357 if (!checkPnotesNoteId($noteid, $_SESSION['authUser'])) {
358 die("Message is not assigned to you. Viewing is disallowed.");
360 // Update the message if it already exists; it's appended to an existing note in Patient Notes.
361 $result = getPnoteById($noteid);
362 if ($result) {
363 if (empty($title)) {
364 $title = $result['title'];
366 $body = $result['body'];
367 // if our reply-to is 0 it breaks multi patient select and other functionality
368 // this most likely didn't break before due to php implicit type conversion of 0 to ""
369 if (empty($reply_to) && $result['pid'] != 0) {
370 $reply_to = $result['pid'];
372 $form_message_status = $result['message_status'];
373 $datetime = $result['date'];
375 break;
376 case "delete":
377 // Delete selected message(s) from the Messages box (only).
378 $delete_id = $_POST['delete_id'];
379 for ($i = 0; $i < count($delete_id); $i++) {
380 deletePnote($delete_id[$i]);
381 EventAuditLogger::instance()->newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "pnotes: id " . $delete_id[$i]);
383 break;
385 // This is for sorting the records.
386 $sort = array("users.lname", "patient_data.lname", "pnotes.title", "pnotes.date", "pnotes.message_status");
387 $sortby = (isset($_REQUEST['sortby']) && ($_REQUEST['sortby'] != "")) ? $_REQUEST['sortby'] : $sort[3];
388 $sortorder = (isset($_REQUEST['sortorder']) && ($_REQUEST['sortorder'] != "")) ? $_REQUEST['sortorder'] : "desc";
389 $begin = isset($_REQUEST['begin']) ? $_REQUEST['begin'] : 0;
391 if ($task == "addnew" or $task == "edit") {
392 // Display the Messages page layout.
393 echo "<form name='form_patient' id='new_note'
394 class='form-horizontal'
395 action=\"messages.php?showall=" . attr_url($showall) . "&sortby=" . attr_url($sortby) . "&sortorder=" . attr_url($sortorder) . "&begin=" . attr_url($begin) . "&$activity_string_html\"
396 method='post'>
397 <input type='hidden' name='noteid' id='noteid' value='" . attr($noteid) . "' />
399 <input type='hidden' name='task' id='task' value='add' />";
400 if ($task == "addnew") {
401 $attach_id = $_REQUEST['attach'] ?? null;
402 $attach_type = $_REQUEST['gptype'] ?? null;
403 if (!empty($attach_id) && !empty($attach_type)) {
404 echo "<input type='hidden' name='attachment_id' id='attachment_id' value='" . attr($attach_id) . "' />";
405 echo "<input type='hidden' name='attachment_type' id='attachment_type' value='" . attr($attach_type) . "' />";
407 $message_legend = xl('Create New Message');
408 $onclick = "onclick=multi_sel_patient()";
409 } elseif ($task == "edit") {
410 $message_legend = xl('Add To Existing Message');
411 $onclick = "";
414 <div class='col-md-12'>
415 <div class="jumbotron jumbotron-fluid p-2">
416 <h4><?php echo text($message_legend); ?></h4>
417 <div class="row">
418 <div class="col-12 oe-custom-line">
419 <div class="row">
420 <div class="col-6 col-md-3">
421 <label for="form_note_type"><?php echo xlt('Type'); ?>:</label>
422 <?php
423 if ($title == "") {
424 $title = "Unassigned";
426 // Added 6/2009 by BM to incorporate the patient notes into the list_options listings.
427 generate_form_field(array('data_type' => 1, 'field_id' => 'note_type', 'list_id' => 'note_type', 'empty_title' => 'SKIP', 'order_by' => 'title', 'class' => 'form-control'), $title);
429 </div>
430 <div class="col-6 col-md-3">
431 <label for="form_message_status"><?php echo xlt('Status'); ?>:</label>
432 <?php
433 if ($form_message_status == "") {
434 $form_message_status = 'New';
436 generate_form_field(array('data_type' => 1, 'field_id' => 'message_status', 'list_id' => 'message_status', 'empty_title' => 'SKIP', 'order_by' => 'title', 'class' => 'form-control'), $form_message_status); ?>
437 </div>
438 <div class="col-6 col-md-4">
439 <?php
440 if ($task != "addnew" && $result['pid'] != 0) { ?>
441 <a class="patLink" onclick="goPid('<?php echo attr(addslashes($result['pid'])); ?>')" title='<?php echo xla('Click me to Open Patient Dashboard') ?>'><?php echo xlt('Patient'); ?>:</a><label for="form_patient">&nbsp</label>
442 <?php
443 } else { ?>
444 <span class='<?php echo($task == "addnew" ? "text-danger" : "") ?>'><?php echo xlt('Patient'); ?>:</span></a><label for="form_patient"></label>
445 <?php
448 if ($reply_to) {
449 $prow = sqlQuery("SELECT lname, fname,pid, pubpid, DOB " .
450 "FROM patient_data WHERE pid = ?", array($reply_to));
451 $patientname = $prow['lname'] . ", " . $prow['fname'];
453 if ($task == "addnew" || $result['pid'] == 0) {
454 $cursor = "oe-cursor-add";
455 $background = "oe-patient-background";
456 } elseif ($task == "edit") {
457 $cursor = "oe-cursor-stop";
458 $background = '';
461 <input type='text' id='form_patient' name='form_patient' class='form-control <?php echo $cursor . " " . $background;?>' onclick="multi_sel_patient()" placeholder='<?php echo xla("Click to add patient"); ?>' value='<?php echo attr($patientname); ?>' readonly />
462 <input type='hidden' class="form-control" name='reply_to' id='reply_to' value='<?php echo attr($reply_to); ?>'/>
463 </div>
464 <div class="col-6 col-md-2 d-flex flex-wrap">
465 <?php
466 if ($task == "addnew" || $result['pid'] == 0) {
467 echo "<label class='oe-empty-label' for='clear_patients'></label>";
468 echo '<button type="button" id="clear_patients" class="btn btn-secondary btn-undo float-left flip" value="' . xla('Clear') . '">' . xlt("Clear") . '</button>';
469 } ?>
470 </div>
471 </div>
472 </div>
473 </div>
474 <div class="row">
475 <div class="col-12 oe-custom-line">
476 <div class="row">
477 <?php if ($GLOBALS['messages_due_date']) { ?>
478 <div class="col-6 col-sm-2">
479 <label for="form_note_type"><?php echo xlt('Due date'); ?>:</label>
480 <?php generate_form_field(array('data_type' => 4, 'field_id' => 'datetime', 'edit_options' => 'F'), empty($datetime) ? date('Y-m-d H:i') : $datetime) ?>
481 </div>
482 <?php } ?>
483 <div class="col-6 col-sm-4 d-flex align-items-end flex-wrap">
484 <label for="assigned_to_text"><?php echo xlt('To{{Destination}}'); ?>:</label>
485 <input type='text' name='assigned_to_text' class='form-control oe-cursor-stop' id='assigned_to_text' readonly='readonly' value='' placeholder='<?php echo xla("SELECT Users FROM The Dropdown LIST"); ?>' />
486 <input type='hidden' name='assigned_to' id='assigned_to' />
487 </div>
488 <div class="col-6 col-sm-4">
489 <label class="oe-empty-label" for="users"></label>
490 <select name='users' id='users' class='form-control' onchange='addtolist(this);'>
491 <?php
492 echo "<option value='--'";
493 echo ">" . xlt('Select User');
494 echo "</option>\n";
495 $ures = sqlStatement("SELECT username, fname, lname FROM users " .
496 "WHERE username != '' AND active = 1 AND " .
497 "( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
498 "ORDER BY lname, fname");
499 while ($urow = sqlFetchArray($ures)) {
500 echo " <option value='" . attr($urow['username']) . "'";
501 echo ">" . text($urow['lname']);
502 if ($urow['fname']) {
503 echo ", " . text($urow['fname']);
505 echo "</option>\n";
508 </select>
509 </div>
510 <div class="col-6 col-sm-2 d-flex align-items-end flex-wrap">
511 <label class="oe-empty-label" for="users"></label>
512 <button type="button" name="clear_user" id="clear_user" class="btn btn-secondary btn-undo float-left flip" value="<?php echo xla('Clear'); ?>"><?php echo xlt('Clear'); ?></button>
513 </div>
514 </div>
515 <div class='col-12 oe-margin-t-3'>
516 <?php
517 if ($noteid) {
518 include "templates/linked_documents.php";
520 // Get the related procedure order IDs if any.
521 $tmp = sqlStatement(
522 "SELECT id1 FROM gprelations WHERE " .
523 "type1 = ? AND type2 = ? AND id2 = ?",
524 array('2', '6', $noteid)
526 if (sqlNumRows($tmp)) {
527 echo " <tr>\n";
528 echo " <td class='text'><span class='font-weight-bold'>" . xlt('Linked procedure order') . ":</span>\n";
529 while ($gprow = sqlFetchArray($tmp)) {
530 echo " <a href='";
531 echo $GLOBALS['webroot'] . "/interface/orders/single_order_results.php?orderid=";
532 echo attr_url($gprow['id1']);
533 echo "' target='_blank' onclick='top.restoreSession()'>";
534 echo text($gprow['id1']);
535 echo "</a>\n";
537 echo " </td>\n";
538 echo " </tr>\n";
542 </div>
543 </div>
544 <!-- <div class="row"> -->
545 <div class='col-12'>
546 <?php
547 if ($noteid) {
548 $body = preg_replace('/(:\d{2}\s\()' . $result['pid'] . '(\sto\s)/', '${1}' . $patientname . '${2}', $body);
549 $body = preg_replace('/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}\s\([^)(]+\s)(to)(\s[^)(]+\))/', '${1}' . xl('to{{Destination}}') . '${3}', $body);
550 $body = pnoteConvertLinks(nl2br(text(oeFormatPatientNote($body))));
551 echo "<div style='height: 120px; resize: vertical;' class='border overflow-auto text text-light bg-dark oe-margin-t-3 p-2 mb-2 w-100'>" . $body . "</div>";
554 <textarea name='note' id='note' class='form-control oe-margin-t-3 p-1 text-dark bg-light' rows="5"><?php echo nl2br(text($note)); ?></textarea>
555 </div>
556 <div class="col-12 position-override oe-margin-t-10">
557 <?php if ($noteid) { ?>
558 <!-- This is for displaying an existing note. -->
559 <button type="button" class="btn btn-primary btn-send-msg" id="newnote" value="<?php echo xla('Send message'); ?>"><?php echo xlt('Send message'); ?></button>
560 <button type="button" class="btn btn-primary btn-print" id="printnote" value="<?php echo xla('Print message'); ?>"><?php echo xlt('Print message'); ?></button>
561 <button type="button" class="btn btn-secondary btn-cancel" id="cancel" value="<?php echo xla('Cancel'); ?>"><?php echo xlt('Cancel'); ?></button>
562 <?php } else { ?>
563 <!-- This is for displaying a new note. -->
564 <button type="button" class="btn btn-primary btn-send-msg" id="newnote" value="<?php echo xla('Send message'); ?>"><?php echo xlt('Send message'); ?></button>
565 <button type="button" class="btn btn-cancel btn-secondary" id="cancel" value="<?php echo xla('Cancel'); ?>"><?php echo xlt('Cancel'); ?></button>
566 <?php }
568 </div>
569 <!-- </div> -->
570 </div>
571 </div>
572 </div>
573 </form>
574 <?php
575 } else {
576 for ($i = 0; $i < count($sort); $i++) {
577 $sortlink[$i] = "<a class='arrowhead' href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sort[$i]) . "&sortorder=asc&$activity_string_html\" onclick=\"top.restoreSession()\" alt=\"" . xla('Sort Up') . "\"><i class='fa fa-sort-down fa-lg' aria-hidden='true'></i></a>";
579 for ($i = 0; $i < count($sort); $i++) {
580 if ($sortby == $sort[$i]) {
581 switch ($sortorder) {
582 case "asc":
583 $sortlink[$i] = "<a class='arrowhead' href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=desc&$activity_string_html\" onclick=\"top.restoreSession()\" alt=\"" . xla('Sort Up') . "\"><i class='fa fa-sort-up fa-lg' aria-hidden='true'></i></a>";
584 break;
585 case "desc":
586 $sortlink[$i] = "<a class='arrowhead' href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=asc&$activity_string_html\" onclick=\"top.restoreSession()\" alt=\"" . xla('Sort Down') . "\"><i class='fa fa-sort-down fa-lg' aria-hidden='true'></i></a>";
587 break;
588 } break;
591 // Manage page numbering and display beneath the Messages table.
592 $listnumber = 25;
593 $total = getPnotesByUser($active, $show_all, $_SESSION['authUser'], true);
594 if ($begin == "" or $begin == 0) {
595 $begin = 0;
597 $prev = $begin - $listnumber;
598 $next = $begin + $listnumber;
599 $start = $begin + 1;
600 $end = $listnumber + $start - 1;
602 $chevron_icon_left = $_SESSION['language_direction'] == 'ltr' ? 'fa-chevron-circle-left' : 'fa-chevron-circle-right';
603 $chevron_icon_right = $_SESSION['language_direction'] == 'ltr' ? 'fa-chevron-circle-right' : 'fa-chevron-circle-left';
605 if ($end >= $total) {
606 $end = $total;
608 if ($end < $start) {
609 $start = 0;
611 if ($prev >= 0) {
612 $prevlink = "<a href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=" . attr($sortorder) . "&begin=" . attr($prev) . "&$activity_string_html\" onclick=\"top.restoreSession()\"><i class=\"fa " . $chevron_icon_left . " chevron_color\" aria-hidden=\"true\"></i></a>";
613 } else {
614 $prevlink = "<i class=\"fa " . $chevron_icon_left . " text-muted\" aria-hidden=\"true\" title=\"" . xla("On first page") . "\"></i>";
617 if ($next < $total) {
618 $nextlink = "<a href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=" . attr($sortorder) . "&begin=" . attr($next) . "&$activity_string_html\" onclick=\"top.restoreSession()\"><i class=\"fa . $chevron_icon_right . chevron_color\" aria-hidden=\"true\"></i></a>";
619 } else {
620 $nextlink = "<i class=\"fa " . $chevron_icon_right . " text-muted\" aria-hidden=\"true\" title=\"" . xla("On first page") . "\"></i>";
622 // Display the Messages table header.
623 echo "
624 <table class=\"w-100\">
625 <tr>
626 <td>
627 <form name='MessageList' id='MessageList' action=\"messages.php?showall=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=" . attr($sortorder) . "&begin=" . attr($begin) . "&$activity_string_html\" method='post'>
628 <table class='table table-sm table-hover w-100'>
629 <input type='hidden' name='task' value='delete' />
630 <thead class='table-primary'>
631 <tr height='24'>
632 <th align='center' width='25'><input type='checkbox' id='checkAll' onclick='selectAll()'></th>
633 <th width='20%' class='font-weight-bold'>&nbsp;" . xlt('From') . " $sortlink[0]</th>
634 <th width='20%' class='font-weight-bold'>&nbsp;" . xlt('Patient') . " $sortlink[1]</th>
635 <th class='font-weight-bold'>&nbsp;" . xlt('Type') . " $sortlink[2]</th>
636 <th width='15%' class='font-weight-bold'>&nbsp;" . xlt($GLOBALS['messages_due_date'] ? 'Due date' : 'Date') . " $sortlink[3]</th>
637 <th width='15%' class='font-weight-bold'>&nbsp;" . xlt('Status') . " $sortlink[4]</th>
638 </tr>
639 </thead>";
640 // Display the Messages table body.
641 $count = 0;
642 $result = getPnotesByUser($active, $show_all, $_SESSION['authUser'], false, $sortby, $sortorder, $begin, $listnumber);
643 while ($myrow = sqlFetchArray($result)) {
644 $name = $myrow['user'];
645 $name = $myrow['users_lname'];
646 if ($myrow['users_fname']) {
647 $name .= ", " . $myrow['users_fname'];
649 $patient = $myrow['pid'];
650 if ($patient > 0) {
651 $patient = $myrow['patient_data_lname'];
652 if ($myrow['patient_data_fname']) {
653 $patient .= ", " . $myrow['patient_data_fname'];
655 } else {
656 $patient = "* " . xl('Patient must be set manually') . " *";
658 $count++;
659 echo "
660 <tr id=\"row" . attr($count) . "\" height='24'>
661 <td align='center'>
662 <input type='checkbox' id=\"check" . attr($count) . "\" name=\"delete_id[]\" value=\"" .
663 attr($myrow['id']) . "\" onclick=\"if(this.checked==true){ selectRow('row" . attr(addslashes($count)) . "'); }else{ deselectRow('row" . attr(addslashes($count)) . "'); }\"></td>
664 <td>
665 <div>" . text($name) . "</div>
666 </td>
667 <td>
668 <div><a href=\"messages.php?showall=" . attr_url($showall) . "&sortby=" . attr_url($sortby) . "&sortorder=" . attr_url($sortorder) . "&begin=" . attr_url($begin) . "&task=edit&noteid=" .
669 attr_url($myrow['id']) . "&$activity_string_html\" onclick=\"top.restoreSession()\">" .
670 text($patient) . "</a></div>
671 </td>
672 <td>
673 <div>" .
674 xlt($myrow['title']) . "</div>
675 <td>
676 <div>" . text(oeFormatDateTime($myrow['date'])) . "</div>
677 </td>
678 <td>
679 <div>" . text(getListItemTitle('message_status', $myrow['message_status'])) . "</div>
680 </td>
681 </tr>";
683 // Display the Messages table footer.
685 echo " </table>
686 </form>
687 <div class='row oe-margin-t-10'>
689 <div class=\"col-12 col-md-12 col-lg-12\"><a href=\"messages.php?showall=" . attr_url($showall) . "&sortby=" . attr_url($sortby) . "&sortorder=" . attr_url($sortorder) . "&begin=" . attr_url($begin) . "&task=addnew&$activity_string_html\" class=\"btn btn-primary btn-add\" onclick=\"top.restoreSession()\">" .
690 xlt('Add New{{Message}}') . "</a> &nbsp; <a href=\"javascript:confirmDeleteSelected()\" class=\"btn btn-danger btn-delete\" onclick=\"top.restoreSession()\">" .
691 xlt('Delete') . "</a>";
693 if ($GLOBALS['phimail_enable']) {
694 echo "&nbsp; <a href='trusted-messages.php' onclick='top.restoreSession()' class='btn btn-secondary btn-mail'>" . xlt("Compose Trusted Direct Message") . "</a>";
695 echo "&nbsp; <button class='btn btn-secondary btn-refresh trusted-messages-force-check'>" . xlt("Check New Trusted Messages") . "</button>";
697 echo "
698 <div class=\"text-right\">$prevlink &nbsp; " . text($end) . " " . xlt('of') . " " . text($total) . " &nbsp; $nextlink</div>
699 </div>
700 </div>
701 </td>
702 </tr>
703 </table>
704 <br />";
707 <script>
708 // This is to confirm delete action.
709 function confirmDeleteSelected() {
710 var int_checked = 0;
711 var elem = document.forms.namedItem("MessageList").getElementsByTagName("input");
713 for (i=0; i < elem.length; i++){
714 if(elem[i].checked == true){
715 int_checked = ++int_checked;
718 if (int_checked > 0){
719 if (confirm("<?php echo xls('Do you really want to delete the selection?'); ?>")) {
720 document.MessageList.submit();
722 } else {
723 alert("<?php echo xls('Please select message(s) to delete'); ?>");
728 // This is to allow selection of all items in Messages table for deletion.
729 function selectAll() {
730 if (document.getElementById("checkAll").checked === true) {
731 document.getElementById("checkAll").checked = true;<?php
732 for ($i = 1; $i <= $count; $i++) {
733 echo "document.getElementById(\"check$i\").checked=true; document.getElementById(\"row$i\").style.background='var(--gray200)'; ";
734 } ?>
735 } else {
736 document.getElementById("checkAll").checked = false;<?php
737 for ($i = 1; $i <= $count; $i++) {
738 echo "document.getElementById(\"check$i\").checked=false; document.getElementById(\"row$i\").style.background='var(--light)'; ";
739 } ?>
743 // The two functions below are for managing row styles in Messages table.
744 function selectRow(row) {
745 document.getElementById(row).style.background = "var(--gray200)";
748 function deselectRow(row) {
749 document.getElementById(row).style.background = "var(--light)";
751 </script>
752 <?php
755 </div>
756 </div><!--end of messages div-->
757 <div class="row tab-pane" role="tabpanel" id="reminders-div">
758 <div class="col-sm-12">
759 <div class="mb-3">
760 <h4><?php echo xlt('Reminders'); ?></h4>
761 </div>
762 <?php require_once '../dated_reminders/dated_reminders.php'; ?>
763 </div>
764 </div><!--end of reminders div-->
765 <?php if ($GLOBALS['disable_rcb'] != '1') { ?>
766 <div class="row tab-pane" role="tabpanel" id="recalls-div">
767 <div class="col-sm-6 col-md-6 col-lg-6">
768 <h4><?php echo xlt('Recalls'); ?></h4>
769 <button class="btn btn-primary btn-add" onclick="goReminderRecall('addRecall');"><?php echo xlt('New Recall'); ?></button>
770 <a class="btn btn-secondary btn-transmit" onclick="goReminderRecall('Recalls');"><span><?php echo xlt('Recall Board'); ?></span></a>
771 </div>
772 </div><!--end of recalls div-->
773 <?php } ?>
774 <div class="row tab-pane" role="tabpanel" id="sms-div">
775 <div class="col-sm-4 col-md-4 col-lg-4">
776 <?php if ($logged_in) { ?>
777 <h4><?php echo xlt('SMS Zone'); ?></h4>
778 <form id="smsForm" class="input-group">
779 <select id="SMS_patient" type="text" class="form-control m-0 w-100" placeholder="<?php echo xla("Patient Name"); ?>"></select>
780 <span class="input-group-addon" onclick="SMS_direct();">&nbsp;&nbsp;<i id='open-sms-tooltip' class="fas fa-2x fa-phone"></i></span>
781 <input type="hidden" id="sms_pid" />
782 <input type="hidden" id="sms_mobile" value="" />
783 <input type="hidden" id="sms_allow" value="" />
784 </form>
785 <?php } ?>
786 </div>
787 </div><!--end of sms div-->
788 </div>
789 </div><!--end of container div-->
790 <?php $oemr_ui->oeBelowContainerDiv();?>
791 <?php
792 //home of the help modal ;)
793 //$GLOBALS['enable_help'] = 0; // Please comment out line if you want help modal to function on this page
794 if ($GLOBALS['enable_help'] == 1) {
795 echo "<script>var helpFile = 'message_center_help.php'</script>";
796 //help_modal.php lives in interface, set path accordingly
797 require "../../help_modal.php";
800 <script>
801 var collectvalidation = <?php echo $collectthis; ?>;
803 $(function () {
804 var webRoot = <?php echo js_escape($GLOBALS['web_root']); ?>;
806 $('.datetimepicker').datetimepicker({
807 <?php $datetimepicker_timepicker = true; ?>
808 <?php $datetimepicker_showseconds = false; ?>
809 <?php $datetimepicker_formatInput = true; ?>
810 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
811 ,minDate : 0 //only future
814 <?php if ($GLOBALS['phimail_enable']) : ?>
815 $('.trusted-messages-force-check').click(function() {
816 window.top.restoreSession();
817 request = new FormData;
818 request.append("ajax", "1");
819 request.append("csrf_token_form", <?php echo js_escape(CsrfUtils::collectCsrfToken()); ?>);
820 request.append("background_service", "phimail");
821 request.append("background_force", "1");
822 fetch(webRoot + "/library/ajax/execute_background_services.php", {
823 method: 'POST',
824 credentials: 'same-origin',
825 body: request
826 }).then((response) => {
827 if (response.status !== 200) {
828 console.log('Background Service refresh failed. Status Code: ' + response.status);
829 } else {
830 // we've refreshed give them time to reload the page
831 setTimeout(function() {
832 window.location.reload();
833 }, 500);
835 }).catch(function(error) {
836 console.log('Background Service refresh failed: ', error);
837 alert(window.xl("Check new messages failed. Check the server logs for more information."));
840 <?php endif; ?>
843 $(function () {
844 $( "ul.navbar-nav" ).children().click(function(){
845 $(".collapse").collapse('hide');
848 $(function () {
849 $('#see-all-tooltip').attr({"title": <?php echo xlj('Click to show messages for all users'); ?>, "data-toggle":"tooltip", "data-placement":"bottom"}).tooltip();
850 $('#just-mine-tooltip').attr({"title": <?php echo xlj('Click to show messages for only the current user'); ?>, "data-toggle":"tooltip", "data-placement":"bottom"}).tooltip();
851 $('#open-sms-tooltip').attr({"title": <?php echo xlj('Click to open SMS for patient'); ?>, "data-toggle":"tooltip", "data-placement":"bottom"}).tooltip();
853 $(function () {
854 var f = $("#smsForm");
855 $("#SMS_patient").select2({
856 ajax: {
857 url: "save.php",
858 dataType: 'json',
859 data: function(params) {
860 return {
861 go: "sms_search",
862 term: params.term
865 processResults: function(data) {
866 return {
867 results: $.map(data, function(item, index) {
868 return {
869 text: item.value,
870 id: index,
871 value: item.Label + ' ' + item.mobile,
872 pid: item.pid,
873 mobile: item.mobile,
874 allow: item.allow
879 cache: true
881 dropdownAutoWidth: true,
882 placeholder: xl('Search for patient...'),
883 theme: 'bootstrap4'
886 $('#SMS_patient').on('select2:select', function (e) {
887 e.preventDefault();
888 $("#SMS_patient").val(e.params.data.value);
889 $("#sms_pid").val(e.params.data.pid);
890 $("#sms_mobile").val(e.params.data.mobile);
891 $("#sms_allow").val(e.params.data.allow);
895 $(function () {
896 $("#newnote").click(function (event) {
897 NewNote(event);
900 $("#printnote").click(function () {
901 PrintNote();
904 var obj = $("#form_message_status");
905 obj.onchange = function () {
906 SaveNote();
909 $("#cancel").click(function () {
910 CancelNote();
913 $("#form_patient").focus();
915 //clear button in messages
916 $("#clear_user").click(function(){
917 $("#assigned_to_text").val("<?php echo xls('Select Users From The Dropdown List'); ?>");
918 $("#assigned_to").val("");
919 $("#users").val("--");
922 //clear inputs of patients
923 $("#clear_patients").click(function(){
924 $("#reply_to").val("");
925 $("#form_patient").val("");
929 var NewNote = function (event) {
930 top.restoreSession();
931 if(document.getElementById("form_message_status").value !== 'Done'){
932 collectvalidation.assigned_to = {
933 presence: {message: "<?php echo xls('Recipient required unless status is Done'); ?>"}
936 else{
937 delete collectvalidation.assigned_to;
940 if(document.getElementById("form_message_status").value == 'Done'){
941 delete collectvalidation.note;
944 $('#newnote').attr('disabled', true);
946 const submit = submitme(1, event, 'new_note', collectvalidation);
947 if(!submit){
948 $('#newnote').attr('disabled', false);
950 else {
951 $("#new_note").submit();
954 var PrintNote = function () {
955 <?php if ($noteid) { ?>
956 top.restoreSession();
957 window.open('../../patient_file/summary/pnotes_print.php?noteid=' + <?php echo js_url($noteid); ?>, '_blank', 'resizable=1,scrollbars=1,width=600,height=500');
958 <?php } ?>
962 var SaveNote = function () {
963 <?php if ($noteid) { ?>
964 top.restoreSession();
965 $("#task").val("save");
966 $("#new_note").submit();
967 <?php } ?>
970 var CancelNote = function () {
971 top.restoreSession();
972 $("#task").val("");
973 $("#new_note").submit();
976 // This is for callback by the find-patient popup.
977 function setpatient(pid, lname, fname, dob) {
978 var f = document.getElementById('new_note');
979 f.form_patient.value += lname + ', ' + fname + '; ';
980 f.reply_to.value += pid + ';';
981 <?php if ($noteid) { ?>
982 //used when direct messaging service inserts a pnote with indeterminate patient
983 //to allow the user to assign the message to a patient.
984 top.restoreSession();
985 $("#task").val("savePatient");
986 $("#new_note").submit();
987 <?php } ?>
990 // This is for callback by the multi_patients_finder popup.
991 function setMultiPatients(patientsList) {
992 var f = document.getElementById('new_note');
993 f.form_patient.value='';
994 f.reply_to.value='';
995 $.each(patientsList, function (key, patient) {
996 f.form_patient.value += patient.lname + ', ' + patient.fname + '; ';
997 f.reply_to.value += patient.pid + ';';
1000 <?php if ($noteid) { ?>
1001 //used when direct messaging service inserts a pnote with indeterminate patient
1002 //to allow the user to assign the message to a patient.
1003 top.restoreSession();
1004 $("#task").val("savePatient");
1005 $("#new_note").submit();
1006 <?php } ?>
1009 // This invokes the find-patient popup.
1010 function sel_patient() {
1011 dlgopen('../../main/calendar/find_patient_popup.php', '_blank', 625, 400);
1014 function multi_sel_patient() {
1015 $('#reply_to').trigger('click');
1016 var url = '../../main/finder/multi_patients_finder.php'
1017 // for edit selected list
1018 if ($('#reply_to').val() !== '') {
1019 url = url + '?patients=' + $('#reply_to').val() + '&csrf_token_form=<?php echo attr_url(CsrfUtils::collectCsrfToken()); ?>';
1021 dlgopen(url, '_blank', 625, 400);
1024 function addtolist(sel) {
1025 $('#assigned_to').trigger("click");
1026 var itemtext = document.getElementById('assigned_to_text');
1027 var item = document.getElementById('assigned_to');
1028 if (sel.value !== '--') {
1029 if (item.value) {
1030 if (item.value.indexOf(sel.value) === -1) {
1031 itemtext.value = itemtext.value + ' ; ' + sel.options[sel.selectedIndex].text;
1032 item.value = item.value + ';' + sel.value;
1034 } else {
1035 itemtext.value = sel.options[sel.selectedIndex].text;
1036 item.value = sel.value;
1041 function SMS_direct() {
1042 var pid = $("#sms_pid").val();
1043 var m = $("#sms_mobile").val();
1044 var allow = $("#sms_allow").val();
1045 if ((pid === '') || (m === '')) {
1046 alert('<?php echo xls("MedEx needs a valid mobile number to send SMS messages..."); ?>');
1047 } else if (allow === 'NO') {
1048 alert('<?php echo xls("This patient does not allow SMS messaging!"); ?>');
1049 } else {
1050 top.restoreSession();
1051 window.open('messages.php?nomenu=1&go=SMS_bot&pid=' + encodeURIComponent(pid) + '&m=' + encodeURIComponent(m), 'SMS_bot', 'width=370,height=600,resizable=0');
1055 $(function () {
1056 const attachment = <?php echo js_escape($_REQUEST['jobId'] ?? '') ?>;
1057 const attach = <?php echo js_escape($_REQUEST['attach'] ?? '') ?>;
1058 if (attachment && attach) {
1059 let el = document.createElement('label').innerText = xl("Attaching Fax Id") + ": " + jsText(attachment);
1060 document.getElementById('note').after(el);
1063 function viewFaxAttachment(e, docid) {
1064 let actionUrl = top.webroot_url + '/interface/modules/custom_modules/oe-module-faxsms/viewFax?type=fax';
1065 if (e) {
1066 e.preventDefault();
1068 try {
1069 top.restoreSession();
1070 } catch (error) {
1071 console.log('Session restore failed!');
1073 $.post(actionUrl, {
1074 'type': 'fax',
1075 'docuri': '',
1076 'docid': docid,
1077 'pid': '',
1078 'download': ''
1079 }).done(function (json) {
1080 try {
1081 data = JSON.parse(json);
1082 } catch {
1083 data = json;
1085 const binary = atob(data.base64.replace(/\s/g, ''));
1086 const len = binary.length;
1087 const buffer = new ArrayBuffer(len);
1088 const view = new Uint8Array(buffer);
1089 for (let i = 0; i < len; i++) {
1090 view[i] = binary.charCodeAt(i);
1092 const blob = new Blob([view], {type: data.mime});
1093 const dataUrl = URL.createObjectURL(blob);
1094 let width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ?
1095 document.documentElement.clientWidth : screen.width;
1096 let height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ?
1097 document.documentElement.clientHeight : screen.height;
1098 height = screen.height ? screen.height * 0.95 : height;
1099 let left = (width / 4);
1100 let top = '10';
1101 let win = window.open(
1102 '', '',
1103 'toolbar=0, location=0, directories=0, status=0, menubar=0, ' +
1104 'scrollbars=0, resizable=0, copyhistory=0, ' +
1105 'width=' + width / 1.75 + ', height=' + height + ', top=' + top + ', left=' + left
1107 win.document.write("<iframe width='100%' height='100%' style='border:none;' src='" + dataUrl + "'></iframe>");
1109 return false;
1111 </script>
1112 <?php
1115 </body>
1116 </html>