‪TYPO3CMS  9.5
LocalizationUtility.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
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.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
17 use Psr\Http\Message\ServerRequestInterface;
24 
29 {
33  protected static ‪$locallangPath = 'Resources/Private/Language/';
34 
40  protected static ‪$LOCAL_LANG = [];
41 
50  protected static ‪$LOCAL_LANG_UNSET = [];
51 
55  protected static ‪$configurationManager;
56 
67  public static function ‪translate($key, $extensionName = null, $arguments = null, string $languageKey = null, array $alternativeLanguageKeys = null)
68  {
69  if ((string)$key === '') {
70  // Early return guard: returns null if the key was empty, because the key may be a dynamic value
71  // (from for example Fluid). Returning null allows null coalescing to a default value when that happens.
72  return null;
73  }
74  $value = null;
75  if (GeneralUtility::isFirstPartOfStr($key, 'LLL:')) {
76  $keyParts = explode(':', $key);
77  unset($keyParts[0]);
78  $key = array_pop($keyParts);
79  $languageFilePath = implode(':', $keyParts);
80  } else {
81  if (empty($extensionName)) {
82  throw new \InvalidArgumentException(
83  'Parameter $extensionName cannot be empty if a fully-qualified key is not specified.',
84  1498144052
85  );
86  }
87  $languageFilePath = static::getLanguageFilePath($extensionName);
88  }
89  $languageKeys = static::getLanguageKeys();
90  if ($languageKey === null) {
91  $languageKey = $languageKeys['languageKey'];
92  }
93  if (empty($alternativeLanguageKeys)) {
94  $alternativeLanguageKeys = $languageKeys['alternativeLanguageKeys'];
95  }
96  static::initializeLocalization($languageFilePath, $languageKey, $alternativeLanguageKeys, $extensionName);
97 
98  // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG
99  if (!empty(self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'])
100  || isset(self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$key])
101  ) {
102  // Local language translation for key exists
103  $value = self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'];
104  } elseif (!empty($alternativeLanguageKeys)) {
105  $languages = array_reverse($alternativeLanguageKeys);
106  foreach ($languages as $language) {
107  if (!empty(self::$LOCAL_LANG[$languageFilePath][$language][$key][0]['target'])
108  || isset(self::$LOCAL_LANG_UNSET[$languageFilePath][$language][$key])
109  ) {
110  // Alternative language translation for key exists
111  $value = self::$LOCAL_LANG[$languageFilePath][$language][$key][0]['target'];
112  break;
113  }
114  }
115  }
116  if ($value === null && (!empty(self::$LOCAL_LANG[$languageFilePath]['default'][$key][0]['target'])
117  || isset(self::$LOCAL_LANG_UNSET[$languageFilePath]['default'][$key]))
118  ) {
119  // Default language translation for key exists
120  // No charset conversion because default is English and thereby ASCII
121  $value = self::$LOCAL_LANG[$languageFilePath]['default'][$key][0]['target'];
122  }
123 
124  if (is_array($arguments) && $value !== null) {
125  // This unrolls arguments from $arguments - instead of calling vsprintf which receives arguments as an array.
126  // The reason is that only sprintf() will return an error message if the number of arguments does not match
127  // the number of placeholders in the format string. Whereas, vsprintf would silently return nothing.
128  return sprintf($value, ...array_values($arguments)) ?: sprintf('Error: could not translate key "%s" with value "%s" and %d argument(s)!', $key, $value, count($arguments));
129  }
130  return $value;
131  }
132 
142  protected static function ‪initializeLocalization(string $languageFilePath, string $languageKey, array $alternativeLanguageKeys, string $extensionName = null)
143  {
144  $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class);
145 
146  if (empty(self::$LOCAL_LANG[$languageFilePath][$languageKey])) {
147  $parsedData = $languageFactory->getParsedData($languageFilePath, $languageKey);
148  foreach ($parsedData as $tempLanguageKey => $data) {
149  if (!empty($data)) {
150  self::$LOCAL_LANG[$languageFilePath][$tempLanguageKey] = $data;
151  }
152  }
153  }
154  if ($languageKey !== 'default') {
155  foreach ($alternativeLanguageKeys as $alternativeLanguageKey) {
156  if (empty(self::$LOCAL_LANG[$languageFilePath][$alternativeLanguageKey])) {
157  $tempLL = $languageFactory->getParsedData($languageFilePath, $alternativeLanguageKey);
158  if (isset($tempLL[$alternativeLanguageKey])) {
159  self::$LOCAL_LANG[$languageFilePath][$alternativeLanguageKey] = $tempLL[$alternativeLanguageKey];
160  }
161  }
162  }
163  }
164  if (!empty($extensionName)) {
165  static::loadTypoScriptLabels($extensionName, $languageFilePath);
166  }
167  }
168 
175  protected static function ‪getLanguageFilePath(string $extensionName): string
176  {
177  return 'EXT:' . GeneralUtility::camelCaseToLowerCaseUnderscored($extensionName) . '/' . self::$locallangPath . 'locallang.xlf';
178  }
179 
186  protected static function ‪getLanguageKeys(): array
187  {
188  $languageKeys = [
189  'languageKey' => 'default',
190  'alternativeLanguageKeys' => [],
191  ];
192  if (TYPO3_MODE === 'FE') {
193  $tsfe = static::getTypoScriptFrontendController();
194  $siteLanguage = ‪self::getCurrentSiteLanguage();
195 
196  // Get values from site language, which takes precedence over TypoScript settings
197  if ($siteLanguage instanceof SiteLanguage) {
198  $languageKeys['languageKey'] = $siteLanguage->getTypo3Language();
199  } elseif (isset($tsfe->config['config']['language'])) {
200  $languageKeys['languageKey'] = $tsfe->config['config']['language'];
201  if (isset($tsfe->config['config']['language_alt'])) {
202  $languageKeys['alternativeLanguageKeys'][] = $tsfe->config['config']['language_alt'];
203  }
204  }
205 
206  if (empty($languageKeys['alternativeLanguageKeys'])) {
207  ‪$locales = GeneralUtility::makeInstance(Locales::class);
208  if (in_array($languageKeys['languageKey'], ‪$locales->getLocales())) {
209  foreach (‪$locales->getLocaleDependencies($languageKeys['languageKey']) as $language) {
210  $languageKeys['alternativeLanguageKeys'][] = $language;
211  }
212  }
213  }
214  } elseif (!empty(‪$GLOBALS['BE_USER']->uc['lang'])) {
215  $languageKeys['languageKey'] = ‪$GLOBALS['BE_USER']->uc['lang'];
216  } elseif (!empty(static::getLanguageService()->lang)) {
217  $languageKeys['languageKey'] = static::getLanguageService()->lang;
218  }
219  return $languageKeys;
220  }
221 
230  protected static function ‪loadTypoScriptLabels($extensionName, $languageFilePath)
231  {
232  ‪$configurationManager = static::getConfigurationManager();
234  if (!is_array($frameworkConfiguration['_LOCAL_LANG'] ?? false)) {
235  return;
236  }
237  self::$LOCAL_LANG_UNSET[$languageFilePath] = [];
238  foreach ($frameworkConfiguration['_LOCAL_LANG'] as $languageKey => $labels) {
239  if (!is_array($labels)) {
240  continue;
241  }
242  foreach ($labels as $labelKey => $labelValue) {
243  if (is_string($labelValue)) {
244  self::$LOCAL_LANG[$languageFilePath][$languageKey][$labelKey][0]['target'] = $labelValue;
245  if ($labelValue === '') {
246  self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$labelKey] = '';
247  }
248  } elseif (is_array($labelValue)) {
249  $labelValue = ‪self::flattenTypoScriptLabelArray($labelValue, $labelKey);
250  foreach ($labelValue as $key => $value) {
251  self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'] = $value;
252  if ($value === '') {
253  self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$key] = '';
254  }
255  }
256  }
257  }
258  }
259  }
260 
272  protected static function ‪flattenTypoScriptLabelArray(array $labelValues, $parentKey = '')
273  {
274  $result = [];
275  foreach ($labelValues as $key => $labelValue) {
276  if (!empty($parentKey)) {
277  if ($key === '_typoScriptNodeValue') {
278  $key = $parentKey;
279  } else {
280  $key = $parentKey . '.' . $key;
281  }
282  }
283  if (is_array($labelValue)) {
284  $labelValue = ‪self::flattenTypoScriptLabelArray($labelValue, $key);
285  $result = array_merge($result, $labelValue);
286  } else {
287  $result[$key] = $labelValue;
288  }
289  }
290  return $result;
291  }
292 
298  protected static function ‪getConfigurationManager()
299  {
300  if (static::$configurationManager !== null) {
301  return static::$configurationManager;
302  }
303  $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
304  ‪$configurationManager = $objectManager->get(ConfigurationManagerInterface::class);
305  static::$configurationManager = ‪$configurationManager;
307  }
308 
315  protected static function ‪getCurrentSiteLanguage(): ?SiteLanguage
316  {
317  if (‪$GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) {
318  return ‪$GLOBALS['TYPO3_REQUEST']->getAttribute('language', null);
319  }
320  return null;
321  }
322 
326  protected static function ‪getTypoScriptFrontendController()
327  {
328  return ‪$GLOBALS['TSFE'];
329  }
330 
334  protected static function ‪getLanguageService()
335  {
336  return ‪$GLOBALS['LANG'];
337  }
338 }
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getCurrentSiteLanguage
‪static SiteLanguage null getCurrentSiteLanguage()
Definition: LocalizationUtility.php:311
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getTypoScriptFrontendController
‪static TYPO3 CMS Frontend Controller TypoScriptFrontendController getTypoScriptFrontendController()
Definition: LocalizationUtility.php:322
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility
Definition: LocalizationUtility.php:29
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\loadTypoScriptLabels
‪static loadTypoScriptLabels($extensionName, $languageFilePath)
Definition: LocalizationUtility.php:226
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$locallangPath
‪static string $locallangPath
Definition: LocalizationUtility.php:32
‪TYPO3\CMS\Core\Localization\LocalizationFactory
Definition: LocalizationFactory.php:25
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$configurationManager
‪static TYPO3 CMS Extbase Configuration ConfigurationManagerInterface $configurationManager
Definition: LocalizationUtility.php:51
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
Definition: ConfigurationManagerInterface.php:22
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface\getConfiguration
‪array getConfiguration($configurationType, $extensionName=null, $pluginName=null)
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:29
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$LOCAL_LANG
‪static array $LOCAL_LANG
Definition: LocalizationUtility.php:38
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface\CONFIGURATION_TYPE_FRAMEWORK
‪const CONFIGURATION_TYPE_FRAMEWORK
Definition: ConfigurationManagerInterface.php:23
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:25
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\translate
‪static string null translate($key, $extensionName=null, $arguments=null, string $languageKey=null, array $alternativeLanguageKeys=null)
Definition: LocalizationUtility.php:63
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\initializeLocalization
‪static initializeLocalization(string $languageFilePath, string $languageKey, array $alternativeLanguageKeys, string $extensionName=null)
Definition: LocalizationUtility.php:138
‪$locales
‪$locales
Definition: be_users.php:6
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\flattenTypoScriptLabelArray
‪static array flattenTypoScriptLabelArray(array $labelValues, $parentKey='')
Definition: LocalizationUtility.php:268
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageFilePath
‪static string getLanguageFilePath(string $extensionName)
Definition: LocalizationUtility.php:171
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$LOCAL_LANG_UNSET
‪static array $LOCAL_LANG_UNSET
Definition: LocalizationUtility.php:47
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getConfigurationManager
‪static TYPO3 CMS Extbase Configuration ConfigurationManagerInterface getConfigurationManager()
Definition: LocalizationUtility.php:294
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Extbase\Utility
Definition: DebuggerUtility.php:2
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageKeys
‪static array getLanguageKeys()
Definition: LocalizationUtility.php:182
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:25
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageService
‪static TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: LocalizationUtility.php:330