for vscoders (#4037)
[openemr.git] / portal / get_patient_documents.php
blob32dac59932b2ac643d3a17e71ef6863ec7d01516
1 <?php
3 /**
4 * Download documents from OpenEMR to the patient portal in a zip file(get_patient_documents.php)
6 * This program is used to download patient documents in a zip file in the Patient Portal.
7 * The original author did not pursue this but I thought it would be a good addition to
8 * the patient portal
10 * @package OpenEMR
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 * @copyright Copyright (c) 2012 Giorgos Vasilakos <giorg.vasilakos@gmail.com>
16 * @copyright Copyright (c) 2015-2017 Terry Hill <terry@lillysystems.com>
17 * @copyright Copyright (c) 2019 Stephen Waite <stephen.waite@cmsvt.com>
18 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
21 require_once("verify_session.php");
22 require_once("$srcdir/documents.php");
23 require_once($GLOBALS['fileroot'] . "/controllers/C_Document.class.php");
25 // get the temporary folder
26 $tmp = $GLOBALS['temporary_files_dir'];
27 // get all the documents of the patient
28 $sql = "SELECT url, id, mimetype, `name` FROM `documents` WHERE `foreign_id` = ? AND `deleted` = 0";
29 $fres = sqlStatement($sql, array($pid));
31 // for every document
32 while ($file = sqlFetchArray($fres)) {
33 // find the document category
34 $sql = "SELECT name, lft, rght FROM `categories`, `categories_to_documents`
35 WHERE `categories_to_documents`.`category_id` = `categories`.`id`
36 AND `categories_to_documents`.`document_id` = ?";
37 $catres = sqlStatement($sql, array($file['id']));
38 $cat = sqlFetchArray($catres);
40 // find the tree of the documents category
41 $sql = "SELECT name FROM categories WHERE lft < ? AND rght > ? ORDER BY lft ASC";
42 $pathres = sqlStatement($sql, array($cat['lft'], $cat['rght']));
44 // create the tree of the categories
45 $path = "";
46 while ($parent = sqlFetchArray($pathres)) {
47 $path .= convert_safe_file_dir_name($parent['name']) . "/";
50 $path .= convert_safe_file_dir_name($cat['name']) . "/";
51 // create the folder structure at the temporary dir
52 if (!is_dir($tmp . "/" . $pid . "/" . $path)) {
53 if (!mkdir($tmp . "/" . $pid . "/" . $path, 0777, true)) {
54 echo xlt("Error creating directory!") . "<br />";
58 // copy the document
59 $documentId = $file['id'];
60 $obj = new \C_Document();
61 $document = $obj->retrieve_action("", $documentId, true, true, true);
62 if ($document) {
63 $pos = strpos(substr($file['name'], -5), '.');
64 // check if has an extension or find it from the mimetype
65 if ($pos === false) {
66 $file['name'] = $file['name'] . get_extension($file['mimetype']);
69 $dest = $tmp . "/" . $pid . "/" . $path . "/" . convert_safe_file_dir_name($file['name']);
70 if (file_exists($dest)) {
71 $x = 1;
72 do {
73 $dest = $tmp . "/" . $pid . "/" . $path . "/" . $x . "_" . convert_safe_file_dir_name($file['name']);
74 $x++;
75 } while (file_exists($dest));
78 file_put_contents($dest, $document);
79 } else {
80 echo xlt("Can't find file!") . "<br />";
84 // zip the folder
85 Zip($tmp . "/" . $pid . "/", $tmp . "/" . $pid . '.zip');
87 // serve it to the patient
88 header('Content-type: application/zip');
89 header('Content-Disposition: attachment; filename="patient_documents.zip"');
90 readfile($tmp . "/" . $pid . '.zip');
92 // remove the temporary folders and files
93 recursive_remove_directory($tmp . "/" . $pid);
94 unlink($tmp . "/" . $pid . '.zip');
96 function recursive_remove_directory($directory, $empty = false)
98 if (substr($directory, -1) == '/') {
99 $directory = substr($directory, 0, -1);
102 if (!file_exists($directory) || !is_dir($directory)) {
103 return false;
104 } elseif (is_readable($directory)) {
105 $handle = opendir($directory);
106 while (false !== ($item = readdir($handle))) {
107 if ($item != '.' && $item != '..') {
108 $path = $directory . '/' . $item;
109 if (is_dir($path)) {
110 recursive_remove_directory($path);
111 } else {
112 unlink($path);
117 closedir($handle);
118 if ($empty == false) {
119 if (!rmdir($directory)) {
120 return false;
125 return true;
129 function Zip($source, $destination)
131 if (!extension_loaded('zip') || !file_exists($source)) {
132 return false;
135 $zip = new ZipArchive();
136 if (!$zip->open($destination, ZipArchive::CREATE)) {
137 return false;
140 $source = str_replace('\\', '/', realpath($source));
141 if (is_dir($source) === true) {
142 $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
143 foreach ($files as $file) {
144 if ($file == $source . "/..") {
145 continue;
148 $file = str_replace('\\', '/', realpath($file));
149 if (is_dir($file) === true) {
150 $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
151 } elseif (is_file($file) === true) {
152 $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
155 } elseif (is_file($source) === true) {
156 $zip->addFromString(basename($source), file_get_contents($source));
159 return $zip->close();