Merge pull request #627 from MatthewVita/message_broken_link_fix
[openemr.git] / patients / get_patient_documents.php
blob234cc2ff39ac30b45251e89a0a1ab8c6bc36b8d3
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 * Copyright (C) 2015 Terry Hill <terry@lillysystems.com>
10 * Copyright (C) 2012 Giorgos Vasilakos <giorg.vasilakos@gmail.com>
12 * LICENSE: This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 3
15 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
23 * @package OpenEMR
24 * @author Terry Hill <terry@lilysystems.com>
25 * @author Giorgos Vasilakos <giorg.vasilakos@gmail.com>
26 * @link http://www.open-emr.org
30 require_once("verify_session.php");
31 include_once("$srcdir/documents.php");
32 require_once($GLOBALS['fileroot'] . "/controllers/C_Document.class.php");
34 // TODO: see if this can be removed (test in PHP 5 and 7)... throwing a warning
35 use C_Document;
37 // get the temporary folder
38 $tmp = $GLOBALS['temporary_files_dir'];
39 // get all the documents of the patient
40 $sql = "SELECT url, id, mimetype FROM `documents` WHERE `foreign_id` = ?";
41 $fres = sqlStatement($sql, array($pid));
43 // for every document
44 while ($file = sqlFetchArray($fres)) {
45 // find the document category
46 $sql = "SELECT name, lft, rght FROM `categories`, `categories_to_documents`
47 WHERE `categories_to_documents`.`category_id` = `categories`.`id`
48 AND `categories_to_documents`.`document_id` = ?";
49 $catres = sqlStatement($sql, array($file['id']));
50 $cat = sqlFetchArray($catres);
52 // find the tree of the documents category
53 $sql = "SELECT name FROM categories WHERE lft < ? AND rght > ? ORDER BY lft ASC";
54 $pathres = sqlStatement($sql, array($cat['lft'], $cat['rght']));
56 // create the tree of the categories
57 $path = "";
58 while ($parent = sqlFetchArray($pathres)) {
59 $path .= convert_safe_file_dir_name($parent['name'])."/";
61 $path .= convert_safe_file_dir_name($cat['name'])."/";
62 // create the folder structure at the temporary dir
63 if (!is_dir($tmp."/".$pid."/".$path)) {
64 if (!mkdir($tmp."/".$pid."/".$path, 0777, true )){
65 echo xlt("Error creating directory!")."<br />";
69 // copy the document
70 $documentId = $file['id'];
71 $obj = new \C_Document();
72 $document = $obj->retrieve_action("", $documentId, true, true, true);
73 if ($document) {
74 $pos = strpos(substr($file['url'], -5), '.');
75 // check if has an extension or find it from the mimetype
76 if ($pos === false) {
77 $file['url'] = $file['url'].get_extension($file['mimetype']);
79 $dest = $tmp."/".$pid."/".$path."/".convert_safe_file_dir_name(basename($file['url']));
80 if (file_exists($dest)) {
81 $x = 1;
82 do {
83 $dest = $tmp."/".$pid."/".$path."/". $x ."_".convert_safe_file_dir_name(basename($file['url']));
84 $x++;
85 } while (file_exists($dest));
87 file_put_contents($dest,$document);
89 else {
90 echo xlt("Can't find file!")."<br />";
94 // zip the folder
95 Zip($tmp."/".$pid."/", $tmp."/".$pid.'.zip');
97 // serve it to the patient
98 header('Content-type: application/zip');
99 header('Content-Disposition: attachment; filename="patient_documents.zip"');
100 readfile($tmp."/".$pid.'.zip');
102 // remove the temporary folders and files
103 recursive_remove_directory($tmp."/".$pid);
104 unlink($tmp."/".$pid.'.zip');
106 function recursive_remove_directory($directory, $empty=FALSE) {
107 if(substr($directory,-1) == '/') {
108 $directory = substr($directory,0,-1);
110 if(!file_exists($directory) || !is_dir($directory)) {
111 return FALSE;
112 } elseif(is_readable($directory)) {
113 $handle = opendir($directory);
114 while (FALSE !== ($item = readdir($handle))) {
115 if($item != '.' && $item != '..') {
116 $path = $directory.'/'.$item;
117 if(is_dir($path)) {
118 recursive_remove_directory($path);
119 } else {
120 unlink($path);
124 closedir($handle);
125 if($empty == FALSE) {
126 if(!rmdir($directory)) {
127 return FALSE;
131 return TRUE;
135 function Zip($source, $destination) {
136 if (!extension_loaded('zip') || !file_exists($source)) {
137 return false;
139 $zip = new ZipArchive();
140 if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
141 return false;
143 $source = str_replace('\\', '/', realpath($source));
144 if (is_dir($source) === true) {
145 $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
146 foreach ($files as $file) {
147 if($file == $source."/..")
148 continue;
149 $file = str_replace('\\', '/', realpath($file));
150 if (is_dir($file) === true) {
151 $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
153 else if (is_file($file) === true) {
154 $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
158 else if (is_file($source) === true) {
159 $zip->addFromString(basename($source), file_get_contents($source));
161 return $zip->close();