setLanguageId($p_languageId); } $this->m_prefix = $p_prefix; } // constructor /** * Return the filename prefix. * @return string */ function getPrefix() { return $this->m_prefix; } // fn getPrefix /** * This will return 'gs' or 'xml' * @return string */ function getMode() { return $this->m_mode; } // fn getMode /** * Set the mode to be 'xml' or 'gs'. * @param string $p_value * @return void */ function setMode($p_value) { $p_value = strtolower($p_value); if (($p_value == 'xml') || ($p_value == 'gs')) { $this->m_mode = $p_value; } } // fn setMode /** * Set the language code - this can take either the two-letter language code * or the LL_CC extended version , where LL is the language code and CC * is the country code. * * @param string $p_languageId * @return void */ function setLanguageId($p_languageId) { if (strlen($p_languageId) > 2) { list ($this->m_languageCode, $this->m_countryCode) = explode('_', $p_languageId); $this->m_languageId = $p_languageId; } else { $this->m_languageCode = $p_languageId; $this->m_languageId = $p_languageId; } } // fn setLanguageId /** * Register a string in the translation table. * @param string $p_key * @param string $p_value * @return void */ function registerString($p_key, $p_value) { if (substr($p_value, strlen($p_value)-3) == ":en"){ $p_value = substr($p_value, 0, strlen($p_value)-3); } $this->m_translationTable[$p_key] = $p_value; } // fn registerString /** * Return the total number of strings in the translation table. * @return int */ function getNumStrings() { return count($this->m_translationTable); } // fn getNumStrings /** * Get the language code that is in the form _. * * @return string */ function getLanguageId() { return $this->m_languageId; } // fn getLanguageId /** * Get the two-letter language code for the translation table. * @return string */ function getLanguageCode() { return $this->m_languageCode; } // fn getLanguageCode /** * Get the two-letter country code. * @return string */ function getCountryCode() { return $this->m_countryCode; } // fn getCountryCode /** * Return the file path for the last file loaded. * @return string */ function getSourceFile() { return $this->m_filePath; } // fn getSourceFile /** * This is only for use by the LocalizerFileFormat functions. * @access private */ function _setSourceFile($p_value) { $this->m_filePath = $p_value; } // fn _setSourceFile /** * Return true if this LocalizerLanguage has the exact same * translation strings as the given LocalizerLanguage. * * @param LocalizerLanguage $p_localizerLanguage * @return boolean */ function equal($p_localizerLanguage) { if (count($this->m_translationTable) != count($p_localizerLanguage->m_translationTable)) { return false; } foreach ($this->m_translationTable as $key => $value) { if (!array_key_exists($key, $p_localizerLanguage->m_translationTable)) { //echo "missing translation string: '$key'
"; return false; } if ($p_localizerLanguage->m_translationTable[$key] != $value) { //echo "Non-matching values: '".$p_localizerLanguage->m_translationTable[$key]."' != '".$value."'
"; return false; } } return true; } // fn equal /** * Return a table indexed by the english language name, with the value being the * target language equivalent. * * @return array */ function getTranslationTable() { return $this->m_translationTable; } /** * Get the full path to the translation file. * * @param string $p_mode * Either 'gs' or 'xml'. * @return string */ function getFilePath($p_mode = null) { global $g_localizerConfig; if (is_null($p_mode)) { $p_mode = $this->m_mode; } if ($p_mode == 'xml') { $relativePath = '/'.$this->m_languageId.'/'.$this->m_prefix.'.xml'; } else { $relativePath = '/'.$this->m_languageCode.'/'.$this->m_prefix.'.php'; } return $g_localizerConfig['TRANSLATION_DIR'].$relativePath; } // fn getFilePath /** * Return TRUE if the given string exists in the translation table. * * @param string $p_string * * @return boolean */ function keyExists($p_string) { return (isset($this->m_translationTable[$p_string])); } // fn stringExists /** * Add a string to the translation table. * * @param string $p_key * The english translation of the string. * * @param string $p_value * Optional. If not specified, the value will be set to the same * value as the key. * * @param int $p_position * Optional. By default the string will be added to the end of the * translation table. * * @return boolean */ function addString($p_key, $p_value = null, $p_position = null) { if (!is_null($p_position) && (!is_numeric($p_position) || ($p_position < 0) || ($p_position > count($this->m_translationTable)))) { return false; } if (!is_string($p_key) || !is_string($p_value)) { return false; } if (is_null($p_position)) { // Position is not specified - add the string at the end if (is_null($p_value)) { $this->m_translationTable[$p_key] = $p_key; } else { $this->m_translationTable[$p_key] = $p_value; } return true; } else { // The position is specified $begin = array_slice($this->m_translationTable, 0, $p_position); $end = array_slice($this->m_translationTable, $p_position); if (is_null($p_value)) { $newStr = array($p_key => $p_key); } else { $newStr = array($p_key => $p_value); } $this->m_translationTable = array_merge($begin, $newStr, $end); return true; } } // fn addString /** * Get the position of a key or a value. * @param string $p_key * @param string $p_value * @return mixed * The position of the key/value in the array, FALSE if not found. */ function getPosition($p_key = null, $p_value = null) { $position = 0; if (!is_null($p_key)) { foreach ($this->m_translationTable as $key => $value) { if ($p_key == $key) { return $position; } $position++; } } elseif (!is_null($p_value)) { foreach ($this->m_translationTable as $value) { if ($p_value == $value) { return $position; } $position++; } } return false; } // fn getPosition /** * Get the string at the given position. * * @return array * An array of two elements, the first is the key, the second is the value. * They are indexed by 'key' and 'value'. */ function getStringAtPosition($p_position) { if (is_null($p_position) || !is_numeric($p_position) || ($p_position < 0) || ($p_position > count($this->m_translationTable))) { return false; } $returnValue = array_splice($this->m_translationTable, $p_position, 0); $keys = array_keys($returnValue); $key = array_pop($keys); $value = array_pop($returnValue); return array('key' => $key, 'value' => $value); } // fn getStringAtPosition /** * Change the key and optionally the value of the * translation string. If the value isnt specified, * it is not changed. If the key does not exist, * it will be added. In this case, you can use p_position * to specify where to add the string. * * @param string $p_oldKey * @param string $p_newKey * @param string $p_value * @param int $p_position * @return boolean */ function updateString($p_oldKey, $p_newKey, $p_value = null, $p_position = null) { if (!is_string($p_oldKey) || !is_string($p_newKey)) { return false; } // Does the old string exist? if (!isset($this->m_translationTable[$p_oldKey])) { return $this->addString($p_newKey, $p_value, $p_position); } if ($p_oldKey == $p_newKey) { // Just updating the value if (!is_null($p_value) && ($p_value != $this->m_translationTable[$p_oldKey])) { $this->m_translationTable[$p_oldKey] = $p_value; return true; } // No changes else { return true; } } // Updating the key (and possibly the value) if (is_null($p_value)) { $p_value = $this->m_translationTable[$p_oldKey]; } $position = $this->getPosition($p_oldKey); $success = $this->deleteString($p_oldKey); $success &= $this->addString($p_newKey, $p_value, $position); return $success; } // fn updateString /** * Move a string to a different position in the translation array. * This allows similiar strings to be grouped together. * * @param int $p_startPositionOrKey * @param int $p_endPosition * * @return boolean * TRUE on success, FALSE on failure. */ function moveString($p_startPositionOrKey, $p_endPosition) { // Check parameters if (is_numeric($p_startPositionOrKey) && (($p_startPositionOrKey < 0) || ($p_startPositionOrKey > count($this->m_translationTable)))) { return false; } if (!is_numeric($p_endPosition) || ($p_endPosition < 0) || ($p_endPosition > count($this->m_translationTable))) { return false; } $startPosition = null; if (is_numeric($p_startPositionOrKey)) { $startPosition = $p_startPositionOrKey; } elseif (is_string($p_startPositionOrKey)) { if (!isset($this->m_translationTable[$p_startPositionOrKey])) { return false; } $startPosition = $this->getPosition($p_startPositionOrKey); } else { return false; } // Success if we dont have to move the string anywhere if ($startPosition == $p_endPosition) { return true; } // Delete the string in the old position $result = $this->deleteStringAtPosition($startPosition); if (!$result) { return false; } $key = $result['key']; $value = $result['value']; // Add the string in the new position $result = $this->addString($key, $value, $p_endPosition); if (!$result) { return false; } return true; } // fn moveString /** * Delete the string given by $p_key. * @param string $p_key * @return mixed * The deleted string as array('key' => $key, 'value' => $value) on success, * FALSE if it didnt exist. */ function deleteString($p_key) { if (isset($this->m_translationTable[$p_key])) { $value = $this->m_translationTable[$p_key]; unset($this->m_translationTable[$p_key]); return array('key'=>$p_key, 'value'=>$value); } return false; } // fn deleteString /** * Delete a string at a specific position in the array. * @param int $p_position * @return mixed * The deleted string as array($key, $value) on success, FALSE on failure. */ function deleteStringAtPosition($p_position) { if (!is_numeric($p_position) || ($p_position < 0) || ($p_position > count($this->m_translationTable))) { return false; } $returnValue = array_splice($this->m_translationTable, $p_position, 1); $keys = array_keys($returnValue); $key = array_pop($keys); $value = array_pop($returnValue); return array('key' => $key, 'value' => $value); } // fn deleteStringAtPosition /** * Synchronize the positions of the strings in the translation table * with the positions of the string in the default language translation table. */ function fixPositions() { global $g_localizerConfig; $defaultLanguage = new LocalizerLanguage($this->m_prefix, $g_localizerConfig['DEFAULT_LANGUAGE']); $defaultLanguage->loadFile(Localizer::GetMode()); $defaultTranslationTable = $defaultLanguage->getTranslationTable(); $count = 0; $modified = false; foreach ($defaultTranslationTable as $key => $value) { if ($this->getPosition($key) != $count) { $this->moveString($key, $count); $modified = true; } $count++; } return $modified; } // fn fixPositions /** * Sync with the default language file. This means * adding any missing strings and fixing the positions of the strings to * be the same as the default language file. */ function syncToDefault() { global $g_localizerConfig; $defaultLanguage = new LocalizerLanguage($this->m_prefix, $g_localizerConfig['DEFAULT_LANGUAGE']); $defaultLanguage->loadFile(Localizer::GetMode()); $defaultTranslationTable = $defaultLanguage->getTranslationTable(); $count = 0; $modified = false; foreach ($defaultTranslationTable as $key => $value) { if (!isset($this->m_translationTable[$key])) { $this->addString($key, '', $count); $modified = true; } $count++; } if ($g_localizerConfig['DELETE_UNUSED_ON_SYNC'] === true) { foreach ($this->m_translationTable as $key => $value) { if (!isset($defaultTranslationTable[$key])) { $this->deleteString($key, '', $count); $modified = true; } $count++; } } return ($this->fixPositions() || $modified); } // fn syncToDefault /** * Find the keys/values that match the given keyword. * * @param string $p_keyword * * @return array */ function search($p_keyword) { $matches = array(); foreach ($this->m_translationTable as $key => $value) { if (empty($p_keyword) || stristr($key, $p_keyword) || stristr($value, $p_keyword)) { $matches[$key] = $value; } } return $matches; } // fn search /** * Load a language file of the given type. * * @param string $p_type * If not specified, it will use the current mode. * * @return boolean */ function loadFile($p_type = null) { if (is_null($p_type)) { if (!empty($this->m_mode)) { $p_type = $this->m_mode; } else { $p_type = Localizer::GetMode(); if (is_null($p_type)) { return false; } } } $className = 'LocalizerFileFormat_'.strtoupper($p_type); if (class_exists($className)) { $object = new $className(); if (method_exists($object, 'load')) { return $object->load($this); } } return false; } // fn loadFile /** * Save the translation table as the given type. * * @param string $p_type * If not specified, it will use the current mode. * * @return boolean */ function saveFile($p_type = null) { // Figure out the current mode. if (is_null($p_type)) { if (!empty($this->m_mode)) { $p_type = $this->m_mode; } else { $p_type = Localizer::GetMode(); if (is_null($p_type)) { return false; } } } // Save in the requested mode. $className = 'LocalizerFileFormat_'.strtoupper($p_type); if (class_exists($className)) { $object = new $className(); if (method_exists($object, 'save')) { return $object->save($this); } } return false; } // fn saveFile /** * Erase all the values in the translation table, but * keep the keys. * @return void */ function clearValues() { foreach ($this->m_translationTable as $key => $value) { $this->m_translationTable[$key] = ''; } } // fn clearValues /** * For debugging purposes, displays the the translation table * in an HTML table. */ function dumpToHtml() { echo "
";
    	if (!empty($this->m_filePath)) {
    		echo "File: ".$this->m_filePath."
"; } echo "Language Code: ".$this->m_languageId."
"; echo ""; foreach ($this->m_translationTable as $key => $value) { echo ""; } echo "
'$key''$value'
"; echo "
"; } // fn dumpToHtml } // class LocalizerLanguage ?>