Skip to content

Commit

Permalink
Store documents in remote cloud bucket (openemr#7233)
Browse files Browse the repository at this point in the history
* Store documents in remote cloud bucket

* Refactored to remove fiber code

* Refactored to rename class to make clear the purpose

* Generic message - remote upload completed

* Restructured the dispatch and response

* PSR Fix

* Adding document retrieval from s3 bucket

* PSR fix

* Fixed datatype

* adding attribute

* fixing type error

* Tested and working

* Name changes complete
  • Loading branch information
juggernautsei committed Apr 18, 2024
1 parent 7f38fd0 commit d277140
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 0 deletions.
16 changes: 16 additions & 0 deletions controllers/C_Document.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use OpenEMR\Services\FacilityService;
use OpenEMR\Services\PatientService;
use OpenEMR\Events\PatientDocuments\PatientDocumentTreeViewFilterEvent;
use OpenEMR\Events\PatientDocuments\PatientRetrieveOffsiteDocument;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class C_Document extends Controller
{
Expand All @@ -39,6 +41,10 @@ class C_Document extends Controller
private $cryptoGen;
private bool $skip_acl_check = false;
private DocumentTemplateService $templateService;
/**
* @var EventDispatcherInterface $eventDispatcher
*/
private $eventDispatcher;

public function __construct($template_mod = "general")
{
Expand Down Expand Up @@ -795,6 +801,16 @@ public function retrieve_action(string $patient_id = null, $document_id, $as_fil
if (file_exists($temp_url)) {
$url = $temp_url;
}
//fire a remote call to see if the file is stored somewhere else
$s3Key = explode("//", $temp_url); //split the url to get the s3 key
$retrieveOffsiteDocument = new PatientRetrieveOffsiteDocument("/" . $s3Key[1]);
$this->eventDispatcher->dispatch($retrieveOffsiteDocument, PatientRetrieveOffsiteDocument::REMOTE_DOCUMENT_LOCATION);
//this is for the s3 bucket module. If the file is not found locally, it will be found remotely
if ($retrieveOffsiteDocument->getOffsiteUrl() != null) {
header('Content-Description: File Transfer');
header("Location: " . $retrieveOffsiteDocument->getOffsiteUrl());
exit;
}

if (!file_exists($url)) {
echo xl('The requested document is not present at the expected location on the filesystem or there are not sufficient permissions to access it.', '', '', ' ') . $url;
Expand Down
29 changes: 29 additions & 0 deletions library/classes/Document.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,16 @@
use OpenEMR\Common\Crypto\CryptoGen;
use OpenEMR\Common\ORDataObject\ORDataObject;
use OpenEMR\Common\Uuid\UuidRegistry;
use OpenEMR\Events\PatientDocuments\PatientDocumentStoreOffsite;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class Document extends ORDataObject
{
/**
* @var EventDispatcherInterface $eventDispatcher
*/
private $eventDispatcher;

public const TABLE_NAME = "documents";

/**
Expand Down Expand Up @@ -248,6 +255,8 @@ public function __construct($id = "")
if ($id != "") {
$this->populate();
}

$this->eventDispatcher = $GLOBALS['kernel']->getEventDispatcher();
}

/**
Expand Down Expand Up @@ -981,6 +990,26 @@ function createDocument(
$this->couch_docid = $docid;
$this->couch_revid = $revid;
} else {
// Store it remotely.
$offSiteUpload = new PatientDocumentStoreOffsite($data);
$offSiteUpload->setPatientId($patient_id) ?? '';
$offSiteUpload->setRemoteFileName($filename) ?? '';
$offSiteUpload->setRemoteMimeType($mimetype) ?? '';
$offSiteUpload->setRemoteCategory($category_id) ?? '';
/**
* There must be a return to terminate processing.
*/
$this->eventDispatcher->dispatch($offSiteUpload, PatientDocumentStoreOffsite::REMOTE_STORAGE_LOCATION);

/**
* If the response from the listener is true then the file was uploaded to another location.
* Else resume the local file storage
*/

if ($GLOBALS['documentStoredRemotely']) {
return xlt("Document was uploaded to remote storage"); // terminate processing
}

// Storing document files locally.
$repository = $GLOBALS['oer_config']['documents']['repository'];
$higher_level_path = preg_replace("/[^A-Za-z0-9\/]/", "_", $higher_level_path);
Expand Down
72 changes: 72 additions & 0 deletions src/Events/PatientDocuments/PatientDocumentStoreOffsite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

/**
* PatientDocumentStoreOffsite
*
* @package OpenEMR
* @link http:https://www.open-emr.org
* @author Sherwin Gaddis <[email protected]>
* @copyright Copyright (c) 2024 Sherwin Gaddis <[email protected]>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/

namespace OpenEMR\Events\PatientDocuments;

use Symfony\Contracts\EventDispatcher\Event;

class PatientDocumentStoreOffsite extends Event
{
const REMOTE_STORAGE_LOCATION = 'documents.remote.storage.location';
private mixed $data;
private string $remoteFileName;
private string $mimeType;
private mixed $category;
private mixed $patientId;

public function __construct($data)
{
$this->data = $data;
}
public function getData()
{
return $this->data;
}

public function setRemoteFileName(string $filename): void
{
$this->remoteFileName = $filename;
}

public function getRemoteFileName(): string
{
return $this->remoteFileName;
}

public function setRemoteMimeType(string $mimeType): void
{
$this->mimeType = $mimeType;
}

public function getRemoteMimeType(): string
{
return $this->mimeType;
}
public function setRemoteCategory($category): void
{
$this->category = $category;
}

public function getRemoteCategory(): mixed
{
return $this->category;
}

public function setPatientId(string $patientId): void
{
$this->patientId = $patientId;
}
public function getPatientId(): mixed
{
return $this->patientId;
}
}
36 changes: 36 additions & 0 deletions src/Events/PatientDocuments/PatientRetrieveOffsiteDocument.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/**
* PatientRetrieveOffsiteDocument
*
* @package OpenEMR
* @link http:https://www.open-emr.org
* @author Sherwin Gaddis <[email protected]>
* @copyright Copyright (c) 2024 Sherwin Gaddis <[email protected]>
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/

namespace OpenEMR\Events\PatientDocuments;

use Symfony\Contracts\EventDispatcher\Event;

class PatientRetrieveOffsiteDocument extends Event
{
const REMOTE_DOCUMENT_LOCATION = 'remote.document.retrieve.location';
private string $url;
private $offsiteurl;
public function __construct($url)
{
$this->url = $url;
}

public function setOffsiteUrl(string $offsitedUrl): void
{
$this->offsiteurl = $offsiteUrl;
}

public function getOffsiteUrl()
{
return $this->offsiteurl;
}
}

0 comments on commit d277140

Please sign in to comment.