[FEATURE] Allow user-defined additional backend languages
authorXavier Perseguers <xavier@typo3.org>
Tue, 6 Sep 2011 13:23:42 +0000 (15:23 +0200)
committerAndreas Wolf <andreas.wolf@ikt-werk.de>
Tue, 6 Sep 2011 22:02:47 +0000 (00:02 +0200)
At the moment, any language may be used for Frontend output. But in Backend, the list
of supported languages is hardcoded at various places. This prevents additional
languages to be defined locally, for instance when translating TYPO3 into a new
language, before it gets officially supported by the Core.

Change-Id: Ibd3236a82790f9f20c91ff3663d6625694ef7cf6
Resolves: #29513
Releases: 4.6
Reviewed-on: http://review.typo3.org/4797
Reviewed-by: Helmut Hummel
Tested-by: Helmut Hummel
Reviewed-by: Andreas Wolf
Tested-by: Andreas Wolf
t3lib/l10n/class.t3lib_l10n_locales.php
t3lib/stddb/tbl_be.php
typo3/sysext/em/classes/connection/class.tx_em_connection_extdirectserver.php
typo3/sysext/em/classes/translations/class.tx_em_translations.php

index 6046b13..160f0ff 100644 (file)
  *
  * Defining backend system languages
  * When adding new keys, remember to:
- *             - Update pages.lang item array (t3lib/stddb/tbl_be.php)
  *             - Add character encoding for lang. key in t3lib/class.t3lib_cs.php (default for new languages is "utf-8")
  *             - Add mappings for language in t3lib/class.t3lib_cs.php (TYPO3/ISO, language/script, script/charset)
