mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
Cleanup and optimization of the handling/loading of the dictionary files.
SVN:trunk[3978]
This commit is contained in:
@@ -77,7 +77,6 @@ class Config
|
||||
protected $m_aDataModels;
|
||||
protected $m_aWebServiceCategories;
|
||||
protected $m_aAddons;
|
||||
protected $m_aDictionaries;
|
||||
|
||||
protected $m_aModuleSettings;
|
||||
|
||||
@@ -1053,7 +1052,6 @@ class Config
|
||||
// Default AddOn, always present can be moved to an official iTop Module later if needed
|
||||
'user rights' => 'addons/userrights/userrightsprofile.class.inc.php',
|
||||
);
|
||||
$this->m_aDictionaries = self::ScanDictionariesDir();
|
||||
|
||||
foreach($this->m_aSettings as $sPropCode => $aSettingInfo)
|
||||
{
|
||||
@@ -1173,10 +1171,7 @@ class Config
|
||||
// Add one, by default
|
||||
$MyModules['addons']['user rights'] = '/addons/userrights/userrightsnull.class.inc.php';
|
||||
}
|
||||
if (!array_key_exists('dictionaries', $MyModules))
|
||||
{
|
||||
throw new ConfigException('Missing item in configuration file', array('file' => $sConfigFile, 'expected' => '$MyModules[\'dictionaries\']'));
|
||||
}
|
||||
|
||||
$this->m_aAppModules = $MyModules['application'];
|
||||
$this->m_aDataModels = $MyModules['business'];
|
||||
if (isset($MyModules['webservices']))
|
||||
@@ -1184,7 +1179,6 @@ class Config
|
||||
$this->m_aWebServiceCategories = $MyModules['webservices'];
|
||||
}
|
||||
$this->m_aAddons = $MyModules['addons'];
|
||||
$this->m_aDictionaries = $MyModules['dictionaries'];
|
||||
|
||||
foreach($MySettings as $sPropCode => $rawvalue)
|
||||
{
|
||||
@@ -1304,15 +1298,6 @@ class Config
|
||||
$this->m_aAddons = $aAddons;
|
||||
}
|
||||
|
||||
public function GetDictionaries()
|
||||
{
|
||||
return $this->m_aDictionaries;
|
||||
}
|
||||
public function SetDictionaries($aDictionaries)
|
||||
{
|
||||
$this->m_aDictionaries = $aDictionaries;
|
||||
}
|
||||
|
||||
public function GetDBHost()
|
||||
{
|
||||
return $this->m_sDBHost;
|
||||
@@ -1608,10 +1593,6 @@ class Config
|
||||
{
|
||||
$aSettings['addon_list'][] = $sFile;
|
||||
}
|
||||
foreach($this->m_aDictionaries as $sFile)
|
||||
{
|
||||
$aSettings['dictionary_list'][] = $sFile;
|
||||
}
|
||||
return $aSettings;
|
||||
}
|
||||
|
||||
@@ -1780,12 +1761,6 @@ class Config
|
||||
fwrite($hFile, "\t\t'$sKey' => '$sFile',\n");
|
||||
}
|
||||
fwrite($hFile, "\t),\n");
|
||||
fwrite($hFile, "\t'dictionaries' => array (\n");
|
||||
foreach($this->m_aDictionaries as $sFile)
|
||||
{
|
||||
fwrite($hFile, "\t\t'$sFile',\n");
|
||||
}
|
||||
fwrite($hFile, "\t),\n");
|
||||
fwrite($hFile, ");\n");
|
||||
fwrite($hFile, '?'.'>'); // Avoid perturbing the syntax highlighting !
|
||||
return fclose($hFile);
|
||||
@@ -1795,26 +1770,6 @@ class Config
|
||||
throw new ConfigException("Could not write to configuration file", array('file' => $sFileName));
|
||||
}
|
||||
}
|
||||
|
||||
protected static function ScanDictionariesDir()
|
||||
{
|
||||
$aResult = array();
|
||||
// Populate automatically the list of dictionary files
|
||||
$sDir = APPROOT.'/dictionaries';
|
||||
if ($hDir = @opendir($sDir))
|
||||
{
|
||||
while (($sFile = readdir($hDir)) !== false)
|
||||
{
|
||||
$aMatches = array();
|
||||
if (preg_match("/^([^\.]+\.)?dictionary\.itop\.(ui|core)\.php$/i", $sFile, $aMatches)) // Dictionary files named like [<Lang>.]dictionary.[core|ui].php are loaded automatically
|
||||
{
|
||||
$aResult[] = 'dictionaries/'.$sFile;
|
||||
}
|
||||
}
|
||||
closedir($hDir);
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to initialize a configuration from the page arguments
|
||||
@@ -1882,7 +1837,6 @@ class Config
|
||||
}
|
||||
$aDataModels = $oEmptyConfig->GetDataModels();
|
||||
$aWebServiceCategories = $oEmptyConfig->GetWebServiceCategories();
|
||||
$aDictionaries = $oEmptyConfig->GetDictionaries();
|
||||
// Merge the values with the ones provided by the modules
|
||||
// Make sure when don't load the same file twice...
|
||||
|
||||
@@ -1935,15 +1889,6 @@ class Config
|
||||
$this->SetAppModules($aAppModules);
|
||||
$this->SetDataModels($aDataModels);
|
||||
$this->SetWebServiceCategories($aWebServiceCategories);
|
||||
|
||||
// Scan dictionaries
|
||||
//
|
||||
foreach (glob(APPROOT.$sModulesDir.'/dictionaries/*.dict.php') as $sFilePath)
|
||||
{
|
||||
$sFile = basename($sFilePath);
|
||||
$aDictionaries[] = $sModulesDir.'/dictionaries/'.$sFile;
|
||||
}
|
||||
$this->SetDictionaries($aDictionaries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1970,7 +1915,6 @@ class Config
|
||||
$sNewPrefix = 'env-'.$sTargetEnv.'/';
|
||||
self::ChangePrefix($this->m_aDataModels, $sSearchPrefix, $sNewPrefix);
|
||||
self::ChangePrefix($this->m_aWebServiceCategories, $sSearchPrefix, $sNewPrefix);
|
||||
self::ChangePrefix($this->m_aDictionaries, $sSearchPrefix, $sNewPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2012 Combodo SARL
|
||||
// Copyright (C) 2010-2016 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -57,26 +57,13 @@ define('DICT_ERR_EXCEPTION', 2); // when a string is missing, throw an exception
|
||||
|
||||
class Dict
|
||||
{
|
||||
protected static $m_bTraceFiles = false;
|
||||
protected static $m_aEntryFiles = array();
|
||||
|
||||
protected static $m_iErrorMode = DICT_ERR_STRING;
|
||||
protected static $m_sDefaultLanguage = 'EN US';
|
||||
protected static $m_sCurrentLanguage = null; // No language selected by default
|
||||
|
||||
protected static $m_aLanguages = array(); // array( code => array( 'description' => '...', 'localized_description' => '...') ...)
|
||||
protected static $m_aData = array();
|
||||
|
||||
|
||||
public static function EnableTraceFiles()
|
||||
{
|
||||
self::$m_bTraceFiles = true;
|
||||
}
|
||||
|
||||
public static function GetEntryFiles()
|
||||
{
|
||||
return self::$m_aEntryFiles;
|
||||
}
|
||||
protected static $m_sApplicationPrefix = null;
|
||||
|
||||
public static function SetDefaultLanguage($sLanguageCode)
|
||||
{
|
||||
@@ -119,11 +106,20 @@ class Dict
|
||||
self::$m_iErrorMode = $iErrorMode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a localised string from the dictonary
|
||||
* @param string $sStringCode The code identifying the dictionary entry
|
||||
* @param string $sDefault Default value if there is no match in the dictionary
|
||||
* @param bool $bUserLanguageOnly True to allow the use of the default language as a fallback, false otherwise
|
||||
* @throws DictExceptionMissingString
|
||||
* @return unknown|Ambigous <>|string
|
||||
*/
|
||||
public static function S($sStringCode, $sDefault = null, $bUserLanguageOnly = false)
|
||||
{
|
||||
// Attempt to find the string in the user language
|
||||
//
|
||||
self::InitLangIfNeeded(self::GetUserLanguage());
|
||||
|
||||
if (!array_key_exists(self::GetUserLanguage(), self::$m_aData))
|
||||
{
|
||||
// It may happen, when something happens before the dictionnaries get loaded
|
||||
@@ -138,6 +134,8 @@ class Dict
|
||||
{
|
||||
// Attempt to find the string in the default language
|
||||
//
|
||||
self::InitLangIfNeeded(self::$m_sDefaultLanguage);
|
||||
|
||||
$aDefaultDictionary = self::$m_aData[self::$m_sDefaultLanguage];
|
||||
if (array_key_exists($sStringCode, $aDefaultDictionary))
|
||||
{
|
||||
@@ -175,6 +173,12 @@ class Dict
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats a localized string with numbered placeholders (%1$s...) for the additional arguments
|
||||
* See vsprintf for more information about the syntax of the placeholders
|
||||
* @param string $sFormatCode
|
||||
* @return string
|
||||
*/
|
||||
public static function Format($sFormatCode /*, ... arguments ....*/)
|
||||
{
|
||||
$sLocalizedFormat = self::S($sFormatCode);
|
||||
@@ -189,43 +193,95 @@ class Dict
|
||||
|
||||
return vsprintf($sLocalizedFormat, $aArguments);
|
||||
}
|
||||
|
||||
|
||||
// sLanguageCode: Code identifying the language i.e. FR-FR
|
||||
// sEnglishLanguageDesc: Description of the language code, in English. i.e. French (France)
|
||||
// sLocalizedLanguageDesc: Description of the language code, in its own language. i.e. Français (France)
|
||||
// aEntries: Hash array of dictionnary entries
|
||||
// ~~ or ~* can be used to indicate entries still to be translated.
|
||||
public static function Add($sLanguageCode, $sEnglishLanguageDesc, $sLocalizedLanguageDesc, $aEntries)
|
||||
|
||||
/**
|
||||
* Initialize a the entries for a given language (replaces the former Add() method)
|
||||
* @param string $sLanguageCode Code identifying the language i.e. 'FR-FR', 'EN-US'
|
||||
* @param hash $aEntries Hash array of dictionnary entries
|
||||
*/
|
||||
public static function SetEntries($sLanguageCode, $aEntries)
|
||||
{
|
||||
if (self::$m_bTraceFiles)
|
||||
self::$m_aData[$sLanguageCode] = $aEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of available languages
|
||||
* @param hash $aLanguagesList
|
||||
*/
|
||||
public static function SetLanguagesList($aLanguagesList)
|
||||
{
|
||||
self::$m_aLanguages = $aLanguagesList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a language from the language dictionary, if not already loaded
|
||||
* @param string $sLangCode Language code
|
||||
* @return boolean
|
||||
*/
|
||||
public static function InitLangIfNeeded($sLangCode)
|
||||
{
|
||||
if (array_key_exists($sLangCode, self::$m_aData)) return true;
|
||||
|
||||
$bResult = false;
|
||||
|
||||
if (function_exists('apc_fetch') && (self::$m_sApplicationPrefix !== null))
|
||||
{
|
||||
$aBacktrace = debug_backtrace();
|
||||
$sFile = $aBacktrace[0]["file"];
|
||||
|
||||
foreach($aEntries as $sKey => $sValue)
|
||||
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
||||
//
|
||||
self::$m_aData[$sLangCode] = apc_fetch(self::$m_sApplicationPrefix.'-dict-'.$sLangCode);
|
||||
if (self::$m_aData[$sLangCode] === false)
|
||||
{
|
||||
self::$m_aEntryFiles[$sLanguageCode][$sKey] = array(
|
||||
'file' => $sFile,
|
||||
'value' => $sValue
|
||||
);
|
||||
unset(self::$m_aData[$sLangCode]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!array_key_exists($sLanguageCode, self::$m_aLanguages))
|
||||
if (!$bResult)
|
||||
{
|
||||
self::$m_aLanguages[$sLanguageCode] = array('description' => $sEnglishLanguageDesc, 'localized_description' => $sLocalizedLanguageDesc);
|
||||
self::$m_aData[$sLanguageCode] = array();
|
||||
}
|
||||
foreach($aEntries as $sCode => $sValue)
|
||||
{
|
||||
self::$m_aData[$sLanguageCode][$sCode] = self::FilterString($sValue);
|
||||
$sDictFile = APPROOT.'env-'.utils::GetCurrentEnvironment().'/dictionaries/'.str_replace(' ', '-', strtolower($sLangCode)).'.dict.php';
|
||||
require_once($sDictFile);
|
||||
|
||||
if (function_exists('apc_store') && (self::$m_sApplicationPrefix !== null))
|
||||
{
|
||||
apc_store(self::$m_sApplicationPrefix.'-dict-'.$sLangCode, self::$m_aData[$sLangCode]);
|
||||
}
|
||||
$bResult = true;
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable caching (cached using APC)
|
||||
* @param string $sApplicationPrefix The prefix for uniquely identiying this iTop instance
|
||||
*/
|
||||
public static function EnableCache($sApplicationPrefix)
|
||||
{
|
||||
self::$m_sApplicationPrefix = $sApplicationPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the cached entries (cached using APC)
|
||||
* @param string $sApplicationPrefix The prefix for uniquely identiying this iTop instance
|
||||
*/
|
||||
public static function ResetCache($sApplicationPrefix)
|
||||
{
|
||||
if (function_exists('apc_delete'))
|
||||
{
|
||||
foreach(self::$m_aLanguages as $sLang => $void)
|
||||
{
|
||||
apc_delete($sApplicationPrefix.'-dict-'.$sLang);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Clone a string in every language (if it exists in that language)
|
||||
*/
|
||||
*/
|
||||
public static function CloneString($sSourceCode, $sDestCode)
|
||||
{
|
||||
foreach(self::$m_aLanguages as $sLanguageCode => $foo)
|
||||
@@ -236,14 +292,14 @@ class Dict
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function MakeStats($sLanguageCode, $sLanguageRef = 'EN US')
|
||||
{
|
||||
$aMissing = array(); // Strings missing for the target language
|
||||
$aUnexpected = array(); // Strings defined for the target language, but not found in the reference dictionary
|
||||
$aNotTranslated = array(); // Strings having the same value in both dictionaries
|
||||
$aOK = array(); // Strings having different values in both dictionaries
|
||||
|
||||
|
||||
foreach (self::$m_aData[$sLanguageRef] as $sStringCode => $sValue)
|
||||
{
|
||||
if (!array_key_exists($sStringCode, self::$m_aData[$sLanguageCode]))
|
||||
@@ -251,7 +307,7 @@ class Dict
|
||||
$aMissing[$sStringCode] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach (self::$m_aData[$sLanguageCode] as $sStringCode => $sValue)
|
||||
{
|
||||
if (!array_key_exists($sStringCode, self::$m_aData[$sLanguageRef]))
|
||||
@@ -279,57 +335,24 @@ class Dict
|
||||
{
|
||||
MyHelpers::var_dump_html(self::$m_aData);
|
||||
}
|
||||
|
||||
public static function InCache($sApplicationPrefix)
|
||||
{
|
||||
if (function_exists('apc_fetch'))
|
||||
{
|
||||
$bResult = false;
|
||||
// Note: For versions of APC older than 3.0.17, fetch() accepts only one parameter
|
||||
//
|
||||
self::$m_aData = apc_fetch($sApplicationPrefix.'-dict');
|
||||
if (is_bool(self::$m_aData) && (self::$m_aData === false))
|
||||
{
|
||||
self::$m_aData = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$m_aLanguages = apc_fetch($sApplicationPrefix.'-languages');
|
||||
if (is_bool(self::$m_aLanguages) && (self::$m_aLanguages === false))
|
||||
{
|
||||
self::$m_aLanguages = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
return $bResult;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function InitCache($sApplicationPrefix)
|
||||
{
|
||||
if (function_exists('apc_store'))
|
||||
{
|
||||
apc_store($sApplicationPrefix.'-languages', self::$m_aLanguages);
|
||||
apc_store($sApplicationPrefix.'-dict', self::$m_aData);
|
||||
}
|
||||
}
|
||||
|
||||
public static function ResetCache($sApplicationPrefix)
|
||||
// Obsolete: only used by the setup/compiler which replaces this method invocation by its own handler !!
|
||||
// sLanguageCode: Code identifying the language i.e. FR-FR
|
||||
// sEnglishLanguageDesc: Description of the language code, in English. i.e. French (France)
|
||||
// sLocalizedLanguageDesc: Description of the language code, in its own language. i.e. Français (France)
|
||||
// aEntries: Hash array of dictionnary entries
|
||||
// ~~ or ~* can be used to indicate entries still to be translated.
|
||||
public static function Add($sLanguageCode, $sEnglishLanguageDesc, $sLocalizedLanguageDesc, $aEntries)
|
||||
{
|
||||
if (function_exists('apc_delete'))
|
||||
if (!array_key_exists($sLanguageCode, self::$m_aLanguages))
|
||||
{
|
||||
apc_delete($sApplicationPrefix.'-languages');
|
||||
apc_delete($sApplicationPrefix.'-dict');
|
||||
self::$m_aLanguages[$sLanguageCode] = array('description' => $sEnglishLanguageDesc, 'localized_description' => $sLocalizedLanguageDesc);
|
||||
self::$m_aData[$sLanguageCode] = array();
|
||||
}
|
||||
foreach($aEntries as $sCode => $sValue)
|
||||
{
|
||||
self::$m_aData[$sLanguageCode][$sCode] = self::FilterString($sValue);
|
||||
}
|
||||
}
|
||||
|
||||
protected static function FilterString($s)
|
||||
{
|
||||
return str_replace(array('~~', '~*'), '', $s);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -4219,15 +4219,13 @@ abstract class MetaModel
|
||||
// needed when some error occur
|
||||
$sAppIdentity = 'itop-'.MetaModel::GetEnvironmentId();
|
||||
$bDictInitializedFromData = false;
|
||||
if (!self::$m_bUseAPCCache || !Dict::InCache($sAppIdentity))
|
||||
if (self::$m_bUseAPCCache)
|
||||
{
|
||||
$bDictInitializedFromData = true;
|
||||
foreach (self::$m_oConfig->GetDictionaries() as $sModule => $sToInclude)
|
||||
{
|
||||
self::IncludeModule('dictionaries', $sToInclude);
|
||||
}
|
||||
}
|
||||
// Set the language... after the dictionaries have been loaded!
|
||||
Dict::EnableCache($sAppIdentity);
|
||||
}
|
||||
require_once(APPROOT.'env-'.utils::GetCurrentEnvironment().'/dictionaries/languages.php');
|
||||
|
||||
// Set the default language...
|
||||
Dict::SetDefaultLanguage(self::$m_oConfig->GetDefaultLanguage());
|
||||
|
||||
// Romain: this is the only way I've found to cope with the fact that
|
||||
@@ -4332,11 +4330,6 @@ abstract class MetaModel
|
||||
$oKPI->ComputeAndReport('Metamodel APC (store)');
|
||||
}
|
||||
}
|
||||
|
||||
if (self::$m_bUseAPCCache && $bDictInitializedFromData)
|
||||
{
|
||||
Dict::InitCache($sAppIdentity);
|
||||
}
|
||||
|
||||
self::$m_sDBName = $sSource;
|
||||
self::$m_sTablePrefix = $sTablePrefix;
|
||||
|
||||
@@ -473,6 +473,9 @@ class ApplicationInstaller
|
||||
|
||||
$oFactory = new ModelFactory($aDirsToScan);
|
||||
|
||||
$oDictModule = new MFDictModule('dictionaries', 'iTop Dictionaries', APPROOT.'dictionaries');
|
||||
$oFactory->LoadModule($oDictModule);
|
||||
|
||||
$sDeltaFile = APPROOT.'core/datamodel.core.xml';
|
||||
if (file_exists($sDeltaFile))
|
||||
{
|
||||
|
||||
@@ -424,10 +424,7 @@ EOF;
|
||||
}
|
||||
|
||||
$oDictionaries = $this->oFactory->GetNodes('dictionaries/dictionary');
|
||||
foreach($oDictionaries as $oDictionaryNode)
|
||||
{
|
||||
$this->CompileDictionary($oDictionaryNode, $sTempTargetDir, $sFinalTargetDir);
|
||||
}
|
||||
$this->CompileDictionaries($oDictionaries, $sTempTargetDir, $sFinalTargetDir);
|
||||
|
||||
// Compile the branding
|
||||
//
|
||||
@@ -2084,37 +2081,63 @@ EOF;
|
||||
return $sPHP;
|
||||
} // function CompileUserRights
|
||||
|
||||
protected function CompileDictionary($oDictionaryNode, $sTempTargetDir, $sFinalTargetDir)
|
||||
protected function CompileDictionaries($oDictionaries, $sTempTargetDir, $sFinalTargetDir)
|
||||
{
|
||||
$sLang = $oDictionaryNode->getAttribute('id');
|
||||
$sEnglishLanguageDesc = $oDictionaryNode->GetChildText('english_description');
|
||||
$sLocalizedLanguageDesc = $oDictionaryNode->GetChildText('localized_description');
|
||||
|
||||
$aEntriesPHP = array();
|
||||
$oEntries = $oDictionaryNode->GetUniqueElement('entries');
|
||||
foreach($oEntries->getElementsByTagName('entry') as $oEntry)
|
||||
$aLanguages = array();
|
||||
foreach($oDictionaries as $oDictionaryNode)
|
||||
{
|
||||
$sStringCode = $oEntry->getAttribute('id');
|
||||
$sValue = $oEntry->GetText();
|
||||
$aEntriesPHP[] = "\t'$sStringCode' => ".self::QuoteForPHP($sValue, true).",";
|
||||
}
|
||||
$sEntriesPHP = implode("\n", $aEntriesPHP);
|
||||
$sLang = $oDictionaryNode->getAttribute('id');
|
||||
$sEnglishLanguageDesc = $oDictionaryNode->GetChildText('english_description');
|
||||
$sLocalizedLanguageDesc = $oDictionaryNode->GetChildText('localized_description');
|
||||
$aLanguages[$sLang] = array('description' => $sEnglishLanguageDesc, 'localized_description' => $sLocalizedLanguageDesc);
|
||||
|
||||
$sEscEnglishLanguageDesc = self::QuoteForPHP($sEnglishLanguageDesc);
|
||||
$sEscLocalizedLanguageDesc = self::QuoteForPHP($sLocalizedLanguageDesc);
|
||||
$sPHPDict =
|
||||
$aEntriesPHP = array();
|
||||
$oEntries = $oDictionaryNode->GetUniqueElement('entries');
|
||||
foreach ($oEntries->getElementsByTagName('entry') as $oEntry)
|
||||
{
|
||||
$sStringCode = $oEntry->getAttribute('id');
|
||||
$sValue = $oEntry->GetText();
|
||||
$aEntriesPHP[] = "\t'$sStringCode' => ".self::QuoteForPHP(self::FilterDictString($sValue), true).",";
|
||||
}
|
||||
$sEntriesPHP = implode("\n", $aEntriesPHP);
|
||||
|
||||
$sPHPDict =
|
||||
<<<EOF
|
||||
<?php
|
||||
//
|
||||
// Dictionary built by the compiler for the language "$sLang"
|
||||
//
|
||||
Dict::Add('$sLang', $sEscEnglishLanguageDesc, $sEscLocalizedLanguageDesc, array(
|
||||
Dict::SetEntries('$sLang', array(
|
||||
$sEntriesPHP
|
||||
));
|
||||
EOF;
|
||||
$sSafeLang = str_replace(' ', '-', strtolower(trim($sLang)));
|
||||
$sDictFile = $sTempTargetDir.'/dictionaries/'.$sSafeLang.'.dict.php';
|
||||
file_put_contents($sDictFile, $sPHPDict);
|
||||
$sSafeLang = str_replace(' ', '-', strtolower(trim($sLang)));
|
||||
$sDictFile = $sTempTargetDir.'/dictionaries/'.$sSafeLang.'.dict.php';
|
||||
file_put_contents($sDictFile, $sPHPDict);
|
||||
}
|
||||
$sLanguagesFile = $sTempTargetDir.'/dictionaries/languages.php';
|
||||
$sLanguagesDump = var_export($aLanguages, true);
|
||||
$sLanguagesFileContent =
|
||||
<<<EOF
|
||||
<?php
|
||||
//
|
||||
// Dictionary index built by the compiler
|
||||
//
|
||||
Dict::SetLanguagesList(
|
||||
$sLanguagesDump
|
||||
);
|
||||
EOF;
|
||||
|
||||
file_put_contents($sLanguagesFile, $sLanguagesFileContent);
|
||||
}
|
||||
|
||||
protected static function FilterDictString($s)
|
||||
{
|
||||
if (strpos($s, '~') !== false)
|
||||
{
|
||||
return str_replace(array('~~', '~*'), '', $s);
|
||||
}
|
||||
return $s;
|
||||
}
|
||||
|
||||
// Transform the file references into the corresponding filename (and create the file in the relevant directory)
|
||||
|
||||
@@ -206,6 +206,54 @@ class MFCoreModule extends MFModule
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MFDictModule: an optional module, consisting only of dictionaries
|
||||
* @package ModelFactory
|
||||
*/
|
||||
class MFDictModule extends MFModule
|
||||
{
|
||||
public function __construct($sName, $sLabel, $sRootDir)
|
||||
{
|
||||
$this->sId = $sName;
|
||||
|
||||
$this->sName = $sName;
|
||||
$this->sVersion = '1.0';
|
||||
|
||||
$this->sRootDir = $sRootDir;
|
||||
$this->sLabel = $sLabel;
|
||||
$this->aDataModels = array();
|
||||
}
|
||||
|
||||
public function GetRootDir()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function GetModuleDir()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function GetDictionaryFiles()
|
||||
{
|
||||
$aDictionaries = array();
|
||||
if ($hDir = opendir($this->sRootDir))
|
||||
{
|
||||
while (($sFile = readdir($hDir)) !== false)
|
||||
{
|
||||
$aMatches = array();
|
||||
if (preg_match("/^.*dictionary\\.itop.*.php$/i", $sFile, $aMatches)) // Dictionary files are named like <Lang>.dict.<ModuleName>.php
|
||||
{
|
||||
$aDictionaries[] = $this->sRootDir.'/'.$sFile;
|
||||
}
|
||||
}
|
||||
closedir($hDir);
|
||||
}
|
||||
return $aDictionaries;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ModelFactory: the class that manages the in-memory representation of the XML MetaModel
|
||||
* @package ModelFactory
|
||||
@@ -549,14 +597,23 @@ class ModelFactory
|
||||
$oXmlEntry->appendChild($oXmlValue);
|
||||
if (array_key_exists($sLanguageCode, $this->aDictKeys) && array_key_exists($sCode, $this->aDictKeys[$sLanguageCode]))
|
||||
{
|
||||
$oXmlEntries->RedefineChildNode($oXmlEntry);
|
||||
$oMe = $this->aDictKeys[$sLanguageCode][$sCode];
|
||||
$sFlag = $oMe->getAttribute('_alteration');
|
||||
$oMe->parentNode->replaceChild($oXmlEntry, $oMe);
|
||||
$sNewFlag = $sFlag;
|
||||
if ($sFlag == '')
|
||||
{
|
||||
$sNewFlag = 'replaced';
|
||||
}
|
||||
$oXmlEntry->setAttribute('_alteration', $sNewFlag);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$oXmlEntry->setAttribute('_alteration', 'added');
|
||||
$oXmlEntries->appendChild($oXmlEntry);
|
||||
}
|
||||
$this->aDictKeys[$sLanguageCode][$sCode] = true;
|
||||
$this->aDictKeys[$sLanguageCode][$sCode] = $oXmlEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,6 +341,9 @@ class RunTimeEnvironment
|
||||
|
||||
// Do load the required modules
|
||||
//
|
||||
$oDictModule = new MFDictModule('dictionaries', 'iTop Dictionaries', APPROOT.'dictionaries');
|
||||
$aRet[] = $oDictModule;
|
||||
|
||||
$oFactory = new ModelFactory($aDirsToCompile);
|
||||
$sDeltaFile = APPROOT.'core/datamodel.core.xml';
|
||||
if (file_exists($sDeltaFile))
|
||||
|
||||
Reference in New Issue
Block a user