Commit 7e9f22b7 authored by Christian Kuhn's avatar Christian Kuhn Committed by Andreas Fernandez
Browse files

[TASK] Remove static method variables

Static method variables are even more pita than static class
variables, especially if their state is created from db rows
or path information: It is nearly impossible to get rid of
this state at a later point again, even reflection does not
help here.

The patch abandons all 'static $foo' method variables from
the system, using these strategies:

* Remove some entirely which were used as first level cache
  and only cache-away simple non db related code structures.
* Switch some to use cache framework cache_runtime instead
  which can be evicted easily.
* Use class properties in some cases instead.

Change-Id: Ic699846a2c6ec661ee1124ace50df1aa04a1954b
Resolves: #85206
Releases: master
Reviewed-on: https://review.typo3.org/57167


Tested-by: default avatarTYPO3com <no-reply@typo3.com>
Reviewed-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring's avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Andreas Fernandez's avatarAndreas Fernandez <a.fernandez@scripting-base.de>
parent 48e16416
......@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Backend\Form\Utility;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\ArrayUtility;
......@@ -95,13 +96,12 @@ class FormEngineUtility
*/
public static function getTSconfigForTableRow($table, $row, $field = '')
{
static $cache;
if ($cache === null) {
$cache = [];
}
$runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
$cache = $runtimeCache->get('formEngineUtilityTsConfigForTableRow') ?: [];
$cacheIdentifier = $table . ':' . $row['uid'];
if (!isset($cache[$cacheIdentifier])) {
$cache[$cacheIdentifier] = BackendUtility::getTCEFORM_TSconfig($table, $row);
$runtimeCache->set('formEngineUtilityTsConfigForTableRow', $cache);
}
if ($field && isset($cache[$cacheIdentifier][$field])) {
return $cache[$cacheIdentifier][$field];
......
......@@ -277,6 +277,12 @@ abstract class AbstractTreeView
*/
public $recs = [];
/**
* @var bool
* @deprecated since v9, will be removed in v10
*/
private $setDataFromArrayDeprecationThrown = false;
/**
* Constructor
*/
......@@ -1015,10 +1021,9 @@ abstract class AbstractTreeView
*/
public function setDataFromArray(&$dataArr, $traverse = false, $pid = 0)
{
static $deprecationThrown = false;
if (!$deprecationThrown) {
if (!$this->setDataFromArrayDeprecationThrown) {
// Throw deprecation only once for this recursive method
$deprecationThrown = true;
$this->setDataFromArrayDeprecationThrown = true;
trigger_error('Method setDataFromArray() of AbstractTreeView has been deprecated', E_USER_DEPRECATED);
}
......
......@@ -364,12 +364,13 @@ class BackendUtility
*/
public static function BEgetRootLine($uid, $clause = '', $workspaceOL = false, array $additionalFields = [])
{
static $BEgetRootLine_cache = [];
$runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
$beGetRootLineCache = $runtimeCache->get('backendUtilityBeGetRootLine') ?: [];
$output = [];
$pid = $uid;
$ident = $pid . '-' . $clause . '-' . $workspaceOL . ($additionalFields ? '-' . implode(',', $additionalFields) : '');
if (is_array($BEgetRootLine_cache[$ident] ?? false)) {
$output = $BEgetRootLine_cache[$ident];
if (is_array($beGetRootLineCache[$ident] ?? false)) {
$output = $beGetRootLineCache[$ident];
} else {
$loopCheck = 100;
$theRowArray = [];
......@@ -422,7 +423,8 @@ class BackendUtility
$output[$c]['_ORIG_pid'] = $val['_ORIG_pid'];
}
}
$BEgetRootLine_cache[$ident] = $output;
$beGetRootLineCache[$ident] = $output;
$runtimeCache->set('backendUtilityBeGetRootLine', $beGetRootLineCache);
}
return $output;
}
......@@ -439,10 +441,11 @@ class BackendUtility
*/
protected static function getPageForRootline($uid, $clause, $workspaceOL, array $additionalFields = [])
{
static $getPageForRootline_cache = [];
$runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
$pageForRootlineCache = $runtimeCache->get('backendUtilityPageForRootLine') ?: [];
$ident = $uid . '-' . $clause . '-' . $workspaceOL;
if (is_array($getPageForRootline_cache[$ident] ?? false)) {
$row = $getPageForRootline_cache[$ident];
if (is_array($pageForRootlineCache[$ident] ?? false)) {
$row = $pageForRootlineCache[$ident];
} else {
$queryBuilder = static::getQueryBuilderForTable('pages');
$queryBuilder->getRestrictions()
......@@ -485,7 +488,8 @@ class BackendUtility
} else {
self::fixVersioningPid('pages', $row);
}
$getPageForRootline_cache[$ident] = $row;
$pageForRootlineCache[$ident] = $row;
$runtimeCache->set('backendUtilityPageForRootLine', $pageForRootlineCache);
}
}
}
......@@ -3466,16 +3470,12 @@ class BackendUtility
*/
public static function getTSCpidCached($table, $uid, $pid)
{
// A local first level cache
static $firstLevelCache;
if (!is_array($firstLevelCache)) {
$firstLevelCache = [];
}
$runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
$firstLevelCache = $runtimeCache->get('backendUtilityTscPidCached') ?: [];
$key = $table . ':' . $uid . ':' . $pid;
if (!isset($firstLevelCache[$key])) {
$firstLevelCache[$key] = static::getTSCpid($table, $uid, $pid);
$runtimeCache->set('backendUtilityTscPidCached', $firstLevelCache);
}
return $firstLevelCache[$key];
}
......
......@@ -21,6 +21,8 @@ use Prophecy\Prophecy\ObjectProphecy;
use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems;
use TYPO3\CMS\Backend\Module\ModuleLoader;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
......@@ -59,6 +61,13 @@ class TcaSelectItemsTest extends UnitTestCase
$backendUserProphecy = $this->prophesize(BackendUserAuthentication::class);
$GLOBALS['BE_USER'] = $backendUserProphecy->reveal();
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get(Argument::cetera())->willReturn(false);
$cacheProphecy->set(Argument::cetera())->willReturn(false);
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
}
protected function tearDown()
......
......@@ -15,7 +15,11 @@ namespace TYPO3\CMS\Backend\Tests\Unit\Form;
* The TYPO3 project - inspiring people to share!
*/
use Prophecy\Argument;
use TYPO3\CMS\Backend\Form\InlineStackProcessor;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
......@@ -23,6 +27,35 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
*/
class InlineStackProcessorTest extends UnitTestCase
{
/**
* @var array A backup of registered singleton instances
*/
protected $singletonInstances = [];
/**
* Set up
*/
public function setUp()
{
parent::setUp();
$this->singletonInstances = GeneralUtility::getSingletonInstances();
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get(Argument::cetera())->willReturn(false);
$cacheProphecy->set(Argument::cetera())->willReturn(false);
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
}
/**
* Tear down
*/
protected function tearDown()
{
GeneralUtility::resetSingletonInstances($this->singletonInstances);
parent::tearDown();
}
/**
* @return array
*/
......
......@@ -24,14 +24,19 @@ class ProcessedValueForGroupWithMultipleAllowedTablesFixture extends \TYPO3\CMS\
*/
public static function getRecordWSOL($table, $uid, $fields = '*', $where = '', $useDeleteClause = true, $unsetMovePointers = false)
{
static $called = 0;
++$called;
if ($called === 1) {
return ['title' => 'Page 1'];
if ($uid == 1) {
return [
'uid' => 1,
'title' => 'Page 1'
];
}
if ($called === 2) {
return ['header' => 'Configuration 2'];
if ($uid == 2) {
return [
'uid' => 2,
'header' => 'Configuration 2'
];
}
throw new \RuntimeException('Unexpected call', 1528631953);
}
/**
......@@ -39,13 +44,12 @@ class ProcessedValueForGroupWithMultipleAllowedTablesFixture extends \TYPO3\CMS\
*/
public static function getRecordTitle($table, $row, $prep = false, $forceResult = true)
{
static $called = 0;
++$called;
if ($called === 1) {
if ($row['uid'] === 1) {
return 'Page 1';
}
if ($called === 2) {
if ($row['uid'] === 2) {
return 'Configuration 2';
}
throw new \RuntimeException('Unexpected call', 1528631954);
}
}
......@@ -24,14 +24,19 @@ class ProcessedValueForGroupWithOneAllowedTableFixture extends \TYPO3\CMS\Backen
*/
public static function getRecordWSOL($table, $uid, $fields = '*', $where = '', $useDeleteClause = true, $unsetMovePointers = false)
{
static $called = 0;
++$called;
if ($called === 1) {
return ['title' => 'Page 1'];
if ($uid == 1) {
return [
'uid' => 1,
'title' => 'Page 1'
];
}
if ($called === 2) {
return ['title' => 'Page 2'];
if ($uid == 2) {
return [
'uid' => 2,
'title' => 'Page 2'
];
}
throw new \RuntimeException('Unexpected call', 1528631951);
}
/**
......@@ -39,13 +44,12 @@ class ProcessedValueForGroupWithOneAllowedTableFixture extends \TYPO3\CMS\Backen
*/
public static function getRecordTitle($table, $row, $prep = false, $forceResult = true)
{
static $called = 0;
++$called;
if ($called === 1) {
if ($row['uid'] === 1) {
return 'Page 1';
}
if ($called === 2) {
if ($row['uid'] === 2) {
return 'Page 2';
}
throw new \RuntimeException('Unexpected call', 1528631952);
}
}
......@@ -1664,7 +1664,8 @@ class BackendUserAuthentication extends AbstractUserAuthentication
*/
public function getFileMountRecords()
{
static $fileMountRecordCache = [];
$runtimeCache = GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
$fileMountRecordCache = $runtimeCache->get('backendUserAuthenticationFileMountRecords') ?: [];
if (!empty($fileMountRecordCache)) {
return $fileMountRecordCache;
......@@ -1798,6 +1799,7 @@ class BackendUserAuthentication extends AbstractUserAuthentication
}
}
$runtimeCache->set('backendUserAuthenticationFileMountRecords', $fileMountRecordCache);
return $fileMountRecordCache;
}
......
......@@ -247,11 +247,8 @@ class PreviewProcessing
*/
protected function getGraphicalFunctionsObject()
{
static $graphicalFunctionsObject = null;
if ($graphicalFunctionsObject === null) {
$graphicalFunctionsObject = GeneralUtility::makeInstance(GraphicalFunctions::class);
$graphicalFunctionsObject->init();
}
$graphicalFunctionsObject = GeneralUtility::makeInstance(GraphicalFunctions::class);
$graphicalFunctionsObject->init();
return $graphicalFunctionsObject;
}
}
......@@ -158,13 +158,8 @@ class LocalImageProcessor implements ProcessorInterface
*/
protected function getGraphicalFunctionsObject()
{
static $graphicalFunctionsObject = null;
if ($graphicalFunctionsObject === null) {
$graphicalFunctionsObject = GeneralUtility::makeInstance(GraphicalFunctions::class);
$graphicalFunctionsObject->init();
}
$graphicalFunctionsObject = GeneralUtility::makeInstance(GraphicalFunctions::class);
$graphicalFunctionsObject->init();
return $graphicalFunctionsObject;
}
}
......@@ -2731,8 +2731,10 @@ class ResourceStorage implements ResourceStorageInterface
/**
* Returns the destination path/fileName of a unique fileName/foldername in that path.
* If $theFile exists in $theDest (directory) the file have numbers appended up to $this->maxNumber. Hereafter a unique string will be appended.
* This function is used by fx. DataHandler when files are attached to records and needs to be uniquely named in the uploads/* folders
* If $theFile exists in $theDest (directory) the file have numbers appended up to $this->maxNumber.
* Hereafter a unique string will be appended.
* This function is used by fx. DataHandler when files are attached to records
* and needs to be uniquely named in the uploads/* folders
*
* @param FolderInterface $folder
* @param string $theFile The input fileName to check
......@@ -2744,14 +2746,9 @@ class ResourceStorage implements ResourceStorageInterface
*/
protected function getUniqueName(FolderInterface $folder, $theFile, $dontCheckForUnique = false)
{
static $maxNumber = 99, $uniqueNamePrefix = '';
$maxNumber = 99;
// Fetches info about path, name, extension of $theFile
$origFileInfo = PathUtility::pathinfo($theFile);
// Adds prefix
if ($uniqueNamePrefix) {
$origFileInfo['basename'] = $uniqueNamePrefix . $origFileInfo['basename'];
$origFileInfo['filename'] = $uniqueNamePrefix . $origFileInfo['filename'];
}
// Check if the file exists and if not - return the fileName...
// The destinations file
$theDestFile = $origFileInfo['basename'];
......
......@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Utility;
use GuzzleHttp\Exception\RequestException;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Core\ApplicationContext;
use TYPO3\CMS\Core\Core\ClassLoadingInformation;
use TYPO3\CMS\Core\Core\Environment;
......@@ -1578,17 +1579,15 @@ class GeneralUtility
*/
public static function xml2array($string, $NSprefix = '', $reportDocTag = false)
{
static $firstLevelCache = [];
$runtimeCache = static::makeInstance(CacheManager::class)->getCache('cache_runtime');
$firstLevelCache = $runtimeCache->get('generalUtilityXml2Array') ?: [];
$identifier = md5($string . $NSprefix . ($reportDocTag ? '1' : '0'));
// Look up in first level cache
if (!empty($firstLevelCache[$identifier])) {
$array = $firstLevelCache[$identifier];
} else {
$array = self::xml2arrayProcess(trim($string), $NSprefix, $reportDocTag);
// Store content in first level cache
$firstLevelCache[$identifier] = $array;
if (empty($firstLevelCache[$identifier])) {
$firstLevelCache[$identifier] = self::xml2arrayProcess(trim($string), $NSprefix, $reportDocTag);
$runtimeCache->set('generalUtilityXml2Array', $firstLevelCache);
}
return $array;
return $firstLevelCache[$identifier];
}
/**
......
......@@ -370,12 +370,6 @@ class PathUtility
*/
public static function stripPathSitePrefix($path)
{
static $pathSiteLength = null;
// calculate length when first needed
if (!isset($pathSiteLength)) {
$pathSiteLength = strlen(PATH_site);
}
return substr($path, $pathSiteLength);
return substr($path, strlen(PATH_site));
}
}
......@@ -18,6 +18,8 @@ namespace TYPO3\CMS\Core\Tests\Unit\Configuration\FlexForm;
use Doctrine\DBAL\Driver\Statement;
use Prophecy\Argument;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidCombinedPointerFieldException;
use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidIdentifierException;
use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidParentRowException;
......@@ -54,6 +56,36 @@ use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
*/
class FlexFormToolsTest extends UnitTestCase
{
/**
* @var array A backup of registered singleton instances
*/
protected $singletonInstances = [];
/**
* Set up
*/
public function setUp()
{
parent::setUp();
$this->singletonInstances = GeneralUtility::getSingletonInstances();
// Underlying static GeneralUtility::xml2array() uses caches that have to be mocked here
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get(Argument::cetera())->willReturn(false);
$cacheProphecy->set(Argument::cetera())->willReturn(false);
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
}
/**
* Tear down
*/
protected function tearDown()
{
GeneralUtility::resetSingletonInstances($this->singletonInstances);
parent::tearDown();
}
/**
* @test
*/
......
......@@ -15,6 +15,8 @@ namespace TYPO3\CMS\Core\Tests\Unit\Resource;
*/
use Prophecy\Argument;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Resource\Driver\AbstractDriver;
use TYPO3\CMS\Core\Resource\Driver\LocalDriver;
use TYPO3\CMS\Core\Resource\DuplicationBehavior;
......@@ -59,6 +61,12 @@ class ResourceStorageTest extends BaseTestCase
FileRepository::class,
$fileRepositoryMock
);
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get(Argument::cetera())->willReturn(false);
$cacheProphecy->set(Argument::cetera())->willReturn(false);
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
}
protected function tearDown()
......
......@@ -16,6 +16,9 @@ namespace TYPO3\CMS\Core\Tests\Unit\TypoScript\Parser;
* The TYPO3 project - inspiring people to share!
*/
use Prophecy\Argument;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser;
use TYPO3\CMS\Core\Utility\GeneralUtility;
......@@ -42,7 +45,7 @@ class TypoScriptParserTest extends UnitTestCase
}
/**
*
* Tear down
*/
protected function tearDown(): void
{
......@@ -375,6 +378,14 @@ class TypoScriptParserTest extends UnitTestCase
*/
public function includeFilesWithConditions(string $typoScript): void
{
// This test triggers an BackendUtility::BEgetRootLine() down below, we need to suppress the cache call
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get(Argument::cetera())->willReturn(false);
$cacheProphecy->set(Argument::cetera())->willReturn(false);
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
$resolvedIncludeLines = TypoScriptParser::checkIncludeLines($typoScript);
$this->assertContains('foo = bar', $resolvedIncludeLines);
$this->assertNotContains('INCLUDE_TYPOSCRIPT', $resolvedIncludeLines);
......
......@@ -21,6 +21,8 @@ use Prophecy\Argument;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
use Psr\Log\LoggerInterface;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Package\Package;
......@@ -36,11 +38,12 @@ use TYPO3\CMS\Core\Tests\Unit\Utility\Fixtures\TwoParametersConstructorFixture;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\TestingFramework\Core\FileStreamWrapper;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
/**
* Testcase for class \TYPO3\CMS\Core\Utility\GeneralUtility
* Test case
*/
class GeneralUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
class GeneralUtilityTest extends UnitTestCase
{
const NO_FIX_PERMISSIONS_ON_WINDOWS = 'fixPermissions() not available on Windows (method does nothing)';
......@@ -4539,6 +4542,12 @@ class GeneralUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
*/
public function xml2arrayHandlesWhitespaces(string $input)
{
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get('generalUtilityXml2Array')->shouldBeCalled()->willReturn(false);
$cacheProphecy->set('generalUtilityXml2Array', Argument::cetera())->shouldBeCalled();
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
$expected = [
'data' => [
'settings.persistenceIdentifier' => [
......@@ -4595,6 +4604,12 @@ class GeneralUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
*/
public function xml2arrayHandlesTagNamespaces(string $input)
{
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get('generalUtilityXml2Array')->shouldBeCalled()->willReturn(false);
$cacheProphecy->set('generalUtilityXml2Array', Argument::cetera())->shouldBeCalled();
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
$expected = [
'data' => [
'settings.persistenceIdentifier' => [
......@@ -4655,6 +4670,12 @@ class GeneralUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
*/
public function xml2arrayHandlesDocumentTag(string $input, string $docTag)
{
$cacheManagerProphecy = $this->prophesize(CacheManager::class);
$cacheProphecy = $this->prophesize(FrontendInterface::class);
$cacheManagerProphecy->getCache('cache_runtime')->willReturn($cacheProphecy->reveal());
$cacheProphecy->get('generalUtilityXml2Array')->shouldBeCalled()->willReturn(false);
$cacheProphecy->set('generalUtilityXml2Array', Argument::cetera())->shouldBeCalled();
GeneralUtility::setSingletonInstance(CacheManager::class, $cacheManagerProphecy->reveal());
$expected = [
'data' => [
'settings.persistenceIdentifier' => [
......@@ -4705,6 +4726,12 @@ class GeneralUtilityTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
*/