diff --git a/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php b/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php index 3adc246fa94deef19cf56b8cd052628caffa28b4..c70cd961ed50520274a775214a426430e5314d52 100644 --- a/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php +++ b/typo3/sysext/core/Classes/Cache/Backend/FileBackend.php @@ -402,4 +402,27 @@ class FileBackend extends SimpleFileBackend implements FreezableBackendInterface $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; return $this->isCacheFileExpired($pathAndFilename) ? false : require_once $pathAndFilename; } + + /** + * Loads PHP code from the cache and require it right away. + * + * @param string $entryIdentifier An identifier which describes the cache entry to load + * @throws \InvalidArgumentException + * @return mixed Potential return value from the include operation + * @api + */ + public function require(string $entryIdentifier) + { + if ($this->frozen) { + if (isset($this->cacheEntryIdentifiers[$entryIdentifier])) { + return require $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; + } + return false; + } + if ($entryIdentifier !== PathUtility::basename($entryIdentifier)) { + throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1532528246); + } + $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; + return $this->isCacheFileExpired($pathAndFilename) ? false : require $pathAndFilename; + } } diff --git a/typo3/sysext/core/Classes/Cache/Backend/NullBackend.php b/typo3/sysext/core/Classes/Cache/Backend/NullBackend.php index 62cc4c62a3e46f239655248b707de778c3fa95b8..8acc59694076d836c16d6bd1f9201f4a590d0d8c 100644 --- a/typo3/sysext/core/Classes/Cache/Backend/NullBackend.php +++ b/typo3/sysext/core/Classes/Cache/Backend/NullBackend.php @@ -128,4 +128,14 @@ class NullBackend extends AbstractBackend implements PhpCapableBackendInterface, public function requireOnce($identifier) { } + + /** + * Does nothing + * + * @param string $identifier An identifier which describes the cache entry to load + * @api + */ + public function require(string $identifier) + { + } } diff --git a/typo3/sysext/core/Classes/Cache/Backend/PhpCapableBackendInterface.php b/typo3/sysext/core/Classes/Cache/Backend/PhpCapableBackendInterface.php index b71cc2bedf943e77e5265cd35159de70b65b8e7a..c207c1b4e68016d43ddc08a9a0fcd523db65b5b3 100644 --- a/typo3/sysext/core/Classes/Cache/Backend/PhpCapableBackendInterface.php +++ b/typo3/sysext/core/Classes/Cache/Backend/PhpCapableBackendInterface.php @@ -30,4 +30,6 @@ interface PhpCapableBackendInterface extends BackendInterface * @api */ public function requireOnce($entryIdentifier); + + // @todo: Add require() as breaking patch in v10.0 to the interface } diff --git a/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php b/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php index 3c7359122fcc34e035345a9ce3b85f3bae47279b..ea4ff390984ea3caaad2ed7436be5213beafac41 100644 --- a/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php +++ b/typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php @@ -362,4 +362,21 @@ class SimpleFileBackend extends AbstractBackend implements PhpCapableBackendInte } return file_exists($pathAndFilename) ? require_once $pathAndFilename : false; } + + /** + * Loads PHP code from the cache and require it right away. + * + * @param string $entryIdentifier An identifier which describes the cache entry to load + * @return mixed Potential return value from the include operation + * @throws \InvalidArgumentException + * @api + */ + public function require(string $entryIdentifier) + { + $pathAndFilename = $this->cacheDirectory . $entryIdentifier . $this->cacheEntryFileExtension; + if ($entryIdentifier !== PathUtility::basename($entryIdentifier)) { + throw new \InvalidArgumentException('The specified entry identifier must not contain a path segment.', 1532528267); + } + return file_exists($pathAndFilename) ? require $pathAndFilename : false; + } } diff --git a/typo3/sysext/core/Classes/Cache/Frontend/PhpFrontend.php b/typo3/sysext/core/Classes/Cache/Frontend/PhpFrontend.php index 9baebfd54aba54d3d922d04ee876f3520da99d99..ee5b8958cc01170971f975d3f28ec8747a36192e 100644 --- a/typo3/sysext/core/Classes/Cache/Frontend/PhpFrontend.php +++ b/typo3/sysext/core/Classes/Cache/Frontend/PhpFrontend.php @@ -113,4 +113,19 @@ class PhpFrontend extends AbstractFrontend { return $this->backend->requireOnce($entryIdentifier); } + + /** + * Loads PHP code from the cache and require() it right away. Note require() + * in comparison to requireOnce() is only "safe" if the cache entry only contain stuff + * that can be required multiple times during one request. For instance a class definition + * would fail here. + * + * @param string $entryIdentifier An identifier which describes the cache entry to load + * @return mixed Potential return value from the include operation + * @api + */ + public function require(string $entryIdentifier) + { + return $this->backend->require($entryIdentifier); + } } diff --git a/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php b/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php index 8d33e412119975bab2b04a02e3a4254e563bcae2..0163d73d06703765f827c6960259a36b64c98963 100644 --- a/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php +++ b/typo3/sysext/core/Classes/Http/MiddlewareStackResolver.php @@ -64,7 +64,7 @@ class MiddlewareStackResolver // Check if the registered middlewares from all active packages have already been cached $cacheIdentifier = $this->getCacheIdentifier($stackName); if ($this->cache->has($cacheIdentifier)) { - return $this->cache->requireOnce($cacheIdentifier); + return $this->cache->require($cacheIdentifier); } $allMiddlewares = $this->loadConfiguration(); diff --git a/typo3/sysext/core/Classes/Package/PackageManager.php b/typo3/sysext/core/Classes/Package/PackageManager.php index c632c63b850633568f08ddf0ea353576b0faf95c..9df6c56928ad042fef13b729159605f2a4a0e890 100644 --- a/typo3/sysext/core/Classes/Package/PackageManager.php +++ b/typo3/sysext/core/Classes/Package/PackageManager.php @@ -207,7 +207,7 @@ class PackageManager implements SingletonInterface protected function loadPackageManagerStatesFromCache() { $cacheEntryIdentifier = $this->getCacheEntryIdentifier(); - if ($cacheEntryIdentifier === null || !$this->coreCache->has($cacheEntryIdentifier) || !($packageCache = $this->coreCache->requireOnce($cacheEntryIdentifier))) { + if ($cacheEntryIdentifier === null || !$this->coreCache->has($cacheEntryIdentifier) || !($packageCache = $this->coreCache->require($cacheEntryIdentifier))) { throw new Exception\PackageManagerCacheUnavailableException('The package state cache could not be loaded.', 1393883342); } $this->packageStatesConfiguration = $packageCache['packageStatesConfiguration']; diff --git a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php index e2894e8e57c0e275e9a6183b26f04b58b8a9d1ef..c6af44fb453dae525612c679c9f37df8f77fab21 100644 --- a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php +++ b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php @@ -1534,7 +1534,7 @@ tt_content.' . $key . $suffix . ' { /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface */ $codeCache = self::getCacheManager()->getCache('cache_core'); if ($codeCache->has($cacheIdentifier)) { - $codeCache->requireOnce($cacheIdentifier); + $codeCache->require($cacheIdentifier); } else { self::loadSingleExtLocalconfFiles(); self::createExtLocalconfCacheEntry(); @@ -1632,7 +1632,7 @@ tt_content.' . $key . $suffix . ' { $cacheIdentifier = static::getBaseTcaCacheIdentifier(); /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface */ $codeCache = static::getCacheManager()->getCache('cache_core'); - $cacheData = $codeCache->requireOnce($cacheIdentifier); + $cacheData = $codeCache->require($cacheIdentifier); if ($cacheData) { $GLOBALS['TCA'] = $cacheData['tca']; GeneralUtility::setSingletonInstance( @@ -1778,7 +1778,7 @@ tt_content.' . $key . $suffix . ' { /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface */ $codeCache = self::getCacheManager()->getCache('cache_core'); if ($codeCache->has($cacheIdentifier)) { - $codeCache->requireOnce($cacheIdentifier); + $codeCache->require($cacheIdentifier); } else { self::loadSingleExtTablesFiles(); self::createExtTablesCacheEntry(); diff --git a/typo3/sysext/core/Tests/Unit/Cache/Backend/FileBackendTest.php b/typo3/sysext/core/Tests/Unit/Cache/Backend/FileBackendTest.php index 21382e89bb7539beea7ba3b52f2fd8652debc6de..55c706e0e3ee3a318c35eb83264e49eed7c25924 100644 --- a/typo3/sysext/core/Tests/Unit/Cache/Backend/FileBackendTest.php +++ b/typo3/sysext/core/Tests/Unit/Cache/Backend/FileBackendTest.php @@ -694,6 +694,93 @@ class FileBackendTest extends UnitTestCase $this->assertEquals('foo', $loadedData); } + /** + * @test + * @dataProvider invalidEntryIdentifiers + * @param string $identifier + */ + public function requireThrowsExceptionForInvalidIdentifier(string $identifier): void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionCode(1532528246); + $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache')); + + $backend = $this->getMockBuilder(FileBackend::class) + ->setMethods(['dummy']) + ->disableOriginalConstructor() + ->getMock(); + $backend->setCacheDirectory('vfs://Foo/'); + $backend->setCache($mockCache); + + $backend->require($identifier); + } + + /** + * @test + */ + public function requireIncludesAndReturnsResultOfIncludedPhpFile(): void + { + $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache')); + $backend = $this->getMockBuilder(FileBackend::class) + ->setMethods(['dummy']) + ->disableOriginalConstructor() + ->getMock(); + $backend->setCacheDirectory('vfs://Foo/'); + $backend->setCache($mockCache); + + $entryIdentifier = 'SomePhpEntry2'; + + $data = '<?php return "foo2"; ?>'; + $backend->set($entryIdentifier, $data); + + $loadedData = $backend->require($entryIdentifier); + $this->assertEquals('foo2', $loadedData); + } + + /** + * @test + */ + public function requireDoesNotCheckExpiryTimeIfBackendIsFrozen(): void + { + $mockCache = $this->createMock(AbstractFrontend::class); + $mockCache->expects($this->atLeastOnce())->method('getIdentifier')->will($this->returnValue('UnitTestCache')); + $backend = $this->getMockBuilder(FileBackend::class) + ->setMethods(['isCacheFileExpired']) + ->disableOriginalConstructor() + ->getMock(); + $backend->setCacheDirectory('vfs://Foo/'); + $backend->setCache($mockCache); + + $backend->expects($this->once())->method('isCacheFileExpired'); // Indirectly called by freeze() -> get() + + $data = '<?php return "foo"; ?>'; + $backend->set('FooEntry2', $data); + + $backend->freeze(); + + $loadedData = $backend->require('FooEntry2'); + $this->assertEquals('foo', $loadedData); + } + + /** + * @test + */ + public function requireCanLoadSameEntryMultipleTimes(): void + { + $frontendProphecy = $this->prophesize(AbstractFrontend::class); + $frontendProphecy->getIdentifier()->willReturn('UnitTestCache'); + $subject = new FileBackend('Testing'); + $subject->setCacheDirectory('vfs://Foo/'); + $subject->setCache($frontendProphecy->reveal()); + $subject->set('BarEntry', '<?php return "foo"; ?>'); + $loadedData = $subject->require('BarEntry'); + $this->assertEquals('foo', $loadedData); + $loadedData = $subject->require('BarEntry'); + $this->assertEquals('foo', $loadedData); + } + /** * @test * @throws Exception diff --git a/typo3/sysext/core/Tests/Unit/Cache/Frontend/PhpFrontendTest.php b/typo3/sysext/core/Tests/Unit/Cache/Frontend/PhpFrontendTest.php index d1e7f961d4b428ed4a2ff7abcf707022f2cabd2d..3f2618e035570418aef04c0252d7694eaab82584 100644 --- a/typo3/sysext/core/Tests/Unit/Cache/Frontend/PhpFrontendTest.php +++ b/typo3/sysext/core/Tests/Unit/Cache/Frontend/PhpFrontendTest.php @@ -75,4 +75,16 @@ class PhpFrontendTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase $result = $cache->requireOnce('Foo-Bar'); $this->assertSame('hello world!', $result); } + + /** + * @test + */ + public function requireCallsTheBackendsRequireMethod() + { + $mockBackend = $this->createMock(\TYPO3\CMS\Core\Cache\Backend\SimpleFileBackend::class); + $mockBackend->expects($this->once())->method('require')->with('Foo-Bar')->will($this->returnValue('hello world!')); + $cache = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\Frontend\PhpFrontend::class, 'PhpFrontend', $mockBackend); + $result = $cache->require('Foo-Bar'); + $this->assertSame('hello world!', $result); + } } diff --git a/typo3/sysext/core/Tests/Unit/Utility/ExtensionManagementUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/ExtensionManagementUtilityTest.php index 54d2296c1f8e2bd8ba9a06dcf7ad85428dcd56ed..6e1f83cfde1f8c73b9fafaad0116d5098f265fca 100644 --- a/typo3/sysext/core/Tests/Unit/Utility/ExtensionManagementUtilityTest.php +++ b/typo3/sysext/core/Tests/Unit/Utility/ExtensionManagementUtilityTest.php @@ -1216,7 +1216,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase public function loadExtLocalconfRequiresCacheFileIfExistsAndCachingIsAllowed() { $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1227,7 +1227,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache)); ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager); $mockCache->expects($this->any())->method('has')->will($this->returnValue(true)); - $mockCache->expects($this->once())->method('requireOnce'); + $mockCache->expects($this->once())->method('require'); ExtensionManagementUtility::loadExtLocalconf(true); } @@ -1340,7 +1340,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase file_put_contents($extLocalconfLocation, "<?php\n\n" . $uniqueStringInLocalconf . "\n\n?>"); $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager); $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1363,7 +1363,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase $packageManager = $this->createMockPackageManagerWithMockPackage($extensionName); $GLOBALS['TYPO3_LOADED_EXT'] = new LoadedExtensionsArray($packageManager); $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1385,7 +1385,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase public function createExtLocalconfCacheEntryWritesCacheEntryWithNoTags() { $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1439,7 +1439,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase public function loadBaseTcaRequiresCacheFileIfExistsAndCachingIsAllowed() { $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1449,7 +1449,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase ->getMock(); $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache)); ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager); - $mockCache->expects($this->once())->method('requireOnce')->willReturn(['tca' => [], 'categoryRegistry' => \serialize(CategoryRegistry::getInstance())]); + $mockCache->expects($this->once())->method('require')->willReturn(['tca' => [], 'categoryRegistry' => \serialize(CategoryRegistry::getInstance())]); ExtensionManagementUtilityAccessibleProxy::loadBaseTca(true); } @@ -1471,7 +1471,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase $tableConfiguration = '<?php return array(\'foo\' => \'' . $uniqueStringInTableConfiguration . '\'); ?>'; file_put_contents($packagePath . 'Configuration/TCA/' . $uniqueTableName . '.php', $tableConfiguration); $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1481,7 +1481,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase ->getMock(); $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache)); ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager); - $mockCache->expects($this->once())->method('requireOnce')->will($this->returnValue(false)); + $mockCache->expects($this->once())->method('require')->will($this->returnValue(false)); $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->stringContains($uniqueStringInTableConfiguration), $this->anything()); ExtensionManagementUtility::loadBaseTca(true); } @@ -1492,7 +1492,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase public function loadBaseTcaWritesCacheEntryWithNoTags() { $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1502,7 +1502,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase ->getMock(); $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache)); ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager); - $mockCache->expects($this->once())->method('requireOnce')->will($this->returnValue(false)); + $mockCache->expects($this->once())->method('require')->will($this->returnValue(false)); $mockCache->expects($this->once())->method('set')->with($this->anything(), $this->anything(), $this->equalTo([])); ExtensionManagementUtilityAccessibleProxy::loadBaseTca(); } @@ -1547,7 +1547,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase public function loadExtTablesRequiresCacheFileIfExistsAndCachingIsAllowed() { $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1558,7 +1558,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache)); ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager); $mockCache->expects($this->any())->method('has')->will($this->returnValue(true)); - $mockCache->expects($this->once())->method('requireOnce'); + $mockCache->expects($this->once())->method('require'); // Reset the internal cache access tracking variable of extMgm // This method is only in the ProxyClass! ExtensionManagementUtilityAccessibleProxy::resetExtTablesWasReadFromCacheOnceBoolean(); @@ -1584,7 +1584,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase ] ]; $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1608,7 +1608,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase $extensionName => [], ]; $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); @@ -1630,7 +1630,7 @@ class ExtensionManagementUtilityTest extends UnitTestCase public function createExtTablesCacheEntryWritesCacheEntryWithNoTags() { $mockCache = $this->getMockBuilder(PhpFrontend::class) - ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce']) + ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'require']) ->disableOriginalConstructor() ->getMock(); diff --git a/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php b/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php index 50c9e324089982b0da68da5d469123eff46315d6..e6b647be61b798baa1935acf53c265199c8d2002 100644 --- a/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php +++ b/typo3/sysext/lowlevel/Classes/Controller/ConfigurationController.php @@ -21,8 +21,7 @@ use TYPO3\CMS\Backend\Configuration\SiteTcaConfiguration; use TYPO3\CMS\Backend\Routing\Router; use TYPO3\CMS\Backend\Template\ModuleTemplate; use TYPO3\CMS\Core\Authentication\BackendUserAuthentication; -use TYPO3\CMS\Core\Cache\Backend\NullBackend; -use TYPO3\CMS\Core\Cache\Frontend\PhpFrontend; +use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\MiddlewareStackResolver; use TYPO3\CMS\Core\Localization\LanguageService; @@ -225,18 +224,11 @@ class ConfigurationController } elseif ($selectedTreeDetails['type'] === 'httpMiddlewareStacks') { // Keep the order of the keys $sortKeysByName = false; - // Fake a PHP frontend with a null backend to avoid PHP Opcache conflicts - // When using >requireOnce() multiple times in one request - $cache = GeneralUtility::makeInstance( - PhpFrontend::class, - 'middleware', - GeneralUtility::makeInstance(NullBackend::class, 'Production') - ); $stackResolver = GeneralUtility::makeInstance( MiddlewareStackResolver::class, GeneralUtility::makeInstance(PackageManager::class), GeneralUtility::makeInstance(DependencyOrderingService::class), - $cache + GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_core') ); $renderArray = []; foreach (['frontend', 'backend'] as $stackName) {