[BUGFIX] Clearing label through TS doesn't work
authorMarkus Klein <klein.t3@mfc-linz.at>
Fri, 5 Apr 2013 19:03:05 +0000 (21:03 +0200)
committerStefan Neufeind <typo3.neufeind@speedpartner.de>
Sat, 13 Apr 2013 18:32:34 +0000 (20:32 +0200)
Overriding labels of non-default languages using TypoScript
fails if the value is empty.
The problem is that we cannot distinguish between missing translations
and labels cleared by TypoScript.
(In both cases ['target'] === "")

Fixes: #43959
Releases: 6.1, 6.0, 4.7, 4.6
Change-Id: I06697d44a5e4621f8bf45feb5fd3551705af8a2b
Reviewed-on: https://review.typo3.org/19619
Reviewed-by: Anja Leichsenring
Tested-by: Anja Leichsenring
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Stefan Neufeind
Tested-by: Stefan Neufeind
typo3/sysext/extbase/Classes/Utility/LocalizationUtility.php
typo3/sysext/extbase/Tests/Unit/Utility/LocalizationUtilityTest.php

index 77db27d..11ac739 100644 (file)
@@ -42,14 +42,24 @@ class LocalizationUtility {
        /**
         * Local Language content
         *
-        * @var string
+        * @var array
         */
        static protected $LOCAL_LANG = array();
 
        /**
+        * Contains those LL keys, which have been set to (empty) in TypoScript.
+        * This is necessary, as we cannot distinguish between a nonexisting
+        * translation and a label that has been cleared by TS.
+        * In both cases ['key'][0]['target'] is "".
+        *
+        * @var array
+        */
+       static protected $LOCAL_LANG_UNSET = array();
+
+       /**
         * Local Language content charset for individual labels (overriding)
         *
-        * @var string
+        * @var array
         */
        static protected $LOCAL_LANG_charset = array();
 
@@ -84,7 +94,9 @@ class LocalizationUtility {
                } else {
                        self::initializeLocalization($extensionName);
                        // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG
-                       if (!empty(self::$LOCAL_LANG[$extensionName][self::$languageKey][$key][0]['target'])) {
+                       if (!empty(self::$LOCAL_LANG[$extensionName][self::$languageKey][$key][0]['target'])
+                               || isset(self::$LOCAL_LANG_UNSET[$extensionName][self::$languageKey][$key])
+                       ) {
                                // Local language translation for key exists
                                $value = self::$LOCAL_LANG[$extensionName][self::$languageKey][$key][0]['target'];
                                if (!empty(self::$LOCAL_LANG_charset[$extensionName][self::$languageKey][$key])) {
@@ -93,7 +105,9 @@ class LocalizationUtility {
                        } elseif (count(self::$alternativeLanguageKeys)) {
                                $languages = array_reverse(self::$alternativeLanguageKeys);
                                foreach ($languages as $language) {
-                                       if (!empty(self::$LOCAL_LANG[$extensionName][$language][$key][0]['target'])) {
+                                       if (!empty(self::$LOCAL_LANG[$extensionName][$language][$key][0]['target'])
+                                               || isset(self::$LOCAL_LANG_UNSET[$extensionName][$language][$key])
+                                       ) {
                                                // Alternative language translation for key exists
                                                $value = self::$LOCAL_LANG[$extensionName][$language][$key][0]['target'];
                                                if (!empty(self::$LOCAL_LANG_charset[$extensionName][$language][$key])) {
@@ -103,7 +117,9 @@ class LocalizationUtility {
                                        }
                                }
                        }
-                       if ($value === NULL && !empty(self::$LOCAL_LANG[$extensionName]['default'][$key][0]['target'])) {
+                       if ($value === NULL && (!empty(self::$LOCAL_LANG[$extensionName]['default'][$key][0]['target'])
+                               || isset(self::$LOCAL_LANG_UNSET[$extensionName]['default'][$key]))
+                       ) {
                                // Default language translation for key exists
                                // No charset conversion because default is English and thereby ASCII
                                $value = self::$LOCAL_LANG[$extensionName]['default'][$key][0]['target'];
@@ -203,6 +219,7 @@ class LocalizationUtility {
                if (!is_array($frameworkConfiguration['_LOCAL_LANG'])) {
                        return;
                }
+               self::$LOCAL_LANG_UNSET[$extensionName] = array();
                foreach ($frameworkConfiguration['_LOCAL_LANG'] as $languageKey => $labels) {
                        if (!(is_array($labels) && isset(self::$LOCAL_LANG[$extensionName][$languageKey]))) {
                                continue;
@@ -210,6 +227,9 @@ class LocalizationUtility {
                        foreach ($labels as $labelKey => $labelValue) {
                                if (is_string($labelValue)) {
                                        self::$LOCAL_LANG[$extensionName][$languageKey][$labelKey][0]['target'] = $labelValue;
+                                       if ($labelValue === '') {
+                                               self::$LOCAL_LANG_UNSET[$extensionName][$languageKey][$labelKey] = '';
+                                       }
                                        if (is_object($GLOBALS['LANG'])) {
                                                self::$LOCAL_LANG_charset[$extensionName][$languageKey][$labelKey] = $GLOBALS['LANG']->csConvObj->charSetArray[$languageKey];
                                        } else {
@@ -219,6 +239,9 @@ class LocalizationUtility {
                                        $labelValue = self::flattenTypoScriptLabelArray($labelValue, $labelKey);
                                        foreach ($labelValue as $key => $value) {
                                                self::$LOCAL_LANG[$extensionName][$languageKey][$key][0]['target'] = $value;
+                                               if ($value === '') {
+                                                       self::$LOCAL_LANG_UNSET[$extensionName][$languageKey][$key] = '';
+                                               }
                                        }
                                }
                        }
index eaef253..c379cdb 100644 (file)
@@ -369,6 +369,35 @@ class LocalizationUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase
                $result = $this->localization->_getStatic('LOCAL_LANG');
                $this->assertEquals($expected, $result['extensionKey'][$languageKey]);
        }
+
+       /**
+        * @return void
+        * @test
+        */
+       public function clearLabelWithTypoScript() {
+               $this->localization->_setStatic('LOCAL_LANG', $this->LOCAL_LANG);
+               $this->localization->_setStatic('languageKey', 'dk');
+
+               $typoScriptLocalLang = array(
+                       '_LOCAL_LANG' => array(
+                               'dk' => array(
+                                       'key1' => '',
+                               )
+                       )
+               );
+
+               $configurationType = \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK;
+
+               $configurationManager = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager', array('getConfiguration'));
+               $configurationManager->expects($this->at(0))->method('getConfiguration')->with($configurationType, 'extensionKey', NULL)->will($this->returnValue($typoScriptLocalLang));
+
+               $this->localization->staticExpects($this->atLeastOnce())->method('getConfigurationManager')->will($this->returnValue($configurationManager));
+
+               $this->localization->_call('loadTypoScriptLabels', 'extensionKey');
+               $result = $this->localization->translate('key1', 'extensionKey');
+               $this->assertNotNull($result);
+               $this->assertEquals('', $result);
+       }
 }
 
 ?>
\ No newline at end of file