‪TYPO3CMS  9.5
LanguageService.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 
19 
29 {
35  public ‪$lang = 'default';
36 
42  public ‪$debugKey = false;
43 
49  public ‪$LL_files_cache = [];
50 
56  public ‪$LL_labels_cache = [];
57 
64  protected ‪$languageDependencies = [];
65 
71  protected ‪$languageFileCache = [];
72 
76  public function ‪__construct()
77  {
78  $this->debugKey = (bool)‪$GLOBALS['TYPO3_CONF_VARS']['BE']['languageDebug'];
79  }
80 
90  public function ‪init($languageKey)
91  {
92  // Find the requested language in this list based on the $languageKey
94  ‪$locales = GeneralUtility::makeInstance(Locales::class);
95  // Language is found. Configure it:
96  if (in_array($languageKey, ‪$locales->getLocales())) {
97  // The current language key
98  $this->lang = $languageKey;
99  $this->languageDependencies[] = $languageKey;
100  foreach (‪$locales->getLocaleDependencies($languageKey) as $language) {
101  $this->languageDependencies[] = $language;
102  }
103  }
104  }
105 
112  public function ‪debugLL($value)
113  {
114  return $this->debugKey ? '[' . $value . ']' : '';
115  }
116 
124  public function ‪getLL($index)
125  {
126  return $this->‪getLLL($index, ‪$GLOBALS['LOCAL_LANG']);
127  }
128 
136  public function ‪getLLL($index, $localLanguage)
137  {
138  // Get Local Language. Special handling for all extensions that
139  // read PHP LL files and pass arrays here directly.
140  if (isset($localLanguage[$this->lang][$index])) {
141  $value = is_string($localLanguage[$this->lang][$index])
142  ? $localLanguage[‪$this->lang][$index]
143  : $localLanguage[‪$this->lang][$index][0]['target'];
144  } elseif (isset($localLanguage['default'][$index])) {
145  $value = is_string($localLanguage['default'][$index])
146  ? $localLanguage['default'][$index]
147  : $localLanguage['default'][$index][0]['target'];
148  } else {
149  $value = '';
150  }
151  return $value . $this->‪debugLL($index);
152  }
153 
164  public function ‪sL($input)
165  {
166  $identifier = $input . '_' . (int)$this->debugKey;
167  if (isset($this->LL_labels_cache[$this->lang][$identifier])) {
168  return $this->LL_labels_cache[‪$this->lang][$identifier];
169  }
170  if (strpos($input, 'LLL:') === 0) {
171  $restStr = trim(substr($input, 4));
172  $extPrfx = '';
173  // ll-file referred to is found in an extension.
174  if (strpos($restStr, 'EXT:') === 0) {
175  $restStr = trim(substr($restStr, 4));
176  $extPrfx = 'EXT:';
177  }
178  $parts = explode(':', $restStr);
179  $parts[0] = $extPrfx . $parts[0];
180  // Getting data if not cached
181  if (!isset($this->LL_files_cache[$parts[0]])) {
182  $this->LL_files_cache[$parts[0]] = $this->‪readLLfile($parts[0]);
183  }
184  ‪$output = $this->‪getLLL($parts[1], $this->LL_files_cache[$parts[0]]);
185  } else {
186  // Use a constant non-localizable label
187  ‪$output = $input;
188  }
189  ‪$output .= $this->‪debugLL($input);
190  $this->LL_labels_cache[‪$this->lang][$identifier] = ‪$output;
191  return ‪$output;
192  }
193 
201  public function ‪loadSingleTableDescription($table)
202  {
203  // First the 'table' cannot already be loaded in [columns]
204  // and secondly there must be a references to locallang files available in [refs]
205  if (is_array(‪$GLOBALS['TCA_DESCR'][$table]) && !isset(‪$GLOBALS['TCA_DESCR'][$table]['columns']) && is_array(‪$GLOBALS['TCA_DESCR'][$table]['refs'])) {
206  // Init $TCA_DESCR for $table-key
207  ‪$GLOBALS['TCA_DESCR'][$table]['columns'] = [];
208  // Get local-lang for each file in $TCA_DESCR[$table]['refs'] as they are ordered.
209  foreach (‪$GLOBALS['TCA_DESCR'][$table]['refs'] as $llfile) {
210  $localLanguage = $this->‪includeLLFile($llfile, false, true);
211  // Traverse all keys
212  if (is_array($localLanguage['default'])) {
213  foreach ($localLanguage['default'] as $lkey => $lVal) {
214  // Exploding by '.':
215  // 0-n => fieldname,
216  // n+1 => type from (alttitle, description, details, syntax, image_descr,image,seeAlso),
217  // n+2 => special instruction, if any
218  $keyParts = explode('.', $lkey);
219  $keyPartsCount = count($keyParts);
220  // Check if last part is special instruction
221  // Only "+" is currently supported
222  $specialInstruction = $keyParts[$keyPartsCount - 1] === '+';
223  if ($specialInstruction) {
224  array_pop($keyParts);
225  }
226  // If there are more than 2 parts, get the type from the last part
227  // and merge back the other parts with a dot (.)
228  // Otherwise just get type and field name straightaway
229  if ($keyPartsCount > 2) {
230  $type = array_pop($keyParts);
231  $fieldName = implode('.', $keyParts);
232  } else {
233  $fieldName = $keyParts[0];
234  $type = $keyParts[1];
235  }
236  // Detecting 'hidden' labels, converting to normal fieldname
237  if ($fieldName === '_') {
238  $fieldName = '';
239  }
240  if ($fieldName !== '' && $fieldName[0] === '_') {
241  $fieldName = substr($fieldName, 1);
242  }
243  // Append label
244  $label = $lVal[0]['target'] ?: $lVal[0]['source'];
245  if ($specialInstruction) {
246  ‪$GLOBALS['TCA_DESCR'][$table]['columns'][$fieldName][$type] .= LF . $label;
247  } else {
248  // Substitute label
249  ‪$GLOBALS['TCA_DESCR'][$table]['columns'][$fieldName][$type] = $label;
250  }
251  }
252  }
253  }
254  }
255  }
256 
266  public function ‪includeLLFile($fileRef, $setGlobal = true, $mergeLocalOntoDefault = false)
267  {
268  $globalLanguage = [];
269  // Get default file
270  $localLanguage = $this->‪readLLfile($fileRef);
271  if (is_array($localLanguage) && !empty($localLanguage)) {
272  // it depends on, whether we should return the result or set it in the global $LOCAL_LANG array
273  if ($setGlobal) {
274  $globalLanguage = (array)(‪$GLOBALS['LOCAL_LANG'] ?? []);
275  ‪ArrayUtility::mergeRecursiveWithOverrule($globalLanguage, $localLanguage);
276  } else {
277  $globalLanguage = $localLanguage;
278  }
279  // Merge local onto default
280  if ($mergeLocalOntoDefault && $this->lang !== 'default' && is_array($globalLanguage[$this->lang]) && is_array($globalLanguage['default'])) {
281  // array_merge can be used so far the keys are not
282  // numeric - which we assume they are not...
283  $globalLanguage['default'] = array_merge($globalLanguage['default'], $globalLanguage[$this->lang]);
284  unset($globalLanguage[$this->lang]);
285  }
286  }
287  // Return value if not global is set.
288  if (!$setGlobal) {
289  return $globalLanguage;
290  }
291  ‪$GLOBALS['LOCAL_LANG'] = $globalLanguage;
292  return null;
293  }
294 
301  protected function ‪readLLfile($fileRef)
302  {
303  if (isset($this->languageFileCache[$fileRef . $this->lang])) {
304  return $this->languageFileCache[$fileRef . ‪$this->lang];
305  }
306 
308  $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class);
309 
310  if ($this->lang !== 'default') {
311  $languages = array_reverse($this->languageDependencies);
312  } else {
313  $languages = ['default'];
314  }
315  $localLanguage = [];
316  foreach ($languages as $language) {
317  $tempLL = $languageFactory->getParsedData($fileRef, $language);
318  $localLanguage['default'] = $tempLL['default'];
319  if (!isset($localLanguage[$this->lang])) {
320  $localLanguage[‪$this->lang] = $localLanguage['default'];
321  }
322  if ($this->lang !== 'default' && isset($tempLL[$language])) {
323  // Merge current language labels onto labels from previous language
324  // This way we have a labels with fall back applied
325  ‪ArrayUtility::mergeRecursiveWithOverrule($localLanguage[$this->lang], $tempLL[$language], true, false);
326  }
327  }
328  $this->languageFileCache[$fileRef . ‪$this->lang] = $localLanguage;
329 
330  return $localLanguage;
331  }
332 
341  public function ‪getLabelsWithPrefix($prefix, $strip = '')
342  {
343  $extraction = [];
344  $labels = array_merge((array)‪$GLOBALS['LOCAL_LANG']['default'], (array)‪$GLOBALS['LOCAL_LANG'][$this->lang]);
345  // Regular expression to strip the selection prefix and possibly something from the label name:
346  $labelPattern = '#^' . preg_quote($prefix, '#') . '(' . preg_quote($strip, '#') . ')?#';
347  // Iterate through all locallang labels:
348  foreach ($labels as $label => $value) {
349  if (strpos($label, $prefix) === 0) {
350  $key = preg_replace($labelPattern, '', $label);
351  $extraction[$key] = $value;
352  }
353  }
354  return $extraction;
355  }
356 }
‪TYPO3\CMS\Core\Localization\LanguageService\includeLLFile
‪mixed includeLLFile($fileRef, $setGlobal=true, $mergeLocalOntoDefault=false)
Definition: LanguageService.php:260
‪TYPO3\CMS\Core\Localization\LanguageService\$lang
‪string $lang
Definition: LanguageService.php:34
‪TYPO3\CMS\Core\Localization\LanguageService\$languageFileCache
‪array $languageFileCache
Definition: LanguageService.php:65
‪TYPO3\CMS\Core\Localization\LanguageService\__construct
‪__construct()
Definition: LanguageService.php:70
‪TYPO3\CMS\Core\Localization\LanguageService\getLabelsWithPrefix
‪array getLabelsWithPrefix($prefix, $strip='')
Definition: LanguageService.php:335
‪TYPO3\CMS\Core\Localization\LanguageService\$LL_files_cache
‪array $LL_files_cache
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Utility\ArrayUtility\mergeRecursiveWithOverrule
‪static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
Definition: ArrayUtility.php:614
‪TYPO3\CMS\Core\Localization\LanguageService\readLLfile
‪array readLLfile($fileRef)
Definition: LanguageService.php:295
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪string sL($input)
Definition: LanguageService.php:158
‪TYPO3\CMS\Core\Localization
‪TYPO3\CMS\Core\Localization\LanguageService\loadSingleTableDescription
‪loadSingleTableDescription($table)
Definition: LanguageService.php:195
‪TYPO3\CMS\Core\Localization\LanguageService\$debugKey
‪bool $debugKey
Definition: LanguageService.php:40
‪TYPO3\CMS\Core\Localization\LanguageService\getLLL
‪string getLLL($index, $localLanguage)
Definition: LanguageService.php:130
‪TYPO3\CMS\Core\Localization\LanguageService\init
‪init($languageKey)
Definition: LanguageService.php:84
‪TYPO3\CMS\Core\Localization\LanguageService\debugLL
‪string debugLL($value)
Definition: LanguageService.php:106
‪TYPO3\CMS\Core\Localization\LanguageService\$LL_labels_cache
‪array $LL_labels_cache
Definition: LanguageService.php:52
‪$locales
‪$locales
Definition: be_users.php:6
‪$output
‪$output
Definition: annotationChecker.php:113
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:23
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:29
‪TYPO3\CMS\Core\Localization\LanguageService\$languageDependencies
‪array $languageDependencies
Definition: LanguageService.php:59
‪TYPO3\CMS\Core\Localization\LanguageService\getLL
‪string getLL($index)
Definition: LanguageService.php:118
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45