diff --git a/bin/build-lang-cache.php b/bin/build-lang-cache.php
new file mode 100644
index 00000000..29611533
--- /dev/null
+++ b/bin/build-lang-cache.php
@@ -0,0 +1,133 @@
+#!/usr/bin/env php
+term as $term) {
+ $k = strval($term->key[0]);
+ $v = strval($term->value[0]);
+
+ $pageterms[$k] = $v;
+ }
+
+ $locale[$pagename] = $pageterms;
+ }
+
+ return $locale;
+}
+
+function squash_locales(array & $target, array $source) {
+ foreach($source as $pagename => $pageterms) {
+ if(!array_key_exists($pagename, $target)) {
+ $target[$pagename] = $pageterms;
+ } else {
+ foreach($pageterms as $term => $val) {
+ $target[$pagename][$term] = $val;
+ }
+ }
+ }
+}
+
+function find_overrides(array $base, array $overrides) {
+ $o = array();
+
+ foreach($overrides as $pagename => $pageterms) {
+ if(!array_key_exists($pagename, $base)) {
+ $o[$pagename] = $pageterms;
+ }
+ }
+
+ foreach($base as $pagename => $pageterms) {
+ if(!array_key_exists($pagename, $overrides)) {
+ continue;
+ }
+
+ foreach($pageterms as $term => $value) {
+ if(!array_key_exists($term, $overrides[$pagename])) {
+ continue;
+ }
+
+ if ($overrides[$pagename][$term] != $value) {
+ if (!array_key_exists($pagename, $o)) {
+ $o[$pagename] = array();
+ }
+ $o[$pagename][$term] = $overrides[$pagename][$term];
+ }
+ }
+ }
+
+ return $o;
+}
diff --git a/htdocs/includes/db_lib.php b/htdocs/includes/db_lib.php
index 60d43f06..9a5894af 100644
--- a/htdocs/includes/db_lib.php
+++ b/htdocs/includes/db_lib.php
@@ -662,6 +662,7 @@ class ReportConfig
public $reportId;
public $testTypeId;
public $title;
+ public $name;
public $headerText;
public $titleText;
@@ -729,7 +730,7 @@ class ReportConfig
public static function getObject($record, $lab_config_id)
{
- global $LANG_ARRAY, $LOCAL_PATH;
+ global $LOCAL_PATH;
if($record == null)
return null;
@@ -752,16 +753,16 @@ public static function getObject($record, $lab_config_id)
switch($report_config->reportId)
{
case 1:
- $report_config->name = $LANG_ARRAY["reports"]["MENU_PATIENT"];
+ $report_config->name = LangUtil::$pageTerms->getTerm("reports", "MENU_PATIENT");
break;
case 2:
- $report_config->name = $LANG_ARRAY["reports"]["MENU_SPECIMEN"];
+ $report_config->name = LangUtil::$pageTerms->getTerm("reports", "MENU_SPECIMEN");
break;
case 3:
- $report_config->name = $LANG_ARRAY["reports"]["MENU_TESTRECORDS"];
+ $report_config->name = LangUtil::$pageTerms->getTerm("reports", "MENU_TESTRECORDS");
break;
case 4:
- $report_config->name = $LANG_ARRAY["reports"]["MENU_DAILYLOGS"];
+ $report_config->name = LangUtil::$pageTerms->getTerm("reports", "MENU_DAILYLOGS");
break;
}
diff --git a/htdocs/includes/header.php b/htdocs/includes/header.php
index 58f17b1e..52aed878 100644
--- a/htdocs/includes/header.php
+++ b/htdocs/includes/header.php
@@ -28,7 +28,6 @@
require_once(__DIR__."/page_elems.php");
require_once(__DIR__."/script_elems.php");
include_once(__DIR__."/../lang/lang_util.php");
-LangUtil::setPageId("header");
require_once(__DIR__."/perms_check.php");
$script_elems = new ScriptElems();
@@ -76,21 +75,21 @@
- : |
- |
+ : |
+ |
- |
+ |
- |
+ |
- |
+ |
-
+
@@ -137,7 +136,7 @@
# Highlight current page tab
echo " class='here' ";
}
- if (strpos($key, LangUtil::$pageTerms['MENU_BACKUP']) !== false) {
+ if (strpos($key, LangUtil::getTerm("header", 'MENU_BACKUP')) !== false) {
// echo " target='_blank' ";
}
if (strpos($_SERVER['PHP_SELF'], "_home.php") !== false && strpos($value, "lab_configs.php") !== false) {
diff --git a/htdocs/lang/lang_edit.php b/htdocs/lang/lang_edit.php
index 5c791d10..ee83c0ca 100755
--- a/htdocs/lang/lang_edit.php
+++ b/htdocs/lang/lang_edit.php
@@ -1,388 +1,346 @@
-enableJQueryForm();
-//$script_elems->enableAutogrowTextarea();
-function get_locale_page_select()
-{
- global $DEFAULT_LANG, $LANGDATA_PATH, $log;
- libxml_use_internal_errors(true);
- $default_lang_pages = simplexml_load_file($LANGDATA_PATH.$DEFAULT_LANG.".xml");
- if ($default_lang_pages === false) {
- $log->error("Loading $LANGDATA_PATH$DEFAULT_LANG.xml failed.");
- foreach (libxml_get_errors() as $error) {
- $log->error($error->message);
- }
- }
- /*$utf_encoded_content = utf8_encode(file_get_contents($LANGDATA_PATH.$DEFAULT_LANG.".xml"));
- $default_lang_pages = simplexml_load_string($utf_encoded_content);*/
- foreach($default_lang_pages as $default_lang_page)
- {
- $page_id = $default_lang_page['id'];
- $page_descr = $default_lang_page['descr'];
- echo "";
- }
- # Catalog options
- if($CATALOG_TRANSLATION === true)
- {
- echo "";
- echo "";
- echo "";
- echo "";
- }
-}
-
-function get_edit_locale_form($lang_code, $lab_config_id)
-{
- global $DEFAULT_LANG, $page_elems, $LANGDATA_PATH;
- $default_lang_pages = simplexml_load_file($LANGDATA_PATH."default.xml");
- $target_lang_pages = simplexml_load_file($LANGDATA_PATH.$lang_code.".xml");
- /*
- $utf_encoded_content = utf8_encode(file_get_contents($LANGDATA_PATH."default.xml"));
- $default_lang_pages = simplexml_load_string($utf_encoded_content);
- $utf_encoded_content = utf8_encode(file_get_contents($LANGDATA_PATH.$lang_code.".xml"));
- $target_lang_pages = simplexml_load_string($utf_encoded_content);
- */
- $default_pages_list = array();
- $target_pages_list = array();
- foreach($default_lang_pages as $default_lang_page)
- {
- $default_pages_list[] = $default_lang_page;
- }
- foreach($target_lang_pages as $target_lang_page)
- {
- $target_pages_list[] = $target_lang_page;
- }
- # Test Catalog pages
- $default_catalog_pages = simplexml_load_file($LANGDATA_PATH."default_catalog.xml");
- $target_catalog_pages = simplexml_load_file($LANGDATA_PATH.$lang_code."_catalog.xml");
- $default_catalog_list = array();
- $target_catalog_list = array();
- foreach($default_catalog_pages as $default_catalog_page)
- {
- $default_catalog_list[] = $default_catalog_page;
- }
- foreach($target_catalog_pages as $target_catalog_page)
- {
- $target_catalog_list[] = $target_catalog_page;
- }
- for($i = 0; $i < count($default_pages_list);$i++)
- {
- $page_id = $default_pages_list[$i]['id'];
- $page_descr = $default_pages_list[$i]['descr'];
- echo "";
- }
- # Catalog translation forms
- for($i = 0; $i < count($default_catalog_list);$i++)
- {
- $page_id = $default_catalog_list[$i]['id'];
- $page_descr = $default_catalog_list[$i]['descr'];
- echo "";
- echo "
";
- }
-}
-?>
-
-Page Help
-'>« |*/
-?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+enableJQueryForm();
+//$script_elems->enableAutogrowTextarea();
+function get_locale_page_select()
+{
+ global $DEFAULT_LANG, $LANGDATA_PATH, $log;
+ libxml_use_internal_errors(true);
+ $default_lang_pages = simplexml_load_file($LANGDATA_PATH . $DEFAULT_LANG . ".xml");
+ if ($default_lang_pages === false) {
+ $log->error("Loading $LANGDATA_PATH$DEFAULT_LANG.xml failed.");
+ foreach (libxml_get_errors() as $error) {
+ $log->error($error->message);
+ }
+ }
+ /*$utf_encoded_content = utf8_encode(file_get_contents($LANGDATA_PATH.$DEFAULT_LANG.".xml"));
+ $default_lang_pages = simplexml_load_string($utf_encoded_content);*/
+ foreach ($default_lang_pages as $default_lang_page) {
+ $page_id = $default_lang_page['id'];
+ $page_descr = $default_lang_page['descr'];
+ echo "";
+ }
+ # Catalog options
+ if ($CATALOG_TRANSLATION === true) {
+ echo "";
+ echo "";
+ echo "";
+ echo "";
+ }
+}
+
+function get_edit_locale_form($lang_code, $lab_config_id)
+{
+ global $page_elems, $LANGDATA_PATH;
+
+ $default_lang_pages = LangUtil::load_locale_file(__DIR__."/../Language/$lang_code.xml");
+ $override_lang_pages = LangUtil::load_locale_file($LANGDATA_PATH . $lang_code . ".xml");
+
+ $target_lang_pages = LangUtil::merge_locales($default_lang_pages, $override_lang_pages);
+
+ # Test Catalog pages
+ $default_catalog_pages = simplexml_load_file($LANGDATA_PATH . "default_catalog.xml");
+ $target_catalog_pages = simplexml_load_file($LANGDATA_PATH . $lang_code . "_catalog.xml");
+ $default_catalog_list = [];
+ $target_catalog_list = [];
+ foreach ($default_catalog_pages as $default_catalog_page) {
+ $default_catalog_list[] = $default_catalog_page;
+ }
+ foreach ($target_catalog_pages as $target_catalog_page) {
+ $target_catalog_list[] = $target_catalog_page;
+ }
+ foreach ($default_lang_pages as $page_id => $default_terms) {
+ echo "";
+ echo "
";
+ }
+ # Catalog translation forms
+ for ($i = 0; $i < count($default_catalog_list); $i++) {
+ $page_id = $default_catalog_list[$i]['id'];
+ echo "";
+ echo "
";
+ }
+}
+?>
+
+Page Help
+
+
+
+
+
+
+
+
diff --git a/htdocs/lang/lang_update.php b/htdocs/lang/lang_update.php
index 20121f3a..9decde36 100755
--- a/htdocs/lang/lang_update.php
+++ b/htdocs/lang/lang_update.php
@@ -1,53 +1,68 @@
-validateOnParse = true;
-$pages->load($xml_file_name);
-$xpath = new DOMXPath($pages);
-
-# Get appropriate element
-# For each , match by 'key' attrib and update the 'value' attribs
-$keys = $xpath->query("page[@id='".$page_id."']/term/key");
-$values = $xpath->query("page[@id='".$page_id."']/term/value");
-$term_count = 0;
-foreach($keys as $key)
-{
- if(isset($_REQUEST[$key->nodeValue]))
- {
- $new_value = trim($_REQUEST[$key->nodeValue]);
- $old_value = $values->item($term_count)->nodeValue;
- echo $key->nodeValue.": ".$old_value." ".$new_value."
";
- if($new_value != $old_value && $new_value != "")
- {
- # If new value is not empty and not equal to existing value: Update
- $values->item($term_count)->nodeValue = htmlspecialchars($new_value);
- }
- }
- $term_count++;
-}
-
-# Store back updated XML into file
-$pages->save($LANGDATA_PATH.$lang_id.'.xml');
-
-# Convert updated XML to updated PHP file
-lang_xml2php($lang_id, $LANGDATA_PATH);
-?>
\ No newline at end of file
+ $value) {
+ $merged[$page_id][$key] = trim($value);
+}
+
+$new_overrides = LangUtil::find_overrides($language, $merged);
+
+$new_xml = new DOMDocument('1.0', 'UTF-8');
+$new_xml->formatOutput = true;
+
+$pages_el = $new_xml->createElement("pages");
+$pages_el->setAttribute("lang", $lang_id);
+$new_xml->appendChild($pages_el);
+
+foreach($new_overrides as $pagename => $page) {
+ $page_el = $new_xml->createElement("page");
+ $page_el->setAttribute("id", $pagename);
+ $page_el->setAttribute("descr", $descriptions[$pagename]);
+
+ $sorted_terms = array_keys($page);
+ sort($sorted_terms, SORT_STRING | SORT_FLAG_CASE);
+
+ foreach($sorted_terms as $key) {
+ $value = $page[$key];
+
+ $term_el = $new_xml->createElement("term");
+ $key_el = $new_xml->createElement("key", $key);
+ $val_el = $new_xml->createElement("value", $value);
+ $term_el->appendChild($key_el);
+ $term_el->appendChild($val_el);
+ $page_el->appendChild($term_el);
+ }
+ $pages_el->appendChild($page_el);
+}
+
+# Store back updated XML into file (only the changed terms)
+$new_xml->save($LANGDATA_PATH.$lang_id.'.xml');
+
+// # Convert updated locale to updated PHP file
+lang2php($merged, $LANGDATA_PATH, $lang_id);
+?>
diff --git a/htdocs/lang/lang_util.php b/htdocs/lang/lang_util.php
index 9ae3f796..5930da0c 100755
--- a/htdocs/lang/lang_util.php
+++ b/htdocs/lang/lang_util.php
@@ -4,7 +4,7 @@
#
if(!class_exists('LangUtil')) {
- require_once('lang_util_class.php');
+ require_once('lang_util_v2.php');
}
LangUtil::init();
diff --git a/htdocs/lang/lang_util_class.php b/htdocs/lang/lang_util_class.php
index 0d2c8294..27cc5e77 100644
--- a/htdocs/lang/lang_util_class.php
+++ b/htdocs/lang/lang_util_class.php
@@ -6,7 +6,6 @@
class LangUtil
{
- public static $generalPageId = "general";
public static $pageId;
public static $generalTerms;
public static $pageTerms;
@@ -14,7 +13,7 @@ class LangUtil
public static function init()
{
global $LANG_ARRAY;
- self::$generalTerms = $LANG_ARRAY[self::$generalPageId];
+ self::$generalTerms = $LANG_ARRAY["general"];
}
@@ -50,16 +49,6 @@ public static function getPageTitle($page_id)
}
return $retval;
}
- public static function getStockTerm($key)
- {
- global $LANG_ARRAY;
- $retval = $LANG_ARRAY['stocks'][$key];
- if($retval == null)
- {
- $retval = "[ERROR]";
- }
- return $retval;
- }
public static function getTitle()
{
@@ -125,15 +114,6 @@ public static function getSpecimenName($specimen_type_id)
return "[ERROR]";
}
- public static function getMeasureRemarks($lab_config_id, $measure_id)
- {
- # Fetches existing result interpretation (remarks) strings
- global $REMARKS_ARRAY;
- $retval = null;
- if(isset($REMARKS_ARRAY[$measure_id]))
- $retval = $REMARKS_ARRAY[$measure_id];
- return $retval;
- }
public static function getSearchCondition($condition)
{
global $LANG_ARRAY;
@@ -146,4 +126,4 @@ public static function getSearchCondition($condition)
}
}
-?>
\ No newline at end of file
+?>
diff --git a/htdocs/lang/lang_util_v2.php b/htdocs/lang/lang_util_v2.php
new file mode 100644
index 00000000..e043cf49
--- /dev/null
+++ b/htdocs/lang/lang_util_v2.php
@@ -0,0 +1,401 @@
+offsetSet($offset, $value);
+ }
+
+ public function offsetUnset($offset): void
+ {
+ LangUtil::$pageTerms->offsetUnset($offset);
+ }
+
+ public function offsetExists($offset): bool
+ {
+ return LangUtil::$pageTerms->termExists("general", $offset);
+ }
+
+ public function offsetGet($offset)
+ {
+ return LangUtil::$pageTerms->getTerm("general", $offset);
+ }
+}
+
+class Terms implements ArrayAccess
+{
+ private ?string $currentLocale = null;
+ private ?string $currentPageId = null;
+
+ private ?array $languageCache = null;
+
+ public function offsetSet($offset, $value): void
+ {
+ throw new Exception("Language terms may not be modified at runtime.");
+ }
+
+ public function offsetUnset($offset): void
+ {
+ throw new Exception("Language terms may not be modified at runtime.");
+ }
+
+ public function offsetExists($offset): bool
+ {
+ return $this->termExists($this->currentPageId, $offset);
+ }
+
+ public function termExists(string $pageName, string $term): bool
+ {
+ $this->EnsureCache();
+
+ return $this->languageCache != null &&
+ key_exists($pageName, $this->languageCache) &&
+ key_exists($term, $this->languageCache[$pageName]);
+ }
+
+ public function offsetGet($offset)
+ {
+ $page = $this->currentPageId;
+ if ($this->currentPageId == null) {
+ $page = "general";
+ }
+
+ return $this->getTerm($page, $offset);
+ }
+
+ public function getTerm(string $pageName, string $term): string
+ {
+ $this->EnsureCache();
+
+ $locale = $this->currentLocale;
+
+ if (!key_exists($pageName, $this->languageCache)) {
+ return "[MISSING PAGE: $locale:$pageName]";
+ }
+
+ $page = $this->languageCache[$pageName];
+
+ if (!key_exists($term, $page)) {
+ return "[MISSING TERM: $locale:$pageName:$term]";
+ }
+
+ return $page[$term];
+ }
+
+ public function SetPageId(string $pageId)
+ {
+ global $log;
+
+ if ($this->currentLocale != null && $this->currentLocale != "") {
+ if (!array_key_exists($pageId, $this->languageCache)) {
+ $log->error("Language page does not exist in memory: $pageId (" . $this->currentLocale . ")");
+ }
+ }
+
+ $this->currentPageId = $pageId;
+ }
+
+ private function TryLocaleValue(?string $value): bool
+ {
+ if ($value == null || $value == "") {
+ return false;
+ }
+
+ if ($value == "default") {
+ return false;
+ }
+
+ if (!file_exists(__DIR__ . "/../Language/$value.php")) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private function ResolveLocale(): string
+ {
+ if ($this->currentLocale != null) {
+ return $this->currentLocale;
+ }
+
+ if ($this->TryLocaleValue($_SESSION['locale'])) {
+ $this->currentLocale = $_SESSION['locale'];
+ return $this->currentLocale;
+ }
+
+ if (array_key_exists("BLIS_DEFAULT_LOCALE", $_ENV) && $this->TryLocaleValue($_ENV['BLIS_DEFAULT_LOCALE'])) {
+ $this->currentLocale = $_ENV['BLIS_DEFAULT_LOCALE'];
+ return $this->currentLocale;
+ }
+
+ $this->currentLocale = "en";
+ return $this->currentLocale;
+ }
+
+ private function load_legacy_php_locale(string $filename): ?array
+ {
+ global $log;
+
+ if (!file_exists($filename)) {
+ $log->error("File $filename does not exist.");
+ return null;
+ }
+
+ $GLOBALS['LANG_ARRAY'] = null;
+ global $LANG_ARRAY;
+
+ /**
+ * Inherently unsafe code: if the language file has been modified to include dangerous code,
+ * it will be executed here.
+ * This should be replaced with a new format for language loading...
+ */
+ include "$filename";
+
+ if (!$GLOBALS['LANG_ARRAY']) {
+ $log->error("Failed to load LANG_ARRAY from $filename\n");
+ return null;
+ }
+
+ return $GLOBALS['LANG_ARRAY'];
+ }
+
+ function squash_locales(array &$target, array $source)
+ {
+ foreach ($source as $pagename => $pageterms) {
+ if (!array_key_exists($pagename, $target)) {
+ $target[$pagename] = $pageterms;
+ } else {
+ foreach ($pageterms as $term => $val) {
+ $target[$pagename][$term] = $val;
+ }
+ }
+ }
+ }
+
+ private function RefreshCache()
+ {
+ global $log;
+
+ // Reset current cache
+ $this->languageCache = array();
+ $locale = $this->ResolveLocale();
+ $log->info("Locale resolved to $locale");
+
+ $base_language = $this->load_legacy_php_locale(__DIR__ . "/../Language/$locale.php");
+ if (!$base_language) {
+ $log->error("Failed to load base language files from htdocs/Language/$locale.php");
+ return;
+ }
+ $log->info("Loaded base file: $locale.php");
+
+ // TODO: Fix this to resolve better...
+ $lab_id = $_SESSION['lab_config_id'];
+ if ($lab_id) {
+ $lab_language = $this->load_legacy_php_locale(__DIR__ . "/../../local/langdata_$lab_id/$locale.php");
+ if (!$lab_language) {
+ $log->warn("Failed to load language files from local/langdata_$lab_id/$locale.php");
+ } else {
+ $log->info("Loaded lab file: local/langdata_$lab_id/$locale.php");
+ $this->squash_locales($base_language, $lab_language);
+ }
+ }
+
+ $this->languageCache = $base_language;
+ }
+
+ private function EnsureCache()
+ {
+ if ($this->languageCache == null || count($this->languageCache) == 0) {
+ $this->RefreshCache();
+ }
+ }
+}
+
+class LangUtil
+{
+ public static string $pageId;
+
+ public static Terms $pageTerms;
+ public static GeneralTermsShim $generalTerms;
+
+ public static function init()
+ {
+ self::$pageTerms = new Terms();
+ self::$generalTerms = new GeneralTermsShim();
+ }
+
+ public static function setPageId(string $page_id)
+ {
+ self::$pageTerms->SetPageId($page_id);
+ }
+
+ public static function getGeneralTerm(string $key)
+ {
+ # Returns general term string
+ return self::$generalTerms[$key];
+ }
+
+ public static function getPageTitle(string $page_id)
+ {
+ return self::$pageTerms->getTerm($page_id, "TITLE");
+ }
+
+ public static function getTitle()
+ {
+ $retval = self::$pageTerms["TITLE"];
+ if ($retval == null) {
+ $retval = "[ERROR]";
+ }
+ return $retval;
+ }
+
+ public static function getPageTerm($key)
+ {
+ return self::$pageTerms[$key];
+ }
+
+ public static function getTerm(string $pageName, string $term)
+ {
+ return self::$pageTerms->getTerm($pageName, $term);
+ }
+
+ # Fetching test catalog related terms
+ public static function getTestName($test_type_id)
+ {
+ global $CATALOG_ARRAY;
+ if (isset($CATALOG_ARRAY["test"][$test_type_id])) {
+ return $CATALOG_ARRAY["test"][$test_type_id];
+ }
+ return "[ERROR]";
+ }
+
+ public static function getLabSectionName($test_category_id)
+ {
+ global $CATALOG_ARRAY;
+ if (isset($CATALOG_ARRAY["section"][$test_category_id])) {
+ return $CATALOG_ARRAY["section"][$test_category_id];
+ }
+ return "[ERROR]";
+ }
+
+ public static function getMeasureName($measure_id)
+ {
+ global $CATALOG_ARRAY;
+ if (isset($CATALOG_ARRAY["measure"][$measure_id])) {
+ return $CATALOG_ARRAY["measure"][$measure_id];
+ }
+ return "[ERROR]";
+ }
+
+ public static function getSpecimenName($specimen_type_id)
+ {
+ global $CATALOG_ARRAY;
+ if (isset($CATALOG_ARRAY["specimen"][$specimen_type_id])) {
+ return $CATALOG_ARRAY["specimen"][$specimen_type_id];
+ }
+ return "[ERROR]";
+ }
+
+ public static function getSearchCondition($condition)
+ {
+ global $LANG_ARRAY;
+ $retval = $LANG_ARRAY["search_condition"][$condition];
+ if ($retval == null) {
+ $retval = "[ERROR]";
+ }
+ return $retval;
+ }
+
+ /**
+ * Returns a multilevel array keyed by page, then term
+ */
+ public static function load_locale_file(string $filename)
+ {
+ $file = simplexml_load_file($filename);
+
+ $locale = array();
+ foreach ($file as $page) {
+ $pagename = strval($page['id']);
+
+ $pageterms = array();
+ foreach ($page->term as $term) {
+ $k = strval($term->key[0]);
+ $v = strval($term->value[0]);
+
+ $pageterms[$k] = $v;
+ }
+
+ $locale[$pagename] = $pageterms;
+ }
+
+ return $locale;
+ }
+
+ public static function load_page_descriptions(string $filename)
+ {
+ $file = simplexml_load_file($filename);
+
+ $descriptions = array();
+ foreach ($file as $page) {
+ $pagename = strval($page['id']);
+ $descr = strval($page['descr']);
+ $descriptions[$pagename] = $descr;
+ }
+
+ return $descriptions;
+ }
+
+ public static function merge_locales(array $base, array $source): array
+ {
+ foreach ($source as $pagename => $pageterms) {
+ if (!array_key_exists($pagename, $base)) {
+ $base[$pagename] = $pageterms;
+ } else {
+ foreach ($pageterms as $term => $val) {
+ $base[$pagename][$term] = $val;
+ }
+ }
+ }
+
+ return $base;
+ }
+
+ public static function find_overrides(array $base, array $overrides)
+ {
+ $o = array();
+
+ foreach ($overrides as $pagename => $pageterms) {
+ if (!array_key_exists($pagename, $base)) {
+ $o[$pagename] = $pageterms;
+ }
+ }
+
+ foreach ($base as $pagename => $pageterms) {
+ if (!array_key_exists($pagename, $overrides)) {
+ continue;
+ }
+
+ foreach ($pageterms as $term => $value) {
+ if (!array_key_exists($term, $overrides[$pagename])) {
+ continue;
+ }
+
+ if ($overrides[$pagename][$term] != $value) {
+ if (!array_key_exists($pagename, $o)) {
+ $o[$pagename] = array();
+ }
+ $o[$pagename][$term] = $overrides[$pagename][$term];
+ }
+ }
+ }
+
+ return $o;
+ }
+}
diff --git a/htdocs/lang/lang_xml2php.php b/htdocs/lang/lang_xml2php.php
index 2d132d83..b9f169bf 100755
--- a/htdocs/lang/lang_xml2php.php
+++ b/htdocs/lang/lang_xml2php.php
@@ -5,7 +5,7 @@
#
-require_once(dirname(__FILE__)."/../includes/db_lib.php");
+require_once(dirname(__FILE__) . "/../includes/db_lib.php");
#
# Functions for handling language translation
@@ -13,222 +13,265 @@
function lang_xml2php($lang_code, $langdata_path)
{
- $handle = fopen($langdata_path.$lang_code.".php", "w");
- $string_data = << array ( ';
+ fwrite($handle, "\t" . $string_data . "\n");
+ $terms = $page->term;
+ $term_count = 0;
+ foreach ($terms as $term) {
+ $term_count++;
+ $string_data = "\"" . $term->key . "\" => \"" . $term->value . "\"";
+ if ($term_count != count($terms)) {
+ $string_data .= ", ";
+ }
+ fwrite($handle, "\t\t" . $string_data . "\n");
+ }
+
+ $string_data = ") ";
+ fwrite($handle, "\t" . $string_data);
+ if ($page_count < count($pages)) {
+ $string_data = ", ";
+ fwrite($handle, $string_data . "\n");
+ }
+ }
+
+ $string_data = <<
+EOF;
+ fwrite($handle, "\n" . $string_data);
+ fclose($handle);
+}
- $pages = simplexml_load_file($langdata_path.$lang_code.".xml");
+/**
+ * Save an in-memory language array to PHP
+ */
+function lang2php(array $pages, string $langdata_path, string $lang_code)
+{
+ global $log;
- $page_count = 0;
- foreach($pages as $page)
- {
- $page_count++;
- $string_data = '"'.$page['id'].'" => array ( ';
- fwrite($handle, "\t".$string_data."\n");
- $terms = $page->term;
- $term_count = 0;
- foreach($terms as $term)
- {
- $term_count++;
- $string_data = "\"".$term->key."\" => \"".$term->value."\"";
- if($term_count != count($terms))
- {
- $string_data .= ", ";
- }
- fwrite($handle, "\t\t".$string_data."\n");
- }
-
- $string_data = ") ";
- fwrite($handle, "\t".$string_data);
- if($page_count < count($pages))
- {
- $string_data = ", ";
- fwrite($handle, $string_data."\n");
- }
- }
+ $target_file = "$langdata_path/$lang_code.php";
+ $log->info("Saving updated language to $target_file");
- $string_data = << $page) {
+ $page_count++;
+ $string_data = '"' . $pagename . '" => array ( ';
+ fwrite($handle, "\t" . $string_data . "\n");
+
+ $sorted_terms = array_keys($page);
+ sort($sorted_terms, SORT_STRING | SORT_FLAG_CASE);
+
+ $term_count = 0;
+ foreach ($sorted_terms as $key) {
+ $value = $page[$key];
+ $term_count++;
+ $string_data = "\"$key\" => \"$value\"";
+ if ($term_count != count($page)) {
+ $string_data .= ", ";
+ }
+ fwrite($handle, "\t\t" . $string_data . "\n");
+ }
+
+ $string_data = ") ";
+ fwrite($handle, "\t" . $string_data);
+ if ($page_count < count($pages)) {
+ $string_data = ", ";
+ fwrite($handle, $string_data . "\n");
+ }
+ }
+
+ $string_data = <<
+return \$LANG_ARRAY;
EOF;
- fwrite($handle, "\n".$string_data);
- fclose($handle);
+ fwrite($handle, "\n" . $string_data);
+ fclose($handle);
}
#
# Functions for handling test catalog translation
#
-function catalog_db2xml($lang_id="default")
+function catalog_db2xml($lang_id = "default")
{
- # Start catalog
- $string_data = <<
EOF;
- $handle = fopen("../../langdata/".$lang_id."_catalog.xml", "w");
- fwrite($handle, $string_data);
- $query_string = "SELECT * FROM test_category";
- $resultset = query_associative_all($query_string);
- foreach($resultset as $record)
- {
- $key = $record['test_category_id'];
- $value = $record['name'];
- $string_data = <<
$key
$value
EOF;
- fwrite($handle, $string_data);
- }
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- # Add test types
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- $query_string = "SELECT * FROM test_type WHERE disabled=0";
- $resultset = query_associative_all($query_string);
- foreach($resultset as $record)
- {
- $key = $record['test_type_id'];
- $value = $record['name'];
- $string_data = <<
$key
$value
EOF;
- fwrite($handle, $string_data);
- }
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- # Add measures
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- $query_string = "SELECT * FROM measure";
- $resultset = query_associative_all($query_string);
- foreach($resultset as $record)
- {
- $key = $record['measure_id'];
- $value = $record['name'];
- $string_data = <<
$key
$value
EOF;
- fwrite($handle, $string_data);
- }
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- # Add specimen types
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- $query_string = "SELECT * FROM specimen_type WHERE disabled=0";
- $resultset = query_associative_all($query_string);
- foreach($resultset as $record)
- {
- $key = $record['specimen_type_id'];
- $value = $record['name'];
- $string_data = <<
$key
$value
EOF;
- fwrite($handle, $string_data);
- }
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- # End catalog
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- fclose($handle);
+ fwrite($handle, $string_data);
+ fclose($handle);
}
function catalog_xml2php($lang_code)
{
- $handle = fopen("../../langdata/".$lang_code."_catalog.php", "w");
- $string_data = << array ( ';
- fwrite($handle, "\t".$string_data."\n");
- $terms = $entity->term;
- $term_count = 0;
- foreach($terms as $term)
- {
- $term_count++;
- $string_data = "\"".$term->key."\" => \"".$term->value."\"";
- if($term_count != count($terms))
- {
- $string_data .= ", ";
- }
- fwrite($handle, "\t\t".$string_data."\n");
- }
-
- $string_data = ") ";
- fwrite($handle, "\t".$string_data);
- if($catalog_count < count($catalog))
- {
- $string_data = ", ";
- fwrite($handle, $string_data."\n");
- }
- }
- $string_data = << array ( ';
+ fwrite($handle, "\t" . $string_data . "\n");
+ $terms = $entity->term;
+ $term_count = 0;
+ foreach ($terms as $term) {
+ $term_count++;
+ $string_data = "\"" . $term->key . "\" => \"" . $term->value . "\"";
+ if ($term_count != count($terms)) {
+ $string_data .= ", ";
+ }
+ fwrite($handle, "\t\t" . $string_data . "\n");
+ }
+
+ $string_data = ") ";
+ fwrite($handle, "\t" . $string_data);
+ if ($catalog_count < count($catalog)) {
+ $string_data = ", ";
+ fwrite($handle, $string_data . "\n");
+ }
+ }
+ $string_data = <<
EOF;
- fwrite($handle, "\n".$string_data);
- fclose($handle);
- /*
+ fwrite($handle, "\n" . $string_data);
+ fclose($handle);
+ /*
include($lang_code."_catalog.php");
foreach($CATALOG_ARRAY as $key=>$value)
{
@@ -243,23 +286,23 @@ function catalog_xml2php($lang_code)
function update_testtype_xml($test_type_id, $test_name)
{
- catalog_db2xml();
- catalog_xml2php("default");
- # TODO: Extend to other languages
+ catalog_db2xml();
+ catalog_xml2php("default");
+ # TODO: Extend to other languages
}
function update_specimentype_xml($specimen_type_id, $specimen_name)
{
- catalog_db2xml();
- catalog_xml2php("default");
- # TODO: Extend to other languages
+ catalog_db2xml();
+ catalog_xml2php("default");
+ # TODO: Extend to other languages
}
function update_measure_xml($measure_id, $measure_name)
{
- catalog_db2xml();
- catalog_xml2php("default");
- # TODO: Extend to other languages
+ catalog_db2xml();
+ catalog_xml2php("default");
+ # TODO: Extend to other languages
}
@@ -269,168 +312,157 @@ function update_measure_xml($measure_id, $measure_name)
function remarks_xml2php($langdata_path)
{
- # Converts updated XML file to corresponding PHP list
- # TODO:
- $handle = fopen($langdata_path."remarks.php", "w");
- $string_data = << array ( ';
- fwrite($handle, "\t".$string_data."\n");
- $ranges = $measure->range;
- $range_count = 0;
- foreach($ranges as $range)
- {
- $range_count++;
- $string_data = "\"".$range->key."\" => \"".$range->value."\"";
- if($range_count != count($ranges))
- {
- $string_data .= ", ";
- }
- fwrite($handle, "\t\t".$string_data."\n");
- }
-
- $string_data = ") ";
- fwrite($handle, "\t".$string_data);
- if($measure_count < count($measures))
- {
- $string_data = ", ";
- fwrite($handle, $string_data."\n");
- }
- }
- $string_data = << array ( ';
+ fwrite($handle, "\t" . $string_data . "\n");
+ $ranges = $measure->range;
+ $range_count = 0;
+ foreach ($ranges as $range) {
+ $range_count++;
+ $string_data = "\"" . $range->key . "\" => \"" . $range->value . "\"";
+ if ($range_count != count($ranges)) {
+ $string_data .= ", ";
+ }
+ fwrite($handle, "\t\t" . $string_data . "\n");
+ }
+
+ $string_data = ") ";
+ fwrite($handle, "\t" . $string_data);
+ if ($measure_count < count($measures)) {
+ $string_data = ", ";
+ fwrite($handle, $string_data . "\n");
+ }
+ }
+ $string_data = <<
EOF;
- fwrite($handle, "\n".$string_data);
- fclose($handle);
+ fwrite($handle, "\n" . $string_data);
+ fclose($handle);
}
function remarks_db2xml($langdata_path, $lab_config_id)
{
- # Creates XML file from existing test measures (indicators) in catalog
- global $VERSION;
- $new_version = $VERSION;
- $handle = fopen($langdata_path."remarks.xml", "w");
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- $saved_db = DbUtil::switchToLabConfigRevamp($lab_config_id);
- $query_string = "SELECT * FROM measure";
- $resultset = query_associative_all($query_string);
- foreach($resultset as $record)
- {
- $curr_measure = Measure::getObject($record);
- $id = $curr_measure->measureId;
- $descr = $curr_measure->name;
- $string_data = <<measureId;
+ $descr = $curr_measure->name;
+ $string_data = <<
EOF;
- fwrite($handle, $string_data);
- $range_type = $curr_measure->getRangeType();
- $range_values = $curr_measure->getRangeValues();
- if($range_type == Measure::$RANGE_NUMERIC)
- {
- $lower_bound = htmlspecialchars($range_values[0]);
- $upper_bound = htmlspecialchars($range_values[1]);
- $string_data = <<getRangeType();
+ $range_values = $curr_measure->getRangeValues();
+ if ($range_type == Measure::$RANGE_NUMERIC) {
+ $lower_bound = htmlspecialchars($range_values[0]);
+ $upper_bound = htmlspecialchars($range_values[1]);
+ $string_data = <<
$range_values[0]:$range_values[1]
EOF;
- fwrite($handle, $string_data);
- }
- else if($range_type == Measure::$RANGE_OPTIONS)
- {
- foreach($range_values as $range_value)
- {
- $range_value_xml = htmlspecialchars($range_value);
- $string_data = <<
$range_value_xml
EOF;
- fwrite($handle, $string_data);
- }
- }
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- }
- $string_data = <<
EOF;
- fwrite($handle, $string_data);
- fclose($handle);
- DbUtil::switchRestore($saved_db);
+ fwrite($handle, $string_data);
+ fclose($handle);
+ DbUtil::switchRestore($saved_db);
}
function update_remarks_xml($langdata_path, $updated_remarks)
{
- # Updates the XML file after changes made to a test measure (indicator)
- # updated_remarks[measure_id] = {[range]=>[interpretation]}
- global $VERSION;
- $new_version = $VERSION;
- $file_name = $langdata_path."remarks.xml";
- $dest_file_name = $langdata_path."remarks.xml";
- $xml_doc = new DOMDocument();
- $xml_doc->load($file_name);
- $xpath = new DOMXpath($xml_doc);
- $root_node = $xml_doc->getElementsByTagName("measures");
- $root_node->item(0)->setAttribute("version", $new_version);
- foreach($updated_remarks as $key=>$value)
- {
- $measure_id = $key;
- $remarks_map = $value;
- $measure = Measure::getById($measure_id);
- # Remove old measure node
- $old_measure_node = $xpath->query("//measures/measure[@id='".$measure_id."']");
- $old_measure_node = $root_node->item(0)->removeChild($old_measure_node->item(0));
- # Create new measure node based on supplied values
- $new_measure_node = $xml_doc->createElement("measure");
- $new_measure_node->setAttribute("id", $measure_id);
- $new_measure_node->setAttribute("descr", $measure->name);
- foreach($remarks_map as $key2=>$value2)
- {
- $range = $key2;
- $remark = $value2;
- $new_range_node = $xml_doc->createElement("range");
- $new_key_node = $xml_doc->createElement("key", $range);
- $new_value_node = $xml_doc->createElement("value", $remark);
- $new_range_node->appendChild($new_key_node);
- $new_range_node->appendChild($new_value_node);
- $new_measure_node->appendChild($new_range_node);
- }
- # Append updated measure node to XML root node
- $root_node->item(0)->appendChild($new_measure_node);
- }
- # Save changes back into XML file
- $xml_doc->formatOutput = true;
- $xml_doc->preserveWhiteSpace = true;
- $xml_doc->save($dest_file_name);
+ # Updates the XML file after changes made to a test measure (indicator)
+ # updated_remarks[measure_id] = {[range]=>[interpretation]}
+ global $VERSION;
+ $new_version = $VERSION;
+ $file_name = $langdata_path . "remarks.xml";
+ $dest_file_name = $langdata_path . "remarks.xml";
+ $xml_doc = new DOMDocument();
+ $xml_doc->load($file_name);
+ $xpath = new DOMXpath($xml_doc);
+ $root_node = $xml_doc->getElementsByTagName("measures");
+ $root_node->item(0)->setAttribute("version", $new_version);
+ foreach ($updated_remarks as $key => $value) {
+ $measure_id = $key;
+ $remarks_map = $value;
+ $measure = Measure::getById($measure_id);
+ # Remove old measure node
+ $old_measure_node = $xpath->query("//measures/measure[@id='" . $measure_id . "']");
+ $old_measure_node = $root_node->item(0)->removeChild($old_measure_node->item(0));
+ # Create new measure node based on supplied values
+ $new_measure_node = $xml_doc->createElement("measure");
+ $new_measure_node->setAttribute("id", $measure_id);
+ $new_measure_node->setAttribute("descr", $measure->name);
+ foreach ($remarks_map as $key2 => $value2) {
+ $range = $key2;
+ $remark = $value2;
+ $new_range_node = $xml_doc->createElement("range");
+ $new_key_node = $xml_doc->createElement("key", $range);
+ $new_value_node = $xml_doc->createElement("value", $remark);
+ $new_range_node->appendChild($new_key_node);
+ $new_range_node->appendChild($new_value_node);
+ $new_measure_node->appendChild($new_range_node);
+ }
+ # Append updated measure node to XML root node
+ $root_node->item(0)->appendChild($new_measure_node);
+ }
+ # Save changes back into XML file
+ $xml_doc->formatOutput = true;
+ $xml_doc->preserveWhiteSpace = true;
+ $xml_doc->save($dest_file_name);
}
@@ -443,5 +475,3 @@ function update_remarks_xml($langdata_path, $updated_remarks)
//catalog_db2xml("fr");
//catalog_xml2php("fr");
-
-?>