‪TYPO3CMS  ‪main
LanguageService.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
21 
46 {
50  public string ‪$lang = 'default';
51 
52  protected ?‪Locale ‪$locale = null;
56  public bool ‪$debugKey = false;
57 
61  protected array ‪$labels = [];
62 
66  protected array ‪$overrideLabels = [];
67 
71 
76  {
77  $this->locales = ‪$locales;
78  $this->localizationFactory = ‪$localizationFactory;
79  $this->runtimeCache = ‪$runtimeCache;
80  $this->debugKey = (bool)‪$GLOBALS['TYPO3_CONF_VARS']['BE']['languageDebug'];
81  }
82 
95  public function ‪init(‪Locale|string $languageKey): void
96  {
97  if ($languageKey instanceof ‪Locale) {
98  $this->locale = $languageKey;
99  } else {
100  $this->locale = $this->locales->createLocale($languageKey);
101  }
102  $this->lang = $this->‪getTypo3LanguageKey();
103  }
104 
110  protected function ‪debugLL(string $labelIdentifier): string
111  {
112  return $this->debugKey ? '[' . $labelIdentifier . ']' : '';
113  }
114 
122  public function ‪getLL($index)
123  {
124  return $this->‪getLLL($index, $this->labels);
125  }
126 
134  protected function ‪getLLL(string $index, array $localLanguage): string
135  {
136  if (isset($localLanguage[$this->lang][$index])) {
137  $value = is_string($localLanguage[$this->lang][$index])
138  ? $localLanguage[‪$this->lang][$index]
139  : $localLanguage[‪$this->lang][$index][0]['target'];
140  } elseif (isset($localLanguage['default'][$index])) {
141  $value = is_string($localLanguage['default'][$index])
142  ? $localLanguage['default'][$index]
143  : $localLanguage['default'][$index][0]['target'];
144  } else {
145  $value = '';
146  }
147  return $value . $this->‪debugLL($index);
148  }
149 
163  public function ‪sL($input): string
164  {
165  $input = (string)$input;
166  // early return for empty input to avoid cache and language file reading on first hit.
167  if ($input === '') {
168  return $input;
169  }
170  // Use a constant non-localizable label
171  if (!str_starts_with(trim($input), 'LLL:')) {
172  return $input;
173  }
174 
175  $cacheIdentifier = 'labels_' . (string)$this->locale . '_' . md5($input . '_' . (int)‪$this->debugKey);
176  $cacheEntry = $this->runtimeCache->get($cacheIdentifier);
177  if ($cacheEntry !== false) {
178  return $cacheEntry;
179  }
180  // Remove the LLL: prefix
181  $restStr = substr(trim($input), 4);
182  $extensionPrefix = '';
183  // ll-file referred to is found in an extension
184  if (‪PathUtility::isExtensionPath(trim($restStr))) {
185  $restStr = substr(trim($restStr), 4);
186  $extensionPrefix = 'EXT:';
187  }
188  $parts = explode(':', trim($restStr));
189  $parts[0] = $extensionPrefix . $parts[0];
190  $labelsFromFile = $this->‪readLLfile($parts[0]);
191  if (is_array($this->‪overrideLabels[$parts[0]] ?? null)) {
192  $labelsFromFile = array_replace_recursive($labelsFromFile, $this->‪overrideLabels[$parts[0]]);
193  }
194  ‪$output = $this->‪getLLL($parts[1] ?? '', $labelsFromFile);
195  ‪$output .= $this->‪debugLL($input);
196  $this->runtimeCache->set($cacheIdentifier, ‪$output);
197  return ‪$output;
198  }
199 
207  public function ‪includeLLFile(string $fileRef): array
208  {
209  $localLanguage = $this->‪readLLfile($fileRef);
210  if (!empty($localLanguage)) {
211  $this->labels = array_replace_recursive($this->labels, $localLanguage);
212  }
213  return $localLanguage;
214  }
215 
221  public function ‪translateLabel(array|string $input, string $fallback): string
222  {
223  if (is_array($input) && isset($input[$this->lang])) {
224  return $this->‪sL((string)$input[$this->lang]);
225  }
226  if (is_string($input)) {
227  return $this->‪sL($input);
228  }
229  return $this->‪sL($fallback);
230  }
231 
237  public function getLabelsFromResource(string $fileRef): array
238  {
239  ‪$labelArray = [];
240  $labelsFromFile = $this->‪readLLfile($fileRef);
241  foreach ($labelsFromFile['default'] as $key => $value) {
242  ‪$labelArray[$key] = $this->‪getLLL($key, $labelsFromFile);
243  }
245  }
246 
253  protected function ‪readLLfile(string $fileRef): array
254  {
255  $cacheIdentifier = 'labels_file_' . md5($fileRef . (string)$this->locale);
256  $cacheEntry = $this->runtimeCache->get($cacheIdentifier);
257  if (is_array($cacheEntry)) {
258  return $cacheEntry;
259  }
260 
261  $mainLanguageKey = $this->‪getTypo3LanguageKey();
262  $localLanguage = [];
263  $allLocales = array_merge([$mainLanguageKey], $this->locale->getDependencies());
264  $allLocales = array_reverse($allLocales);
265  foreach ($allLocales as ‪$locale) {
266  $tempLL = $this->localizationFactory->getParsedData($fileRef, ‪$locale);
267  $localLanguage['default'] = $tempLL['default'];
268  if (!isset($localLanguage[$mainLanguageKey])) {
269  $localLanguage[$mainLanguageKey] = $localLanguage['default'];
270  }
271  if ($mainLanguageKey !== 'default') {
272  // Fallback as long as TYPO3 supports "da_DK" and "da-DK"
273  if ((!isset($tempLL[‪$locale]) || $tempLL[‪$locale] === []) && str_contains(‪$locale, '-')) {
274  $underscoredLocale = str_replace('-', '_', ‪$locale);
275  $tempLL = $this->localizationFactory->getParsedData($fileRef, $underscoredLocale);
276  if (isset($tempLL[$underscoredLocale])) {
277  $tempLL[‪$locale] = $tempLL[$underscoredLocale];
278  }
279  }
280  if (isset($tempLL[‪$locale])) {
281  // Merge current language labels onto labels from previous language
282  // This way we have a labels with fall back applied
283  ArrayUtility::mergeRecursiveWithOverrule($localLanguage[$mainLanguageKey], $tempLL[‪$locale], true, false);
284  }
285  }
286  }
287 
288  $this->runtimeCache->set($cacheIdentifier, $localLanguage);
289  return $localLanguage;
290  }
291 
296  public function ‪overrideLabels(string $fileRef, array ‪$labels): void
297  {
298  $localLanguage = [
299  'default' => ‪$labels['default'] ?? [],
300  ];
301  $mainLanguageKey = $this->‪getTypo3LanguageKey();
302  if ($mainLanguageKey !== 'default') {
303  $allLocales = array_merge([$mainLanguageKey], $this->locale->getDependencies());
304  $allLocales = array_reverse($allLocales);
305  foreach ($allLocales as $language) {
306  // Populate the initial values with default, if no labels for the current language are given
307  if (!isset($localLanguage[$mainLanguageKey])) {
308  $localLanguage[$mainLanguageKey] = $localLanguage['default'];
309  }
310  if (isset(‪$labels[$language])) {
311  $localLanguage[$mainLanguageKey] = array_replace_recursive($localLanguage[$mainLanguageKey], ‪$labels[$language]);
312  }
313  }
314  }
315  $this->‪overrideLabels[$fileRef] = $localLanguage;
316  }
317 
318  public function ‪getLocale(): ?‪Locale
319  {
320  return ‪$this->locale;
321  }
322 
323  private function ‪getTypo3LanguageKey(): string
324  {
325  if ($this->locale === null) {
326  return 'default';
327  }
328  if ($this->locale->getName() === 'en') {
329  return 'default';
330  }
331  return $this->locale->getName();
332  }
333 }
‪TYPO3\CMS\Core\Localization\LanguageService\readLLfile
‪array< string, getLabelsFromResource(string $fileRef):array { $labelArray=[];$labelsFromFile=$this-> readLLfile($fileRef)
‪TYPO3\CMS\Core\Localization\LanguageService\includeLLFile
‪array includeLLFile(string $fileRef)
Definition: LanguageService.php:207
‪TYPO3\CMS\Core\Localization\LanguageService\getLLL
‪string getLLL(string $index, array $localLanguage)
Definition: LanguageService.php:134
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static isExtensionPath(string $path)
Definition: PathUtility.php:117
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Localization\LanguageService\$lang
‪string $lang
Definition: LanguageService.php:50
‪TYPO3\CMS\Core\Localization\LocalizationFactory
Definition: LocalizationFactory.php:31
‪TYPO3\CMS\Core\Localization\LanguageService\$localizationFactory
‪LocalizationFactory $localizationFactory
Definition: LanguageService.php:69
‪TYPO3\CMS\Core\Localization\LanguageService\debugLL
‪debugLL(string $labelIdentifier)
Definition: LanguageService.php:110
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:36
‪TYPO3\CMS\Core\Localization\LanguageService\init
‪init(Locale|string $languageKey)
Definition: LanguageService.php:95
‪TYPO3\CMS\Core\Localization\LanguageService\translateLabel
‪translateLabel(array|string $input, string $fallback)
Definition: LanguageService.php:221
‪TYPO3\CMS\Core\Localization\LanguageService\$labelArray
‪foreach($labelsFromFile['default'] as $key=> $value) return $labelArray
Definition: LanguageService.php:241
‪TYPO3\CMS\Core\Localization
Definition: CacheWarmer.php:18
‪TYPO3\CMS\Core\Localization\LanguageService\$runtimeCache
‪FrontendInterface $runtimeCache
Definition: LanguageService.php:70
‪TYPO3\CMS\Core\Localization\LanguageService\$debugKey
‪bool $debugKey
Definition: LanguageService.php:56
‪TYPO3\CMS\Core\Localization\LanguageService\getLocale
‪getLocale()
Definition: LanguageService.php:318
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪sL($input)
Definition: LanguageService.php:163
‪TYPO3\CMS\Core\Localization\LanguageService\__construct
‪__construct(Locales $locales, LocalizationFactory $localizationFactory, FrontendInterface $runtimeCache)
Definition: LanguageService.php:75
‪$output
‪$output
Definition: annotationChecker.php:119
‪TYPO3\CMS\Core\Localization\LanguageService\$labels
‪array $labels
Definition: LanguageService.php:61
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Localization\LanguageService\overrideLabels
‪overrideLabels(string $fileRef, array $labels)
Definition: LanguageService.php:296
‪TYPO3\CMS\Core\Localization\LanguageService\$locale
‪Locale $locale
Definition: LanguageService.php:52
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:26
‪TYPO3\CMS\Core\Localization\LanguageService\$overrideLabels
‪array $overrideLabels
Definition: LanguageService.php:66
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Localization\Locale
Definition: Locale.php:30
‪TYPO3\CMS\Core\Localization\LanguageService\getTypo3LanguageKey
‪getTypo3LanguageKey()
Definition: LanguageService.php:323
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Localization\LanguageService\$locales
‪Locales $locales
Definition: LanguageService.php:68
‪TYPO3\CMS\Core\Localization\LanguageService\getLL
‪string getLL($index)
Definition: LanguageService.php:122
‪TYPO3\CMS\Core\Localization\LanguageService\readLLfile
‪array readLLfile(string $fileRef)
Definition: LanguageService.php:253