protected static function initializeGlobalVariables()
{
// Unset variable(s) in global scope (security issue #13959)
- $GLOBALS['TYPO3_MISC'] = [];
$GLOBALS['T3_VAR'] = [];
$GLOBALS['T3_SERVICES'] = [];
}
*/
protected static function initializeGlobalTimeTrackingVariables()
{
- // Microtime of (nearly) script start
- $GLOBALS['TYPO3_MISC']['microtime_start'] = microtime(true);
// EXEC_TIME is set so that the rest of the script has a common value for the script execution time
$GLOBALS['EXEC_TIME'] = time();
// $ACCESS_TIME is a common time in minutes for access control
*/
public $starttime = 0;
+ /**
+ * Is set via finish() with the millisecond time when the request handler is finished.
+ *
+ * @var int
+ */
+ protected $finishtime = 0;
+
/**
* Log Rendering flag. If set, ->push() and ->pull() is called from the cObj->cObjGetSingle().
* This determines whether or not the TypoScript parsing activity is logged. But it also slows down the rendering
/**
* Sets the starting time
+ *
+ * @see finish()
+ * @param float|null $starttime
*/
- public function start()
+ public function start(?float $starttime = null)
{
if (!$this->isEnabled) {
return;
}
- $this->starttime = $this->getMilliseconds();
+ $this->starttime = $this->getMilliseconds($starttime);
}
/**
if (!isset($microtime)) {
$microtime = microtime(true);
}
- return round($microtime * 1000);
+ return (int)round($microtime * 1000);
}
/**
}
/**
- * Get total parse time in milliseconds(without backend user initialization)
+ * Usually called when the page generation and output is prepared.
+ *
+ * @see start()
+ */
+ public function finish(): void
+ {
+ if ($this->isEnabled) {
+ $this->finishtime = microtime(true);
+ }
+ }
+
+ /**
+ * Get total parse time in milliseconds
*
* @return int
*/
public function getParseTime(): int
{
- // Compensates for the time consumed with Back end user initialization.
- $processStart = $this->getMilliseconds($GLOBALS['TYPO3_MISC']['microtime_start'] ?? null);
-
- $beUserInitializationStart = $this->getMilliseconds($GLOBALS['TYPO3_MISC']['microtime_BE_USER_start'] ?? null);
- $beUserInitializationEnd = $this->getMilliseconds($GLOBALS['TYPO3_MISC']['microtime_BE_USER_end'] ?? null);
- $beUserInitialization = $beUserInitializationEnd - $beUserInitializationStart;
-
- $processEnd = $this->getMilliseconds($GLOBALS['TYPO3_MISC']['microtime_end'] ?? null);
- $totalParseTime = $processEnd - $processStart;
-
- if ($beUserInitialization > 0) {
- $totalParseTime -= $beUserInitialization;
+ if (!$this->starttime) {
+ $this->start(microtime(true));
}
-
- return $totalParseTime;
+ if (!$this->finishtime) {
+ $this->finish();
+ }
+ return $this->getDifferenceToStarttime($this->finishtime ?? null);
}
/*******************************************
--- /dev/null
+.. include:: ../../Includes.txt
+
+=================================================================
+Breaking: #88498 - Global data for TimeTracker statistics removed
+=================================================================
+
+See :issue:`88498`
+
+Description
+===========
+
+The TimeTracker used some global variables to store :php:`microtime()` when a Frontend request was started
+and ended, as information for the Admin Panel and as HTTP Header, if debug mode is enabled for Frontend.
+
+This information is now encapsulated within the TimeTracker object, making the following global variables
+obsolete:
+
+* :php:`$GLOBALS['TYPO3_MISC']['microtime_start']`
+* :php:`$GLOBALS['TYPO3_MISC']['microtime_end']`
+* :php:`$GLOBALS['TYPO3_MISC']['microtime_BE_USER_start']`
+* :php:`$GLOBALS['TYPO3_MISC']['microtime_BE_USER_end']`
+
+This also results in having :php:`$GLOBALS['TYPO3_MISC']` to not be set anymore.
+
+
+Impact
+======
+
+Accessing the global variables will trigger a PHP warning, as they do not exist anymore.
+
+
+Affected Installations
+======================
+
+Any TYPO3 installation with an extension working with any of the global variables.
+
+
+Migration
+=========
+
+Remove the usages and either use the newly introduced `TimeTracker->finish()` to calculate data, or set
+your own variables, if microtime is needed.
+
+.. index:: PHP-API, FullyScanned
$this->assertStringStartsWith($fakedAbsolutePart, $this->subject->_call('getPathThisScriptCli'));
}
- /**
- * @test
- */
- public function initializeGlobalVariablesSetsGlobalTypo3MiscArray()
- {
- unset($GLOBALS['TYPO3_MISC']);
- $this->subject->_call('initializeGlobalVariables');
- $this->assertIsArray($GLOBALS['TYPO3_MISC']);
- }
-
/**
* @test
*/
$this->assertTrue(isset($GLOBALS[$variable]));
}
- /**
- * @test
- */
- public function initializeGlobalTimeTrackingVariablesSetsGlobalTypo3MiscMicrotimeStart()
- {
- unset($GLOBALS['TYPO3_MISC']['microtime_start']);
- $this->subject->_call('initializeGlobalTimeTrackingVariables');
- $this->assertTrue(isset($GLOBALS['TYPO3_MISC']['microtime_start']));
- }
-
/**
* @test
*/
/**
* @test
*/
- public function getParseTimeReturnsZeroOrOneIfNoValuesAreSet()
+ public function getParseTimeReturnsZeroOrOneIfNoValuesAreSet(): void
{
- unset(
- $GLOBALS['TYPO3_MISC']['microtime_end'],
- $GLOBALS['TYPO3_MISC']['microtime_start'],
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_start'],
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_end']
- );
$parseTime = (new TimeTracker())->getParseTime();
self::assertLessThanOrEqual(1, $parseTime);
}
/**
* @test
*/
- public function getParseTimeReturnsTotalParseTimeInMillisecondsWithoutBeUserInitialization()
+ public function getParseTimeReturnsTotalParseTimeInMilliseconds(): void
{
- $baseValue = time();
- $GLOBALS['TYPO3_MISC']['microtime_start'] = $baseValue;
- $GLOBALS['TYPO3_MISC']['microtime_end'] = $baseValue + 10;
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_start'] = $baseValue + 1;
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_end'] = $baseValue + 3;
- $parseTime = (new TimeTracker())->getParseTime();
- self::assertSame(8000, $parseTime);
- }
-
- /**
- * @test
- */
- public function getParseTimeReturnsParseTimeIfOnlyOneBeUserTimeWasSet()
- {
- $baseValue = time();
- $GLOBALS['TYPO3_MISC']['microtime_start'] = $baseValue;
- $GLOBALS['TYPO3_MISC']['microtime_end'] = $baseValue + 10;
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_start'] = $baseValue + 1;
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_end'] = 0;
- $parseTime = (new TimeTracker())->getParseTime();
- self::assertSame(10000, $parseTime);
- }
-
- /**
- * @test
- */
- public function getParseTimeReturnsParseTimeIfNoBeUserTimeWasSet()
- {
- $baseValue = time();
- $GLOBALS['TYPO3_MISC']['microtime_start'] = $baseValue;
- $GLOBALS['TYPO3_MISC']['microtime_end'] = $baseValue + 10;
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_start'] = 0;
- $GLOBALS['TYPO3_MISC']['microtime_BE_USER_end'] = 0;
- $parseTime = (new TimeTracker())->getParseTime();
- self::assertSame(10000, $parseTime);
+ $subject = new TimeTracker();
+ $subject->start();
+ sleep(1);
+ $subject->finish();
+ self::assertLessThan(1010, $subject->getParseTime());
}
}
// Store session data for fe_users
$controller->fe_user->storeSessionData();
- // Statistics
- $GLOBALS['TYPO3_MISC']['microtime_end'] = microtime(true);
- if ($isOutputting && ($controller->config['config']['debug'] ?? !empty($GLOBALS['TYPO3_CONF_VARS']['FE']['debug']))) {
- $response = $response->withHeader('X-TYPO3-Parsetime', $this->timeTracker->getParseTime() . 'ms');
- }
-
// Hook for "end-of-frontend"
$_params = ['pObj' => &$controller];
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['hook_eofe'] ?? [] as $_funcRef) {
GeneralUtility::callUserFunction($_funcRef, $_params, $controller);
}
- // Finish time tracking (started in TYPO3\CMS\Frontend\Middleware\TimeTrackerInitialization)
- $this->timeTracker->pull();
-
if ($isOutputting) {
$response->getBody()->write($controller->content);
+ return $response;
}
-
- return $isOutputting ? $response : new NullResponse();
+ return new NullResponse();
}
/**
use Psr\Http\Server\RequestHandlerInterface;
use TYPO3\CMS\Core\TimeTracker\TimeTracker;
use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
/**
* Initializes the time tracker (singleton) for the whole TYPO3 Frontend
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
- $configuredCookieName = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieName']) ?: 'be_typo_user';
+ $timeTrackingEnabled = $this->isBackendUserCookieSet($request);
$timeTracker = GeneralUtility::makeInstance(
TimeTracker::class,
- !empty($request->getCookieParams()[$configuredCookieName])
+ $timeTrackingEnabled
);
- $timeTracker->start();
+ $timeTracker->start(microtime(true));
$timeTracker->push('');
- return $handler->handle($request);
+ $response = $handler->handle($request);
+
+ // Finish time tracking
+ $timeTracker->pull();
+ $timeTracker->finish();
+
+ if ($this->isDebugModeEnabled()) {
+ return $response->withHeader('X-TYPO3-Parsetime', $timeTracker->getParseTime() . 'ms');
+ }
+ return $response;
+ }
+
+ protected function isBackendUserCookieSet(ServerRequestInterface $request): bool
+ {
+ $configuredCookieName = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieName']) ?: 'be_typo_user';
+ return !empty($request->getCookieParams()[$configuredCookieName]);
+ }
+
+ protected function isDebugModeEnabled(): bool
+ {
+ $controller = $GLOBALS['TSFE'];
+ if ($controller instanceof TypoScriptFrontendController && !empty($controller->config['config']['debug'] ?? false)) {
+ return true;
+ }
+ return !empty($GLOBALS['TYPO3_CONF_VARS']['FE']['debug']);
}
}
'Breaking-88458-RemovedFrontendTrackUserFtuFunctionality.rst',
],
],
+ '$GLOBALS[\'TYPO3_CONF_VARS\'][\'TYPO3_MISC\'][\'microtime_start\']' => [
+ 'restFiles' => [
+ 'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
+ ],
+ ],
+ '$GLOBALS[\'TYPO3_CONF_VARS\'][\'TYPO3_MISC\'][\'microtime_end\']' => [
+ 'restFiles' => [
+ 'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
+ ],
+ ],
+ '$GLOBALS[\'TYPO3_CONF_VARS\'][\'TYPO3_MISC\'][\'microtime_BE_USER_start\']' => [
+ 'restFiles' => [
+ 'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
+ ],
+ ],
+ '$GLOBALS[\'TYPO3_CONF_VARS\'][\'TYPO3_MISC\'][\'microtime_BE_USER_end\']' => [
+ 'restFiles' => [
+ 'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
+ ],
+ ],
];
'Breaking-87567-GlobalVariableTBE_TEMPLATERemoved.rst',
],
],
+ '$GLOBALS[\'TYPO3_MISC\']' => [
+ 'restFiles' => [
+ 'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
+ ],
+ ],
];