示例#1
0
 /**
  * Create a new document and store its data.
  * This is a mix of new code and code moved from C_Document.class.php.
  *
  * @param  string  $patient_id   Patient pid; if not known then this may be a simple directory name
  * @param  integer $category_id  The desired document category ID
  * @param  string  $filename     Desired filename, may be modified for uniqueness
  * @param  string  $mimetype     MIME type
  * @param  string  &$data        The actual data to store (not encoded)
  * @param  string  $higher_level_path Optional subdirectory within the local document repository
  * @param  string  $path_depth   Number of directory levels in $higher_level_path, if specified
  * @param  integer $owner        Owner/user/service that is requesting this action
  * @return string                Empty string if success, otherwise error message text
  */
 function createDocument($patient_id, $category_id, $filename, $mimetype, &$data, $higher_level_path = '', $path_depth = 1, $owner = 0)
 {
     // The original code used the encounter ID but never set it to anything.
     // That was probably a mistake, but we reference it here for documentation
     // and leave it empty. Logically, documents are not tied to encounters.
     $encounter_id = '';
     $this->storagemethod = $GLOBALS['document_storage_method'];
     $this->mimetype = $mimetype;
     if ($this->storagemethod == 1) {
         // Store it using CouchDB.
         $couch = new CouchDB();
         $docname = $_SESSION['authId'] . $filename . $patient_id . $encounter_id . date("%Y-%m-%d H:i:s");
         $docid = $couch->stringToId($docname);
         $json = json_encode(base64_encode($data));
         $db = $GLOBALS['couchdb_dbase'];
         $couchdata = array($db, $docid, $patient_id, $encounter_id, $mimetype, $json);
         $resp = $couch->check_saveDOC($couchdata);
         if (!$resp->id || !$resp->_rev) {
             // Not sure what this is supposed to do.  The references to id, rev,
             // _id and _rev seem pretty weird.
             $couchdata = array($db, $docid, $patient_id, $encounter_id);
             $resp = $couch->retrieve_doc($couchdata);
             $docid = $resp->_id;
             $revid = $resp->_rev;
         } else {
             $docid = $resp->id;
             $revid = $resp->rev;
         }
         if (!$docid && !$revid) {
             return xl('CouchDB save failed');
         }
         $this->url = $filename;
         $this->couch_docid = $docid;
         $this->couch_revid = $revid;
     } else {
         // Storing document files locally.
         $repository = $GLOBALS['oer_config']['documents']['repository'];
         $higher_level_path = preg_replace("/[^A-Za-z0-9\\/]/", "_", $higher_level_path);
         if (!empty($higher_level_path) && (is_numeric($patient_id) && $patient_id > 0)) {
             // Allow higher level directory structure in documents directory and a patient is mapped.
             $filepath = $repository . $higher_level_path . "/";
         } else {
             if (!empty($higher_level_path)) {
                 // Allow higher level directory structure in documents directory and there is no patient mapping
                 // (will create up to 10000 random directories and increment the path_depth by 1).
                 $filepath = $repository . $higher_level_path . '/' . rand(1, 10000) . '/';
                 ++$path_depth;
             } else {
                 if (!is_numeric($patient_id) || !($patient_id > 0)) {
                     // This is the default action except there is no patient mapping (when patient_id is 00 or direct)
                     // (will create up to 10000 random directories and set the path_depth to 2).
                     $filepath = $repository . $patient_id . '/' . rand(1, 10000) . '/';
                     $path_depth = 2;
                     $patient_id = 0;
                 } else {
                     // This is the default action where the patient is used as one level directory structure in documents directory.
                     $filepath = $repository . $patient_id . '/';
                     $path_depth = 1;
                 }
             }
         }
         if (!file_exists($filepath)) {
             if (!mkdir($filepath, 0700, true)) {
                 return xl('Unable to create patient document subdirectory');
             }
         }
         // Filename modification to force valid characters and uniqueness.
         $filename = preg_replace("/[^a-zA-Z0-9_.]/", "_", $filename);
         $fnsuffix = 0;
         $fn1 = $filename;
         $fn2 = '';
         $fn3 = '';
         $dotpos = strrpos($filename, '.');
         if ($dotpos !== FALSE) {
             $fn1 = substr($filename, 0, $dotpos);
             $fn2 = '.';
             $fn3 = substr($filename, $dotpos + 1);
         }
         while (file_exists($filepath . $filename)) {
             if (++$fnsuffix > 10000) {
                 return xl('Failed to compute a unique filename');
             }
             $filename = $fn1 . '_' . $fnsuffix . $fn2 . $fn3;
         }
         $this->url = "file://" . $filepath . $filename;
         if (is_numeric($path_depth)) {
             // this is for when directory structure is more than one level
             $this->path_depth = $path_depth;
         }
         // Store the file into its proper directory.
         if (file_put_contents($filepath . $filename, $data) === FALSE) {
             return xl('Failed to create') . " {$filepath}{$filename}";
         }
     }
     $this->size = strlen($data);
     $this->hash = sha1($data);
     $this->type = $this->type_array['file_url'];
     $this->owner = $owner ? $owner : $_SESSION['authUserID'];
     $this->set_foreign_id($patient_id);
     $this->persist();
     $this->populate();
     if (is_numeric($this->get_id()) && is_numeric($category_id)) {
         $sql = "REPLACE INTO categories_to_documents set " . "category_id = '{$category_id}', " . "document_id = '" . $this->get_id() . "'";
         $this->_db->Execute($sql);
     }
     return '';
 }
