‪TYPO3CMS  9.5
LocallangXmlParser.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 
21 
27 {
33  protected ‪$parsedTargetFiles;
34 
43  {
44  $this->sourcePath = ‪$sourcePath;
45  $this->languageKey = ‪$languageKey;
46  // Parse source
47  $parsedSource = $this->‪parseXmlFile();
48  // Parse target
49  $localizedTargetPath = $this->‪getLocalizedFileName($this->sourcePath, $this->languageKey);
50  $targetPath = $this->languageKey !== 'default' && @is_file($localizedTargetPath) ? $localizedTargetPath : ‪$this->sourcePath;
51  try {
52  $parsedTarget = $this->‪getParsedTargetData($targetPath);
53  } catch (‪InvalidXmlFileException $e) {
54  $parsedTarget = $this->‪getParsedTargetData($this->sourcePath);
55  }
56  $LOCAL_LANG = [];
57  $LOCAL_LANG[‪$languageKey] = $parsedSource;
59  return $LOCAL_LANG;
60  }
61 
70  protected function ‪doParsingFromRootForElement(\SimpleXMLElement $root, $element)
71  {
72  $bodyOfFileTag = $root->data->languageKey;
73  if ($bodyOfFileTag === null) {
74  throw new ‪InvalidXmlFileException('Invalid locallang.xml language file "' . ‪PathUtility::stripPathSitePrefix($this->sourcePath) . '"', 1487944884);
75  }
76 
77  if ($element === 'source' || $this->languageKey === 'default') {
78  $parsedData = $this->‪getParsedDataForElement($bodyOfFileTag, $element);
79  } else {
80  $parsedData = [];
81  }
82  if ($element === 'target') {
83  // Check if the source llxml file contains localized records
84  $localizedBodyOfFileTag = $root->data->xpath('languageKey[@index=\'' . $this->languageKey . '\']');
85  if (isset($localizedBodyOfFileTag[0]) && $localizedBodyOfFileTag[0] instanceof \SimpleXMLElement) {
86  $parsedDataTarget = $this->getParsedDataForElement($localizedBodyOfFileTag[0], $element);
87  $mergedData = $parsedDataTarget + $parsedData;
88  if ($this->languageKey === 'default') {
89  $parsedData = array_intersect_key($mergedData, $parsedData, $parsedDataTarget);
90  } else {
91  $parsedData = array_intersect_key($mergedData, $parsedDataTarget);
92  }
93  }
94  }
95  return $parsedData;
96  }
97 
105  protected function getParsedDataForElement(\SimpleXMLElement $bodyOfFileTag, $element)
106  {
107  $parsedData = [];
108  $children = $bodyOfFileTag->children();
109  if ($children->count() === 0) {
110  // Check for externally-referenced resource:
111  // <languageKey index="fr">EXT:yourext/path/to/localized/locallang.xml</languageKey>
112  $reference = sprintf('%s', $bodyOfFileTag);
113  if (substr($reference, -4) === '.xml') {
114  return $this->getParsedTargetData(GeneralUtility::getFileAbsFileName($reference));
115  }
116  }
118  foreach ($children as $translationElement) {
119  if ($translationElement->getName() === 'label') {
120  $parsedData[(string)$translationElement['index']][0] = [
121  $element => (string)$translationElement
122  ];
123  }
124  }
125  return $parsedData;
126  }
127 
134  protected function doParsingFromRoot(\SimpleXMLElement $root)
135  {
136  return $this->doParsingFromRootForElement($root, 'source');
137  }
138 
145  protected function doParsingTargetFromRoot(\SimpleXMLElement $root)
146  {
147  return $this->doParsingFromRootForElement($root, 'target');
148  }
149 
158  public function getParsedTargetData($path)
159  {
160  if (!isset($this->parsedTargetFiles[$path])) {
161  $this->parsedTargetFiles[$path] = $this->parseXmlTargetFile($path);
162  }
163  return $this->parsedTargetFiles[$path];
164  }
165 
173  protected function parseXmlTargetFile($targetPath)
174  {
175  $rootXmlNode = false;
176  if (file_exists($targetPath)) {
177  $xmlContent = file_get_contents($targetPath);
178  // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
179  $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
180  $rootXmlNode = simplexml_load_string($xmlContent, 'SimpleXMLElement', LIBXML_NOWARNING);
181  libxml_disable_entity_loader($previousValueOfEntityLoader);
182  }
183  if (!isset($rootXmlNode) || $rootXmlNode === false) {
184  $xmlError = libxml_get_last_error();
185  throw new InvalidXmlFileException(
186  'The path provided does not point to existing and accessible well-formed XML file. Reason: ' . $xmlError->message . ' in ' . $targetPath . ', line ' . $xmlError->line,
187  1278155987
188  );
189  }
190  return $this->doParsingTargetFromRoot($rootXmlNode);
191  }
192 }
‪TYPO3\CMS\Core\Localization\Parser\LocallangXmlParser\getParsedDataForElement
‪array getParsedDataForElement(\SimpleXMLElement $bodyOfFileTag, $element)
Definition: LocallangXmlParser.php:104
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:23
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:371
‪TYPO3\CMS\Core\Localization\Parser\LocallangXmlParser\doParsingFromRootForElement
‪array doParsingFromRootForElement(\SimpleXMLElement $root, $element)
Definition: LocallangXmlParser.php:69
‪TYPO3\CMS\Core\Localization\Parser\LocallangXmlParser\$parsedTargetFiles
‪array $parsedTargetFiles
Definition: LocallangXmlParser.php:32
‪TYPO3\CMS\Core\Localization\Parser\AbstractXmlParser\$sourcePath
‪string $sourcePath
Definition: AbstractXmlParser.php:31
‪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\Parser\AbstractXmlParser\getLocalizedFileName
‪string null getLocalizedFileName($fileRef, $language, $sameLocation=false)
Definition: AbstractXmlParser.php:96
‪TYPO3\CMS\Core\Localization\Parser\AbstractXmlParser
Definition: AbstractXmlParser.php:28
‪TYPO3\CMS\Core\Localization\Parser\LocallangXmlParser\getParsedData
‪array getParsedData($sourcePath, $languageKey)
Definition: LocallangXmlParser.php:41
‪TYPO3\CMS\Core\Localization\Parser\AbstractXmlParser\$languageKey
‪string $languageKey
Definition: AbstractXmlParser.php:35
‪TYPO3\CMS\Core\Utility\ArrayUtility
Definition: ArrayUtility.php:23
‪TYPO3\CMS\Core\Localization\Parser
Definition: AbstractXmlParser.php:2
‪TYPO3\CMS\Core\Localization\Parser\AbstractXmlParser\parseXmlFile
‪array parseXmlFile()
Definition: AbstractXmlParser.php:70
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Localization\Exception\InvalidXmlFileException
Definition: InvalidXmlFileException.php:21
‪TYPO3\CMS\Core\Localization\Parser\LocallangXmlParser
Definition: LocallangXmlParser.php:27
‪TYPO3\CMS\Core\Localization\Parser\LocallangXmlParser\getParsedTargetData
‪array getParsedTargetData($path)
Definition: LocallangXmlParser.php:157