mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 02:28:44 +02:00
New way to compile the dictionaries, allowing for incremental modification via XML
SVN:trunk[2712]
This commit is contained in:
@@ -1570,10 +1570,6 @@ class Config
|
||||
{
|
||||
$aWebServiceCategories = array_unique(array_merge($aWebServiceCategories, $aModuleInfo['webservice']));
|
||||
}
|
||||
if (isset($aModuleInfo['dictionary']))
|
||||
{
|
||||
$aDictionaries = array_unique(array_merge($aDictionaries, $aModuleInfo['dictionary']));
|
||||
}
|
||||
if (isset($aModuleInfo['settings']))
|
||||
{
|
||||
list($sName, $sVersion) = ModuleDiscovery::GetModuleName($sModuleId);
|
||||
@@ -1609,6 +1605,17 @@ class Config
|
||||
$this->SetAppModules($aAppModules);
|
||||
$this->SetDataModels($aDataModels);
|
||||
$this->SetWebServiceCategories($aWebServiceCategories);
|
||||
|
||||
// Scan dictionaries
|
||||
//
|
||||
if (!is_null($sModulesDir))
|
||||
{
|
||||
foreach(glob(APPROOT.$sModulesDir.'/dictionaries/*.dict.php') as $sFilePath)
|
||||
{
|
||||
$sFile = basename($sFilePath);
|
||||
$aDictionaries[] = $sModulesDir.'/dictionaries/'.$sFile;
|
||||
}
|
||||
}
|
||||
$this->SetDictionaries($aDictionaries);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,21 @@ EOF;
|
||||
{
|
||||
$this->Log("Compilation of module $sModuleName in version $sModuleVersion produced not code at all. No file written.");
|
||||
}
|
||||
|
||||
} // foreach module
|
||||
|
||||
// Compile the dictionaries -out of the modules
|
||||
//
|
||||
$sDictDir = $sTargetDir.'/dictionaries';
|
||||
if (!is_dir($sDictDir))
|
||||
{
|
||||
$this->Log("Creating directory $sDictDir");
|
||||
mkdir($sDictDir, 0777, true);
|
||||
}
|
||||
|
||||
$oDictionaries = $this->oFactory->ListActiveChildNodes('dictionaries', 'dictionary');
|
||||
foreach($oDictionaries as $oDictionaryNode)
|
||||
{
|
||||
$this->CompileDictionary($oDictionaryNode, $sTargetDir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,10 +465,18 @@ EOF;
|
||||
/**
|
||||
* Adds quotes and escape characters
|
||||
*/
|
||||
protected function QuoteForPHP($sStr)
|
||||
protected function QuoteForPHP($sStr, $bSimpleQuotes = false)
|
||||
{
|
||||
$sEscaped = str_replace(array('\\', '"', "\n"), array('\\\\', '\\"', '\\n'), $sStr);
|
||||
$sRet = '"'.$sEscaped.'"';
|
||||
if ($bSimpleQuotes)
|
||||
{
|
||||
$sEscaped = str_replace(array('\\', "'"), array('\\\\', "\\'"), $sStr);
|
||||
$sRet = "'$sEscaped'";
|
||||
}
|
||||
else
|
||||
{
|
||||
$sEscaped = str_replace(array('\\', '"', "\n"), array('\\\\', '\\"', '\\n'), $sStr);
|
||||
$sRet = '"'.$sEscaped.'"';
|
||||
}
|
||||
return $sRet;
|
||||
}
|
||||
|
||||
@@ -1408,8 +1430,38 @@ EOF;
|
||||
return $sPHP;
|
||||
} // function CompileUserRights
|
||||
|
||||
protected function CompileDictionary($oDictionaryNode, $sTargetDir)
|
||||
{
|
||||
$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)
|
||||
{
|
||||
$sStringCode = $oEntry->getAttribute('id');
|
||||
$sValue = $oEntry->GetText();
|
||||
$aEntriesPHP[] = "\t'$sStringCode' => ".self::QuoteForPHP($sValue, true).",";
|
||||
}
|
||||
$sEntriesPHP = implode("\n", $aEntriesPHP);
|
||||
|
||||
$sEscEnglishLanguageDesc = self::QuoteForPHP($sEnglishLanguageDesc);
|
||||
$sEscLocalizedLanguageDesc = self::QuoteForPHP($sLocalizedLanguageDesc);
|
||||
$sPHPDict =
|
||||
<<<EOF
|
||||
<?php
|
||||
//
|
||||
// Dictionary built by the compiler for the language "$sLang"
|
||||
//
|
||||
Dict::Add('$sLang', $sEscEnglishLanguageDesc, $sEscLocalizedLanguageDesc, array(
|
||||
$sEntriesPHP
|
||||
));
|
||||
EOF;
|
||||
$sSafeLang = str_replace(' ', '-', strtolower(trim($sLang)));
|
||||
$sDictFile = $sTargetDir.'/dictionaries/'.$sSafeLang.'.dict.php';
|
||||
file_put_contents($sDictFile, $sPHPDict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
?>
|
||||
@@ -111,6 +111,24 @@ class MFModule
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function GetDictionaryFiles()
|
||||
{
|
||||
$aDictionaries = array();
|
||||
if ($hDir = opendir($this->sRootDir))
|
||||
{
|
||||
while (($sFile = readdir($hDir)) !== false)
|
||||
{
|
||||
$aMatches = array();
|
||||
if (preg_match("/^[^\\.]+.dict.".$this->sName.".php$/i", $sFile, $aMatches)) // Dictionary files are named like <Lang>.dict.<ModuleName>.php
|
||||
{
|
||||
$aDictionaries[] = $this->sRootDir.'/'.$sFile;
|
||||
}
|
||||
}
|
||||
closedir($hDir);
|
||||
}
|
||||
return $aDictionaries;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,15 +143,20 @@ class ModelFactory
|
||||
protected $oModules;
|
||||
protected $oClasses;
|
||||
protected $oMenus;
|
||||
protected $oDictionaries;
|
||||
static protected $aLoadedClasses;
|
||||
static protected $aWellKnownParents = array('DBObject', 'CMDBObject','cmdbAbstractObject');
|
||||
// static protected $aWellKnownMenus = array('DataAdministration', 'Catalogs', 'ConfigManagement', 'Contact', 'ConfigManagementCI', 'ConfigManagement:Shortcuts', 'ServiceManagement');
|
||||
static protected $aLoadedModules;
|
||||
static protected $aLoadErrors;
|
||||
|
||||
protected $aDict;
|
||||
protected $aDictKeys;
|
||||
|
||||
|
||||
public function __construct($aRootDirs, $aRootNodeExtensions = array())
|
||||
{
|
||||
$this->aDict = array();
|
||||
$this->aDictKeys = array();
|
||||
$this->aRootDirs = $aRootDirs;
|
||||
$this->oDOMDocument = new MFDocument();
|
||||
$this->oRoot = $this->oDOMDocument->CreateElement('itop_design');
|
||||
@@ -143,6 +166,9 @@ class ModelFactory
|
||||
$this->oRoot->AppendChild($this->oModules);
|
||||
$this->oClasses = $this->oDOMDocument->CreateElement('classes');
|
||||
$this->oRoot->AppendChild($this->oClasses);
|
||||
$this->oDictionaries = $this->oDOMDocument->CreateElement('dictionaries');
|
||||
$this->oRoot->AppendChild($this->oDictionaries);
|
||||
|
||||
foreach (self::$aWellKnownParents as $sWellKnownParent)
|
||||
{
|
||||
$this->AddWellKnownParent($sWellKnownParent);
|
||||
@@ -353,6 +379,65 @@ class ModelFactory
|
||||
$oDeltaRoot = $oDocument->childNodes->item(0);
|
||||
$this->LoadDelta($oDocument, $oDeltaRoot, $this->oDOMDocument);
|
||||
}
|
||||
|
||||
$aDictionaries = $oModule->GetDictionaryFiles();
|
||||
|
||||
try
|
||||
{
|
||||
$this->ResetTempDictionary();
|
||||
foreach($aDictionaries as $sPHPFile)
|
||||
{
|
||||
$sDictFileContents = file_get_contents($sPHPFile);
|
||||
$sDictFileContents = str_replace(array('<'.'?'.'php', '?'.'>'), '', $sDictFileContents);
|
||||
$sDictFileContents = str_replace('Dict::Add', '$this->AddToTempDictionary', $sDictFileContents);
|
||||
eval($sDictFileContents);
|
||||
}
|
||||
|
||||
foreach ($this->aDict as $sLanguageCode => $aDictDefinition)
|
||||
{
|
||||
$oNodes = $this->GetNodeById('dictionary', $sLanguageCode, $this->oDictionaries);
|
||||
if ($oNodes->length == 0)
|
||||
{
|
||||
$oXmlDict = $this->oDOMDocument->CreateElement('dictionary');
|
||||
$oXmlDict->setAttribute('id', $sLanguageCode);
|
||||
$this->oDictionaries->AddChildNode($oXmlDict);
|
||||
$oXmlEntries = $this->oDOMDocument->CreateElement('english_description', $aDictDefinition['english_description']);
|
||||
$oXmlDict->AppendChild($oXmlEntries);
|
||||
$oXmlEntries = $this->oDOMDocument->CreateElement('localized_description', $aDictDefinition['localized_description']);
|
||||
$oXmlDict->AppendChild($oXmlEntries);
|
||||
$oXmlEntries = $this->oDOMDocument->CreateElement('entries');
|
||||
$oXmlDict->AppendChild($oXmlEntries);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oXmlDict = $oNodes->item(0);
|
||||
$oXmlEntries = $oXmlDict->GetUniqueElement('entries');
|
||||
}
|
||||
|
||||
foreach ($aDictDefinition['entries'] as $sCode => $sLabel)
|
||||
{
|
||||
|
||||
$oXmlEntry = $this->oDOMDocument->CreateElement('entry');
|
||||
$oXmlEntry->setAttribute('id', $sCode);
|
||||
$oXmlValue = $this->oDOMDocument->CreateCDATASection($sLabel);
|
||||
$oXmlEntry->appendChild($oXmlValue);
|
||||
if (array_key_exists($sLanguageCode, $this->aDictKeys) && array_key_exists($sCode, $this->aDictKeys[$sLanguageCode]))
|
||||
{
|
||||
$oXmlEntries->RedefineChildNode($oXmlEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oXmlEntries->appendChild($oXmlEntry);
|
||||
}
|
||||
$this->aDictKeys[$sLanguageCode][$sCode] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
throw new Exception('Failed to load dictionary file "'.$sPHPFile.'", reason: '.$e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
catch(Exception $e)
|
||||
{
|
||||
@@ -365,6 +450,33 @@ class ModelFactory
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Collects the PHP Dict entries into the ModelFactory for transforming the dictionary into an XML structure
|
||||
* @param string $sLanguageCode The language code
|
||||
* @param string $sEnglishLanguageDesc English description of the language (unused but kept for API compatibility)
|
||||
* @param string $sLocalizedLanguageDesc Localized description of the language (unused but kept for API compatibility)
|
||||
* @param hash $aEntries The entries to load: string_code => translation
|
||||
*/
|
||||
protected function AddToTempDictionary($sLanguageCode, $sEnglishLanguageDesc, $sLocalizedLanguageDesc, $aEntries)
|
||||
{
|
||||
$this->aDict[$sLanguageCode]['english_description'] = $sEnglishLanguageDesc;
|
||||
$this->aDict[$sLanguageCode]['localized_description'] = $sLocalizedLanguageDesc;
|
||||
if (!array_key_exists('entries', $this->aDict[$sLanguageCode]))
|
||||
{
|
||||
$this->aDict[$sLanguageCode]['entries'] = array();
|
||||
}
|
||||
|
||||
foreach($aEntries as $sKey => $sValue)
|
||||
{
|
||||
$this->aDict[$sLanguageCode]['entries'][$sKey] = $sValue;
|
||||
}
|
||||
}
|
||||
|
||||
protected function ResetTempDictionary()
|
||||
{
|
||||
$this->aDict = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* XML load errors (XML format and validation)
|
||||
*/
|
||||
@@ -568,7 +680,7 @@ class ModelFactory
|
||||
|
||||
public function GetClassXMLTemplate($sName, $sIcon)
|
||||
{
|
||||
$sHeader = '<?xml version="1.0" encoding="utf-8"?'.'>';
|
||||
$sHeader = '<?'.'xml version="1.0" encoding="utf-8"?'.'>';
|
||||
return
|
||||
<<<EOF
|
||||
$sHeader
|
||||
|
||||
Reference in New Issue
Block a user