From 81ec05a3fc39845426f302412d53ef6480fc7c3a Mon Sep 17 00:00:00 2001 From: Mathias Schreiber <mathias.schreiber@wmdb.de> Date: Thu, 18 Dec 2014 11:24:21 +0100 Subject: [PATCH] [BUGFIX] Properly handle translation file detection The GeneralUtility::llXmlAutoFileName() method will now also correctly handle paths to files that are not placed within a known directory (ext, sysext, test etc.) if the call is made with $sameFile = TRUE. This allows placing language files in storages like fileadmin. Resolves: #35093 Resolves: #34728 Releases: master, 6.2 Change-Id: Ic5901c3fa98233978abf26db377666dade16f8e6 Reviewed-on: http://review.typo3.org/34285 Reviewed-by: Gernot Ploiner <gp@webprofil.at> Tested-by: Gernot Ploiner <gp@webprofil.at> Reviewed-by: Markus Klein <klein.t3@reelworx.at> Tested-by: Markus Klein <klein.t3@reelworx.at> --- .../Parser/LocallangXmlParser.php | 27 ++++++++++++++----- .../core/Classes/Utility/GeneralUtility.php | 22 ++++++++------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php b/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php index 2d5cff53f3db..c1f3edbc26c4 100644 --- a/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php +++ b/typo3/sysext/core/Classes/Localization/Parser/LocallangXmlParser.php @@ -14,6 +14,9 @@ namespace TYPO3\CMS\Core\Localization\Parser; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Localization\Exception\InvalidXmlFileException; +use TYPO3\CMS\Core\Utility\GeneralUtility; + /** * Parser for XML locallang file. * @@ -43,11 +46,21 @@ class LocallangXmlParser extends AbstractXmlParser { // Parse source $parsedSource = $this->parseXmlFile(); // Parse target - $localizedTargetPath = \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName(\TYPO3\CMS\Core\Utility\GeneralUtility::llXmlAutoFileName($this->sourcePath, $this->languageKey)); - $targetPath = $this->languageKey !== 'default' && @is_file($localizedTargetPath) ? $localizedTargetPath : $this->sourcePath; + $targetPath = $this->sourcePath; + if ($this->languageKey !== 'default') { + $localizedTargetPath = GeneralUtility::getFileAbsFileName(GeneralUtility::llXmlAutoFileName($this->sourcePath, $this->languageKey)); + if (!@is_file($localizedTargetPath)) { + // Global localization is not available, try split localization file + $localizedTargetPath = GeneralUtility::getFileAbsFileName(GeneralUtility::llXmlAutoFileName($this->sourcePath, $this->languageKey, TRUE)); + } + if (!@is_file($localizedTargetPath)) { + $localizedTargetPath = $this->sourcePath; + } + $targetPath = $localizedTargetPath; + } try { $parsedTarget = $this->getParsedTargetData($targetPath); - } catch (\TYPO3\CMS\Core\Localization\Exception\InvalidXmlFileException $e) { + } catch (InvalidXmlFileException $e) { $parsedTarget = $this->getParsedTargetData($this->sourcePath); } $LOCAL_LANG = array(); @@ -59,7 +72,7 @@ class LocallangXmlParser extends AbstractXmlParser { /** * Returns array representation of XLIFF data, starting from a root node. * - * @param SimpleXMLElement $root XML root element + * @param \SimpleXMLElement $root XML root element * @param string $element Target or Source * @return array */ @@ -99,7 +112,7 @@ class LocallangXmlParser extends AbstractXmlParser { // <languageKey index="fr">EXT:yourext/path/to/localized/locallang.xml</languageKey> $reference = sprintf('%s', $bodyOfFileTag); if (substr($reference, -4) === '.xml') { - return $this->getParsedTargetData(\TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName($reference)); + return $this->getParsedTargetData(GeneralUtility::getFileAbsFileName($reference)); } } /** @var \SimpleXMLElement $translationElement */ @@ -154,7 +167,7 @@ class LocallangXmlParser extends AbstractXmlParser { * * @param string $targetPath Path of the target file * @return array - * @throws \TYPO3\CMS\Core\Localization\Exception\InvalidXmlFileException + * @throws InvalidXmlFileException */ protected function parseXmlTargetFile($targetPath) { $rootXmlNode = FALSE; @@ -162,7 +175,7 @@ class LocallangXmlParser extends AbstractXmlParser { $rootXmlNode = simplexml_load_file($targetPath, 'SimpleXmlElement', \LIBXML_NOWARNING); } if (!isset($rootXmlNode) || $rootXmlNode === FALSE) { - throw new \TYPO3\CMS\Core\Localization\Exception\InvalidXmlFileException('The path provided does not point to existing and accessible well-formed XML file (' . $targetPath . ').', 1278155987); + throw new InvalidXmlFileException('The path provided does not point to existing and accessible well-formed XML file (' . $targetPath . ').', 1278155987); } return $this->doParsingTargetFromRoot($rootXmlNode); } diff --git a/typo3/sysext/core/Classes/Utility/GeneralUtility.php b/typo3/sysext/core/Classes/Utility/GeneralUtility.php index 43e3069fe8c0..f662a8a201ca 100755 --- a/typo3/sysext/core/Classes/Utility/GeneralUtility.php +++ b/typo3/sysext/core/Classes/Utility/GeneralUtility.php @@ -3979,18 +3979,24 @@ Connection: close /** * Returns auto-filename for locallang-XML localizations. * - * @param string $fileRef Absolute file reference to locallang-XML file. Must be inside system/global/local extension + * @param string $fileRef Absolute file reference to locallang-XML file. * @param string $language Language key * @param bool $sameLocation if TRUE, then locallang-XML localization file name will be returned with same directory as $fileRef - * @return string Returns the filename reference for the language unless error occurred (or local mode is used) in which case it will be NULL + * @return string Returns the filename reference for the language unless error occurred in which case it will be NULL */ static public function llXmlAutoFileName($fileRef, $language, $sameLocation = FALSE) { + // If $fileRef is already prefixed with "[language key]" then we should return it as this + $fileName = basename($fileRef); + if (self::isFirstPartOfStr($fileName, $language . '.')) { + return $fileRef; + } + if ($sameLocation) { - $location = 'EXT:'; - } else { - // Default location of translations - $location = 'typo3conf/l10n/' . $language . '/'; + return str_replace($fileName, $language . '.' . $fileName, $fileRef); } + + // Default location of translations + $location = 'typo3conf/l10n/' . $language . '/'; // Analyse file reference: // Is system: if (self::isFirstPartOfStr($fileRef, PATH_typo3 . 'sysext/')) { @@ -4017,10 +4023,6 @@ Connection: close } // Add empty first-entry if not there. list($file_extPath, $file_fileName) = $temp; - // If $fileRef is already prefix with "[language key]" then we should return it as this - if (substr($file_fileName, 0, strlen($language) + 1) === $language . '.') { - return $fileRef; - } // The filename is prefixed with "[language key]." because it prevents the llxmltranslate tool from detecting it. return $location . $file_extKey . '/' . ($file_extPath ? $file_extPath . '/' : '') . $language . '.' . $file_fileName; } else { -- GitLab