[BUGFIX] Assure language override without original file 24/37524/5
authorStefan Galinski <stefan@sgalinski.de>
Wed, 4 Mar 2015 14:50:20 +0000 (15:50 +0100)
committerMarkus Klein <markus.klein@typo3.org>
Mon, 17 Aug 2015 22:16:50 +0000 (00:16 +0200)
The language override of language files is currently broken,
because it only works if a localized language file already
exists inside the extension or l10n directory. This patch assures
that the language override takes place even if no file could
be found in the first place.

Resolves: #65513
Releases: master, 6.2
Change-Id: I9269e60c5788c435b06b820c459fd4f077d066ea
Reviewed-on: http://review.typo3.org/37524
Reviewed-by: Daniel Goerz <ervaude@gmail.com>
Reviewed-by: Daniel Maier <dani-maier@gmx.de>
Reviewed-by: Alexander Opitz <opitz.alexander@googlemail.com>
Tested-by: Alexander Opitz <opitz.alexander@googlemail.com>
Reviewed-by: Stefan Galinski <stefan.galinski@gmail.com>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/core/Classes/Localization/LocalizationFactory.php
typo3/sysext/core/Tests/Unit/Localization/LocalizationFactoryTest.php

index 3620588..ddc7014 100644 (file)
@@ -15,7 +15,6 @@ namespace TYPO3\CMS\Core\Localization;
  */
 
 use TYPO3\CMS\Core\Cache\CacheManager;
-use TYPO3\CMS\Core\Localization\Exception\FileNotFoundException;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -94,42 +93,48 @@ class LocalizationFactory implements \TYPO3\CMS\Core\SingletonInterface {
                        $fileReference = 'EXT:' . $mapping[$filePath];
                }
 
-               try {
-                       $hash = md5($fileReference . $languageKey . $charset);
-                       $this->errorMode = $errorMode;
-                       // Check if the default language is processed before processing other language
-                       if (!$this->store->hasData($fileReference, 'default') && $languageKey !== 'default') {
-                               $this->getParsedData($fileReference, 'default', $charset, $this->errorMode);
-                       }
-                       // If the content is parsed (local cache), use it
-                       if ($this->store->hasData($fileReference, $languageKey)) {
-                               return $this->store->getData($fileReference);
-                       }
+               $hash = md5($fileReference . $languageKey . $charset);
+               $this->errorMode = $errorMode;
 
-                       // If the content is in cache (system cache), use it
-                       $data = $this->cacheInstance->get($hash);
-                       if ($data !== FALSE) {
-                               $this->store->setData($fileReference, $languageKey, $data);
-                               return $this->store->getData($fileReference, $languageKey);
-                       }
+               // Check if the default language is processed before processing other language
+               if (!$this->store->hasData($fileReference, 'default') && $languageKey !== 'default') {
+                       $this->getParsedData($fileReference, 'default', $charset, $this->errorMode);
+               }
+               // If the content is parsed (local cache), use it
+               if ($this->store->hasData($fileReference, $languageKey)) {
+                       return $this->store->getData($fileReference);
+               }
+
+               // If the content is in cache (system cache), use it
+               $data = $this->cacheInstance->get($hash);
+               if ($data !== FALSE) {
+                       $this->store->setData($fileReference, $languageKey, $data);
+                       return $this->store->getData($fileReference);
+               }
 
+               try {
                        $this->store->setConfiguration($fileReference, $languageKey, $charset);
                        /** @var $parser \TYPO3\CMS\Core\Localization\Parser\LocalizationParserInterface */
                        $parser = $this->store->getParserInstance($fileReference);
                        // Get parsed data
                        $LOCAL_LANG = $parser->getParsedData($this->store->getAbsoluteFileReference($fileReference), $languageKey, $charset);
-                       // Override localization
-                       if (!$isLocalizationOverride && isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'])) {
-                               $this->localizationOverride($fileReference, $languageKey, $charset, $errorMode, $LOCAL_LANG);
-                       }
-                       // Save parsed data in cache
-                       $this->store->setData($fileReference, $languageKey, $LOCAL_LANG[$languageKey]);
-                       // Cache processed data
-                       $this->cacheInstance->set($hash, $this->store->getDataByLanguage($fileReference, $languageKey));
-               } catch (FileNotFoundException $exception) {
-                       // Source localization file not found
+               } catch (Exception\FileNotFoundException $exception) {
+                       // Source localization file not found, set empty data as there could be an override
                        $this->store->setData($fileReference, $languageKey, array());
+                       $LOCAL_LANG = $this->store->getData($fileReference);
+               }
+
+               // Override localization
+               if (!$isLocalizationOverride && isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'])) {
+                       $this->localizationOverride($fileReference, $languageKey, $charset, $errorMode, $LOCAL_LANG);
                }
+
+               // Save parsed data in cache
+               $this->store->setData($fileReference, $languageKey, $LOCAL_LANG[$languageKey]);
+
+               // Cache processed data
+               $this->cacheInstance->set($hash, $this->store->getDataByLanguage($fileReference, $languageKey));
+
                return $this->store->getData($fileReference);
        }
 
index 2acc0d0..dbd037e 100644 (file)
@@ -60,4 +60,24 @@ class LocalizationFactoryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->assertEquals($overrideLL['default']['buttons.logout'][0]['target'], 'EXIT');
        }
 
+       /**
+        * @test
+        */
+       public function getParsedDataCallsLocalizationOverrideIfFileNotFoundExceptionIsThrown() {
+               /** @var $subject LocalizationFactory */
+               $localizationFactory = $this->getAccessibleMock(LocalizationFactory::class, array('localizationOverride'));
+               $languageStore = $this->getMock(\TYPO3\CMS\Core\Localization\LanguageStore::class, array('hasData', 'setConfiguration', 'getData', 'setData'));
+               $cacheInstance = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\StringFrontend::class, array('get', 'set'), array(), '', FALSE);
+               $localizationFactory->_set('store', $languageStore);
+               $localizationFactory->_set('cacheInstance', $cacheInstance);
+               $languageStore->method('hasData')->willReturn(FALSE);
+               $languageStore->method('getData')->willReturn(array());
+               $languageStore->method('setConfiguration')->willThrowException(new \TYPO3\CMS\Core\Localization\Exception\FileNotFoundException());
+               $cacheInstance->method('get')->willReturn(FALSE);
+               $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride'] = array('foo' => 'bar');
+
+               $localizationFactory->expects($this->once())->method('localizationOverride');
+               $localizationFactory->getParsedData('EXT:backend/Resources/Private/Language/locallang_layout.xlf', 'default');
+       }
+
 }