2 namespace TYPO3\CMS\Core\Localization
;
5 * This file is part of the TYPO3 CMS project.
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
17 use TYPO3\CMS\Core\Utility\ArrayUtility
;
18 use TYPO3\CMS\Core\Utility\GeneralUtility
;
23 * Used to define backend system languages
24 * When adding new keys, remember to:
25 * - Update 'setup' extension labels (sysext/setup/Resources/Private/Language/locallang.xlf)
28 class Locales
implements \TYPO3\CMS\Core\SingletonInterface
31 * Supported TYPO3 languages with locales
35 protected $languages = array(
36 'default' => 'English',
42 'ch' => 'Chinese (Simpl.)',
55 'fr_CA' => 'French (Canada)',
65 'kl' => 'Greenlandic',
75 'pt_BR' => 'Brazilian Portuguese',
87 'zh' => 'Chinese (Trad.)'
91 * Reversed mapping with codes used by TYPO3 4.5 and below
95 protected $isoReverseMapping = array(
96 'bs' => 'ba', // Bosnian
97 'cs' => 'cz', // Czech
98 'da' => 'dk', // Danish
99 'el' => 'gr', // Greek
100 'fr_CA' => 'qc', // French (Canada)
101 'gl' => 'ga', // Galician
102 'ja' => 'jp', // Japanese
103 'ka' => 'ge', // Georgian
104 'kl' => 'gl', // Greenlandic
105 'ko' => 'kr', // Korean
106 'ms' => 'my', // Malay
107 'pt_BR' => 'br', // Portuguese (Brazil)
108 'sl' => 'si', // Slovenian
109 'sv' => 'se', // Swedish
110 'uk' => 'ua', // Ukrainian
111 'vi' => 'vn', // Vietnamese
112 'zh' => 'hk', // Chinese (China)
113 'zh_CN' => 'ch', // Chinese (Simplified)
118 * Mapping with codes used by TYPO3 4.5 and below
122 protected $isoMapping;
125 * Dependencies for locales
129 protected $localeDependencies;
132 * Initializes the languages.
136 public static function initialize()
138 /** @var $instance Locales */
139 $instance = GeneralUtility
::makeInstance(Locales
::class);
140 $instance->isoMapping
= array_flip($instance->isoReverseMapping
);
141 // Allow user-defined locales
142 if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user'])) {
143 foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user'] as $locale => $name) {
144 if (!isset($instance->languages
[$locale])) {
145 $instance->languages
[$locale] = $name;
149 // Initializes the locale dependencies with TYPO3 supported locales
150 $instance->localeDependencies
= array();
151 foreach ($instance->languages
as $locale => $name) {
152 if (strlen($locale) === 5) {
153 $instance->localeDependencies
[$locale] = array(substr($locale, 0, 2));
156 // Merge user-provided locale dependencies
157 if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['dependencies']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['dependencies'])) {
158 ArrayUtility
::mergeRecursiveWithOverrule($instance->localeDependencies
, $GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['dependencies']);
163 * Returns the locales.
167 public function getLocales()
169 return array_keys($this->languages
);
173 * Returns the supported languages indexed by their corresponding locale.
177 public function getLanguages()
179 return $this->languages
;
183 * Returns the mapping between TYPO3 (old) language codes and ISO codes.
187 public function getIsoMapping()
189 return $this->isoMapping
;
193 * Returns the dependencies of a given locale, if any.
195 * @param string $locale
198 public function getLocaleDependencies($locale)
200 $dependencies = array();
201 if (isset($this->localeDependencies
[$locale])) {
202 $dependencies = $this->localeDependencies
[$locale];
203 // Search for dependencies recursively
204 $localeDependencies = $dependencies;
205 foreach ($localeDependencies as $dependency) {
206 if (isset($this->localeDependencies
[$dependency])) {
207 $dependencies = array_merge($dependencies, $this->getLocaleDependencies($dependency));
211 return $dependencies;
216 * Converts the language codes that we get from the client (usually HTTP_ACCEPT_LANGUAGE)
217 * into a TYPO3-readable language code
219 * @param string $languageCodesList List of language codes. something like 'de,en-us;q=0.9,de-de;q=0.7,es-cl;q=0.6,en;q=0.4,es;q=0.3,zh;q=0.1'
220 * @return string A preferred language that TYPO3 supports, or "default" if none found
222 public function getPreferredClientLanguage($languageCodesList)
224 $allLanguageCodesFromLocales = [];
225 foreach ($this->getIsoMapping() as $typo3Lang => $isoLang) {
226 $isoLang = str_replace('_', '-', $isoLang);
227 $allLanguageCodesFromLocales[$isoLang] = $typo3Lang;
229 foreach ($this->getLocales() as $locale) {
230 $locale = str_replace('_', '-', $locale);
231 $allLanguageCodesFromLocales[$locale] = $locale;
233 $selectedLanguage = 'default';
234 $preferredLanguages = GeneralUtility
::trimExplode(',', $languageCodesList);
235 // Order the preferred languages after they key
236 $sortedPreferredLanguages = array();
237 foreach ($preferredLanguages as $preferredLanguage) {
239 if (strpos($preferredLanguage, ';q=') !== false
) {
240 list($preferredLanguage, $quality) = explode(';q=', $preferredLanguage);
242 $sortedPreferredLanguages[$preferredLanguage] = $quality;
244 // Loop through the languages, with the highest priority first
245 arsort($sortedPreferredLanguages, SORT_NUMERIC
);
246 foreach ($sortedPreferredLanguages as $preferredLanguage => $quality) {
247 if (isset($allLanguageCodes[$preferredLanguage])) {
248 $selectedLanguage = $allLanguageCodes[$preferredLanguage];
251 // Strip the country code from the end
252 list($preferredLanguage, ) = explode('-', $preferredLanguage);
253 if (isset($allLanguageCodes[$preferredLanguage])) {
254 $selectedLanguage = $allLanguageCodes[$preferredLanguage];
258 if (!$selectedLanguage ||
$selectedLanguage === 'en') {
259 $selectedLanguage = 'default';
261 return $selectedLanguage;