‪TYPO3CMS  10.4
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 (GeneralUtility::isFirstPartOfStr($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) && $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 (TYPO3_MODE === 'FE') {
196  $siteLanguage = ‪self::getCurrentSiteLanguage();
197 
198  // Get values from site language
199  if ($siteLanguage !== null) {
200  $languageKeys['languageKey'] = $siteLanguage->getTypo3Language();
201  }
202 
203  ‪$locales = GeneralUtility::makeInstance(Locales::class);
204  if (in_array($languageKeys['languageKey'], ‪$locales->getLocales())) {
205  foreach (‪$locales->getLocaleDependencies($languageKeys['languageKey']) as $language) {
206  $languageKeys['alternativeLanguageKeys'][] = $language;
207  }
208  }
209  } elseif (!empty(‪$GLOBALS['BE_USER']->uc['lang'])) {
210  $languageKeys['languageKey'] = ‪$GLOBALS['BE_USER']->uc['lang'];
211  } elseif (!empty(static::getLanguageService()->lang)) {
212  $languageKeys['languageKey'] = static::getLanguageService()->lang;
213  }
214  return $languageKeys;
215  }
216 
225  protected static function ‪loadTypoScriptLabels(string $extensionName, string $languageFilePath): void
226  {
227  ‪$configurationManager = static::getConfigurationManager();
229  if (!is_array($frameworkConfiguration['_LOCAL_LANG'] ?? false)) {
230  return;
231  }
232  self::$LOCAL_LANG_UNSET[$languageFilePath] = [];
233  foreach ($frameworkConfiguration['_LOCAL_LANG'] as $languageKey => $labels) {
234  if (!is_array($labels)) {
235  continue;
236  }
237  foreach ($labels as $labelKey => $labelValue) {
238  if (is_string($labelValue)) {
239  self::$LOCAL_LANG[$languageFilePath][$languageKey][$labelKey][0]['target'] = $labelValue;
240  if ($labelValue === '') {
241  self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$labelKey] = '';
242  }
243  } elseif (is_array($labelValue)) {
244  $labelValue = ‪self::flattenTypoScriptLabelArray($labelValue, $labelKey);
245  foreach ($labelValue as $key => $value) {
246  self::$LOCAL_LANG[$languageFilePath][$languageKey][$key][0]['target'] = $value;
247  if ($value === '') {
248  self::$LOCAL_LANG_UNSET[$languageFilePath][$languageKey][$key] = '';
249  }
250  }
251  }
252  }
253  }
254  }
255 
267  protected static function ‪flattenTypoScriptLabelArray(array $labelValues, string $parentKey = ''): array
268  {
269  $result = [];
270  foreach ($labelValues as $key => $labelValue) {
271  if (!empty($parentKey)) {
272  if ($key === '_typoScriptNodeValue') {
273  $key = $parentKey;
274  } else {
275  $key = $parentKey . '.' . $key;
276  }
277  }
278  if (is_array($labelValue)) {
279  $labelValue = ‪self::flattenTypoScriptLabelArray($labelValue, $key);
280  $result = array_merge($result, $labelValue);
281  } else {
282  $result[$key] = $labelValue;
283  }
284  }
285  return $result;
286  }
287 
293  protected static function ‪getConfigurationManager(): ConfigurationManagerInterface
294  {
295  if (static::$configurationManager !== null) {
296  return static::$configurationManager;
297  }
298  $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
299  ‪$configurationManager = $objectManager->get(ConfigurationManagerInterface::class);
300  static::$configurationManager = ‪$configurationManager;
302  }
303 
310  protected static function ‪getCurrentSiteLanguage(): ?SiteLanguage
311  {
312  if (‪$GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) {
313  return ‪$GLOBALS['TYPO3_REQUEST']->getAttribute('language', null);
314  }
315  return null;
316  }
317 
321  protected static function ‪getLanguageService(): ‪LanguageService
322  {
323  return ‪$GLOBALS['LANG'];
324  }
325 }
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getCurrentSiteLanguage
‪static SiteLanguage null getCurrentSiteLanguage()
Definition: LocalizationUtility.php:306
‪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:28
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\loadTypoScriptLabels
‪static loadTypoScriptLabels(string $extensionName, string $languageFilePath)
Definition: LocalizationUtility.php:221
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\$configurationManager
‪static TYPO3 CMS Extbase Configuration ConfigurationManagerInterface $configurationManager
Definition: LocalizationUtility.php:55
‪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:263
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:30
‪TYPO3\CMS\Core\Utility\GeneralUtility\camelCaseToLowerCaseUnderscored
‪static string camelCaseToLowerCaseUnderscored($string)
Definition: GeneralUtility.php:914
‪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\initializeLocalization
‪static initializeLocalization(string $languageFilePath, string $languageKey, array $alternativeLanguageKeys, string $extensionName=null)
Definition: LocalizationUtility.php:142
‪$locales
‪$locales
Definition: be_users.php:7
‪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\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:289
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪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:46
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageKeys
‪static array getLanguageKeys()
Definition: LocalizationUtility.php:185
‪TYPO3\CMS\Extbase\Object\ObjectManager
Definition: ObjectManager.php:28
‪TYPO3\CMS\Extbase\Utility\LocalizationUtility\getLanguageService
‪static TYPO3 CMS Core Localization LanguageService getLanguageService()
Definition: LocalizationUtility.php:317