- *             - Update 'setup' extension labels (sysext/setup/mod/locallang.xml)
+ *             - Update 'setup' extension labels (sysext/setup/mod/locallang.xlf)
  * That's it!
  *
  * @package    Core
 class t3lib_l10n_Locales implements t3lib_Singleton {
 
        /**
-        * Supported TYPO3 locales
+        * Supported TYPO3 languages with locales
         * @var array
         */
-       protected $locales = array(
-               'default',      // English
-               'ar',           // Arabic
-               'bs',           // Bosnian
-               'bg',           // Bulgarian
-               'ca',           // Catalan; Valencian
-               'ch',           // Chinese (Simplified)
-               'cs',           // Czech
-               'da',           // Danish
-               'de',           // German
-               'el',           // Greek
-               'eo',           // Esperanto
-               'es',           // Spanish; Castilian
-               'et',           // Estonian
-               'eu',           // Basque
-               'fa',           // Persian
-               'fi',           // Finnish
-               'fo',           // Faroese
-               'fr',           // French
-               'fr_CA',        // French (Canada)
-               'gl',           // Galician
-               'he',           // Hebrew
-               'hi',           // Hindi
-               'hr',           // Croatian
-               'hu',           // Hungarian
-               'is',           // Icelandic
-               'it',           // Italian
-               'ja',           // Japanese
-               'ka',           // Georgian
-               'kl',           // Greenlandic
-               'km',           // Khmer
-               'ko',           // Korean
-               'lt',           // Lithuanian
-               'lv',           // Latvian
-               'ms',           // Malay
-               'nl',           // Dutch
-               'no',           // Norwegian
-               'pl',           // Polish
-               'pt',           // Portuguese
-               'pt_BR',        // Portuguese (Brazil)
-               'ro',           // Romanian
-               'ru',           // Russian
-               'sk',           // Slovak
-               'sl',           // Slovenian
-               'sq',           // Albanian
-               'sr',           // Serbian
-               'sv',           // Swedish
-               'th',           // Thai
-               'tr',           // Turkish
-               'uk',           // Ukrainian
-               'vi',           // Vietnamese
-               'zh',           // Chinese (China)
+       protected $languages = array(
+               'default' => 'English',
+               'ar' => 'Arabic',
+               'bs' => 'Bosnian',
+               'bg' => 'Bulgarian',
+               'ca' => 'Catalan',
+               'ch' => 'Chinese (Simpl.)',
+               'cs' => 'Czech',
+               'da' => 'Danish',
+               'de' => 'German',
+               'el' => 'Greek',
+               'eo' => 'Esperanto',
+               'es' => 'Spanish',
+               'et' => 'Estonian',
+               'eu' => 'Basque',
+               'fa' => 'Persian',
+               'fi' => 'Finnish',
+               'fo' => 'Faroese',
+               'fr' => 'French',
+               'fr_CA' => 'French (Canada)',
+               'gl' => 'Galician',
+               'he' => 'Hebrew',
+               'hi' => 'Hindi',
+               'hr' => 'Croatian',
+               'hu' => 'Hungarian',
+               'is' => 'Icelandic',
+               'it' => 'Italian',
+               'ja' => 'Japanese',
+               'ka' => 'Georgian',
+               'kl' => 'Greenlandic',
+               'km' => 'Khmer',
+               'ko' => 'Korean',
+               'lt' => 'Lithuanian',
+               'lv' => 'Latvian',
+               'ms' => 'Malay',
+               'nl' => 'Dutch',
+               'no' => 'Norwegian',
+               'pl' => 'Polish',
+               'pt' => 'Portuguese',
+               'pt_BR' => 'Brazilian Portuguese',
+               'ro' => 'Romanian',
+               'ru' => 'Russian',
+               'sk' => 'Slovak',
+               'sl' => 'Slovenian',
+               'sq' => 'Albanian',
+               'sr' => 'Serbian',
+               'sv' => 'Swedish',
+               'th' => 'Thai',
+               'tr' => 'Turkish',
+               'uk' => 'Ukrainian',
+               'vi' => 'Vietnamese',
+               'zh' => 'Chinese (Trad.)',
        );
 
        /**
+        * Supported TYPO3 locales
+        * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8
+        * @var array
+        */
+       protected $locales = array();
+
+       /**
         * Mapping with codes used by TYPO3 4.5 and below
         * @var array
         */
@@ -148,9 +154,18 @@ class t3lib_l10n_Locales implements t3lib_Singleton {
                $instance = t3lib_div::makeInstance('t3lib_l10n_Locales');
                $instance->isoMapping = array_flip($instance->isoReverseMapping);
 
+                       // Allow user-defined locales
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user'] as $locale => $name) {
+                               if (!isset($instance->languages[$locale])) {
+                                       $instance->languages[$locale] = $name;
+                               }
+                       }
+               }
+
                        // Initializes the locale dependencies with TYPO3 supported locales
                $instance->localeDependencies = array();
-               foreach ($instance->locales as $locale) {
+               foreach ($instance->languages as $locale => $name) {
                        if (strlen($locale) == 5) {
                                $instance->localeDependencies[$locale] = array(substr($locale, 0, 2));
                        }
@@ -163,6 +178,11 @@ class t3lib_l10n_Locales implements t3lib_Singleton {
                /**
                 * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8
                 */
+               $instance->locales = array_keys($instance->languages);
+
+               /**
+                * @deprecated since TYPO3 4.6, will be removed in TYPO3 4.8
+                */
                define('TYPO3_languages', implode('|', $instance->getLocales()));
        }
 
@@ -172,7 +192,16 @@ class t3lib_l10n_Locales implements t3lib_Singleton {
         * @return array
         */
        public function getLocales() {
-               return $this->locales;
+               return array_keys($this->languages);
+       }
+
+       /**
+        * Returns the supported languages indexed by their corresponding locale.
+        *
+        * @return array
+        */
+       public function getLanguages() {
+               return $this->languages;
        }
 
        /**
@@ -191,7 +220,7 @@ class t3lib_l10n_Locales implements t3lib_Singleton {
         * @deprecated since TYPO3 4.6
         */
        public function getTerLocales() {
-               return $this->convertToTerLocales($this->locales);
+               return $this->convertToTerLocales(array_keys($this->languages));
        }
 
        /**
index a6a26e3..d99171b 100644 (file)
@@ -25,7 +25,7 @@
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 /**
- * Contains the dynamic configuation of the fields in the core tables of TYPO3: be_users, be_groups and sys_filemounts
+ * Contains the dynamic configuration of the fields in the core tables of TYPO3: be_users, be_groups and sys_filemounts
  *
  * Revised for TYPO3 3.6 July/2003 by Kasper Skårhøj
  *
@@ -280,56 +280,7 @@ $TCA['be_users'] = array(
                                'type' => 'select',
                                'items' => array(
                                        array('English', ''),
-                                       array('Albanian', 'sq'),
-                                       array('Arabic', 'ar'),
-                                       array('Basque', 'eu'),
-                                       array('Bosnian', 'bs'),
-                                       array('Brazilian Portuguese', 'pt_BR'),
-                                       array('Bulgarian', 'bg'),
-                                       array('Catalan', 'ca'),
-                                       array('Chinese (Simpl.)', 'ch'),
-                                       array('Chinese (Trad.)', 'zh'),
-                                       array('Croatian', 'hr'),
-                                       array('Czech', 'cs'),
-                                       array('Danish', 'da'),
-                                       array('Dutch', 'nl'),
-                                       array('Esperanto', 'eo'),
-                                       array('Estonian', 'et'),
-                                       array('Faroese', 'fo'),
-                                       array('Finnish', 'fi'),
-                                       array('French', 'fr'),
-                                       array('French (Canada)', 'fr_CA'),
-                                       array('Galician', 'gl'),
-                                       array('Georgian', 'ka'),
-                                       array('German', 'de'),
-                                       array('Greek', 'el'),
-                                       array('Greenlandic', 'kl'),
-                                       array('Hebrew', 'he'),
-                                       array('Hindi', 'hi'),
-                                       array('Hungarian', 'hu'),
-                                       array('Icelandic', 'is'),
-                                       array('Italian', 'it'),
-                                       array('Japanese', 'ja'),
-                                       array('Khmer', 'km'),
-                                       array('Korean', 'ko'),
-                                       array('Latvian', 'lv'),
-                                       array('Lithuanian', 'lt'),
-                                       array('Malay', 'ms'),
-                                       array('Norwegian', 'no'),
-                                       array('Persian', 'fa'),
-                                       array('Polish', 'pl'),
-                                       array('Portuguese', 'pt'),
-                                       array('Romanian', 'ro'),
-                                       array('Russian', 'ru'),
-                                       array('Serbian', 'sr'),
-                                       array('Slovak', 'sk'),
-                                       array('Slovenian', 'sl'),
-                                       array('Spanish', 'es'),
-                                       array('Swedish', 'sv'),
-                                       array('Thai', 'th'),
-                                       array('Turkish', 'tr'),
-                                       array('Ukrainian', 'uk'),
-                                       array('Vietnamese', 'vi'),
+                                       // Other languages are dynamically populated below
                                )
                        )
                ),
@@ -406,6 +357,17 @@ $TCA['be_users'] = array(
        ),
 );
 
+       // Populate available languages
+/** @var $locales t3lib_l10n_locales */
+$locales = t3lib_div::makeInstance('t3lib_l10n_Locales');
+$languageItems = $locales->getLanguages();
+
+unset($languageItems['default']);
+asort($languageItems);
+
+foreach ($languageItems as $locale => $name) {
+       $TCA['be_users']['columns']['lang']['config']['items'][] = array($name, $locale);
+}
 
 /**
  * Backend usergroups - Much permission criterias are based on membership of backend groups.
index 14bb46c..d6c0a63 100644 (file)
@@ -1146,12 +1146,15 @@ class tx_em_Connection_ExtDirectServer {
 
                /** @var $locales t3lib_l10n_Locales */
                $locales = t3lib_div::makeInstance('t3lib_l10n_Locales');
-               $theLanguages = $locales->getLocales();
+               $theLanguages = $locales->getLanguages();
                        //drop default
                array_shift($theLanguages);
                $lang = $meta = array();
-               foreach ($theLanguages as $language) {
+               foreach ($theLanguages as $language => $name) {
                        $label = htmlspecialchars($GLOBALS['LANG']->sL('LLL:EXT:setup/mod/locallang.xml:lang_' . $language));
+                       if ($label === '') {
+                               $label = htmlspecialchars($name);
+                       }
                        $lang[] = array(
                                'label' => $label,
                                'lang' => $language,
index e0d5831..d837efd 100644 (file)
@@ -141,13 +141,18 @@ class tx_em_Translations {
                }
                /** @var $locales t3lib_l10n_Locales */
                $locales = t3lib_div::makeInstance('t3lib_l10n_Locales');
-               $theLanguages = $locales->getLocales();
-               foreach ($theLanguages as $val) {
-                       if ($val != 'default') {
-                               $localLabel = '  -  [' . htmlspecialchars($GLOBALS['LOCAL_LANG']['default']['lang_' . $val][0]['target']) . ']';
-                               $selected = (is_array($selectedLanguages) && in_array($val, $selectedLanguages)) ? ' selected="selected"' : '';
-                               $opt[$GLOBALS['LANG']->getLL('lang_' . $val, 1) . '--' . $val] = '
-                        <option value="' . $val . '"' . $selected . '>' . $GLOBALS['LANG']->getLL('lang_' . $val, 1) . $localLabel . '</option>';
+               $theLanguages = $locales->getLanguages();
+               foreach ($theLanguages as $locale => $name) {
+                       if ($locale !== 'default') {
+                               $defaultName = isset($GLOBALS['LOCAL_LANG']['default']['lang_' . $locale]) ? $GLOBALS['LOCAL_LANG']['default']['lang_' . $locale][0]['target'] : $name;
+                               $localizedName = $GLOBALS['LANG']->getLL('lang_' . $locale, TRUE);
+                               if ($localizedName === '') {
+                                       $localizedName = htmlspecialchars($name);
+                               }
+                               $localLabel = '  -  [' . htmlspecialchars($defaultName) . ']';
+                               $selected = (is_array($selectedLanguages) && in_array($locale, $selectedLanguages)) ? ' selected="selected"' : '';
+                               $opt[$localizedName . '--' . $locale] = '
+                        <option value="' . $locale . '"' . $selected . '>' . $localizedName . $localLabel . '</option>';
                        }
                }
                ksort($opt);