/**
  * @param $name
  *
  * @return Filesystem
  */
 public function create($name)
 {
     switch ($name) {
         case 'local':
             $adapter = new Adapter\Local($this->getParameter('local', 'folder'), $this->getParameter('local', 'create'));
             break;
         case 'sftp_phpseclib':
             $sftp = new \phpseclib\Net\SFTP($this->getParameter('sftp', 'host'), $this->getParameter('sftp', 'port'));
             $sftp->login($this->getParameter('sftp', 'login'), $this->getParameter('sftp', 'password'));
             $adapter = new Adapter\PhpseclibSftp($sftp, $this->getParameter('sftp', 'folder'), true);
             break;
         case 'sftp':
             $configuration = new Ssh\Configuration($this->getParameter('sftp', 'host'), $this->getParameter('sftp', 'port'));
             $authentication = new Ssh\Authentication\Password($this->getParameter('sftp', 'login'), $this->getParameter('sftp', 'password'));
             // for other options, check php-ssh docs
             $session = new Ssh\Session($configuration, $authentication);
             $adapter = new Adapter\Sftp($session->getSftp());
             break;
         case 's3':
             $service = new \Aws\S3\S3Client(array('credentials' => ['key' => $this->getParameter('s3', 'key'), 'secret' => $this->getParameter('s3', 'secret')], 'endpoint' => $this->getParameter('s3', 'endpoint'), 'bucket_endpoint' => $this->getParameter('s3', 'bucket_endpoint'), 'region' => $this->getParameter('s3', 'region'), 'version' => $this->getParameter('s3', 'version')));
             $adapter = new Adapter\AwsS3($service, $this->getParameter('s3', 'bucket'));
             break;
         case 'ftp':
             $adapter = new Adapter\Ftp('/', $this->getParameter('ftp', 'host'), array('username' => $this->getParameter('ftp', 'username'), 'password' => $this->getParameter('ftp', 'password'), 'passive' => $this->getParameter('ftp', 'passive'), 'port' => $this->getParameter('ftp', 'port')));
             break;
         case 'gridfs':
             $client = new MongoClient(sprintf('mongodb://%s:%s', $this->getParameter('gridfs', 'host'), $this->getParameter('gridfs', 'port')));
             $db = $client->selectDB($this->getParameter('gridfs', 'db'));
             $adapter = new Adapter\GridFS(new MongoGridFS($db));
             break;
         case 'mogilefs':
             $adapter = new Adapter\MogileFS('http://*****:*****@%s/%s', $this->getParameter('mysql', 'user'), $this->getParameter('mysql', 'password'), $this->getParameter('mysql', 'host'), $this->getParameter('mysql', 'db'))]);
             $sm = $connection->getSchemaManager();
             $table = new \Doctrine\DBAL\Schema\Table('files');
             if (!$sm->tablesExist(['files'])) {
                 $table = new \Doctrine\DBAL\Schema\Table('files');
                 $table->addColumn('key', 'string');
                 $table->addColumn('content', 'text');
                 $table->addColumn('mtime', 'string');
                 $table->addColumn('checksum', 'string');
                 $sm->createTable($table);
             }
             $adapter = new Adapter\DoctrineDbal($connection, $table->getName());
             break;
         default:
             throw new \RuntimeException(sprintf('Unknown adapter %s', $name));
     }
     return new Filesystem($adapter);
 }
/**
 * Transmit HL7 for the specified lab.
 *
 * @param  integer $ppid  Procedure provider ID.
 * @param  string  $out   The HL7 text to be sent.
 * @return string         Error text, or empty if no errors.
 */
