[BUGFIX] Wrong nested extension configuration handling
authorOliver Hader <oliver@typo3.org>
Sun, 19 Aug 2012 10:33:54 +0000 (12:33 +0200)
committerSusanne Moog <typo3@susannemoog.de>
Sun, 19 Aug 2012 11:03:25 +0000 (13:03 +0200)
Nested default configurations and specific system configuration
of an extension are not merged correctly. This affects reading
configuration properties and persisting them.

Change-Id: I3a68a5acfb380236e644dd42de78619cc2e605a1
Fixes: #39952
Releases: 6.0
Reviewed-on: http://review.typo3.org/13911
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Susanne Moog
Tested-by: Susanne Moog
typo3/sysext/extensionmanager/Classes/Controller/ConfigurationController.php
typo3/sysext/extensionmanager/Classes/Domain/Repository/ConfigurationItemRepository.php
typo3/sysext/extensionmanager/Classes/Utility/Configuration.php
typo3/sysext/extensionmanager/Tests/Repository/ConfigurationItemRepositoryTest.php
typo3/sysext/extensionmanager/Tests/Utility/ConfigurationTest.php [new file with mode: 0644]

index 5804f12..39c7a3a 100644 (file)
@@ -79,12 +79,10 @@ class Tx_Extensionmanager_Controller_ConfigurationController extends Tx_Extensio
                $currentFullConfiguration = $configurationUtility->getCurrentConfiguration($extensionKey);
                $newConfiguration = t3lib_div::array_merge_recursive_overrule($currentFullConfiguration, $config);
 
-               $strippedConfiguration = array();
-               foreach ($newConfiguration as $configurationKey => $configurationValue) {
-                       $strippedConfiguration[$configurationKey]['value'] = $configurationValue['value'];
-               }
-
-               $configurationUtility->writeConfiguration($strippedConfiguration, $extensionKey);
+               $configurationUtility->writeConfiguration(
+                       $configurationUtility->convertValuedToNestedConfiguration($newConfiguration),
+                       $extensionKey
+               );
                $this->redirect('showConfigurationForm', NULL, NULL, array('extension' => array('key' => $extensionKey)));
        }
 
index a88cf33..1885bee 100644 (file)
@@ -211,9 +211,17 @@ class Tx_Extensionmanager_Domain_Repository_ConfigurationItemRepository {
         */
        protected function mergeWithExistingConfiguration(array $configuration, array $extension) {
                $currentExtensionConfig = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][$extension['key']]);
+               $flatExtensionConfig = t3lib_utility_Array::flatten($currentExtensionConfig);
+               $valuedCurrentExtensionConfig = array();
+
+               foreach ($flatExtensionConfig as $key => $value) {
+                       $valuedCurrentExtensionConfig[$key]['value'] = $value;
+               }
+
                if (is_array($currentExtensionConfig)) {
-                       $configuration =  t3lib_div::array_merge_recursive_overrule($configuration, $currentExtensionConfig);
+                       $configuration =  t3lib_div::array_merge_recursive_overrule($configuration, $valuedCurrentExtensionConfig);
                }
+
                return $configuration;
        }
 
index 94640c0..8a97013 100644 (file)
@@ -104,5 +104,26 @@ class Tx_Extensionmanager_Utility_Configuration implements t3lib_Singleton {
 
                return $currentFullConfiguration;
        }
+
+       /**
+        * Converts a valued configuration to a nested configuration.
+        *
+        * array('first.second' => array('value' => 1))
+        * will become
+        * array('first.' => array('second' => ))
+        *
+        * @param array $valuedConfiguration
+        * @return array
+        */
+       public function convertValuedToNestedConfiguration(array $valuedConfiguration) {
+               $nestedConfiguration = array();
+
+               foreach ($valuedConfiguration as $name => $section) {
+                       $path = str_replace('.', './', $name);
+                       $nestedConfiguration = t3lib_utility_Array::setValueByPath($nestedConfiguration, $path, $section['value'], '/');
+               }
+
+               return $nestedConfiguration;
+       }
 }
 ?>
