示例#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
  * @param  string  $tmpfile      The tmp location of file (require for thumbnail generator)
  * @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, $tmpfile = null)
 {
     // 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.
     if ($GLOBALS['generate_doc_thumb']) {
         $thumb_size = $GLOBALS['thumb_doc_max_size'] > 0 ? $GLOBALS['thumb_doc_max_size'] : null;
         $thumbnail_class = new Thumbnail($thumb_size);
         if (!is_null($tmpfile)) {
             $has_thumbnail = $thumbnail_class->file_support_thumbnail($tmpfile);
         } else {
             $has_thumbnail = false;
         }
         if ($has_thumbnail) {
             $thumbnail_resource = $thumbnail_class->create_thumbnail(null, $data);
             if ($thumbnail_resource) {
                 $thumbnail_data = $thumbnail_class->get_string_file($thumbnail_resource);
             } else {
                 $has_thumbnail = false;
             }
         }
     } else {
         $has_thumbnail = false;
     }
     $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));
         if ($has_thumbnail) {
             $th_json = json_encode(base64_encode($thumbnail_data));
             $this->thumb_url = $this->get_thumb_name($filename);
         } else {
             $th_json = false;
         }
         $db = $GLOBALS['couchdb_dbase'];
         $couchdata = array($db, $docid, $patient_id, $encounter_id, $mimetype, $json, $th_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}";
         }
         if ($has_thumbnail) {
             $this->thumb_url = "file://" . $filepath . $this->get_thumb_name($filename);
             // Store the file into its proper directory.
             if (file_put_contents($filepath . $this->get_thumb_name($filename), $thumbnail_data) === FALSE) {
                 return xl('Failed to create') . $filepath . $this->get_thumb_name($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 '';
 }