[BUGFIX] Fix loading of registry entries for namespace 08/32608/8
authorFrank Nägler <typo3@naegler.net>
Fri, 5 Sep 2014 19:01:24 +0000 (21:01 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Sun, 7 Sep 2014 18:59:14 +0000 (20:59 +0200)
When calling get(), all entries for the given namespace are loaded only
if no value for this namespace has been set() before in the same run.

This patch fix this by tracking the loading of namespaces and check the
state before set() or get() is processed. In case the namespace was not
loaded before, the loadEntriesByNamespace() is called to prevent
overwrite of values.

Resolves: #53182
Releases: 6.3, 6.2
Change-Id: Ib09e5892e35cef998413d2f0d8039ed49a7e7226
Reviewed-on: http://review.typo3.org/32608
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/core/Classes/Registry.php
typo3/sysext/core/Tests/Unit/RegistryTest.php

index 2adb2c8..c1ddbc2 100644 (file)
@@ -29,11 +29,16 @@ namespace TYPO3\CMS\Core;
 class Registry implements \TYPO3\CMS\Core\SingletonInterface {
 
        /**
-        * @var         array
+        * @var array
         */
        protected $entries = array();
 
        /**
+        * @var array
+        */
+       protected $loadedNamespaces = array();
+
+       /**
         * Returns a persistent entry.
         *
         * @param string $namespace Extension key for extensions starting with 'tx_' / 'Tx_' / 'user_' or 'core' for core registry entries
@@ -43,7 +48,8 @@ class Registry implements \TYPO3\CMS\Core\SingletonInterface {
         * @throws \InvalidArgumentException Throws an exception if the given namespace is not valid
         */
        public function get($namespace, $key, $defaultValue = NULL) {
-               if (!isset($this->entries[$namespace])) {
+               $this->validateNamespace($namespace);
+               if (!$this->isNamespaceLoaded($namespace)) {
                        $this->loadEntriesByNamespace($namespace);
                }
                return isset($this->entries[$namespace][$key]) ? $this->entries[$namespace][$key] : $defaultValue;
@@ -68,6 +74,9 @@ class Registry implements \TYPO3\CMS\Core\SingletonInterface {
         */
        public function set($namespace, $key, $value) {
                $this->validateNamespace($namespace);
+               if (!$this->isNamespaceLoaded($namespace)) {
+                       $this->loadEntriesByNamespace($namespace);
+               }
                $serializedValue = serialize($value);
                $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid', 'sys_registry', 'entry_namespace = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($namespace, 'sys_registry') . ' AND entry_key = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr($key, 'sys_registry'));
                if ($GLOBALS['TYPO3_DB']->sql_num_rows($res) < 1) {
@@ -112,6 +121,17 @@ class Registry implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * check if the given namespace is loaded
+        *
+        * @param string $namespace Namespace. extension key for extensions or 'core' for core registry entries
+        *
+        * @return bool
+        */
+       protected function isNamespaceLoaded($namespace) {
+               return isset($this->loadedNamespaces[$namespace]);
+       }
+
+       /**
         * Loads all entries of the given namespace into the internal $entries cache.
         *
         * @param string $namespace Namespace. extension key for extensions or 'core' for core registry entries
@@ -125,6 +145,7 @@ class Registry implements \TYPO3\CMS\Core\SingletonInterface {
                        $key = $storedEntry['entry_key'];
                        $this->entries[$namespace][$key] = unserialize($storedEntry['entry_value']);
                }
+               $this->loadedNamespaces[$namespace] = TRUE;
        }
 
        /**
index 600704d..23d4eee 100644 (file)
@@ -110,10 +110,11 @@ class RegistryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         * @test
         */
        public function setAllowsValidNamespaces() {
-               $this->registry->set('tx_thisIsValid', 'someKey', 'someValue');
-               $this->registry->set('thisIsValid', 'someKey', 'someValue');
-               $this->registry->set('user_soIsThis', 'someKey', 'someValue');
-               $this->registry->set('core', 'someKey', 'someValue');
+               $registry = $this->getMock('TYPO3\\CMS\\Core\\Registry', array('loadEntriesByNamespace'));
+               $registry->set('tx_thisIsValid', 'someKey', 'someValue');
+               $registry->set('thisIsValid', 'someKey', 'someValue');
+               $registry->set('user_soIsThis', 'someKey', 'someValue');
+               $registry->set('core', 'someKey', 'someValue');
        }
 
        /**
@@ -125,7 +126,8 @@ class RegistryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'entry_key' => 'someKey',
                        'entry_value' => serialize('someValue')
                ));
-               $this->registry->set('tx_phpunit', 'someKey', 'someValue');
+               $registry = $this->getMock('TYPO3\\CMS\\Core\\Registry', array('loadEntriesByNamespace'));
+               $registry->set('tx_phpunit', 'someKey', 'someValue');
        }
 
        /**
@@ -138,17 +140,8 @@ class RegistryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        'entry_value' => serialize('someValue')
                ));
                $GLOBALS['TYPO3_DB']->expects($this->never())->method('exec_INSERTquery');
-               $this->registry->set('tx_phpunit', 'someKey', 'someValue');
-       }
-
-       /**
-        * @test
-        */
-       public function setStoresValueInTheInternalEntriesCache() {
                $registry = $this->getMock('TYPO3\\CMS\\Core\\Registry', array('loadEntriesByNamespace'));
-               $registry->expects($this->never())->method('loadEntriesByNamespace');
                $registry->set('tx_phpunit', 'someKey', 'someValue');
-               $this->assertEquals('someValue', $registry->get('tx_phpunit', 'someKey'), 'The actual data did not match the expected data.');
        }
 
        /**
@@ -211,4 +204,4 @@ class RegistryTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->assertEquals('someValueInOtherNamespace', $registry->get('tx_otherNamespace', 'someKey', 'defaultValue'), 'A value other than the stored value was returned, thus the entry was removed.');
        }
 
-}
+}
\ No newline at end of file