‪TYPO3CMS  11.5
LocalizationUtility.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
28 
33 {
37  protected static ‪$locallangPath = 'Resources/Private/Language/';
38 
44  protected static ‪$LOCAL_LANG = [];
45 
54  protected static ‪$LOCAL_LANG_UNSET = [];
55 
59  protected static ‪$configurationManager;
60 
71  public static function ‪translate(string $key, ?string $extensionName = null, ?array $arguments = null, ?string $languageKey = null, ?array $alternativeLanguageKeys = null): ?string
72  {
73  if ($key === '') {
74  // Early return guard: returns null if the key was empty, because the key may be a dynamic value
75  // (from for example Fluid). Returning null allows null coalescing to a default value when that happens.
76  return null;
77  }
78  $value = null;
79  if (str_starts_with($key, 'LLL:')) {
80  $keyParts = explode(':', $key);
81  unset($keyParts[0]);
82  $key = array_pop($keyParts);
83  $languageFilePath = implode(':', $keyParts);
84  } else {
85  if (empty($extensionName)) {
86  throw new \InvalidArgumentException(
87  'Parameter $extensionName cannot be empty if a fully-qualified key is not specified.',
88  1498144052
89  );
90  }
91  $languageFilePath = static::getLanguageFilePath($extensionName);
92  }
93  $languageKeys = static::getLanguageKeys();
94  if ($languageKey === null) {
95  $languageKey = $languageKeys['languageKey'];
96  }
97  if (empty($alternativeLanguageKeys)) {
98  $alternativeLanguageKeys = $languageKeys['alternativeLanguageKeys'];
99  }
100  static::initializeLocalization($languageFilePath, $languageKey, $alternativeLanguageKeys, $extensionName);
101 
102  // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG
103  if (!empty(self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'])
104  || isset(self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$key])
105  ) {
106  // Local language translation for key exists
107  $value = self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'];
108  } elseif (!empty($alternativeLanguageKeys)) {
109  $languages = array_reverse($alternativeLanguageKeys);
110  foreach ($languages as $language) {
111  if (!empty(self::$LOCAL_LANG[$languageFilePath][$language][$key][0]['target'])
112  || isset(self::$LOCAL_LANG_UNSET[$languageFilePath][$language][$key])
113  ) {
114  // Alternative language translation for key exists
115  $value = self::$LOCAL_LANG[$languageFilePath][$language][$key][0]['target'];
116  break;
117  }
118  }
119  }
120  if ($value === null && (!empty(self::$LOCAL_LANG[$languageFilePath]['default'][$key][0]['target'])
121  || isset(self::$LOCAL_LANG_UNSET[$languageFilePath]['default'][$key]))
122  ) {
123  // Default language translation for key exists
124  // No charset conversion because default is English and thereby ASCII
125  $value = self::$LOCAL_LANG[$languageFilePath]['default'][$key][0]['target'];
126  }
127 
128  if (is_array($arguments) && $arguments !== [] && $value !== null) {
129  // This unrolls arguments from $arguments - instead of calling vsprintf which receives arguments as an array.
130  // The reason is that only sprintf() will return an error message if the number of arguments does not match
131  // the number of placeholders in the format string. Whereas, vsprintf would silently return nothing.
132  return sprintf($value, ...array_values($arguments)) ?: sprintf('Error: could not translate key "%s" with value "%s" and %d argument(s)!', $key, $value, count($arguments));
133  }
134  return $value;
135  }
136 
146  protected static function ‪initializeLocalization(string $languageFilePath, string $languageKey, array $alternativeLanguageKeys, ?string $extensionName = null): void
147  {
148  $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class);
149 
150  if (empty(self::$LOCAL_LANG[$languageFilePath][$languageKey])) {
151  $parsedData = $languageFactory->getParsedData($languageFilePath, $languageKey);
152  foreach ($parsedData as $tempLanguageKey => $data) {
153  if (!empty($data)) {
154  self::$LOCAL_LANG[$languageFilePath][$tempLanguageKey] = $data;
155  }
156  }
157  }
158  if ($languageKey !== 'default') {
159  foreach ($alternativeLanguageKeys as $alternativeLanguageKey) {
160  if (empty(self::$LOCAL_LANG[$languageFilePath][$alternativeLanguageKey])) {
161  $tempLL = $languageFactory->getParsedData($languageFilePath, $alternativeLanguageKey);
162  if (isset($tempLL[$alternativeLanguageKey])) {
163  self::$LOCAL_LANG[$languageFilePath][$alternativeLanguageKey] = $tempLL[$alternativeLanguageKey];
164  }
165  }
166  }
167  }
168  if (!empty($extensionName)) {
169  static::loadTypoScriptLabels($extensionName, $languageFilePath);
170  }
171  }
172 
179  protected static function ‪getLanguageFilePath(string $extensionName): string
180  {
181  return 'EXT:' . ‪GeneralUtility::camelCaseToLowerCaseUnderscored($extensionName) . '/' . self::$locallangPath . 'locallang.xlf';
182  }
183 
189  protected static function ‪getLanguageKeys(): array
190  {
191  $languageKeys = [
192  'languageKey' => 'default',
193  'alternativeLanguageKeys' => [],
194  ];
195  if ((‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
196  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isFrontend()
197  ) {
198  // Frontend application
199  $siteLanguage = ‪self::getCurrentSiteLanguage();
200 
201  // Get values from site language
202  if ($siteLanguage !== null) {
203  $languageKeys['languageKey'] = $siteLanguage->getTypo3Language();
204  }
205 
206  $locales = GeneralUtility::makeInstance(Locales::class);
207  if (in_array($languageKeys['languageKey'], $locales->getLocales())) {
208  foreach ($locales->getLocaleDependencies($languageKeys['languageKey']) as $language) {
209  $languageKeys['alternativeLanguageKeys'][] = $language;
210  }
211  }
212  } elseif (!empty(‪$GLOBALS['BE_USER']->user['lang'])) {
213  $languageKeys['languageKey'] = ‪$GLOBALS['BE_USER']->user['lang'];
214  } elseif (!empty(static::getLanguageService()->lang)) {
215  $languageKeys['languageKey'] = static::getLanguageService()->lang;
216  }
217  return $languageKeys;
218  }
219 
228  protected static function ‪loadTypoScriptLabels(string $extensionName, string $languageFilePath): void
229  {
230  ‪$configurationManager = static::getConfigurationManager();
232  if (!is_array($frameworkConfiguration['_LOCAL_LANG'] ?? false)) {
233  return;
234  }
235  self::$LOCAL_LANG_UNSET[$languageFilePath] = [];
236  foreach ($frameworkConfiguration['_LOCAL_LANG'] as $languageKey => $labels) {
237  if (!is_array($labels)) {
238  continue;
239  }
240  foreach ($labels as $labelKey => $labelValue) {
241  if (is_string($labelValue)) {
242  self::$LOCAL_LANG[$languageFilePath][$languageKey][$labelKey][0]['target'] = $labelValue;
243  if ($labelValue === '') {
244  self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$labelKey] = '';
245  }
246  } elseif (is_array($labelValue)) {
247  $labelValue = ‪self::flattenTypoScriptLabelArray($labelValue, $labelKey);
248  foreach ($labelValue as $key => $value) {
249  self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'] = $value;
250  if ($value === '') {
251  self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$key] = '';
252  }
253  }
254  }
255  }
256  }
257  }
258 
270  protected static function ‪flattenTypoScriptLabelArray(array $labelValues, string $parentKey = ''): array
271  {
272  $result = [];
273  foreach ($labelValues as $key => $labelValue) {
274  if (!empty($parentKey)) {
275  if ($key === '_typoScriptNodeValue') {
276  $key = $parentKey;
277  } else {
278  $key = $parentKey . '.' . $key;
279  }
280  }
281  if (is_array($labelValue)) {
282  $labelValue = ‪self::flattenTypoScriptLabelArray($labelValue, $key);
283  $result = array_merge($result, $labelValue);
284  } else {
285  $result[$key] = $labelValue;
286  }
287  }
288  return $result;
289  }
290 
296  protected static function ‪getConfigurationManager(): ConfigurationManagerInterface
297  {
298  if (static::$configurationManager !== null) {
299  return static::$configurationManager;
300  }
301  static::$configurationManager = GeneralUtility::makeInstance(ConfigurationManagerInterface::class);
302  return static::$configurationManager;
303  }
304 
311  protected static function ‪getCurrentSiteLanguage(): ?SiteLanguage
312  {
313  if (‪$GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) {
314  return ‪$GLOBALS['TYPO3_REQUEST']->getAttribute('language', null);
315  }
316  return null;
317  }
318 
322  protected static function ‪getLanguageService(): ‪LanguageService
323  {
324  return ‪$GLOBALS['LANG'];
325  }
326 }
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getCurrentSiteLanguage
‪static SiteLanguage null getCurrentSiteLanguage()
Definition: LocalizationUtility.php:307
‪TYPO3\CMS\Core\Http\ApplicationType\fromRequest
‪static static fromRequest(ServerRequestInterface $request)
Definition: ApplicationType.php:62
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility
Definition: LocalizationUtility.php:33
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$locallangPath
‪static string $locallangPath
Definition: LocalizationUtility.php:36
‪TYPO3\CMS\Core\Localization\LocalizationFactory
Definition: LocalizationFactory.php:31
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\loadTypoScriptLabels
‪static loadTypoScriptLabels(string $extensionName, string $languageFilePath)
Definition: LocalizationUtility.php:224
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$configurationManager
‪static TYPO3 CMS Extbase Configuration ConfigurationManagerInterface $configurationManager
Definition: LocalizationUtility.php:55
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\translate
‪static string null translate(string $key, ?string $extensionName=null, ?array $arguments=null, ?string $languageKey=null, ?array $alternativeLanguageKeys=null)
Definition: LocalizationUtility.php:67
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface
Definition: ConfigurationManagerInterface.php:28
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\flattenTypoScriptLabelArray
‪static array flattenTypoScriptLabelArray(array $labelValues, string $parentKey='')
Definition: LocalizationUtility.php:266
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility\camelCaseToLowerCaseUnderscored
‪static string camelCaseToLowerCaseUnderscored($string)
Definition: GeneralUtility.php:853
‪TYPO3\CMS\Core\Http\ApplicationType
Definition: ApplicationType.php:52
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$LOCAL_LANG
‪static array $LOCAL_LANG
Definition: LocalizationUtility.php:42
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface\CONFIGURATION_TYPE_FRAMEWORK
‪const CONFIGURATION_TYPE_FRAMEWORK
Definition: ConfigurationManagerInterface.php:29
‪TYPO3\CMS\Core\Site\Entity\SiteLanguage
Definition: SiteLanguage.php:26
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageFilePath
‪static string getLanguageFilePath(string $extensionName)
Definition: LocalizationUtility.php:175
‪TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface\getConfiguration
‪array getConfiguration(string $configurationType, ?string $extensionName=null, ?string $pluginName=null)
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$LOCAL_LANG_UNSET
‪static array $LOCAL_LANG_UNSET
Definition: LocalizationUtility.php:51
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getConfigurationManager
‪static TYPO3 CMS Extbase Configuration ConfigurationManagerInterface getConfigurationManager()
Definition: LocalizationUtility.php:292
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Extbase\Utility
Definition: DebuggerUtility.php:18
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:42
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\initializeLocalization
‪static initializeLocalization(string $languageFilePath, string $languageKey, array $alternativeLanguageKeys, ?string $extensionName=null)
Definition: LocalizationUtility.php:142
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageKeys
‪static array getLanguageKeys()
Definition: LocalizationUtility.php:185
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageService
‪static TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: LocalizationUtility.php:318