TYPO3 API  SVNRelease
Localization.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2009 Sebastian Kurfürst <sebastian@typo3.org>
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *
00017 *  This script is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  This copyright notice MUST APPEAR in all copies of the script!
00023 ***************************************************************/
00024 
00025 /**
00026  * Localization helper which should be used to fetch localized labels.
00027  *
00028  * @package Extbase
00029  * @subpackage Utility
00030  * @version $ID:$
00031  * @api
00032  */
00033 class Tx_Extbase_Utility_Localization {
00034 
00035     /**
00036      * @var string
00037      */
00038     protected static $locallangPath = 'Resources/Private/Language/';
00039 
00040     /**
00041      * Local Language content
00042      *
00043      * @var string
00044      **/
00045     protected static $LOCAL_LANG = array();
00046 
00047     /**
00048      * Local Language content charset for individual labels (overriding)
00049      *
00050      * @var string
00051      **/
00052     protected static $LOCAL_LANG_charset = array();
00053 
00054     /**
00055      * Key of the language to use
00056      *
00057      * @var string
00058      **/
00059     protected static $languageKey = 'default';
00060 
00061     /**
00062      * Pointer to alternative fall-back language to use
00063      *
00064      * @var string
00065      **/
00066     protected static $alternativeLanguageKey = '';
00067 
00068     /**
00069      * Returns the localized label of the LOCAL_LANG key, $key.
00070      *
00071      * @param string $key The key from the LOCAL_LANG array for which to return the value.
00072      * @param string $extensionName The name of the extension
00073      * @param array $arguments the arguments of the extension, being passed over to vsprintf
00074      * @return string The value from LOCAL_LANG or NULL if no translation was found.
00075      * @author Christopher Hlubek <hlubek@networkteam.com>
00076      * @author Bastian Waidelich <bastian@typo3.org>
00077      * @author Sebastian Kurfuerst <sebastian@typo3.org>
00078      * @api
00079      * @todo: If vsprintf gets a malformed string, it returns FALSE! Should we throw an exception there?
00080      */
00081     static public function translate($key, $extensionName, $arguments = NULL) {
00082         if (t3lib_div::isFirstPartOfStr($key, 'LLL:')) {
00083             $value = self::translateFileReference($key);
00084         } else {
00085             self::initializeLocalization($extensionName);
00086             // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG
00087             if (isset(self::$LOCAL_LANG[$extensionName][self::$languageKey][$key])) {
00088                 $value = self::$LOCAL_LANG[$extensionName][self::$languageKey][$key];
00089                 if (isset(self::$LOCAL_LANG_charset[$extensionName][self::$languageKey][$key])) {
00090                     $value = self::convertCharset($value, self::$LOCAL_LANG_charset[$extensionName][self::$languageKey][$key]);
00091                 }
00092             } elseif (self::$alternativeLanguageKey !== '' && isset(self::$LOCAL_LANG[$extensionName][self::$alternativeLanguageKey][$key])) {
00093                 $value = self::$LOCAL_LANG[$extensionName][self::$alternativeLanguageKey][$key];
00094                 if (isset(self::$LOCAL_LANG_charset[$extensionName][self::$alternativeLanguageKey][$key])) {
00095                     $value = self::convertCharset($value, self::$LOCAL_LANG_charset[$extensionName][self::$alternativeLanguageKey][$key]);
00096                 }
00097             } elseif (isset(self::$LOCAL_LANG[$extensionName]['default'][$key])) {
00098                 $value = self::$LOCAL_LANG[$extensionName]['default'][$key]; // No charset conversion because default is english and thereby ASCII
00099             }
00100         }
00101         if (is_array($arguments)) {
00102             return vsprintf($value, $arguments);
00103         } else {
00104             return $value;
00105         }
00106     }
00107 
00108     /**
00109      * Returns the localized label of the LOCAL_LANG key, $key.
00110      *
00111      * @param string $key The language key including the path to a custom locallang file ("LLL:path:key").
00112      * @return string The value from LOCAL_LANG or NULL if no translation was found.
00113      * @see language::sL()
00114      * @see tslib_fe::sL()
00115      * @author Bastian Waidelich <bastian@typo3.org>
00116      */
00117     protected function translateFileReference($key) {
00118         if (TYPO3_MODE === 'FE') {
00119             return $GLOBALS['TSFE']->sL($key);
00120         } elseif (is_object($GLOBALS['LANG'])) {
00121             $value = $GLOBALS['LANG']->sL($key);
00122             return $value !== '' ? $value : NULL;
00123         } else {
00124             return $key;
00125         }
00126     }
00127 
00128     /**
00129      * Loads local-language values by looking for a "locallang.php" (or "locallang.xml") file in the plugin resources directory and if found includes it.
00130      * Also locallang values set in the TypoScript property "_LOCAL_LANG" are merged onto the values found in the "locallang.php" file.
00131      *
00132      * @return void
00133      * @author Christopher Hlubek <hlubek@networkteam.com>
00134      * @author Bastian Waidelich <bastian@typo3.org>
00135      */
00136     static protected function initializeLocalization($extensionName) {
00137         if (isset(self::$LOCAL_LANG[$extensionName])) {
00138             return;
00139         }
00140         $locallangPathAndFilename = 'EXT:' . t3lib_div::camelCaseToLowerCaseUnderscored($extensionName) . '/' . self::$locallangPath . 'locallang.xml';
00141 
00142         self::setLanguageKeys();
00143 
00144         $renderCharset = (TYPO3_MODE === 'FE' ? $GLOBALS['TSFE']->renderCharset : $GLOBALS['LANG']->charSet);
00145         self::$LOCAL_LANG[$extensionName] = t3lib_div::readLLfile($locallangPathAndFilename, self::$languageKey, $renderCharset);
00146         if (self::$alternativeLanguageKey !== '') {
00147             $alternativeLocalLang = t3lib_div::readLLfile($locallangPathAndFilename, self::$alternativeLanguageKey);
00148             self::$LOCAL_LANG[$extensionName] = array_merge(self::$LOCAL_LANG[$extensionName], $alternativeLocalLang);
00149         }
00150         self::loadTypoScriptLabels($extensionName);
00151     }
00152 
00153     /**
00154      * Sets the currently active language/language_alt keys.
00155      * Default values are "default" for language key and "" for language_alt key.
00156      *
00157      * @return void
00158      * @author Christopher Hlubek <hlubek@networkteam.com>
00159      * @author Bastian Waidelich <bastian@typo3.org>
00160      */
00161     protected function setLanguageKeys() {
00162         self::$languageKey = 'default';
00163         self::$alternativeLanguageKey = '';
00164         if (TYPO3_MODE === 'FE') {
00165             if (isset($GLOBALS['TSFE']->config['config']['language'])) {
00166                 self::$languageKey = $GLOBALS['TSFE']->config['config']['language'];
00167                 if (isset($GLOBALS['TSFE']->config['config']['language_alt'])) {
00168                     self::$alternativeLanguageKey = $GLOBALS['TSFE']->config['config']['language_alt'];
00169                 }
00170             }
00171         } elseif (strlen($GLOBALS['BE_USER']->uc['lang']) > 0) {
00172             self::$languageKey = $GLOBALS['BE_USER']->uc['lang'];
00173         }
00174     }
00175 
00176     /**
00177      * Overwrites labels that are set via typoscript.
00178      * TS locallang labels have to be configured like:
00179      * plugin.tx_myextension._LOCAL_LANG.languageKey.key = value
00180      *
00181      * @return void
00182      * @author Christopher Hlubek <hlubek@networkteam.com>
00183      * @author Bastian Waidelich <bastian@typo3.org>
00184      */
00185     protected function loadTypoScriptLabels($extensionName) {
00186         $objectManager = t3lib_div::makeInstance('Tx_Extbase_Object_ObjectManager');
00187         $configurationManager = $objectManager->get('Tx_Extbase_Configuration_ConfigurationManagerInterface');
00188         $frameworkConfiguration = $configurationManager->getConfiguration(Tx_Extbase_Configuration_ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
00189         if (!is_array($frameworkConfiguration['_LOCAL_LANG'])) {
00190             return;
00191         }
00192         foreach ($frameworkConfiguration['_LOCAL_LANG'] as $languageKey => $labels) {
00193             if (!is_array($labels)) {
00194                 continue;
00195             }
00196             foreach($labels as $labelKey => $labelValue) {
00197                 if (is_string($labelValue)) {
00198                     self::$LOCAL_LANG[$extensionName][$languageKey][$labelKey] = $labelValue;
00199                         // For labels coming from the TypoScript (database) the charset is assumed to be "forceCharset" and if that is not set, assumed to be that of the individual system languages
00200                     if (isset($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) && strlen($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) > 0) {
00201                         self::$LOCAL_LANG_charset[$extensionName][$languageKey][$labelKey] = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
00202                     } elseif (is_object($GLOBALS['LANG'])) {
00203                         self::$LOCAL_LANG_charset[$extensionName][$languageKey][$labelKey] = $GLOBALS['LANG']->csConvObj->charSetArray[$languageKey];
00204                     } else {
00205                         self::$LOCAL_LANG_charset[$extensionName][$languageKey][$labelKey] = $GLOBALS['TSFE']->csConvObj->charSetArray[$languageKey];
00206                     }
00207                 } elseif (is_array($labelValue)) {
00208                     $labelValue = self::flattenTypoScriptLabelArray($labelValue, $labelKey);
00209                     self::$LOCAL_LANG[$extensionName][$languageKey] = array_merge(self::$LOCAL_LANG[$extensionName][$languageKey], $labelValue);
00210                 }
00211             }
00212         }
00213     }
00214 
00215     /**
00216      * Flatten TypoScript label array; converting a hierarchical array into a flat
00217      * array with the keys separated by dots.
00218      *
00219      * Example Input:  array('k1' => array('subkey1' => 'val1'))
00220      * Example Output: array('k1.subkey1' => 'val1')
00221      *
00222      * @param array $labelValues Hierarchical array of labels
00223      * @param string $parentKey the name of the parent key in the recursion; is only needed for recursion.
00224      * @return array flattened array of labels.
00225      */
00226     protected function flattenTypoScriptLabelArray(array $labelValues, $parentKey = '') {
00227         $result = array();
00228         foreach ($labelValues as $key => $labelValue) {
00229             if (!empty($parentKey)) {
00230                 $key = $parentKey . '.' . $key;
00231             }
00232 
00233             if (is_array($labelValue)) {
00234                 $labelValue = self::flattenTypoScriptLabelArray($labelValue, $key);
00235                 $result = array_merge($result, $labelValue);
00236             } else {
00237                 $result[$key] = $labelValue;
00238             }
00239         }
00240         return $result;
00241     }
00242 
00243     /**
00244      * Converts a string from the specified character set to the current.
00245      * The current charset is defined by the TYPO3 mode.
00246      *
00247      * @param string $value string to be converted
00248      * @param string $charset The source charset
00249      * @return string converted string
00250      */
00251     protected function convertCharset($value, $charset) {
00252         if (TYPO3_MODE === 'FE') {
00253             return $GLOBALS['TSFE']->csConv($value, $charset);
00254         } else {
00255             $convertedValue = $GLOBALS['LANG']->csConvObj->conv($value, $GLOBALS['LANG']->csConvObj->parse_charset($charset), $GLOBALS['LANG']->charSet, 1);
00256             return $convertedValue !== NULL ? $convertedValue : $value;
00257         }
00258     }
00259 }
00260 ?>