function send_hl7_order($ppid, $out)
{
    global $srcdir;
    $d0 = "\r";
    $pprow = sqlQuery("SELECT * FROM procedure_providers " . "WHERE ppid = ?", array($ppid));
    if (empty($pprow)) {
        return xl('Procedure provider') . " {$ppid} " . xl('not found');
    }
    $protocol = $pprow['protocol'];
    $remote_host = $pprow['remote_host'];
    // Extract MSH-10 which is the message control ID.
    $segmsh = explode(substr($out, 3, 1), substr($out, 0, strpos($out, $d0)));
    $msgid = $segmsh[9];
    if (empty($msgid)) {
        return xl('Internal error: Cannot find MSH-10');
    }
    if ($protocol == 'DL' || $pprow['orders_path'] === '') {
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Content-Type: application/force-download");
        header("Content-Disposition: attachment; filename=order_{$msgid}.hl7");
        header("Content-Description: File Transfer");
        echo $out;
        exit;
    } else {
        if ($protocol == 'SFTP') {
            // Compute the target path/file name.
            $filename = $msgid . '.txt';
            if ($pprow['orders_path']) {
                $filename = $pprow['orders_path'] . '/' . $filename;
            }
            // Connect to the server and write the file.
            $sftp = new \phpseclib\Net\SFTP($remote_host);
            if (!$sftp->login($pprow['login'], $pprow['password'])) {
                return xl('Login to this remote host failed') . ": '{$remote_host}'";
            }
            if (!$sftp->put($filename, $out)) {
                return xl('Creating this file on remote host failed') . ": '{$filename}'";
            }
        } else {
            if ($protocol == 'FS') {
                // Compute the target path/file name.
                $filename = $msgid . '.txt';
                if ($pprow['orders_path']) {
                    $filename = $pprow['orders_path'] . '/' . $filename;
                }
                $fh = fopen("{$filename}", 'w');
                if ($fh) {
                    fwrite($fh, $out);
                    fclose($fh);
                } else {
                    return xl('Cannot create file') . ' "' . "{$filename}" . '"';
                }
            } else {
                return xl('This protocol is not implemented') . ": '{$protocol}'";
            }
        }
    }
    // Falling through to here indicates success.
    newEvent("proc_order_xmit", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "ID: {$msgid} Protocol: {$protocol} Host: {$remote_host}");
    return '';
}
Beispiel #3
0
 protected function loginToSFTP()
 {
     $this->includeLibrary();
     $result = true;
     $sftpClient = new \phpseclib\Net\SFTP(str_replace('sftp://', '', $this->config->sftp_endpoint));
     if (!$sftpClient->login($this->config->sftp_username, $this->config->sftp_password)) {
         $result = false;
         \XLite\Logger::logCustom("PitneyBowes", 'Error: Cound not start SFTP connection.', false);
     } else {
         $sftpClient->chdir($this->config->sftp_catalog_directory);
     }
     return $result ? $sftpClient : $result;
 }
/**
 * Poll all eligible labs for new results and store them in the database.
 *
 * @param  array   &$info  Conveys information to and from the caller:
 * FROM THE CALLER:
 * $info["$ppid/$filename"]['delete'] = a non-empty value if file deletion is requested.
 * $info['select'] = array of patient matching responses where key is serialized patient
 *   attributes and value is selected pid for this patient, or 0 to create the patient.
 * TO THE CALLER:
 * $info["$ppid/$filename"]['mssgs'] = array of messages from this function.
 * $info['match'] = array of patient matching requests where key is serialized patient
 *   attributes (ss, fname, lname, DOB) and value is TRUE (irrelevant).
 *
 * @return string  Error text, or empty if no errors.
 */
