[!!!][TASK] Streamline TimeTracker global information 69/60769/6
authorBenni Mack <benni@typo3.org>
Thu, 16 May 2019 12:17:03 +0000 (14:17 +0200)
committerGeorg Ringer <georg.ringer@gmail.com>
Sat, 8 Jun 2019 03:52:38 +0000 (05:52 +0200)
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>
typo3/sysext/core/Classes/Core/SystemEnvironmentBuilder.php
typo3/sysext/core/Classes/TimeTracker/TimeTracker.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Core/SystemEnvironmentBuilderTest.php
typo3/sysext/core/Tests/Unit/TimeTracker/TimeTrackerTest.php
typo3/sysext/frontend/Classes/Http/RequestHandler.php
typo3/sysext/frontend/Classes/Middleware/TimeTrackerInitialization.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayDimensionMatcher.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/ArrayGlobalMatcher.php

index bca62ae..1d0f1fd 100644 (file)
@@ -207,7 +207,6 @@ class SystemEnvironmentBuilder
     protected static function initializeGlobalVariables()
     {
         // Unset variable(s) in global scope (security issue #13959)
-        $GLOBALS['TYPO3_MISC'] = [];
         $GLOBALS['T3_VAR'] = [];
         $GLOBALS['T3_SERVICES'] = [];
     }
@@ -218,8 +217,6 @@ class SystemEnvironmentBuilder
      */
     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
index 7f109c2..a5d0bd6 100644 (file)
@@ -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
@@ -142,13 +149,16 @@ class TimeTracker implements SingletonInterface
 
     /**
      * 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);
     }
 
     /**
@@ -281,7 +291,7 @@ class TimeTracker implements SingletonInterface
         if (!isset($microtime)) {
             $microtime = microtime(true);
         }
-        return round($microtime * 1000);
+        return (int)round($microtime * 1000);
     }
 
     /**
@@ -296,27 +306,31 @@ class TimeTracker implements SingletonInterface
     }
 
     /**
-     * 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);
     }
 
     /*******************************************
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst
new file mode 100644 (file)
index 0000000..405ca3e
--- /dev/null
@@ -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
index 083f265..d78e448 100644 (file)
@@ -108,16 +108,6 @@ class SystemEnvironmentBuilderTest extends UnitTestCase
         $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
      */
@@ -165,16 +155,6 @@ class SystemEnvironmentBuilderTest extends UnitTestCase
         $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
      */
index 8e0d3ab..8983703 100644 (file)
@@ -26,14 +26,8 @@ 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);
     }
@@ -41,42 +35,12 @@ class TimeTrackerTest extends UnitTestCase
     /**
      * @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());
     }
 }
index 74280a5..8ecf451 100644 (file)
@@ -154,26 +154,17 @@ class RequestHandler implements RequestHandlerInterface
         // 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();
     }
 
     /**
index fe67cb8..79abaff 100644 (file)
@@ -21,6 +21,7 @@ use Psr\Http\Server\MiddlewareInterface;
 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
@@ -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']);
     }
 }
index a330408..4a1df04 100644 (file)
@@ -291,4 +291,24 @@ return [
             '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',
+        ],
+    ],
 ];
index 7e27dd8..f949eff 100644 (file)
@@ -31,4 +31,9 @@ return [
             'Breaking-87567-GlobalVariableTBE_TEMPLATERemoved.rst',
         ],
     ],
+    '$GLOBALS[\'TYPO3_MISC\']' => [
+        'restFiles' => [
+            'Breaking-88498-GlobalDataForTimeTrackerStatisticsRemoved.rst',
+        ],
+    ],
 ];