Skip to content

Commit

Permalink
[!!!][TASK] Streamline TimeTracker global information
Browse files Browse the repository at this point in the history
This patch removes unused variables:

$GLOBALS['TYPO3_MISC']['microtime_BE_USER_start']
$GLOBALS['TYPO3_MISC']['microtime_BE_USER_end']
$GLOBALS['TYPO3_MISC']['microtime_end']
$GLOBALS['TYPO3_MISC']['microtime_start']

are replaced by properly using
- TimeTracker->start()
- TimeTracker->finish() (new method)

to encapsulate the logic into the main method.

Resolves: #88498
Releases: master
Change-Id: I158e4b3aed002f688f117488cb0300c6523e791f
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/60769
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
  • Loading branch information
bmack authored and georgringer committed Jun 8, 2019
1 parent a6c60ad commit 15e264d
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 99 deletions.
3 changes: 0 additions & 3 deletions typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php
Expand Up @@ -207,7 +207,6 @@ protected static function calculateRootPath(int $entryPointLevel, int $requestTy
protected static function initializeGlobalVariables()
{
// Unset variable(s) in global scope (security issue #13959)
$GLOBALS['TYPO3_MISC'] = [];
$GLOBALS['T3_VAR'] = [];
$GLOBALS['T3_SERVICES'] = [];
}
Expand All @@ -218,8 +217,6 @@ protected static function initializeGlobalVariables()
*/
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
Expand Down
50 changes: 32 additions & 18 deletions typo3/sysext/core/Classes/TimeTracker/TimeTracker.php
Expand Up @@ -38,6 +38,13 @@ class TimeTracker implements SingletonInterface
*/
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
Expand Down Expand Up @@ -142,13 +149,16 @@ public function __construct($isEnabled = true)

/**
* 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);
}

/**
Expand Down Expand Up @@ -281,7 +291,7 @@ public function getMilliseconds($microtime = null)
if (!isset($microtime)) {
$microtime = microtime(true);
}
return round($microtime * 1000);
return (int)round($microtime * 1000);
}

/**
Expand All @@ -296,27 +306,31 @@ public function getDifferenceToStarttime($microtime = null)
}

/**
* 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);
}

/*******************************************
Expand Down
@@ -0,0 +1,44 @@
.. 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
20 changes: 0 additions & 20 deletions typo3/sysext/core/Tests/Unit/Core/SystemEnvironmentBuilderTest.php
Expand Up @@ -108,16 +108,6 @@ public function getPathThisScriptCliAddsCurrentWorkingDirectoryFromServerEnviron
$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
*/
Expand Down Expand Up @@ -165,16 +155,6 @@ public function initializeGlobalTimeTrackingVariablesSetsGlobalVariables($variab
$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
*/
Expand Down
50 changes: 7 additions & 43 deletions typo3/sysext/core/Tests/Unit/TimeTracker/TimeTrackerTest.php
Expand Up @@ -26,57 +26,21 @@ class TimeTrackerTest extends UnitTestCase
/**
* @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());
}
}
13 changes: 2 additions & 11 deletions typo3/sysext/frontend/Classes/Http/RequestHandler.php
Expand Up @@ -154,26 +154,17 @@ public function handle(ServerRequestInterface $request): ResponseInterface
// 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();
}

/**
Expand Down
Expand Up @@ -21,6 +21,7 @@
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
Expand All @@ -38,14 +39,38 @@ class TimeTrackerInitialization implements MiddlewareInterface
*/
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']);
}
}
Expand Up @@ -291,4 +291,24 @@
'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',
],
],
];
Expand Up @@ -31,4 +31,9 @@
'Breaking-87567-GlobalVariableTBE_TEMPLATERemoved.rst',
],
],
'$GLOBALS[\'TYPO3_MISC\']' => [
'restFiles' => [
'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
],
],
];

0 comments on commit 15e264d

Please sign in to comment.