Merge branch 'master' of https://github.com/openemr/openemr into signer-templates
[openemr.git] / portal / get_patient_documents.php
blobebcae4c67b6587d646112752d98a2eff0a956875
1 <?php
2 /**
3 * 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 * The original author did not pursue this but I thought it would be a good addition to
7 * the patient portal
9 * @package OpenEMR
10 * @link https://www.open-emr.org
11 * @author Giorgos Vasilakos <giorg.vasilakos@gmail.com>
12 * @author Terry Hill <terry@lilysystems.com>
13 * @author Stephen Waite <stephen.waite@cmsvt.com>
14 * @copyright Copyright (c) 2012 Giorgos Vasilakos <giorg.vasilakos@gmail.com>
15 * @copyright Copyright (c) 2015-2017 Terry Hill <terry@lillysystems.com>
16 * @copyright Copyright (c) 2019 Stephen Waite <stephen.waite@cmsvt.com>
17 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
20 require_once("verify_session.php");
21 require_once("$srcdir/documents.php");
22 require_once($GLOBALS['fileroot'] . "/controllers/C_Document.class.php");
24 // get the temporary folder
25 $tmp = $GLOBALS['temporary_files_dir'];
26 // get all the documents of the patient
27 $sql = "SELECT url, id, mimetype FROM `documents` WHERE `foreign_id` = ?";
28 $fres = sqlStatement($sql, array($pid));
30 // for every document
31 while ($file = sqlFetchArray($fres)) {
32 // find the document category
33 $sql = "SELECT name, lft, rght FROM `categories`, `categories_to_documents`
34 WHERE `categories_to_documents`.`category_id` = `categories`.`id`
35 AND `categories_to_documents`.`document_id` = ?";
36 $catres = sqlStatement($sql, array($file['id']));
37 $cat = sqlFetchArray($catres);
39 // find the tree of the documents category
40 $sql = "SELECT name FROM categories WHERE lft < ? AND rght > ? ORDER BY lft ASC";
41 $pathres = sqlStatement($sql, array($cat['lft'], $cat['rght']));
43 // create the tree of the categories
44 $path = "";
45 while ($parent = sqlFetchArray($pathres)) {
46 $path .= convert_safe_file_dir_name($parent['name'])."/";
49 $path .= convert_safe_file_dir_name($cat['name'])."/";
50 // create the folder structure at the temporary dir
51 if (!is_dir($tmp."/".$pid."/".$path)) {
52 if (!mkdir($tmp."/".$pid."/".$path, 0777, true)) {
53 echo xlt("Error creating directory!")."<br />";
57 // copy the document
58 $documentId = $file['id'];
59 $obj = new \C_Document();
60 $document = $obj->retrieve_action("", $documentId, true, true, true);
61 if ($document) {
62 $pos = strpos(substr($file['url'], -5), '.');
63 // check if has an extension or find it from the mimetype
64 if ($pos === false) {
65 $file['url'] = $file['url'].get_extension($file['mimetype']);
68 $dest = $tmp."/".$pid."/".$path."/".convert_safe_file_dir_name(basename($file['url']));
69 if (file_exists($dest)) {
70 $x = 1;
71 do {
72 $dest = $tmp."/".$pid."/".$path."/". $x ."_".convert_safe_file_dir_name(basename($file['url']));
73 $x++;
74 } while (file_exists($dest));
77 file_put_contents($dest, $document);
78 } else {
79 echo xlt("Can't find file!")."<br />";
83 // zip the folder
84 Zip($tmp."/".$pid."/", $tmp."/".$pid.'.zip');
86 // serve it to the patient
87 header('Content-type: application/zip');
88 header('Content-Disposition: attachment; filename="patient_documents.zip"');
89 readfile($tmp."/".$pid.'.zip');
91 // remove the temporary folders and files
92 recursive_remove_directory($tmp."/".$pid);
93 unlink($tmp."/".$pid.'.zip');
95 function recursive_remove_directory($directory, $empty = false)
97 if (substr($directory, -1) == '/') {
98 $directory = substr($directory, 0, -1);
101 if (!file_exists($directory) || !is_dir($directory)) {
102 return false;
103 } elseif (is_readable($directory)) {
104 $handle = opendir($directory);
105 while (false !== ($item = readdir($handle))) {
106 if ($item != '.' && $item != '..') {
107 $path = $directory.'/'.$item;
108 if (is_dir($path)) {
109 recursive_remove_directory($path);
110 } else {
111 unlink($path);
116 closedir($handle);
117 if ($empty == false) {
118 if (!rmdir($directory)) {
119 return false;
124 return true;
128 function Zip($source, $destination)
130 if (!extension_loaded('zip') || !file_exists($source)) {
131 return false;
134 $zip = new ZipArchive();
135 if (!$zip->open($destination, ZipArchive::CREATE)) {
136 return false;
139 $source = str_replace('\\', '/', realpath($source));
140 if (is_dir($source) === true) {
141 $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
142 foreach ($files as $file) {
143 if ($file == $source."/..") {
144 continue;
147 $file = str_replace('\\', '/', realpath($file));
148 if (is_dir($file) === true) {
149 $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
150 } else if (is_file($file) === true) {
151 $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
154 } else if (is_file($source) === true) {
155 $zip->addFromString(basename($source), file_get_contents($source));
158 return $zip->close();