[BUGFIX] Allow multiple calls of ExtensionManagementUtility::loadBaseTca 01/54201/2
authorNicole Cordes <typo3@cordes.co>
Thu, 21 Sep 2017 19:17:55 +0000 (21:17 +0200)
committerHelmut Hummel <typo3@helhum.io>
Thu, 21 Sep 2017 20:29:53 +0000 (22:29 +0200)
Although the function itself is marked as private, it can be triggered
twice due to official API in EidUtility::initTCA. As requireOnce returns
true if called multiple times with the same file, this return state has
to be handled as well.

Resolves: #82539
Related: #82408
Releases: 8.7
Change-Id: I1acd519c342e525c06eda44289acdf86c508a898
Reviewed-on: https://review.typo3.org/54201
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Faton Haliti <fha@systime.dk>
Tested-by: Faton Haliti <fha@systime.dk>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Helmut Hummel <typo3@helhum.io>
Tested-by: Helmut Hummel <typo3@helhum.io>
typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
typo3/sysext/core/Tests/Unit/Utility/ExtensionManagementUtilityTest.php

index b00e327..628eb54 100644 (file)
@@ -1688,7 +1688,11 @@ tt_content.' . $key . $suffix . ' {
             /** @var $codeCache \TYPO3\CMS\Core\Cache\Frontend\PhpFrontend */
             $codeCache = static::getCacheManager()->getCache('cache_core');
             $cacheData = $codeCache->requireOnce($cacheIdentifier);
-            if ($cacheData) {
+            if ($cacheData === true) {
+                // requireOnce returns true if the file was already required before. Thus TCA is already loaded.
+                return;
+            }
+            if (is_array($cacheData)) {
                 $GLOBALS['TCA'] = $cacheData['tca'];
                 GeneralUtility::setSingletonInstance(
                     CategoryRegistry::class,
index bf15c4c..28799b7 100644 (file)
@@ -24,6 +24,7 @@ use TYPO3\CMS\Core\Package\PackageManager;
 use TYPO3\CMS\Core\Tests\Unit\Utility\AccessibleProxies\ExtensionManagementUtilityAccessibleProxy;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Frontend\Utility\EidUtility;
 
 /**
  * Test case
@@ -1576,6 +1577,37 @@ class ExtensionManagementUtilityTest extends \TYPO3\TestingFramework\Core\Unit\U
         ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
     }
 
+    /**
+     * @test
+     */
+    public function loadBaseTcaCanBeCalledMultipleTimesWithoutError()
+    {
+        $tcaCache = [
+            'tca' => [
+                'pages' => [],
+            ],
+            'categoryRegistry' => serialize(new CategoryRegistry()),
+        ];
+        $mockCache = $this->getMockBuilder(PhpFrontend::class)
+            ->setMethods(['getIdentifier', 'set', 'get', 'getByTag', 'has', 'remove', 'flush', 'flushByTag', 'requireOnce'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $mockCache->expects($this->at(0))->method('requireOnce')->willReturn($tcaCache);
+        $mockCache->expects($this->at(1))->method('requireOnce')->willReturn(true);
+
+        /** @var CacheManager|\PHPUnit_Framework_MockObject_MockObject $mockCacheManager */
+        $mockCacheManager = $this->getMockBuilder(CacheManager::class)
+            ->setMethods(['getCache'])
+            ->getMock();
+        $mockCacheManager->expects($this->any())->method('getCache')->will($this->returnValue($mockCache));
+        ExtensionManagementUtilityAccessibleProxy::setCacheManager($mockCacheManager);
+
+        EidUtility::initTCA();
+        ExtensionManagementUtilityAccessibleProxy::loadBaseTca();
+
+        $this->assertSame($tcaCache['tca'], $GLOBALS['TCA']);
+    }
+
     /////////////////////////////////////////
     // Tests concerning getBaseTcaCacheIdentifier
     /////////////////////////////////////////