function poll_hl7_results(&$info)
{
    global $srcdir;
    // echo "<!-- post: "; print_r($_POST); echo " -->\n"; // debugging
    // echo "<!-- in:   "; print_r($info); echo " -->\n"; // debugging
    $filecount = 0;
    $badcount = 0;
    if (!isset($info['match'])) {
        $info['match'] = array();
    }
    // match requests
    if (!isset($info['select'])) {
        $info['select'] = array();
    }
    // match request responses
    $ppres = sqlStatement("SELECT * FROM procedure_providers ORDER BY name");
    while ($pprow = sqlFetchArray($ppres)) {
        $ppid = $pprow['ppid'];
        $protocol = $pprow['protocol'];
        $remote_host = $pprow['remote_host'];
        $hl7 = '';
        if ($protocol == 'SFTP') {
            $remote_port = 22;
            // Hostname may have ":port" appended to specify a nonstandard port number.
            if ($i = strrpos($remote_host, ':')) {
                $remote_port = 0 + substr($remote_host, $i + 1);
                $remote_host = substr($remote_host, 0, $i);
            }
            // Compute the target path name.
            $pathname = '.';
            if ($pprow['results_path']) {
                $pathname = $pprow['results_path'] . '/' . $pathname;
            }
            // Connect to the server and enumerate files to process.
            $sftp = new \phpseclib\Net\SFTP($remote_host, $remote_port);
            if (!$sftp->login($pprow['login'], $pprow['password'])) {
                return xl('Login to remote host') . " '{$remote_host}' " . xl('failed');
            }
            $files = $sftp->nlist($pathname);
            foreach ($files as $file) {
                if (substr($file, 0, 1) == '.') {
                    continue;
                }
                ++$filecount;
                if (!isset($info["{$ppid}/{$file}"])) {
                    $info["{$ppid}/{$file}"] = array();
                }
                // Ensure that archive directory exists.
                $prpath = $GLOBALS['OE_SITE_DIR'] . "/procedure_results";
                if (!file_exists($prpath)) {
                    mkdir($prpath);
                }
                $prpath .= '/' . $pprow['ppid'];
                if (!file_exists($prpath)) {
                    mkdir($prpath);
                }
                // Get file contents.
                $hl7 = $sftp->get("{$pathname}/{$file}");
                // If user requested reject and delete, do that.
                if (!empty($info["{$ppid}/{$file}"]['delete'])) {
                    $fh = fopen("{$prpath}/{$file}.rejected", 'w');
                    if ($fh) {
                        fwrite($fh, $hl7);
                        fclose($fh);
                    } else {
                        return xl('Cannot create file') . ' "' . "{$prpath}/{$file}.rejected" . '"';
                    }
                    if (!$sftp->delete("{$pathname}/{$file}")) {
                        return xl('Cannot delete (from SFTP server) file') . ' "' . "{$pathname}/{$file}" . '"';
                    }
                    continue;
                }
                // Do a dry run of its contents and check for errors and match requests.
                $tmp = receive_hl7_results($hl7, $info['match'], $ppid, $pprow['direction'], true, $info['select']);
                $info["{$ppid}/{$file}"]['mssgs'] = $tmp['mssgs'];
                // $info["$ppid/$file"]['match'] = $tmp['match'];
                if (!empty($tmp['fatal']) || !empty($tmp['needmatch'])) {
                    // There are errors or matching requests so skip this file.
                    continue;
                }
                // Now the money shot - not a dry run.
                $tmp = receive_hl7_results($hl7, $info['match'], $ppid, $pprow['direction'], false, $info['select']);
                $info["{$ppid}/{$file}"]['mssgs'] = $tmp['mssgs'];
                // $info["$ppid/$file"]['match'] = $tmp['match'];
                if (empty($tmp['fatal']) && empty($tmp['needmatch'])) {
                    // It worked, archive and delete the file.
                    $fh = fopen("{$prpath}/{$file}", 'w');
                    if ($fh) {
                        fwrite($fh, $hl7);
                        fclose($fh);
                    } else {
                        return xl('Cannot create file') . ' "' . "{$prpath}/{$file}" . '"';
                    }
                    if (!$sftp->delete("{$pathname}/{$file}")) {
                        return xl('Cannot delete (from SFTP server) file') . ' "' . "{$pathname}/{$file}" . '"';
                    }
                }
            }
            // end of this file
        } else {
            if ($protocol == 'FS') {
                // Filesystem directory containing results files.
                $pathname = $pprow['results_path'];
                if (!($dh = opendir($pathname))) {
                    return xl('Unable to access directory') . " '{$pathname}'";
                }
                // Sort by filename just because.
                $files = array();
                while (false !== ($file = readdir($dh))) {
                    if (substr($file, 0, 1) == '.') {
                        continue;
                    }
                    $files[$file] = $file;
                }
                closedir($dh);
                ksort($files);
                // For each file...
                foreach ($files as $file) {
                    ++$filecount;
                    if (!isset($info["{$ppid}/{$file}"])) {
                        $info["{$ppid}/{$file}"] = array();
                    }
                    // Ensure that archive directory exists.
                    $prpath = $GLOBALS['OE_SITE_DIR'] . "/procedure_results";
                    if (!file_exists($prpath)) {
                        mkdir($prpath);
                    }
                    $prpath .= '/' . $pprow['ppid'];
                    if (!file_exists($prpath)) {
                        mkdir($prpath);
                    }
                    // Get file contents.
                    $hl7 = file_get_contents("{$pathname}/{$file}");
                    // If user requested reject and delete, do that.
                    if (!empty($info["{$ppid}/{$file}"]['delete'])) {
                        $fh = fopen("{$prpath}/{$file}.rejected", 'w');
                        if ($fh) {
                            fwrite($fh, $hl7);
                            fclose($fh);
                        } else {
                            return xl('Cannot create file') . ' "' . "{$prpath}/{$file}.rejected" . '"';
                        }
                        if (!unlink("{$pathname}/{$file}")) {
                            return xl('Cannot delete file') . ' "' . "{$pathname}/{$file}" . '"';
                        }
                        continue;
                    }
                    // Do a dry run of its contents and check for errors and match requests.
                    $tmp = receive_hl7_results($hl7, $info['match'], $ppid, $pprow['direction'], true, $info['select']);
                    $info["{$ppid}/{$file}"]['mssgs'] = $tmp['mssgs'];
                    // $info["$ppid/$file"]['match'] = $tmp['match'];
                    if (!empty($tmp['fatal']) || !empty($tmp['needmatch'])) {
                        // There are errors or matching requests so skip this file.
                        continue;
                    }
                    // Now the money shot - not a dry run.
                    $tmp = receive_hl7_results($hl7, $info['match'], $ppid, $pprow['direction'], false, $info['select']);
                    $info["{$ppid}/{$file}"]['mssgs'] = $tmp['mssgs'];
                    // $info["$ppid/$file"]['match'] = $tmp['match'];
                    if (empty($tmp['fatal']) && empty($tmp['needmatch'])) {
                        // It worked, archive and delete the file.
                        $fh = fopen("{$prpath}/{$file}", 'w');
                        if ($fh) {
                            fwrite($fh, $hl7);
                            fclose($fh);
                        } else {
                            return xl('Cannot create file') . ' "' . "{$prpath}/{$file}" . '"';
                        }
                        if (!unlink("{$pathname}/{$file}")) {
                            return xl('Cannot delete file') . ' "' . "{$pathname}/{$file}" . '"';
                        }
                    }
                }
                // end of this file
            }
        }
        // end FS protocol
        // TBD: Insert "else if ($protocol == '???') {...}" to support other protocols.
    }
    // end procedure provider
    // echo "<!-- out: "; print_r($info); echo " -->\n"; // debugging
    return '';
}