4 * Download documents from OpenEMR to the patient portal in a zip file(get_patient_documents.php)
5 * This program is used to download patient documents in a zip file in the Patient Portal.
6 * Added parse and show documents for selection instead of all by default
7 * The original author did not pursue this but I thought it would be a good addition to
11 * @link https://www.open-emr.org
12 * @author Giorgos Vasilakos <giorg.vasilakos@gmail.com>
13 * @author Terry Hill <terry@lilysystems.com>
14 * @author Stephen Waite <stephen.waite@cmsvt.com>
15 * @author Jerry Padgett <sjpadgett@gmail.com>
16 * @copyright Copyright (c) 2012 Giorgos Vasilakos <giorg.vasilakos@gmail.com>
17 * @copyright Copyright (c) 2015-2017 Terry Hill <terry@lillysystems.com>
18 * @copyright Copyright (c) 2019 Stephen Waite <stephen.waite@cmsvt.com>
19 * @copyright Copyright (c) 2017-2024 Jerry Padgett <sjpadgett@gmail.com>
20 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
23 require_once("./verify_session.php");
25 * @Global $srcdir openemr src folder, setup during verify_session.php
27 require_once("$srcdir/documents.php");
28 require_once($GLOBALS['fileroot'] . "/controllers/C_Document.class.php");
30 use OpenEMR\Common\Csrf\CsrfUtils
;
31 use OpenEMR\Core\Header
;
33 // Get all the documents of the patient
34 $sql = "SELECT url, id, mimetype, `name` FROM `documents` WHERE `foreign_id` = ? AND `deleted` = 0";
36 * @Global $pid Patient id setup during verify_session.php
38 $fres = sqlStatement($sql, array($pid));
41 while ($file = sqlFetchArray($fres)) {
42 // Find the document category
43 $sql = "SELECT name, lft, rght FROM `categories`, `categories_to_documents`
44 WHERE `categories_to_documents`.`category_id` = `categories`.`id`
45 AND `categories_to_documents`.`document_id` = ?";
46 $catres = sqlStatement($sql, array($file['id']));
47 $cat = sqlFetchArray($catres);
49 // Find the tree of the document's category
50 $sql = "SELECT name FROM categories WHERE lft < ? AND rght > ? ORDER BY lft ASC";
51 $pathres = sqlStatement($sql, array($cat['lft'], $cat['rght']));
53 // Create the tree of the categories
55 while ($parent = sqlFetchArray($pathres)) {
56 $displayPath .= $parent['name'] . "/";
59 $displayPath .= $cat['name'] . "/";
61 // Store documents under their categories
62 $category = $displayPath;
63 if (!isset($documents[$category])) {
64 $documents[$category] = [];
66 $documents[$category][] = [
68 'name' => $file['name'],
69 'displayPath' => $displayPath
77 <title
><?php
echo xlt("Download On File Documents"); ?
></title
>
78 <?php Header
::setupHeader(['no_main-theme', 'portal-theme']); ?
>
80 // Function to toggle all checkboxes
81 function toggleCheckboxes(className
, sourceCheckbox
) {
82 let checkboxes
= document
.querySelectorAll('.' + className
);
83 for (let i
= 0; i
< checkboxes
.length
; i++
) {
84 checkboxes
[i
].checked
= sourceCheckbox
.checked
;
88 // Function to toggle all checkboxes in the form
89 function toggleAllCheckboxes(sourceCheckbox
) {
90 let checkboxes
= document
.querySelectorAll('input[type="checkbox"]');
91 for (let i
= 0; i
< checkboxes
.length
; i++
) {
92 checkboxes
[i
].checked
= sourceCheckbox
.checked
;
96 // Function to normalize category names for use as class names
97 function normalizeClassName(category
) {
98 return category
.replace(/[^a
-zA
-Z0
-9]/g
, '-');
101 // Function to validate form submission
102 function validateForm(event
) {
103 let checkboxes
= document
.querySelectorAll('input[type="checkbox"]:checked');
104 if (checkboxes
.length
=== 0) {
105 alert(<?php
echo xlj("Please select at least one document to download.") ?
>);
106 event
.preventDefault(); // Prevent form submission
112 <div
class="container-fluid">
113 <h4
><?php
echo xlt("Select Documents to Download"); ?
></h4
>
114 <form id
="download-form" action
="report/document_downloads_action.php" method
="post" onsubmit
="validateForm(event)">
115 <input type
="hidden" name
="csrf_token_form" value
="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
116 <div
class="form-check mb-3">
117 <input
class="form-check-input" type
="checkbox" id
="selectAll" onclick
="toggleAllCheckboxes(this)">
118 <label
class="form-check-label" for="selectAll"><?php
echo xlt("Select All Documents"); ?
></label
>
121 <?php
foreach ($documents as $category => $docs) {
122 $title = str_replace("Categories/", "", $category);
123 if (empty($title)) { // files stored in the root folder so we just set it to be '/'
124 $normalizedTitle = "/";
126 $normalizedTitle = $title;
128 $normalizedCategory = preg_replace('/[^a-zA-Z0-9]/', '', $title);
130 <div
class="col-md-6">
131 <div
class="card mb-4">
132 <div
class="card-header d-flex justify-content-between align-items-center">
133 <h5
class="mb-0"><?php
echo text($normalizedTitle); ?
></h5
>
134 <div
class="form-check">
135 <input
class="form-check-input" type
="checkbox" id
="selectAll<?php echo attr($normalizedCategory); ?>" onclick
="toggleCheckboxes('category-<?php echo attr($normalizedCategory); ?>', this)">
136 <label
class="form-check-label" for="selectAll<?php echo attr($normalizedCategory); ?>"><?php
echo xlt("Select All"); ?
></label
>
139 <div
class="card-body">
140 <?php
foreach ($docs as $doc) { ?
>
141 <div
class="form-check">
142 <input
class="form-check-input category-<?php echo attr($normalizedCategory); ?>" type
="checkbox" name
="documents[]" value
="<?php echo attr($doc['id']); ?>" id
="doc<?php echo attr($doc['id']); ?>">
143 <label
class="form-check-label" for="doc<?php echo attr($doc['id']); ?>">
144 <?php
echo text($doc['name']); ?
>
154 <div
class="col-12 text-right mb-2">
155 <button type
="submit" class="btn btn-primary mt-1"><?php
echo xlt("Download Selected Documents"); ?
></button
>
158 <p
class="alert alert-info"><i
class="fa fa-info-circle"></i
><?php
echo xlt("Your files will download as a zip file"); ?
></p
>