示例#2
0
 function upload_action_process()
 {
     $couchDB = false;
     $harddisk = false;
     if ($GLOBALS['document_storage_method'] == 0) {
         $harddisk = true;
     }
     if ($GLOBALS['document_storage_method'] == 1) {
         $couchDB = true;
     }
     if ($_POST['process'] != "true") {
         return;
     }
     $doDecryption = false;
     $encrypted = $_POST['encrypted'];
     $passphrase = $_POST['passphrase'];
     if (!$GLOBALS['hide_document_encryption'] && $encrypted && $passphrase) {
         $doDecryption = true;
     }
     if (is_numeric($_POST['category_id'])) {
         $category_id = $_POST['category_id'];
     }
     if (is_numeric($_POST['patient_id'])) {
         $patient_id = $_POST['patient_id'];
     }
     foreach ($_FILES as $file) {
         $fname = $file['name'];
         $err = "";
         if ($file['error'] > 0 || empty($file['name']) || $file['size'] == 0) {
             $fname = $file['name'];
             if (empty($fname)) {
                 $fname = htmlentities("<empty>");
             }
             $error = "Error number: " . $file['error'] . " occured while uploading file named: " . $fname . "\n";
             if ($file['size'] == 0) {
                 $error .= "The system does not permit uploading files of with size 0.\n";
             }
         } else {
             if (!file_exists($this->file_path)) {
                 if (!mkdir($this->file_path, 0700)) {
                     $error .= "The system was unable to create the directory for this upload, '" . $this->file_path . "'.\n";
                 }
             }
             if ($_POST['destination'] != '') {
                 $fname = $_POST['destination'];
             }
             $fname = preg_replace("/[^a-zA-Z0-9_.]/", "_", $fname);
             if (file_exists($this->file_path . $fname)) {
                 $error .= xl('File with same name already exists at location:', '', '', ' ') . $this->file_path . "\n";
                 $fname = basename($this->_rename_file($this->file_path . $fname));
                 $file['name'] = $fname;
                 $error .= xl('Current file name was changed to', '', '', ' ') . $fname . "\n";
             }
             if ($doDecryption) {
                 $tmpfile = fopen($file['tmp_name'], "r");
                 $filetext = fread($tmpfile, $file['size']);
                 $plaintext = $this->decrypt($filetext, $passphrase);
                 fclose($tmpfile);
                 unlink($file['tmp_name']);
                 $tmpfile = fopen($file['tmp_name'], "w+");
                 fwrite($tmpfile, $plaintext);
                 fclose($tmpfile);
                 $file['size'] = filesize($file['tmp_name']);
             }
             $docid = '';
             $resp = '';
             if ($couchDB == true) {
                 $couch = new CouchDB();
                 $docname = $_SESSION['authId'] . $patient_id . $encounter . $fname . date("%Y-%m-%d H:i:s");
                 $docid = $couch->stringToId($docname);
                 $tmpfile = fopen($file['tmp_name'], "rb");
                 $filetext = fread($tmpfile, $file['size']);
                 fclose($tmpfile);
                 //--------Temporarily writing the file for calculating the hash--------//
                 //-----------Will be removed after calculating the hash value----------//
                 $temp_file = fopen($this->file_path . $fname, "w");
                 fwrite($temp_file, $filetext);
                 fclose($temp_file);
                 //---------------------------------------------------------------------//
                 $json = json_encode(base64_encode($filetext));
                 $db = $GLOBALS['couchdb_dbase'];
                 $data = array($db, $docid, $patient_id, $encounter, $file['type'], $json);
                 $resp = $couch->check_saveDOC($data);
                 if (!$resp->id || !$resp->_rev) {
                     $data = array($db, $docid, $patient_id, $encounter);
                     $resp = $couch->retrieve_doc($data);
                     $docid = $resp->_id;
                     $revid = $resp->_rev;
                 } else {
                     $docid = $resp->id;
                     $revid = $resp->rev;
                 }
                 if (!$docid && !$revid) {
                     //if couchdb save failed
                     $error .= "<font color='red'><b>" . xl("The file could not be saved to CouchDB.") . "</b></font>\n";
                     if ($GLOBALS['couchdb_log'] == 1) {
                         ob_start();
                         var_dump($resp);
                         $couchError = ob_get_clean();
                         $log_content = date('Y-m-d H:i:s') . " ==> Uploading document: " . $fname . "\r\n";
                         $log_content .= date('Y-m-d H:i:s') . " ==> Failed to Store document content to CouchDB.\r\n";
                         $log_content .= date('Y-m-d H:i:s') . " ==> Document ID: " . $docid . "\r\n";
                         $log_content .= date('Y-m-d H:i:s') . " ==> " . print_r($data, 1) . "\r\n";
                         $log_content .= $couchError;
                         $this->document_upload_download_log($patient_id, $log_content);
                         //log error if any, for testing phase only
                     }
                 }
             }
             if ($harddisk == true) {
                 $uploadSuccess = false;
                 if (move_uploaded_file($file['tmp_name'], $this->file_path . $fname)) {
                     $uploadSuccess = true;
                 } else {
                     $error .= xl("The file could not be succesfully stored, this error is usually related to permissions problems on the storage system") . "\n";
                 }
             }
             $this->assign("upload_success", "true");
             $d = new Document();
             $d->storagemethod = $GLOBALS['document_storage_method'];
             if ($harddisk == true) {
                 $d->url = "file://" . $this->file_path . $fname;
             } else {
                 $d->url = $fname;
             }
             if ($couchDB == true) {
                 $d->couch_docid = $docid;
                 $d->couch_revid = $revid;
             }
             if ($file['type'] == 'text/xml') {
                 $d->mimetype = 'application/xml';
             } else {
                 $d->mimetype = $file['type'];
             }
             $d->size = $file['size'];
             $d->owner = $_SESSION['authUserID'];
             $sha1Hash = sha1_file($this->file_path . $fname);
             if ($couchDB == true) {
                 //Removing the temporary file which is used to create the hash
                 unlink($this->file_path . $fname);
             }
             $d->hash = $sha1Hash;
             $d->type = $d->type_array['file_url'];
             $d->set_foreign_id($patient_id);
             if ($harddisk == true || $couchDB == true && $docid && $revid) {
                 $d->persist();
                 $d->populate();
             }
             $this->assign("file", $d);
             if (is_numeric($d->get_id()) && is_numeric($category_id)) {
                 $sql = "REPLACE INTO categories_to_documents set category_id = '" . $category_id . "', document_id = '" . $d->get_id() . "'";
                 $d->_db->Execute($sql);
             }
             if ($GLOBALS['couchdb_log'] == 1 && $log_content != '') {
                 $log_content .= "\r\n\r\n";
                 $this->document_upload_download_log($patient_id, $log_content);
             }
         }
     }
     $this->assign("error", nl2br($error));
     //$this->_state = false;
     $_POST['process'] = "";
     //return $this->fetch($GLOBALS['template_dir'] . "documents/" . $this->template_mod . "_upload.html");
 }