/** * @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 ''; }
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 ''; }