\ No newline at end of file
index d8477a8..0fff3ab 100644 (file)
@@ -204,26 +204,34 @@ class Tx_Extensionmanager_Repository_ConfigurationItemRepositoryTest extends Tx_
                        )
                ));
                $defaultConfiguration = array(
-                       'FE.' => array(
-                               'enabled' => '0',
-                               'saltedPWHashingMethod' => 'tx_saltedpasswords_salts_md5',
+                       'FE.enabled' => array(
+                               'value' => '0',
                        ),
-                       'BE.' => array(
-                               'enabled' => '1',
-                               'saltedPWHashingMethod' => 'tx_saltedpasswords_salts_md5',
+                       'FE.saltedPWHashingMethod' => array(
+                               'value' => 'tx_saltedpasswords_salts_md5',
+                       ),
+                       'BE.enabled' => array(
+                               'value' => '1',
+                       ),
+                       'BE.saltedPWHashingMethod' => array(
+                               'value' => 'tx_saltedpasswords_salts_md5',
                        ),
                );
                $expectedResult = array(
-                       'FE.' => array(
-                               'enabled' => '1',
-                               'saltedPWHashingMethod' => 'tx_saltedpasswords_salts_sha1',
+                       'FE.enabled' => array(
+                               'value' => '1',
                        ),
-                       'BE.' => array(
-                               'enabled' => '1',
-                               'saltedPWHashingMethod' => 'tx_saltedpasswords_salts_md5',
+                       'FE.saltedPWHashingMethod' => array(
+                               'value' => 'tx_saltedpasswords_salts_sha1',
                        ),
-                       'CLI.' => array(
-                               'enabled' => '0',
+                       'BE.enabled' => array(
+                               'value' => '1',
+                       ),
+                       'BE.saltedPWHashingMethod' => array(
+                               'value' => 'tx_saltedpasswords_salts_md5',
+                       ),
+                       'CLI.enabled' => array(
+                               'value' => '0',
                        )
                );
                $result = $this->configurationItemRepository->mergeWithExistingConfiguration(
diff --git a/typo3/sysext/extensionmanager/Tests/Utility/ConfigurationTest.php b/typo3/sysext/extensionmanager/Tests/Utility/ConfigurationTest.php
new file mode 100644 (file)
index 0000000..941a4c6
--- /dev/null
@@ -0,0 +1,132 @@
+<?php
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2012 Oliver Hader <oliver.hader@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ *
+ * This script is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Testcase for the Tx_Extensionmanager_Utility_Configuration class in the TYPO3 Core.
+ *
+ * @package Extension Manager
+ * @subpackage Tests
+ */
+class Tx_Extensionmanager_Utility_ConfigurationTest extends Tx_Extbase_Tests_Unit_BaseTestCase {
+       /**
+        * @param array $configuration
+        * @param array $expected
+        * @dataProvider convertValuedToNestedConfigurationDataProvider
+        * @test
+        */
+       public function convertValuedToNestedConfiguration(array $configuration, array $expected) {
+               /** @var $fixture Tx_Extensionmanager_Utility_Configuration */
+               $fixture = $this->objectManager->get('Tx_Extensionmanager_Utility_Configuration');
+
+               $this->assertEquals(
+                       $expected,
+                       $fixture->convertValuedToNestedConfiguration($configuration)
+               );
+       }
+
+       /**
+        * @return array
+        */
+       public function convertValuedToNestedConfigurationDataProvider() {
+               return array(
+                       'plain array' => array(
+                               array(
+                                       'first' => array(
+                                               'value' => 'value1',
+                                       ),
+                                       'second' => array(
+                                               'value' => 'value2',
+                                       ),
+                               ),
+                               array(
+                                       'first' => 'value1',
+                                       'second' => 'value2',
+                               ),
+                       ),
+                       'nested value with 2 levels' => array(
+                               array(
+                                       'first.firstSub' => array(
+                                               'value' => 'value1',
+                                       ),
+                                       'second.secondSub' => array(
+                                               'value' => 'value2',
+                                       ),
+                               ),
+                               array(
+                                       'first.' => array(
+                                               'firstSub' => 'value1',
+                                       ),
+                                       'second.' => array(
+                                               'secondSub' => 'value2',
+                                       ),
+                               ),
+                       ),
+                       'nested value with 3 levels' => array(
+                               array(
+                                       'first.firstSub.firstSubSub' => array(
+                                               'value' => 'value1',
+                                       ),
+                                       'second.secondSub.secondSubSub' => array(
+                                               'value' => 'value2',
+                                       ),
+                               ),
+                               array(
+                                       'first.' => array(
+                                               'firstSub.' => array(
+                                                       'firstSubSub' => 'value1',
+                                               ),
+                                       ),
+                                       'second.' => array(
+                                               'secondSub.' => array(
+                                                       'secondSubSub' => 'value2',
+                                               ),
+                                       ),
+                               ),
+                       ),
+                       'mixed nested value with 2 levels' => array(
+                               array(
+                                       'first' => array(
+                                               'value' => 'firstValue',
+                                       ),
+                                       'first.firstSub' => array(
+                                               'value' => 'value1',
+                                       ),
+                                       'second.secondSub' => array(
+                                               'value' => 'value2',
+                                       ),
+                               ),
+                               array(
+                                       'first' => 'firstValue',
+                                       'first.' => array(
+                                               'firstSub' => 'value1',
+                                       ),
+                                       'second.' => array(
+                                               'secondSub' => 'value2',
+                                       ),
+                               ),
+                       ),
+               );
+       }
+}
+?>
\ No newline at end of file