diff --git a/interface/code_systems/dataloads_ajax.php b/interface/code_systems/dataloads_ajax.php
index ed2404e071a..5e90a91c6c6 100644
--- a/interface/code_systems/dataloads_ajax.php
+++ b/interface/code_systems/dataloads_ajax.php
@@ -131,7 +131,7 @@
//
// placemaker for when support DSMIV
//$db_list = array("DSMIV", "ICD9", "ICD10", "RXNORM", "SNOMED");
- $db_list = array("ICD9", "ICD10", "RXNORM", "SNOMED","CQM_VALUESET");
+ $db_list = array("ICD10", "RXNORM", "SNOMED","CQM_VALUESET");
foreach ($db_list as $db) {
?>
diff --git a/library/smarty_legacy/smarty/Smarty_Compiler_Legacy.class.php b/library/smarty_legacy/smarty/Smarty_Compiler_Legacy.class.php
index ad9198a59d1..02ca1556ba7 100644
--- a/library/smarty_legacy/smarty/Smarty_Compiler_Legacy.class.php
+++ b/library/smarty_legacy/smarty/Smarty_Compiler_Legacy.class.php
@@ -1526,78 +1526,80 @@ function _parse_is_expr($is_arg, $tokens)
*/
function _parse_attrs($tag_args)
{
-
- /* Tokenize tag attributes. */
- preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
- )+ |
- [=]
- ~x', $tag_args, $match);
- $tokens = $match[0];
-
$attrs = array();
- /* Parse state:
- 0 - expecting attribute name
- 1 - expecting '='
- 2 - expecting attribute value (not '=') */
- $state = 0;
-
- foreach ($tokens as $token) {
- switch ($state) {
- case 0:
- /* If the token is a valid identifier, we set attribute name
- and go to state 1. */
- if (preg_match('~^\w+$~', $token)) {
- $attr_name = $token;
- $state = 1;
- } else
- $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
- break;
- case 1:
- /* If the token is '=', then we go to state 2. */
- if ($token == '=') {
- $state = 2;
- } else
- $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
- break;
+ if (!empty($tag_args)) {
+ /* Tokenize tag attributes. */
+ preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)
+ )+ |
+ [=]
+ ~x', $tag_args, $match);
+ $tokens = $match[0];
+
+ /* Parse state:
+ 0 - expecting attribute name
+ 1 - expecting '='
+ 2 - expecting attribute value (not '=') */
+ $state = 0;
+
+ foreach ($tokens as $token) {
+ switch ($state) {
+ case 0:
+ /* If the token is a valid identifier, we set attribute name
+ and go to state 1. */
+ if (preg_match('~^\w+$~', $token)) {
+ $attr_name = $token;
+ $state = 1;
+ } else
+ $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
- case 2:
- /* If token is not '=', we set the attribute value and go to
- state 0. */
- if ($token != '=') {
- /* We booleanize the token if it's a non-quoted possible
- boolean value. */
- if (preg_match('~^(on|yes|true)$~', $token)) {
- $token = 'true';
- } else if (preg_match('~^(off|no|false)$~', $token)) {
- $token = 'false';
- } else if ($token == 'null') {
- $token = 'null';
- } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
- /* treat integer literally */
- } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
- /* treat as a string, double-quote it escaping quotes */
- $token = '"'.addslashes($token).'"';
- }
+ case 1:
+ /* If the token is '=', then we go to state 2. */
+ if ($token == '=') {
+ $state = 2;
+ } else
+ $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+ break;
- $attrs[$attr_name] = $token;
- $state = 0;
- } else
- $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
- break;
+ case 2:
+ /* If token is not '=', we set the attribute value and go to
+ state 0. */
+ if ($token != '=') {
+ /* We booleanize the token if it's a non-quoted possible
+ boolean value. */
+ if (preg_match('~^(on|yes|true)$~', $token)) {
+ $token = 'true';
+ } else if (preg_match('~^(off|no|false)$~', $token)) {
+ $token = 'false';
+ } else if ($token == 'null') {
+ $token = 'null';
+ } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) {
+ /* treat integer literally */
+ } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) {
+ /* treat as a string, double-quote it escaping quotes */
+ $token = '"'.addslashes($token).'"';
+ }
+
+ $attrs[$attr_name] = $token;
+ $state = 0;
+ } else
+ $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ break;
+ }
+ $last_token = $token;
}
- $last_token = $token;
- }
- if($state != 0) {
- if($state == 1) {
- $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
- } else {
- $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ if($state != 0) {
+ if($state == 1) {
+ $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);
+ } else {
+ $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);
+ }
}
- }
- $this->_parse_vars_props($attrs);
+ $this->_parse_vars_props($attrs);
+ }
return $attrs;
}
diff --git a/library/standard_tables_capture.inc.php b/library/standard_tables_capture.inc.php
index c748c70d309..633d8eda55b 100644
--- a/library/standard_tables_capture.inc.php
+++ b/library/standard_tables_capture.inc.php
@@ -12,8 +12,8 @@
* @author Roberto Vasquez
* @author Stephen Waite
* @copyright Copyright (c) 2011 Phyaura, LLC
- * @copyright Copyright (c) 2019 Brady Miller
- * @copyright Copyright (c) 2019 Stephen Waite
+ * @copyright Copyright (c) 2019-2022 Brady Miller
+ * @copyright Copyright (c) 2019-2022 Stephen Waite
* @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
*/
@@ -220,7 +220,7 @@ function snomed_import($us_extension = false)
$dir = $dir_snomed;
$dir = str_replace('\\', '/', $dir);
- // executing the create statement for tables, these are defined in snomed_capture.inc file
+ // executing the create statement for tables, these are defined in snomed_capture.inc.php file
// this is skipped if the US extension is being added
if (!$us_extension) {
foreach ($table_array_for_snomed as $val) {
@@ -502,124 +502,79 @@ function icd_import($type)
// followed by the field name, position and length of each fixed length text record in the incoming
// flat files. There are separate definitions for ICD 9 and 10 based on the type passed in
$incoming = array();
- if ($type == 'ICD9') {
- $incoming['SHORT_DX'] = array('#TABLENAME#' => "icd9_dx_code",
- '#FLD1#' => "dx_code", '#POS1#' => 1, '#LEN1#' => 5,
- '#FLD2#' => "short_desc", '#POS2#' => 7, '#LEN2#' => 60);
- $incoming['SHORT_SG'] = array('#TABLENAME#' => "icd9_sg_code",
- '#FLD1#' => "sg_code", '#POS1#' => 1, '#LEN1#' => 4,
- '#FLD2#' => "short_desc", '#POS2#' => 6, '#LEN2#' => 60);
- $incoming['LONG_SG'] = array('#TABLENAME#' => "icd9_sg_long_code",
- '#FLD1#' => "sg_code", '#POS1#' => 1, '#LEN1#' => 4,
- '#FLD2#' => "long_desc", '#POS2#' => 6, '#LEN2#' => 300);
- $incoming['LONG_DX'] = array('#TABLENAME#' => "icd9_dx_long_code",
- '#FLD1#' => "dx_code", '#POS1#' => 1, '#LEN1#' => 5,
- '#FLD2#' => "long_desc", '#POS2#' => 7, '#LEN2#' => 300);
- } else {
- $incoming['icd10pcs_order_'] = array('#TABLENAME#' => "icd10_pcs_order_code",
- '#FLD1#' => "pcs_code", '#POS1#' => 7, '#LEN1#' => 7,
- '#FLD2#' => "valid_for_coding", '#POS2#' => 15, '#LEN2#' => 1,
- '#FLD3#' => "short_desc", '#POS3#' => 17, '#LEN3#' => 60,
- '#FLD4#' => "long_desc", '#POS4#' => 78, '#LEN4#' => 300);
- $incoming['icd10cm_order_'] = array('#TABLENAME#' => "icd10_dx_order_code",
- '#FLD1#' => "dx_code", '#POS1#' => 7, '#LEN1#' => 7,
- '#FLD2#' => "valid_for_coding", '#POS2#' => 15, '#LEN2#' => 1,
- '#FLD3#' => "short_desc", '#POS3#' => 17, '#LEN3#' => 60,
- '#FLD4#' => "long_desc", '#POS4#' => 78, '#LEN4#' => 300);
- $incoming['reimb_map_pr_'] = array('#TABLENAME#' => "icd10_reimbr_pcs_9_10",
- '#FLD1#' => "code", '#POS1#' => 1, '#LEN1#' => 7,
- '#FLD2#' => "code_cnt", '#POS2#' => 9, '#LEN2#' => 1,
- '#FLD3#' => "ICD9_01", '#POS3#' => 11, '#LEN3#' => 5,
- '#FLD4#' => "ICD9_02", '#POS4#' => 17, '#LEN4#' => 5,
- '#FLD5#' => "ICD9_03", '#POS5#' => 23, '#LEN5#' => 5,
- '#FLD6#' => "ICD9_04", '#POS6#' => 29, '#LEN6#' => 5,
- '#FLD7#' => "ICD9_05", '#POS7#' => 35, '#LEN7#' => 5,
- '#FLD8#' => "ICD9_06", '#POS8#' => 41, '#LEN8#' => 5);
- $incoming['reimb_map_dx_'] = array('#TABLENAME#' => "icd10_reimbr_dx_9_10",
- '#FLD1#' => "code", '#POS1#' => 1, '#LEN1#' => 7,
- '#FLD2#' => "code_cnt", '#POS2#' => 9, '#LEN2#' => 1,
- '#FLD3#' => "ICD9_01", '#POS3#' => 11, '#LEN3#' => 5,
- '#FLD4#' => "ICD9_02", '#POS4#' => 17, '#LEN4#' => 5,
- '#FLD5#' => "ICD9_03", '#POS5#' => 23, '#LEN5#' => 5,
- '#FLD6#' => "ICD9_04", '#POS6#' => 29, '#LEN6#' => 5,
- '#FLD7#' => "ICD9_05", '#POS7#' => 35, '#LEN7#' => 5,
- '#FLD8#' => "ICD9_06", '#POS8#' => 41, '#LEN8#' => 5);
- $incoming['I10gem'] = array('#TABLENAME#' => "icd10_gem_dx_10_9",
- '#FLD1#' => "dx_icd10_source", '#POS1#' => 1, '#LEN1#' => 7,
- '#FLD2#' => "dx_icd9_target", '#POS2#' => 9, '#LEN2#' => 5,
- '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
- $incoming['I9gem'] = array('#TABLENAME#' => "icd10_gem_dx_9_10",
- '#FLD1#' => "dx_icd9_source", '#POS1#' => 1, '#LEN1#' => 5,
- '#FLD2#' => "dx_icd10_target", '#POS2#' => 7, '#LEN2#' => 7,
- '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
- $incoming['gem_pcsi9'] = array('#TABLENAME#' => "icd10_gem_pcs_10_9",
- '#FLD1#' => "pcs_icd10_source", '#POS1#' => 1, '#LEN1#' => 7,
- '#FLD2#' => "pcs_icd9_target", '#POS2#' => 9, '#LEN2#' => 5,
- '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
- $incoming['gem_i9pcs'] = array('#TABLENAME#' => "icd10_gem_pcs_9_10",
- '#FLD1#' => "pcs_icd9_source", '#POS1#' => 1, '#LEN1#' => 5,
- '#FLD2#' => "pcs_icd10_target", '#POS2#' => 7, '#LEN2#' => 7,
- '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
- }
-
- // set up the start of the load script to be appended from the incoming array defined above where incoming
- // file matches
- $db_load = "LOAD DATA LOCAL INFILE '#INFILE#' INTO TABLE #TABLENAME# FIELDS TERMINATED BY '\0' (@var) SET revision = 0, ";
- $col_template = "#FLD# = trim(Substring(@var, #POS#, #LEN#))";
-
- // load all data and set active revision
+
+ // find active revision
+ $res = sqlQueryNoLog("SELECT max(revision) rev FROM icd10_pcs_order_code");
+ $next_rev = ($res['rev'] ?? 0) + 1;
+ $incoming['icd10pcs_codes_'] = array(
+ 'TABLENAME' => "icd10_pcs_order_code",
+ 'FLD1' => "pcs_code", 'POS1' => 0, 'LEN1' => 7,
+ 'FLD2' => "long_desc", 'POS2' => 8, 'LEN2' => 300,
+ 'REV' => $next_rev
+ );
+
+ $res = sqlQueryNoLog("SELECT max(revision) rev FROM icd10_dx_order_code");
+ $next_rev = ($res['rev'] ?? 0) + 1;
+ $incoming['icd10cm_order_'] = array(
+ 'TABLENAME' => "icd10_dx_order_code",
+ 'FLD1' => "dx_code", 'POS1' => 6, 'LEN1' => 7,
+ 'FLD2' => "valid_for_coding", 'POS2' => 14, 'LEN2' => 1,
+ 'FLD3' => "short_desc", 'POS3' => 16, 'LEN3' => 60,
+ 'FLD4' => "long_desc", 'POS4' => 77, 'LEN4' => 300,
+ 'REV' => $next_rev
+ );
+
+ // Settings to drastically speed up import with InnoDB
+ sqlStatementNoLog("SET autocommit=0");
+ sqlStatementNoLog("START TRANSACTION");
+
+ // first inactivate older set(s)
+ sqlStatementNoLog("UPDATE icd10_pcs_order_code SET active = 0");
+ sqlStatementNoLog("UPDATE icd10_dx_order_code SET active = 0");
+
if (is_dir($dir) && $handle = opendir($dir)) {
while (false !== ($filename = readdir($handle))) {
- // bypass unwanted entries
- if (!stripos($filename, ".txt") || stripos($filename, "diff") || stripos($filename, "addenda")) {
+ // bypass unwanted entries
+ if (!stripos($filename, ".txt") || stripos($filename, "addenda")) {
continue;
}
- // reset the sql load command and susbtitute the filename
- $run_sql = $db_load;
- $run_sql = str_replace("#INFILE#", $dir . $filename, $run_sql);
$keys = array_keys($incoming);
while ($this_key = array_pop($keys)) {
if (stripos($filename, $this_key) !== false) {
- // now substitute the tablename
- $run_sql = str_replace("#TABLENAME#", $incoming[$this_key]['#TABLENAME#'], $run_sql);
-
- // the range defines the maximum number of fields contained
- // in any of the incoming files
- foreach (range(1, 8) as $field) {
- $fld = "#FLD" . $field . "#";
- $nxtfld = "#FLD" . ($field + 1) . "#";
- $pos = "#POS" . $field . "#";
- $len = "#LEN" . $field . "#";
-
- // concat this fields template in the sql string
- $run_sql .= $col_template;
- $run_sql = str_replace("#FLD#", $incoming[$this_key][$fld], $run_sql);
- $run_sql = str_replace("#POS#", $incoming[$this_key][$pos], $run_sql);
- $run_sql = str_replace("#LEN#", $incoming[$this_key][$len], $run_sql);
- // at the end of this table's field list
- if (!array_key_exists($nxtfld, $incoming[$this_key])) {
- break;
+ $generator = getFileData($dir . $filename);
+ foreach ($generator as $value) {
+ $run_sql = "INSERT INTO `" . $incoming[$this_key]['TABLENAME'] . "` (";
+ $sql_place = "(";
+ $sql_values = [];
+ foreach (range(1, 4) as $field) {
+ $fld = "FLD" . $field;
+ $nxtfld = "FLD" . ($field + 1);
+ $pos = "POS" . $field;
+ $len = "LEN" . $field;
+ $run_sql .= $incoming[$this_key][$fld] . ", ";
+ $sql_place .= "?, ";
+ // concat this fields template in the sql string
+ array_push($sql_values, substr($value, $incoming[$this_key][$pos], $incoming[$this_key][$len]));
+ if (!array_key_exists($nxtfld, $incoming[$this_key])) {
+ $run_sql .= "active, revision) VALUES ";
+ $sql_place .= "?, ?)";
+ array_push($sql_values, 1);
+ array_push($sql_values, $incoming[$this_key]['REV']);
+ sqlStatementNoLog($run_sql . $sql_place, $sql_values);
+ break;
+ } else {
+ $run_sql .= " ";
+ $sql_place .= " ";
+ }
}
-
- $run_sql .= ",";
}
-
- sqlStatement($run_sql);
-
- // now update the revision for this load
- $res = sqlStatement("SELECT max(revision) rev FROM " . escape_table_name($incoming[$this_key]['#TABLENAME#']));
- $row = sqlFetchArray($res);
- $next_rev = $row['rev'] + 1;
- $run_sql = "UPDATE " . $incoming[$this_key]['#TABLENAME#'] . " SET active = 0";
- sqlQuery($run_sql);
- $run_sql = "UPDATE " . $incoming[$this_key]['#TABLENAME#'] . " SET active = 1, revision = ? WHERE revision = 0";
- sqlQuery($run_sql, array($next_rev));
- break;
}
}
}
-
+ // Settings to drastically speed up import with InnoDB
+ sqlStatementNoLog("COMMIT");
+ sqlStatementNoLog("SET autocommit=1");
closedir($handle);
} else {
echo htmlspecialchars(xl('ERROR: No ICD import directory.'), ENT_NOQUOTES) . "
";
@@ -627,17 +582,8 @@ function icd_import($type)
}
// now update the tables where necessary
- if ($type == 'ICD9') {
- sqlStatement("update `icd9_dx_code` SET formatted_dx_code = dx_code");
- sqlStatement("update `icd9_dx_code` SET formatted_dx_code = concat(concat(left(dx_code, 3), '.'), substr(dx_code, 4)) WHERE dx_code RLIKE '^[V0-9]{1}.*' AND LENGTH(dx_code) > 3");
- sqlStatement("update `icd9_dx_code` SET formatted_dx_code = concat(concat(left(dx_code, 4), '.'), substr(dx_code, 5)) WHERE dx_code RLIKE '^[E]{1}.*' AND LENGTH(dx_code) > 4");
- sqlStatement("update `icd9_sg_code` SET formatted_sg_code = concat(concat(left(sg_code, 2), '.'), substr(sg_code, 3))");
- sqlStatement("update `icd9_dx_code` A, `icd9_dx_long_code` B set A.long_desc = B.long_desc where A.dx_code = B.dx_code and A.active = 1 and A.long_desc is NULL");
- sqlStatement("update `icd9_sg_code` A, `icd9_sg_long_code` B set A.long_desc = B.long_desc where A.sg_code = B.sg_code and A.active = 1 and A.long_desc is NULL");
- } else { // ICD 10
- sqlStatement("update `icd10_dx_order_code` SET formatted_dx_code = dx_code");
- sqlStatement("update `icd10_dx_order_code` SET formatted_dx_code = concat(concat(left(dx_code, 3), '.'), substr(dx_code, 4)) WHERE LENGTH(dx_code) > 3");
- }
+ sqlStatement("update `icd10_dx_order_code` SET formatted_dx_code = dx_code");
+ sqlStatement("update `icd10_dx_order_code` SET formatted_dx_code = concat(concat(left(dx_code, 3), '.'), substr(dx_code, 4)) WHERE LENGTH(dx_code) > 3");
// let's fire off an event so people can listen if needed and handle any module upgrading, version checks,
// or any manual processing that needs to occur.
@@ -659,7 +605,7 @@ function valueset_import($type)
}
$dir_valueset = $GLOBALS['temporary_files_dir'] . "/" . $type . "/";
- $dir = str_replace('\\', '/', $dir_valueset);
+ $dir = str_replace('\\', '/', $dir_valueset);
// Settings to drastically speed up import with InnoDB
sqlStatementNoLog("SET autocommit=0");
@@ -711,9 +657,9 @@ function valueset_import($type)
}
}
- sqlStatementNoLog("UPDATE valueset set code_type='SNOMED CT' where code_type='SNOMEDCT'");
- sqlStatementNoLog("UPDATE valueset set code_type='ICD9' where code_type='ICD9CM'");
- sqlStatementNoLog("UPDATE valueset set code_type='ICD10' where code_type='ICD10CM'");
+ sqlStatementNoLog("UPDATE valueset set code_type='SNOMED CT' where code_type='SNOMEDCT'");
+ sqlStatementNoLog("UPDATE valueset set code_type='ICD9' where code_type='ICD9CM'");
+ sqlStatementNoLog("UPDATE valueset set code_type='ICD10' where code_type='ICD10CM'");
}
}
}
@@ -800,3 +746,21 @@ function handle_zip_file($mode, $file)
exit;
}
}
+
+/**
+ * @return Generator
+ */
+function getFileData($fn)
+{
+ $file = fopen($fn, 'r');
+
+ if (!$file) {
+ return;
+ }
+
+ while (($line = fgets($file)) !== false) {
+ yield $line;
+ }
+
+ fclose($file);
+}