From 534e7cf79a8ba25730420da54c156ca7d0935540 Mon Sep 17 00:00:00 2001
From: Markus Klein <markus.klein@typo3.org>
Date: Tue, 5 May 2020 13:33:19 +0200
Subject: [PATCH] [BUGFIX] Fix handling of deprecated cache configuration

When initializing the configuration for a cache any existing
configuration under its old name (cache_ prefixed) is applied
as an additive override now. This ensures that basic configuration
like groups are preserved and not removed with the formerly correct
way to adjust cache-config.

Resolves: #91306
Releases: master
Change-Id: Ic862f80263f410688d2dffb7c13948c1c40488a3
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64407
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Johannes Kasberger <johannes.kasberger@reelworx.at>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: Johannes Kasberger <johannes.kasberger@reelworx.at>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
---
 .../core/Classes/Cache/CacheManager.php       |  7 +++-
 .../Tests/Unit/Cache/CacheManagerTest.php     | 41 +++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/typo3/sysext/core/Classes/Cache/CacheManager.php b/typo3/sysext/core/Classes/Cache/CacheManager.php
index 62ed306d186f..0272037848de 100644
--- a/typo3/sysext/core/Classes/Cache/CacheManager.php
+++ b/typo3/sysext/core/Classes/Cache/CacheManager.php
@@ -93,6 +93,8 @@ class CacheManager implements SingletonInterface
      */
     public function setCacheConfigurations(array $cacheConfigurations)
     {
+        $newConfiguration = [];
+        $migratedConfiguration = [];
         foreach ($cacheConfigurations as $identifier => $configuration) {
             if (!is_array($configuration)) {
                 throw new \InvalidArgumentException('The cache configuration for cache "' . $identifier . '" was not an array as expected.', 1231259656);
@@ -101,9 +103,12 @@ class CacheManager implements SingletonInterface
             if (strpos($identifier, 'cache_') === 0) {
                 trigger_error('Accessing a cache with the "cache_" prefix as in "' . $identifier . '" is not necessary anymore, and should be called without the cache prefix.', E_USER_DEPRECATED);
                 $identifier = substr($identifier, 6);
+                $migratedConfiguration[$identifier] = $configuration;
+            } else {
+                $newConfiguration[$identifier] = $configuration;
             }
-            $this->cacheConfigurations[$identifier] = $configuration;
         }
+        $this->cacheConfigurations = array_replace_recursive($newConfiguration, $migratedConfiguration);
     }
 
     /**
diff --git a/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php b/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php
index 6806e52e96dc..e2ae47958f84 100644
--- a/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php
+++ b/typo3/sysext/core/Tests/Unit/Cache/CacheManagerTest.php
@@ -496,4 +496,45 @@ class CacheManagerTest extends UnitTestCase
         $manager->setCacheConfigurations($configuration);
         $manager->flushCachesInGroupByTags('group2', $tags);
     }
+
+    /**
+     * @test
+     */
+    public function setCacheConfigurationsMergesLegacyConfigCorrectly()
+    {
+        $rawConfiguration = [
+            'pages' => [
+                'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
+                'backend' => \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class,
+                'options' => [
+                    'compression' => true,
+                ],
+                'groups' => ['pages'],
+            ],
+            'cache_pages' => [
+                'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
+                'options' => [
+                    'hostname' => 'redis',
+                ],
+                'groups' => ['pages'],
+            ],
+        ];
+        $expectedConfiguration = [
+            'pages' => [
+                'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class,
+                'backend' => \TYPO3\CMS\Core\Cache\Backend\RedisBackend::class,
+                'options' => [
+                    'compression' => true,
+                    'hostname' => 'redis',
+                ],
+                'groups' => ['pages']
+            ],
+        ];
+        $this->expectDeprecation();
+
+        /** @var \PHPUnit\Framework\MockObject\MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface|CacheManager $manager */
+        $manager = $this->getAccessibleMock(CacheManager::class, ['dummy']);
+        $manager->setCacheConfigurations($rawConfiguration);
+        self::assertEquals($expectedConfiguration, $manager->_get('cacheConfigurations'));
+    }
 }
-- 
GitLab