some portal work
[openemr.git] / library / standard_tables_capture.inc
blob0cdc28f191e720d5dbbf5f230ad920d885d894c2
1 <?php
2 /**
3  * This library contains functions that implement the database load processing
4  * of external database files into openEMR
5  *
6  * @package   OpenEMR
7  * @link      https://www.open-emr.org
8  * @author    Rohit Kumar <pandit.rohit@netsity.com>
9  * @author    (Mac) Kevin McAloon <mcaloon@patienthealthcareanalytics.com>
10  * @author    Brady Miller <brady.g.miller@gmail.com>
11  * @author    Roberto Vasquez <robertogagliotta@gmail.com>
12  * @author    Stephen Waite <stephen.waite@cmsvt.com>
13  * @copyright Copyright (c) 2011 Phyaura, LLC <info@phyaura.com>
14  * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
15  * @copyright Copyright (c) 2019 Stephen Waite <stephen.waite@cmsvt.com>
16  * @license   https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
17  */
19 // Function to copy a package to temp
20 // $type (RXNORM, SNOMED etc.)
21 function temp_copy($filename, $type)
24     if (!file_exists($filename)) {
25         return false;
26     }
28     if (!file_exists($GLOBALS['temporary_files_dir']."/".$type)) {
29         if (!mkdir($GLOBALS['temporary_files_dir']."/".$type, 0777, true)) {
30                 return false;
31         }
32     }
34     if (copy($filename, $GLOBALS['temporary_files_dir']."/".$type."/".basename($filename))) {
35         return true;
36     } else {
37         return false;
38     }
41 // Function to unarchive a package
42 // $type (RXNORM, SNOMED etc.)
43 function temp_unarchive($filename, $type)
45     $filename = $GLOBALS['temporary_files_dir']."/".$type."/".basename($filename);
46     if (!file_exists($filename)) {
47         return false;
48     } else {
49     // let's unzip the file
50     // use checksums to determine the "version"
51     //
52         $zip = new ZipArchive;
53         if ($zip->open($filename, ZipArchive::CREATE) === true) {
54             // cms.gov added a subfolder to the archive :| filed a ticket with them 8-20-19 :)
55             for ($i = 0; $i < $zip->numFiles; $i++) {
56                 $full_file_name = $zip->getNameIndex($i);
57                 $fileinfo = pathinfo($full_file_name);
58                 if (!copy("zip://".$filename."#".$full_file_name, $GLOBALS['temporary_files_dir']."/".
59                     $type."/".$fileinfo['basename'])) {
60                     return false;
61                 };
62             }
63             $zip->close();
64             return true;
65         } else {
66             return false;
67         }
68     }
71 // Function to import the RXNORM tables
72 // $is_windows_flag - pass the IS_WINDOWS constant
73 function rxnorm_import($is_windows_flag)
76     // set paths
77     $dirScripts = $GLOBALS['temporary_files_dir']."/RXNORM/scripts/mysql";
78     $dir = $GLOBALS['temporary_files_dir']."/RXNORM/rrf";
79     $dir=str_replace('\\', '/', $dir);
81     $rx_info = array();
82     $rx_info['rxnatomarchive'] = array('title' => "Archive Data", 'dir' => "$dir", 'origin' => "RXNATOMARCHIVE.RRF", 'filename' => "RXNATOMARCHIVE.RRF", 'table' => "rxnatomarchive", 'required' => 0);
83     $rx_info['rxnconso'] = array('title' => "Concept Names and Sources", 'dir' => "$dir", 'origin' => "RXNCONSO.RRF", 'filename' => "RXNCONSO.RRF", 'table' => "rxnconso",  'required' => 1);
84     $rx_info['rxncui'] = array('title' => "Retired RXCUI Data", 'dir' => "$dir", 'origin' => "RXNCUI.RRF", 'filename' => "RXNCUI.RRF", 'table' => "rxncui", 'required' => 1);
85     $rx_info['rxncuichanges'] = array('title' => "Concept Changes", 'dir' => "$dir", 'origin' => "RXNCUICHANGES.RRF", 'filename' => "RXNCUICHANGES.RRF", 'table' => "rxncuichanges", 'required' => 1);
86     $rx_info['rxndoc'] = array('title' => "Documentation for Abbreviated Values", 'dir' => "$dir", 'origin' => "RXNDOC.RRF", 'filename' => "RXNDOC.RRF", 'table' => "rxndoc", 'required' => 1);
87     $rx_info['rxnrel'] = array('title' => "Relationships", 'dir' => "$dir", 'origin' => "RXNREL.RRF", 'filename' => "RXNREL.RRF", 'table' => "rxnrel", 'required' => 1);
88     $rx_info['rxnsab'] = array('title' => "Source Information", 'dir' => "$dir", 'origin' => "RXNSAB.RRF", 'filename' => "RXNSAB.RRF", 'table' => "rxnsab", 'required' => 0);
89     $rx_info['rxnsat'] = array('title' => "Simple Concept and Atom Attributes", 'dir' => "$dir", 'origin' => "RXNSAT.RRF", 'filename' => "RXNSAT.RRF", 'table' => "rxnsat", 'required' => 0);
90     $rx_info['rxnsty'] = array('title' => "Semantic Types ", 'dir' => "$dir", 'origin' => "RXNSTY.RRF", 'filename' => "RXNSTY.RRF", 'table' => "rxnsty", 'required' => 1);
92     // load scripts
93     $file_load = file_get_contents($dirScripts.'/Table_scripts_mysql_rxn.sql', true);
94     if ($is_windows_flag) {
95         $data_load = file_get_contents($dirScripts.'/Load_scripts_mysql_rxn_win.sql', true);
96     } else {
97         $data_load = file_get_contents($dirScripts.'/Load_scripts_mysql_rxn_unix.sql', true);
98     }
100     $indexes_load = file_get_contents($dirScripts.'/Indexes_mysql_rxn.sql', true);
102     //
103     // Creating the structure for table and applying indexes
104     //
106     $file_array=explode(";", $file_load);
107     foreach ($file_array as $val) {
108         if (trim($val)!='') {
109             sqlStatementNoLog($val);
110         }
111     }
113     $indexes_array=explode(";", $indexes_load);
115     foreach ($indexes_array as $val1) {
116         if (trim($val1)!='') {
117             sqlStatementNoLog($val1);
118         }
119     }
122     // Settings to drastically speed up import with InnoDB
123     sqlStatementNoLog("SET autocommit=0");
124     sqlStatementNoLog("START TRANSACTION");
125     $data=explode(";", $data_load);
126     foreach ($data as $val) {
127         foreach ($rx_info as $key => $value) {
128             $file_name= $value['origin'];
129             $replacement=$dir."/".$file_name;
131             $pattern='/'.$file_name.'/';
132             if (strpos($val, $file_name) !== false) {
133                 $val1 = str_replace($file_name, $replacement, $val);
134                 if (trim($val1)!='') {
135                     sqlStatementNoLog($val1);
136                 }
137             }
138         }
139     }
141     // Settings to drastically speed up import with InnoDB
142     sqlStatementNoLog("COMMIT");
143     sqlStatementNoLog("SET autocommit=1");
145     return true;
148 // Function to import SNOMED tables
149 function snomed_import($us_extension = false)
152     // set up array
153     $table_array_for_snomed=array(
154         "sct_concepts_drop"=>"DROP TABLE IF EXISTS `sct_concepts`",
155         "sct_concepts_structure"=>"CREATE TABLE IF NOT EXISTS `sct_concepts` (
156             `ConceptId` bigint(20) NOT NULL,
157             `ConceptStatus` int(11) NOT NULL,
158             `FullySpecifiedName` varchar(255) NOT NULL,
159             `CTV3ID` varchar(5) NOT NULL,
160             `SNOMEDID` varchar(8) NOT NULL,
161             `IsPrimitive` tinyint(1) NOT NULL,
162             PRIMARY KEY (`ConceptId`)
163             ) ENGINE=InnoDB",
164         "sct_descriptions_drop"=>"DROP TABLE IF EXISTS `sct_descriptions`",
165         "sct_descriptions_structure"=>"CREATE TABLE IF NOT EXISTS `sct_descriptions` (
166             `DescriptionId` bigint(20) NOT NULL,
167             `DescriptionStatus` int(11) NOT NULL,
168             `ConceptId` bigint(20) NOT NULL,
169             `Term` varchar(255) NOT NULL,
170             `InitialCapitalStatus` tinyint(1) NOT NULL,
171             `DescriptionType` int(11) NOT NULL,
172             `LanguageCode` varchar(8) NOT NULL,
173             PRIMARY KEY (`DescriptionId`)
174             ) ENGINE=InnoDB",
175         "sct_relationships_drop"=>"DROP TABLE IF EXISTS `sct_relationships`",
176         "sct_relationships_structure"=>"CREATE TABLE IF NOT EXISTS `sct_relationships` (
177             `RelationshipId` bigint(20) NOT NULL,
178             `ConceptId1` bigint(20) NOT NULL,
179             `RelationshipType` bigint(20) NOT NULL,
180             `ConceptId2` bigint(20) NOT NULL,
181             `CharacteristicType` int(11) NOT NULL,
182             `Refinability` int(11) NOT NULL,
183             `RelationshipGroup` int(11) NOT NULL,
184             PRIMARY KEY (`RelationshipId`)
185             ) ENGINE=InnoDB"
186     );
188     // set up paths
189     $dir_snomed = $GLOBALS['temporary_files_dir']."/SNOMED/";
190     $sub_path="Terminology/Content/";
191     $dir=$dir_snomed;
192     $dir=str_replace('\\', '/', $dir);
194     // executing the create statement for tables, these are defined in snomed_capture.inc file
195     // this is skipped if the US extension is being added
196     if (!$us_extension) {
197         foreach ($table_array_for_snomed as $val) {
198             if (trim($val)!='') {
199                 sqlStatement($val);
200             }
201         }
202     }
204     // reading the SNOMED directory and identifying the files to import and replacing the variables by originals values.
205     if (is_dir($dir) && $handle = opendir($dir)) {
206         while (false !== ($filename = readdir($handle))) {
207             if ($filename != "." && $filename != ".." && !strpos($filename, "zip")) {
208                 $path=$dir."".$filename."/".$sub_path;
209                 if (!(is_dir($path))) {
210                     $path=$dir."".$filename."/RF1Release/".$sub_path;
211                 }
213                 if (is_dir($path) && $handle1 = opendir($path)) {
214                     while (false !== ($filename1 = readdir($handle1))) {
215                         $load_script="Load data local infile '#FILENAME#' into table #TABLE# fields terminated by '\\t' ESCAPED BY '' lines terminated by '\\n' ignore 1 lines   ";
216                         $array_replace=array("#FILENAME#","#TABLE#");
217                         if ($filename1 != "." && $filename1 != "..") {
218                             $file_replace=$path.$filename1;
219                             if (strpos($filename1, "Concepts") !== false) {
220                                 $new_str=str_replace($array_replace, array($file_replace,"sct_concepts"), $load_script);
221                             }
223                             if (strpos($filename1, "Descriptions") !== false) {
224                                 $new_str=str_replace($array_replace, array($file_replace,"sct_descriptions"), $load_script);
225                             }
227                             if (strpos($filename1, "Relationships") !== false) {
228                                 $new_str=str_replace($array_replace, array($file_replace,"sct_relationships"), $load_script);
229                             }
231                             if ($new_str!='') {
232                                 sqlStatement($new_str);
233                             }
234                         }
235                     }
236                 }
238                 closedir($handle1);
239             }
240         }
242         closedir($handle);
243     }
245     return true;
248 function drop_old_sct()
250     $array_to_truncate=array(
251         "sct_concepts_drop"=>"DROP TABLE IF EXISTS `sct_concepts`",
252         "sct_descriptions_drop"=>"DROP TABLE IF EXISTS `sct_descriptions`",
253         "sct_relationships_drop"=>"DROP TABLE IF EXISTS `sct_relationships`"
254     );
255     foreach ($array_to_truncate as $val) {
256         if (trim($val)!='') {
257             sqlStatement($val);
258         }
259     }
262 function drop_old_sct2()
264     $array_to_truncate=array(
265         "sct2_concept_drop"=>"DROP TABLE IF EXISTS `sct2_concept`",
266         "sct2_description_drop"=>"DROP TABLE IF EXISTS `sct2_description`",
267         "sct2_identifier_drop"=>"DROP TABLE IF EXISTS `sct2_identifier`",
268         "sct2_relationship_drop"=>"DROP TABLE IF EXISTS `sct2_relationship`",
269         "sct2_statedrelationship_drop"=>"DROP TABLE IF EXISTS `sct2_statedrelationship`",
270         "sct2_textdefinition_drop"=>"DROP TABLE IF EXISTS `sct2_textdefinition`"
271     );
272     foreach ($array_to_truncate as $val) {
273         if (trim($val)!='') {
274             sqlStatement($val);
275         }
276     }
279 function chg_ct_external_torf1()
281     sqlStatement("UPDATE code_types SET ct_external = 2 WHERE ct_key = 'SNOMED'");
282     sqlStatement("UPDATE code_types SET ct_external = 7 WHERE ct_key = 'SNOMED-CT'");
283     sqlStatement("UPDATE code_types SET ct_external = 9 WHERE ct_key = 'SNOMED-PR'");
286 function chg_ct_external_torf2()
288     sqlStatement("UPDATE code_types SET ct_external = 10 WHERE ct_key = 'SNOMED'");
289     sqlStatement("UPDATE code_types SET ct_external = 11 WHERE ct_key = 'SNOMED-CT'");
290     sqlStatement("UPDATE code_types SET ct_external = 12 WHERE ct_key = 'SNOMED-PR'");
293 function snomedRF2_import()
296     // set up array
297     $table_array_for_snomed=array(
298         "sct2_concept_drop"=>"DROP TABLE IF EXISTS `sct2_concept`",
299         "sct2_concept_structure"=>"CREATE TABLE IF NOT EXISTS `sct2_concept` (
300             `id` bigint(20) NOT NULL,
301             `effectiveTime` date NOT NULL,
302             `active` int(11) NOT NULL,
303             `moduleId` bigint(20) NOT NULL,
304             `definitionStatusId` bigint(25) NOT NULL,
305              PRIMARY KEY (`id`)
306             ) ENGINE=InnoDB",
307         "sct2_description_drop"=>"DROP TABLE IF EXISTS `sct2_description`",
308         "sct2_description_structure"=>"CREATE TABLE IF NOT EXISTS `sct2_description` (
309             `id` bigint(20) NOT NULL,
310             `effectiveTime` date NOT NULL,
311             `active` bigint(11) NOT NULL,
312             `moduleId` bigint(25) NOT NULL,
313             `conceptId` bigint(20) NOT NULL,
314             `languageCode` varchar(8) NOT NULL,
315             `typeId` bigint(25) NOT NULL,
316             `term` varchar(255) NOT NULL,
317             `caseSignificanceId` bigint(25) NOT NULL,
318              PRIMARY KEY (`id`, `active`, `conceptId`)
319             ) ENGINE=InnoDB",
320         "sct2_identifier_drop"=>"DROP TABLE IF EXISTS `sct2_identifier`",
321         "sct2_identifier_structure"=>"CREATE TABLE IF NOT EXISTS `sct2_identifier` (
322             `identifierSchemeId` bigint(25) NOT NULL,
323             `alternateIdentifier` bigint(25) NOT NULL,
324             `effectiveTime` date NOT NULL,
325             `active` int(11) NOT NULL,
326             `moduleId` bigint(25) NOT NULL,
327             `referencedComponentId` bigint(25) NOT NULL,
328              PRIMARY KEY (`identifierSchemeId`)
329             ) ENGINE=InnoDB",
330         "sct2_relationship_drop"=>"DROP TABLE IF EXISTS `sct2_relationship`",
331         "sct2_relationship_structure"=>"CREATE TABLE IF NOT EXISTS `sct2_relationship` (
332             `id` bigint(20) NOT NULL,
333             `effectiveTime` date NOT NULL,
334             `active` int(11) NOT NULL,
335             `moduleId` bigint(25) NOT NULL,
336             `sourceId` bigint(20) NOT NULL,
337             `destinationId` bigint(20) NOT NULL,
338             `typeId` bigint(25) NOT NULL,
339             `characteristicTypeId` bigint(25) NOT NULL,
340             `modifierId` bigint(25) NOT NULL,
341              PRIMARY KEY (`id`)
342             ) ENGINE=InnoDB",
343         "sct2_statedrelationship_drop"=>"DROP TABLE IF EXISTS `sct2_statedrelationship`",
344         "sct2_statedrelationship_structure"=>"CREATE TABLE IF NOT EXISTS `sct2_statedrelationship` (
345             `id` bigint(20) NOT NULL,
346             `effectiveTime` date NOT NULL,
347             `active` int(11) NOT NULL,
348             `moduleId` bigint(25) NOT NULL,
349             `sourceId` bigint(20) NOT NULL,
350             `destinationId` bigint(20) NOT NULL,
351             `relationshipGroup` int(11) NOT NULL,
352             `typeId` bigint(25) NOT NULL,
353              PRIMARY KEY (`id`)
354             ) ENGINE=InnoDB",
355         "sct2_textdefinition_drop"=>"DROP TABLE IF EXISTS `sct2_textdefinition`",
356         "sct2_textdefinition_structure"=>"CREATE TABLE IF NOT EXISTS `sct2_textdefinition` (
357             `id` bigint(20) NOT NULL,
358             `effectiveTime` date NOT NULL,
359             `active` int(11) NOT NULL,
360             `moduleId` bigint(25) NOT NULL,
361             `conceptId` bigint(20) NOT NULL,
362             `languageCode` varchar(8) NOT NULL,
363             `typeId` bigint(25) NOT NULL,
364             `term` varchar(655) NOT NULL,
365              PRIMARY KEY (`id`)
366             ) ENGINE=InnoDB"
367     );
369     // set up paths
370     $dir_snomed = $GLOBALS['temporary_files_dir']."/SNOMED/";
371     // $sub_path="Terminology/Content/";
372     $sub_path="Full/Terminology/";
373     $dir=$dir_snomed;
374     $dir=str_replace('\\', '/', $dir);
376     // executing the create statement for tables, these are defined in snomed_capture.inc file
377     // this is skipped if the US extension is being added
378     //if (!$us_extension) {
379         //var_dump($us_extension);
380     foreach ($table_array_for_snomed as $val) {
381         if (trim($val)!='') {
382             sqlStatement($val);
383         }
384     }
385     //}
387     // reading the SNOMED directory and identifying the files to import and replacing the variables by originals values.
388     if (is_dir($dir) && $handle = opendir($dir)) {
389         while (false !== ($filename = readdir($handle))) {
390             if ($filename != "." && $filename != ".." && !strpos($filename, "zip")) {
391                 $path=$dir."".$filename."/".$sub_path;
392                 if (!(is_dir($path))) {
393                     $path=$dir."".$filename."/RF2Release/".$sub_path;
394                 }
395                 if (is_dir($path) && $handle1 = opendir($path)) {
396                     while (false !== ($filename1 = readdir($handle1))) {
397                         $load_script="Load data local infile '#FILENAME#' into table #TABLE# fields terminated by '\\t' ESCAPED BY '' lines terminated by '\\n' ignore 1 lines   ";
398                         $array_replace=array("#FILENAME#","#TABLE#");
399                         if ($filename1 != "." && $filename1 != "..") {
400                             $file_replace=$path.$filename1;
401                             if (strpos($filename1, "Concept") !== false) {
402                                 $new_str=str_replace($array_replace, array($file_replace,"sct2_concept"), $load_script);
403                             }
404                             if (strpos($filename1, "Description") !== false) {
405                                 $new_str=str_replace($array_replace, array($file_replace,"sct2_description"), $load_script);
406                             }
407                             if (strpos($filename1, "Identifier") !== false) {
408                                 $new_str=str_replace($array_replace, array($file_replace,"sct2_identifier"), $load_script);
409                             }
410                             if (strpos($filename1, "Relationship") !== false) {
411                                 $new_str=str_replace($array_replace, array($file_replace,"sct2_relationship"), $load_script);
412                             }
413                             if (strpos($filename1, "StatedRelationship") !== false) {
414                                 $new_str=str_replace($array_replace, array($file_replace,"sct2_statedrelationship"), $load_script);
415                             }
416                             if (strpos($filename1, "TextDefinition") !== false) {
417                                 $new_str=str_replace($array_replace, array($file_replace,"sct2_textdefinition"), $load_script);
418                             }
419                             if ($new_str!='') {
420                                 sqlStatement($new_str);
421                             }
422                         }
423                     }
424                 }
425                 closedir($handle1);
426             }
427         }
428         closedir($handle);
429     }
430     return true;
433 // Function to import ICD tables $type differentiates ICD 9, 10 and eventually 11 (circa 2018 :-) etc.
435 function icd_import($type)
438     // set up paths
439     $dir_icd = $GLOBALS['temporary_files_dir']."/".$type."/";
440     $dir=str_replace('\\', '/', $dir_icd);
441     $db_load = '';
442     $db_update = '';
444     // the incoming array is a metadata array containing keys that substr match to the incoming filename
445     // followed by the field name, position and length of each fixed length text record in the incoming
446     // flat files. There are separate definitions for ICD 9 and 10 based on the type passed in
447     $incoming = array();
448     if ($type == 'ICD9') {
449         $incoming['SHORT_DX'] = array('#TABLENAME#' => "icd9_dx_code",
450         '#FLD1#' => "dx_code", '#POS1#' => 1, '#LEN1#' => 5,
451         '#FLD2#' => "short_desc", '#POS2#' => 7, '#LEN2#' => 60);
452         $incoming['SHORT_SG'] = array('#TABLENAME#' => "icd9_sg_code",
453         '#FLD1#' => "sg_code", '#POS1#' => 1, '#LEN1#' => 4,
454         '#FLD2#' => "short_desc", '#POS2#' => 6, '#LEN2#' => 60);
455         $incoming['LONG_SG'] = array('#TABLENAME#' => "icd9_sg_long_code",
456         '#FLD1#' => "sg_code", '#POS1#' => 1, '#LEN1#' => 4,
457         '#FLD2#' => "long_desc", '#POS2#' => 6, '#LEN2#' => 300);
458         $incoming['LONG_DX'] = array('#TABLENAME#' => "icd9_dx_long_code",
459         '#FLD1#' => "dx_code", '#POS1#' => 1, '#LEN1#' => 5,
460         '#FLD2#' => "long_desc", '#POS2#' => 7, '#LEN2#' => 300);
461     } else {
462         $incoming['icd10pcs_order_'] = array('#TABLENAME#' => "icd10_pcs_order_code",
463         '#FLD1#' => "pcs_code", '#POS1#' => 7, '#LEN1#' => 7,
464         '#FLD2#' => "valid_for_coding", '#POS2#' => 15, '#LEN2#' => 1,
465         '#FLD3#' => "short_desc", '#POS3#' => 17, '#LEN3#' => 60,
466         '#FLD4#' => "long_desc", '#POS4#' => 78, '#LEN4#' => 300);
467         $incoming['icd10cm_order_'] = array('#TABLENAME#' => "icd10_dx_order_code",
468         '#FLD1#' => "dx_code", '#POS1#' =>7, '#LEN1#' => 7,
469         '#FLD2#' => "valid_for_coding", '#POS2#' => 15, '#LEN2#' => 1,
470         '#FLD3#' => "short_desc", '#POS3#' => 17, '#LEN3#' => 60,
471         '#FLD4#' => "long_desc", '#POS4#' => 78, '#LEN4#' => 300);
472         $incoming['reimb_map_pr_'] = array('#TABLENAME#' => "icd10_reimbr_pcs_9_10",
473         '#FLD1#' => "code", '#POS1#' => 1, '#LEN1#' => 7,
474         '#FLD2#' => "code_cnt", '#POS2#' => 9, '#LEN2#' => 1,
475         '#FLD3#' => "ICD9_01", '#POS3#' => 11, '#LEN3#' => 5,
476         '#FLD4#' => "ICD9_02", '#POS4#' => 17, '#LEN4#' => 5,
477         '#FLD5#' => "ICD9_03", '#POS5#' => 23, '#LEN5#' => 5,
478         '#FLD6#' => "ICD9_04", '#POS6#' => 29, '#LEN6#' => 5,
479         '#FLD7#' => "ICD9_05", '#POS7#' => 35, '#LEN7#' => 5,
480         '#FLD8#' => "ICD9_06", '#POS8#' => 41, '#LEN8#' => 5);
481         $incoming['reimb_map_dx_'] = array('#TABLENAME#' => "icd10_reimbr_dx_9_10",
482         '#FLD1#' => "code", '#POS1#' => 1, '#LEN1#' => 7,
483         '#FLD2#' => "code_cnt", '#POS2#' => 9, '#LEN2#' => 1,
484         '#FLD3#' => "ICD9_01", '#POS3#' => 11, '#LEN3#' => 5,
485         '#FLD4#' => "ICD9_02", '#POS4#' => 17, '#LEN4#' => 5,
486         '#FLD5#' => "ICD9_03", '#POS5#' => 23, '#LEN5#' => 5,
487         '#FLD6#' => "ICD9_04", '#POS6#' => 29, '#LEN6#' => 5,
488         '#FLD7#' => "ICD9_05", '#POS7#' => 35, '#LEN7#' => 5,
489         '#FLD8#' => "ICD9_06", '#POS8#' => 41, '#LEN8#' => 5);
490         $incoming['I10gem'] = array('#TABLENAME#' => "icd10_gem_dx_10_9",
491         '#FLD1#' => "dx_icd10_source", '#POS1#' => 1, '#LEN1#' => 7,
492         '#FLD2#' => "dx_icd9_target", '#POS2#' => 9, '#LEN2#' => 5,
493         '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
494         $incoming['I9gem'] = array('#TABLENAME#' => "icd10_gem_dx_9_10",
495         '#FLD1#' => "dx_icd9_source", '#POS1#' => 1, '#LEN1#' => 5,
496         '#FLD2#' => "dx_icd10_target", '#POS2#' => 7, '#LEN2#' => 7,
497         '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
498         $incoming['gem_pcsi9'] = array('#TABLENAME#' => "icd10_gem_pcs_10_9",
499         '#FLD1#' => "pcs_icd10_source", '#POS1#' => 1, '#LEN1#' => 7,
500         '#FLD2#' => "pcs_icd9_target", '#POS2#' => 9, '#LEN2#' => 5,
501         '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
502         $incoming['gem_i9pcs'] = array('#TABLENAME#' => "icd10_gem_pcs_9_10",
503         '#FLD1#' => "pcs_icd9_source", '#POS1#' => 1, '#LEN1#' => 5,
504         '#FLD2#' => "pcs_icd10_target", '#POS2#' => 7, '#LEN2#' => 7,
505         '#FLD3#' => "flags", '#POS3#' => 15, '#LEN3#' => 5);
506     }
508     // set up the start of the load script to be appended from the incoming array defined above where incoming
509     // file matches
510     $db_load = "LOAD DATA LOCAL INFILE '#INFILE#' INTO TABLE #TABLENAME# FIELDS TERMINATED BY '\0' (@var) SET revision = 0, ";
511     $col_template = "#FLD# = trim(Substring(@var, #POS#, #LEN#))";
513     // load all data and set active revision
514     if (is_dir($dir) && $handle = opendir($dir)) {
515         while (false !== ($filename = readdir($handle))) {
516         // bypass unwanted entries
517             if (!stripos($filename, ".txt") || stripos($filename, "diff") || stripos($filename, "addenda")) {
518                 continue;
519             }
521         // reset the sql load command and susbtitute the filename
522             $run_sql = $db_load;
523             $run_sql = str_replace("#INFILE#", $dir . $filename, $run_sql);
524             $keys = array_keys($incoming);
525             while ($this_key = array_pop($keys)) {
526                 if (stripos($filename, $this_key) !== false) {
527                     // now substitute the tablename
528                         $run_sql = str_replace("#TABLENAME#", $incoming[$this_key]['#TABLENAME#'], $run_sql);
530                     // the range defines the maximum number of fields contained
531                     // in any of the incoming files
532                     foreach (range(1, 8) as $field) {
533                         $fld = "#FLD" . $field . "#";
534                         $nxtfld = "#FLD" . ($field+1) . "#";
535                         $pos = "#POS" . $field . "#";
536                         $len = "#LEN" . $field . "#";
538                 // concat this fields template in the sql string
539                         $run_sql .= $col_template;
540                         $run_sql = str_replace("#FLD#", $incoming[$this_key][$fld], $run_sql);
541                         $run_sql = str_replace("#POS#", $incoming[$this_key][$pos], $run_sql);
542                         $run_sql = str_replace("#LEN#", $incoming[$this_key][$len], $run_sql);
543                 // at the end of this table's field list
544                         if (!array_key_exists($nxtfld, $incoming[$this_key])) {
545                             break;
546                         }
548                         $run_sql .= ",";
549                     }
551                     sqlStatement($run_sql);
553                     // now update the revision for this load
554                     $res = sqlStatement("SELECT max(revision) rev FROM " . escape_table_name($incoming[$this_key]['#TABLENAME#']));
555                     $row = sqlFetchArray($res);
556                     $next_rev = $row['rev'] + 1;
557                     $run_sql = "UPDATE " . $incoming[$this_key]['#TABLENAME#'] . " SET active = 0";
558                     sqlQuery($run_sql);
559                     $run_sql = "UPDATE " . $incoming[$this_key]['#TABLENAME#'] . " SET active = 1, revision = ? WHERE revision = 0";
560                     sqlQuery($run_sql, array($next_rev));
561                     break;
562                 }
563             }
564         }
566         closedir($handle);
567     } else {
568         echo htmlspecialchars(xl('ERROR: No ICD import directory.'), ENT_NOQUOTES)."<br>";
569         return;
570     }
572     // now update the tables where necessary
573     if ($type == 'ICD9') {
574         sqlStatement("update `icd9_dx_code` SET formatted_dx_code = dx_code");
575         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");
576         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");
577         sqlStatement("update `icd9_sg_code` SET formatted_sg_code = concat(concat(left(sg_code, 2), '.'), substr(sg_code, 3))");
578         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");
579         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");
580     } else { // ICD 10
581         sqlStatement("update `icd10_dx_order_code` SET formatted_dx_code = dx_code");
582         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");
583     }
585     return true;
588 function valueset_import($type)
590     $dir_valueset = $GLOBALS['temporary_files_dir']."/".$type."/";
591         $dir = str_replace('\\', '/', $dir_valueset);
593     // Settings to drastically speed up import with InnoDB
594     sqlStatementNoLog("SET autocommit=0");
595     sqlStatementNoLog("START TRANSACTION");
596     if (is_dir($dir) && $handle = opendir($dir)) {
597         while (false !== ($filename = readdir($handle))) {
598             if (stripos($filename, ".xml")) {
599                     $abs_path = $dir.$filename;
600                     $xml  = simplexml_load_file($abs_path, null, null, 'ns0', true);
601                 foreach ($xml->DescribedValueSet as $vset) {
602                     $vset_attr = $vset->attributes();
603                     $nqf = $vset->xpath('ns0:Group[@displayName="NQF Number"]/ns0:Keyword');
604                     foreach ($vset->ConceptList as $cp) {
605                         foreach ($nqf as $nqf_code) {
606                             foreach ($cp->Concept as $con) {
607                                 $con_attr = $con->attributes();
608                                 sqlStatementNoLog("INSERT INTO valueset values(?,?,?,?,?,?,?) on DUPLICATE KEY UPDATE code_system = values(code_system),description = values(description),valueset_name = values(valueset_name)", array($nqf_code,$con_attr->code,$con_attr->codeSystem,$con_attr->codeSystemName,$vset_attr->ID,$con_attr->displayName,$vset_attr->displayName));
609                             }
610                         }
611                     }
612                 }
614                     sqlStatementNoLog("UPDATE valueset set code_type='SNOMED CT' where code_type='SNOMEDCT'");
615                     sqlStatementNoLog("UPDATE valueset set code_type='ICD9' where code_type='ICD9CM'");
616                     sqlStatementNoLog("UPDATE valueset set code_type='ICD10' where code_type='ICD10CM'");
617             }
618         }
619     }
621     // Settings to drastically speed up import with InnoDB
622     sqlStatementNoLog("COMMIT");
623     sqlStatementNoLog("SET autocommit=1");
624         return true;
627 // Function to clean up temp files
628 // $type (RXNORM etc.)
629 function temp_dir_cleanup($type)
631     if (is_dir($GLOBALS['temporary_files_dir']."/".$type)) {
632         rmdir_recursive($GLOBALS['temporary_files_dir']."/".$type);
633     }
636 // Function to update version tracker table if successful
637 // $type (RXNORM etc.)
638 function update_tracker_table($type, $revision, $version, $file_checksum)
640     if ($type == 'RXNORM') {
641         sqlStatement("INSERT INTO `standardized_tables_track` (`imported_date`,`name`,`revision_date`, `revision_version`, `file_checksum`) VALUES (NOW(),'RXNORM',?,?,?)", array($revision, $version, $file_checksum));
642         return true;
643     } else if ($type == 'SNOMED') {
644         sqlStatement("INSERT INTO `standardized_tables_track` (`imported_date`,`name`,`revision_date`, `revision_version`, `file_checksum`) VALUES (NOW(),'SNOMED',?,?,?)", array($revision, $version, $file_checksum));
645         return true;
646     } else if ($type == 'ICD9') {
647         sqlStatement("INSERT INTO `standardized_tables_track` (`imported_date`,`name`,`revision_date`, `revision_version`, `file_checksum`) VALUES (NOW(),'ICD9',?,?,?)", array($revision, $version, $file_checksum));
648         return true;
649     } else if ($type == 'CQM_VALUESET') {
650         sqlStatement("INSERT INTO `standardized_tables_track` (`imported_date`,`name`,`revision_date`, `revision_version`, `file_checksum`) VALUES (NOW(),'CQM_VALUESET',?,?,?)", array($revision, $version, $file_checksum));
651         return true;
652     } else { // $type == 'ICD10')
653         sqlStatement("INSERT INTO `standardized_tables_track` (`imported_date`,`name`,`revision_date`, `revision_version`, `file_checksum`) VALUES (NOW(),'ICD10',?,?,?)", array($revision, $version, $file_checksum));
654         return true;
655     }
657     return false;
660 // Function to delete an entire directory
661 function rmdir_recursive($dir)
663     $files = scandir($dir);
664     array_shift($files);    // remove '.' from array
665     array_shift($files);    // remove '..' from array
667     foreach ($files as $file) {
668         $file = $dir . '/' . $file;
669         if (is_dir($file)) {
670             rmdir_recursive($file);
671             continue;
672         }
674         unlink($file);
675     }
677     rmdir($dir);
680 // function to cleanup temp, copy and unarchive the zip file
681 function handle_zip_file($mode, $file)
683         // 1. copy the file to temp directory
684     if (!temp_copy($file, $mode)) {
685         echo htmlspecialchars(xl('ERROR: Unable to copy the file.'), ENT_NOQUOTES)."<br>";
686         temp_dir_cleanup($mode);
687         exit;
688     }
689         // 2. unarchive the file
690     if (!temp_unarchive($file, $mode)) {
691         echo htmlspecialchars(xl('ERROR: Unable to extract the file.'), ENT_NOQUOTES)."<br>";
692         temp_dir_cleanup($mode);
693         exit;
694     }