[TASK] Deprecate various GeneralUtility methods 91/64091/5
authorBenni Mack <benni@typo3.org>
Tue, 7 Apr 2020 09:16:52 +0000 (11:16 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Sun, 12 Apr 2020 10:41:54 +0000 (12:41 +0200)
Some methods in GeneralUtility nowadays are wrappers to
native PHP methods. We encourage people to use the PHP API
directly.

* GeneralUtility::IPv6Hex2Bin()
* GeneralUtility::IPv6Bin2Hex()
* GeneralUtility::compressIPv6()
* GeneralUtility::milliseconds()

In addition, these methods are unused by Core
* GeneralUtility::linkThisUrl()
* GeneralUtility::flushDirectory()

Reasoning: In order to make our code less coupled, TYPO3 Core should
use native PHP where it makes sense, instead of relying on GeneralUtility
in all places.

Resolves: #91001
Releases: master
Change-Id: I9e3a2f4a4bb42facad2d79f959b36482dba23ec8
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64091
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Alexander Schnitzler <git@alexanderschnitzler.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Alexander Schnitzler <git@alexanderschnitzler.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Classes/Cache/Backend/SimpleFileBackend.php
typo3/sysext/core/Classes/Utility/GeneralUtility.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-91001-VariousMethodsWithinGeneralUtility.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Utility/GeneralUtilityTest.php
typo3/sysext/core/Tests/UnitDeprecated/Utility/GeneralUtilityTest.php
typo3/sysext/indexed_search/Classes/Controller/SearchController.php
typo3/sysext/indexed_search/Classes/Indexer.php
typo3/sysext/indexed_search/Classes/Utility/IndexedSearchUtility.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php

index d2961ff..83e3018 100644 (file)
@@ -297,10 +297,26 @@ class SimpleFileBackend extends AbstractBackend implements PhpCapableBackendInte
 
     /**
      * Removes all cache entries of this cache.
+     * Flushes a directory by first moving to a temporary resource, and then
+     * triggering the remove process. This way directories can be flushed faster
+     * to prevent race conditions on concurrent processes accessing the same directory.
      */
     public function flush()
     {
-        GeneralUtility::flushDirectory($this->cacheDirectory, true);
+        $directory = $this->cacheDirectory;
+        if (is_link($directory)) {
+            // Avoid attempting to rename the symlink see #87367
+            $directory = realpath($directory);
+        }
+
+        if (is_dir($directory)) {
+            $temporaryDirectory = rtrim($directory, '/') . '.' . StringUtility::getUniqueId('remove');
+            if (rename($directory, $temporaryDirectory)) {
+                GeneralUtility::mkdir($directory);
+                clearstatcache();
+                GeneralUtility::rmdir($temporaryDirectory, true);
+            }
+        }
     }
 
     /**
index 9c6f0c1..468bb9c 100644 (file)
@@ -314,8 +314,8 @@ class GeneralUtility
                 } elseif ($maskInt == 128) {
                     $success = $test === $baseIP;
                 } else {
-                    $testBin = self::IPv6Hex2Bin($test);
-                    $baseIPBin = self::IPv6Hex2Bin($baseIP);
+                    $testBin = inet_pton($test);
+                    $baseIPBin = inet_pton($baseIP);
                     $success = true;
                     // Modulo is 0 if this is a 8-bit-boundary
                     $maskIntModulo = $maskInt % 8;
@@ -344,10 +344,11 @@ class GeneralUtility
      *
      * @param string $hex IPv6 address in hex-presentation
      * @return string Binary representation (16 characters, 128 characters)
-     * @see IPv6Bin2Hex()
+     * @deprecated - will be removed in TYPO3 v11.0. Use the native PHP function inet_pton($hex) instead.
      */
     public static function IPv6Hex2Bin($hex)
     {
+        trigger_error('GeneralUtility::IPv6Hex2Bin() will be removed in TYPO3 v11.0. Use the native PHP function inet_pton($hex) instead.', E_USER_DEPRECATED);
         return inet_pton($hex);
     }
 
@@ -356,10 +357,11 @@ class GeneralUtility
      *
      * @param string $bin IPv6 address in hex-presentation
      * @return string Binary representation (16 characters, 128 characters)
-     * @see IPv6Hex2Bin()
+     * @deprecated - will be removed in TYPO3 v11.0. Use the native PHP function inet_ntop($bin) instead.
      */
     public static function IPv6Bin2Hex($bin)
     {
+        trigger_error('GeneralUtility::IPv6Bin2Hex() will be removed in TYPO3 v11.0. Use the native PHP function inet_ntop($bin) instead.', E_USER_DEPRECATED);
         return inet_ntop($bin);
     }
 
@@ -368,7 +370,6 @@ class GeneralUtility
      *
      * @param string $address Given IPv6 address
      * @return string Normalized address
-     * @see compressIPv6()
      */
     public static function normalizeIPv6($address)
     {
@@ -432,9 +433,11 @@ class GeneralUtility
      * @param string $address Given IPv6 address
      * @return string Compressed address
      * @see normalizeIPv6()
+     * @deprecated will be removed in TYPO3 v11.0. Use the native PHP functions inet_ntop(inet_pton($address)) instead.
      */
     public static function compressIPv6($address)
     {
+        trigger_error('GeneralUtility::compressIPv6() will be removed in TYPO3 v11.0. Use the native PHP functions inet_ntop(inet_pton($address)) instead.', E_USER_DEPRECATED);
         return inet_ntop(inet_pton($address));
     }
 
@@ -2104,9 +2107,11 @@ class GeneralUtility
      * @param bool $keepOriginalDirectory Whether to only empty the directory and not remove it
      * @param bool $flushOpcodeCache Also flush the opcode cache right after renaming the directory.
      * @return bool Whether the action was successful
+     * @deprecated will be removed in TYPO3 v11.0. This is a specific logic needed for the caching framework, and should be implemented where needed directly.
      */
     public static function flushDirectory($directory, $keepOriginalDirectory = false, $flushOpcodeCache = false)
     {
+        trigger_error('GeneralUtility::flushDirectory() will be removed in TYPO3 v11.0. This is a specific logic needed for the caching framework, and should be implemented where needed directly.', E_USER_DEPRECATED);
         $result = false;
 
         if (is_link($directory)) {
@@ -2511,9 +2516,11 @@ class GeneralUtility
      * @param string $url URL string
      * @param array $getParams Array of key/value pairs for get parameters to add/overrule with. Can be multidimensional.
      * @return string Output URL with added getParams.
+     * @deprecated will be removed in TYPO3 v11.0. Use PSR-7 URI objects instead.
      */
     public static function linkThisUrl($url, array $getParams = [])
     {
+        trigger_error('GeneralUtility::linkThisUrl() will be removed in TYPO3 v11.0. Use PSR-7 URI objects instead.', E_USER_DEPRECATED);
         $parts = parse_url($url);
         $getP = [];
         if ($parts['query']) {
@@ -2916,9 +2923,11 @@ class GeneralUtility
      * Gets the unixtime as milliseconds.
      *
      * @return int The unixtime as milliseconds
+     * @deprecated will be removed in TYPO3 v11.0. Use the native PHP functions round(microtime(true) * 1000) instead.
      */
     public static function milliseconds()
     {
+        trigger_error('GeneralUtility::milliseconds() will be removed in TYPO3 v11.0. Use the native PHP functions round(microtime(true) * 1000) instead.', E_USER_DEPRECATED);
         return round(microtime(true) * 1000);
     }
 
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-91001-VariousMethodsWithinGeneralUtility.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-91001-VariousMethodsWithinGeneralUtility.rst
new file mode 100644 (file)
index 0000000..8dc4601
--- /dev/null
@@ -0,0 +1,57 @@
+.. include:: ../../Includes.txt
+
+===========================================================
+Deprecation: #91001 - Various methods within GeneralUtility
+===========================================================
+
+See :issue:`91001`
+
+Description
+===========
+
+The following methods within GeneralUtility have been marked as deprecated,
+as the native PHP methods can be used directly:
+
+* :php:`GeneralUtility::IPv6Hex2Bin()`
+* :php:`GeneralUtility::IPv6Bin2Hex()`
+* :php:`GeneralUtility::compressIPv6()`
+* :php:`GeneralUtility::milliseconds()`
+
+In addition, these methods are unused by Core and marked as deprecated as well:
+
+* :php:`GeneralUtility::linkThisUrl()`
+* :php:`GeneralUtility::flushDirectory()`
+
+
+Impact
+======
+
+Calling any methods directly from PHP will trigger a PHP deprecation notice.
+
+
+Affected Installations
+======================
+
+TYPO3 installations with third-party extensions using any of these methods.
+
+
+Migration
+=========
+
+As the following methods are just wrappers around native PHP methods, it is
+recommended to switch to native PHP to speed up performance:
+
+* :php:`GeneralUtility::IPv6Hex2Bin($hex)`: :php:`inet_pton($hex)`
+* :php:`GeneralUtility::IPv6Bin2Hex($bin)`: :php:`inet_ntop($bin)`
+* :php:`GeneralUtility::compressIPv6($address)`: :php:`inet_ntop(inet_pton($address))`
+* :php:`GeneralUtility::milliseconds()`: :php:`round(microtime(true) * 1000)`
+
+As for :php:`GeneralUtility::linkThisUrl()` it is recommended to migrate to
+PSR-7 (UriInterface).
+
+The method :php:`GeneralUtility::flushDirectory()` uses a clearing
+folder structure which is only used for caching to avoid race-conditioning. It
+is recommended to use :php:`GeneralUtility::rmdir()` or implement the code
+directly in the third-party extension.
+
+.. index:: PHP-API, FullyScanned, ext:core
index cc2d97f..421ba27 100644 (file)
@@ -346,63 +346,6 @@ class GeneralUtilityTest extends UnitTestCase
         self::assertFalse(GeneralUtility::cmpIPv6($ip, $list));
     }
 
-    ///////////////////////////////
-    // Tests concerning IPv6Hex2Bin
-    ///////////////////////////////
-    /**
-     * Data provider for IPv6Hex2BinCorrect
-     *
-     * @return array Data sets
-     */
-    public static function IPv6Hex2BinDataProviderCorrect()
-    {
-        return [
-            'empty 1' => ['::', str_pad('', 16, "\x00")],
-            'empty 2, already normalized' => ['0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")],
-            'already normalized' => ['0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"],
-            'expansion in middle 1' => ['1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"],
-            'expansion in middle 2' => ['beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider IPv6Hex2BinDataProviderCorrect
-     */
-    public function IPv6Hex2BinCorrectlyConvertsAddresses($hex, $binary)
-    {
-        self::assertTrue(GeneralUtility::IPv6Hex2Bin($hex) === $binary);
-    }
-
-    ///////////////////////////////
-    // Tests concerning IPv6Bin2Hex
-    ///////////////////////////////
-    /**
-     * Data provider for IPv6Bin2HexCorrect
-     *
-     * @return array Data sets
-     */
-    public static function IPv6Bin2HexDataProviderCorrect()
-    {
-        return [
-            'empty' => [str_pad('', 16, "\x00"), '::'],
-            'non-empty front' => ["\x01" . str_pad('', 15, "\x00"), '100::'],
-            'non-empty back' => [str_pad('', 15, "\x00") . "\x01", '::1'],
-            'normalized' => ["\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78", '102:304::506:78'],
-            'expansion in middle 1' => ["\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02", '1::2'],
-            'expansion in middle 2' => ["\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa", 'beef::fefa'],
-        ];
-    }
-
-    /**
-     * @test
-     * @dataProvider IPv6Bin2HexDataProviderCorrect
-     */
-    public function IPv6Bin2HexCorrectlyConvertsAddresses($binary, $hex)
-    {
-        self::assertEquals(GeneralUtility::IPv6Bin2Hex($binary), $hex);
-    }
-
     ////////////////////////////////////////////////
     // Tests concerning normalizeIPv6 / compressIPv6
     ////////////////////////////////////////////////
@@ -432,26 +375,6 @@ class GeneralUtilityTest extends UnitTestCase
         self::assertEquals($normalized, GeneralUtility::normalizeIPv6($compressed));
     }
 
-    /**
-     * @test
-     * @dataProvider normalizeCompressIPv6DataProviderCorrect
-     */
-    public function compressIPv6CorrectlyCompressesAddresses($compressed, $normalized)
-    {
-        self::assertEquals($compressed, GeneralUtility::compressIPv6($normalized));
-    }
-
-    /**
-     * @test
-     */
-    public function compressIPv6CorrectlyCompressesAddressWithSomeAddressOnRightSide()
-    {
-        if (strtolower(PHP_OS) === 'darwin') {
-            self::markTestSkipped('This test does not work on OSX / Darwin OS.');
-        }
-        self::assertEquals('::f0f', GeneralUtility::compressIPv6('0000:0000:0000:0000:0000:0000:0000:0f0f'));
-    }
-
     ///////////////////////////////
     // Tests concerning validIP
     ///////////////////////////////
index 0ea1a51..cf0d101 100644 (file)
@@ -251,4 +251,92 @@ class GeneralUtilityTest extends UnitTestCase
 
         $requestFactory->request(Argument::any(), Argument::any(), ['headers' => $expectedHeaders])->shouldHaveBeenCalled();
     }
+
+    /**
+     * Data provider for IPv6Hex2BinCorrect
+     *
+     * @return array Data sets
+     */
+    public static function IPv6Hex2BinDataProviderCorrect()
+    {
+        return [
+            'empty 1' => ['::', str_pad('', 16, "\x00")],
+            'empty 2, already normalized' => ['0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")],
+            'already normalized' => ['0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"],
+            'expansion in middle 1' => ['1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"],
+            'expansion in middle 2' => ['beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider IPv6Hex2BinDataProviderCorrect
+     */
+    public function IPv6Hex2BinCorrectlyConvertsAddresses($hex, $binary)
+    {
+        self::assertTrue(GeneralUtility::IPv6Hex2Bin($hex) === $binary);
+    }
+
+    /**
+     * Data provider for IPv6Bin2HexCorrect
+     *
+     * @return array Data sets
+     */
+    public static function IPv6Bin2HexDataProviderCorrect()
+    {
+        return [
+            'empty' => [str_pad('', 16, "\x00"), '::'],
+            'non-empty front' => ["\x01" . str_pad('', 15, "\x00"), '100::'],
+            'non-empty back' => [str_pad('', 15, "\x00") . "\x01", '::1'],
+            'normalized' => ["\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78", '102:304::506:78'],
+            'expansion in middle 1' => ["\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02", '1::2'],
+            'expansion in middle 2' => ["\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa", 'beef::fefa'],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider IPv6Bin2HexDataProviderCorrect
+     */
+    public function IPv6Bin2HexCorrectlyConvertsAddresses($binary, $hex)
+    {
+        self::assertEquals(GeneralUtility::IPv6Bin2Hex($binary), $hex);
+    }
+
+    /**
+     * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat
+     *
+     * @return array Data sets
+     */
+    public static function normalizeCompressIPv6DataProviderCorrect()
+    {
+        return [
+            'empty' => ['::', '0000:0000:0000:0000:0000:0000:0000:0000'],
+            'localhost' => ['::1', '0000:0000:0000:0000:0000:0000:0000:0001'],
+            'expansion in middle 1' => ['1::2', '0001:0000:0000:0000:0000:0000:0000:0002'],
+            'expansion in middle 2' => ['1:2::3', '0001:0002:0000:0000:0000:0000:0000:0003'],
+            'expansion in middle 3' => ['1::2:3', '0001:0000:0000:0000:0000:0000:0002:0003'],
+            'expansion in middle 4' => ['1:2::3:4:5', '0001:0002:0000:0000:0000:0003:0004:0005']
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider normalizeCompressIPv6DataProviderCorrect
+     */
+    public function compressIPv6CorrectlyCompressesAddresses($compressed, $normalized)
+    {
+        self::assertEquals($compressed, GeneralUtility::compressIPv6($normalized));
+    }
+
+    /**
+     * @test
+     */
+    public function compressIPv6CorrectlyCompressesAddressWithSomeAddressOnRightSide()
+    {
+        if (strtolower(PHP_OS) === 'darwin') {
+            self::markTestSkipped('This test does not work on OSX / Darwin OS.');
+        }
+        self::assertEquals('::f0f', GeneralUtility::compressIPv6('0000:0000:0000:0000:0000:0000:0000:0f0f'));
+    }
 }
index cb9c216..85d856b 100644 (file)
@@ -33,6 +33,7 @@ use TYPO3\CMS\Core\Utility\PathUtility;
 use TYPO3\CMS\Core\Utility\RootlineUtility;
 use TYPO3\CMS\Extbase\Annotation as Extbase;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
+use TYPO3\CMS\IndexedSearch\Utility\IndexedSearchUtility;
 
 /**
  * Index search frontend
@@ -276,20 +277,20 @@ class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControlle
         $resultsets = [];
         foreach ($indexCfgs as $freeIndexUid) {
             // Get result rows
-            $tstamp1 = GeneralUtility::milliseconds();
+            $tstamp1 = IndexedSearchUtility::milliseconds();
             if ($hookObj = $this->hookRequest('getResultRows')) {
                 $resultData = $hookObj->getResultRows($this->searchWords, $freeIndexUid);
             } else {
                 $resultData = $this->searchRepository->doSearch($this->searchWords, $freeIndexUid);
             }
             // Display search results
-            $tstamp2 = GeneralUtility::milliseconds();
+            $tstamp2 = IndexedSearchUtility::milliseconds();
             if ($hookObj = $this->hookRequest('getDisplayResults')) {
                 $resultsets[$freeIndexUid] = $hookObj->getDisplayResults($this->searchWords, $resultData, $freeIndexUid);
             } else {
                 $resultsets[$freeIndexUid] = $this->getDisplayResults($this->searchWords, $resultData, $freeIndexUid);
             }
-            $tstamp3 = GeneralUtility::milliseconds();
+            $tstamp3 = IndexedSearchUtility::milliseconds();
             // Create header if we are searching more than one indexing configuration
             if (count($indexCfgs) > 1) {
                 if ($freeIndexUid > 0) {
index cd97341..8a55198 100644 (file)
@@ -347,7 +347,7 @@ class Indexer
                 }
                 $this->log_pull();
                 // Set parsetime
-                $this->updateParsetime($this->hash['phash'], GeneralUtility::milliseconds() - $Pstart);
+                $this->updateParsetime($this->hash['phash'], IndexedSearchUtility::milliseconds() - $Pstart);
                 // Checking external files if configured for.
                 $this->log_push('Checking external files', '');
                 if ($this->conf['index_externals']) {
@@ -926,7 +926,7 @@ class Indexer
                                     }
                                     $this->log_pull();
                                     // Set parsetime
-                                    $this->updateParsetime($phash_arr['phash'], GeneralUtility::milliseconds() - $Pstart);
+                                    $this->updateParsetime($phash_arr['phash'], IndexedSearchUtility::milliseconds() - $Pstart);
                                 } else {
                                     // Update the timestamp
                                     $this->updateTstamp($phash_arr['phash'], $fileInfo['mtime']);
index a4fef6f..b2f0f50 100644 (file)
@@ -163,4 +163,14 @@ class IndexedSearchUtility
 
         return null;
     }
+
+    /**
+     * Gets the unixtime as milliseconds.
+     *
+     * @return int The unixtime as milliseconds
+     */
+    public static function milliseconds()
+    {
+        return round(microtime(true) * 1000);
+    }
 }
index e038460..f0d1361 100644 (file)
@@ -980,4 +980,46 @@ return [
             'Deprecation-90147-UnifiedFileNameValidator.rst'
         ],
     ],
+    'TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Hex2Bin' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 1,
+        'restFiles' => [
+            'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst'
+        ],
+    ],
+    'TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Bin2Hex' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 1,
+        'restFiles' => [
+            'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst'
+        ],
+    ],
+    'TYPO3\CMS\Core\Utility\GeneralUtility::compressIPv6' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 1,
+        'restFiles' => [
+            'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst'
+        ],
+    ],
+    'TYPO3\CMS\Core\Utility\GeneralUtility::milliseconds' => [
+        'numberOfMandatoryArguments' => 0,
+        'maximumNumberOfArguments' => 0,
+        'restFiles' => [
+            'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst'
+        ],
+    ],
+    'TYPO3\CMS\Core\Utility\GeneralUtility::linkThisUrl' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 2,
+        'restFiles' => [
+            'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst'
+        ],
+    ],
+    'TYPO3\CMS\Core\Utility\GeneralUtility::flushDirectory' => [
+        'numberOfMandatoryArguments' => 1,
+        'maximumNumberOfArguments' => 3,
+        'restFiles' => [
+            'Deprecation-91001-VariousMethodsWithinGeneralUtility.rst'
+        ],
+    ],
 ];