[TASK] Switch Locales to regular singleton instance 46/61046/5
authorBenni Mack <benni@typo3.org>
Mon, 17 Jun 2019 04:50:52 +0000 (06:50 +0200)
committerAndreas Fernandez <a.fernandez@scripting-base.de>
Mon, 17 Jun 2019 14:02:43 +0000 (16:02 +0200)
Locales resolves the user-defined TYPO3-languages and
its dependencies via TYPO3_CONF_VARS, which are only
finally available when all extensions' ext_localconf.php is included.

For this reason, Locales::initialize() can be deprecated
and moved into the regular constructor, but then the Bootstrap
should not do the initialization anymore, which happens
at the point now, when Locales first gets initialized (which
happens in Frontend within TSFE and PageRenderer and
in Backend within $LANG).

For this reason, it is removed from Bootstrap, where it was
first placed in TYPO3 4.6 when no proper bootstrap
set up was given.

Resolves: #88569
Releases: master
Change-Id: Ife2e248412c1b206abffcdd21df0d01e44834cea
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/61046
Tested-by: Benjamin Franzke <bfr@qbus.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: TYPO3com <noreply@typo3.com>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
typo3/sysext/core/Classes/Core/Bootstrap.php
typo3/sysext/core/Classes/Localization/LanguageService.php
typo3/sysext/core/Classes/Localization/Locales.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-88569-LocalesinitializeInFavorOfRegularSingletonInstance.rst [new file with mode: 0644]
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallStaticMatcher.php

index baae88c..36c481f 100644 (file)
@@ -30,7 +30,6 @@ use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend;
 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
 use TYPO3\CMS\Core\Imaging\IconRegistry;
 use TYPO3\CMS\Core\IO\PharStreamWrapperInterceptor;
-use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Log\LogManager;
 use TYPO3\CMS\Core\Package\FailsafePackageManager;
 use TYPO3\CMS\Core\Package\PackageManager;
@@ -102,7 +101,6 @@ class Bootstrap
         static::initializeRuntimeActivatedPackagesFromConfiguration($packageManager);
 
         static::setDefaultTimezone();
-        $locales = Locales::initialize();
         static::setMemoryLimit();
 
         $assetsCache = static::createCache('assets', $disableCaching);
@@ -131,7 +129,6 @@ class Bootstrap
             'cache.assets' => $assetsCache,
             CacheManager::class => $cacheManager,
             PackageManager::class => $packageManager,
-            Locales::class => $locales,
         ];
 
         return new class($defaultContainerEntries) implements ContainerInterface {
index ae277e5..e1ea162 100644 (file)
@@ -90,10 +90,9 @@ class LanguageService
     public function init($languageKey)
     {
         // Find the requested language in this list based on the $languageKey
-        /** @var \TYPO3\CMS\Core\Localization\Locales $locales */
         $locales = GeneralUtility::makeInstance(Locales::class);
         // Language is found. Configure it:
-        if (in_array($languageKey, $locales->getLocales())) {
+        if (in_array($languageKey, $locales->getLocales(), true)) {
             // The current language key
             $this->lang = $languageKey;
             $this->languageDependencies[] = $languageKey;
index 0dcd7d6..abdefcb 100644 (file)
@@ -126,31 +126,36 @@ class Locales implements SingletonInterface
         'fr_CA' => ['fr']
     ];
 
-    /**
-     * Initializes the languages.
-     * @return Locales
-     */
-    public static function initialize(): Locales
+    public function __construct()
     {
-        $instance = GeneralUtility::makeInstance(self::class);
         // Allow user-defined locales
         foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['user'] ?? [] as $locale => $name) {
-            if (!isset($instance->languages[$locale])) {
-                $instance->languages[$locale] = $name;
+            if (!isset($this->languages[$locale])) {
+                $this->languages[$locale] = $name;
             }
             // Initializes the locale dependencies with TYPO3 supported locales
             if (strlen($locale) === 5) {
-                $instance->localeDependencies[$locale] = [substr($locale, 0, 2)];
+                $this->localeDependencies[$locale] = [substr($locale, 0, 2)];
             }
         }
         // Merge user-provided locale dependencies
         if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['dependencies'] ?? null)) {
-            $instance->localeDependencies = array_replace_recursive(
-                $instance->localeDependencies,
+            $this->localeDependencies = array_replace_recursive(
+                $this->localeDependencies,
                 $GLOBALS['TYPO3_CONF_VARS']['SYS']['localization']['locales']['dependencies']
             );
         }
-        return $instance;
+    }
+
+    /**
+     * Initializes the languages.
+     * @return Locales
+     * @deprecated will be removed in TYPO3 v11.0. Use the regular constructor instead.
+     */
+    public static function initialize(): Locales
+    {
+        trigger_error('Locales::initialize() will be removed in TYPO3 v11.0, fetch the instance of a class via GeneralUtility::makeInstance() or DependencyInjection', E_USER_DEPRECATED);
+        return new self;
     }
 
     /**
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-88569-LocalesinitializeInFavorOfRegularSingletonInstance.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-88569-LocalesinitializeInFavorOfRegularSingletonInstance.rst
new file mode 100644 (file)
index 0000000..998890a
--- /dev/null
@@ -0,0 +1,39 @@
+.. include:: ../../Includes.txt
+
+==================================================================================
+Deprecation: #88569 - Locales::initialize() in favor of regular singleton instance
+==================================================================================
+
+See :issue:`88569`
+
+Description
+===========
+
+The method :php:`Locales::initialize()` has been deprecated. It was a workaround to re-initialize
+the Singleton Instance of the PHP class `Locales` for user-defined locales, which were
+loaded by an extensions' `ext_localconf.php`.
+
+Locales is now initialized only when needed, and not during the early bootstrap process,
+making this functionality obsolete, as this is taken care of within the regular constructor.
+
+
+Impact
+======
+
+Calling :php:`Locales::initialize()` will trigger a deprecation notice.
+
+
+Affected Installations
+======================
+
+Any TYPO3 installation with a third-party extension calling `Locales::initialize()` directly.
+
+
+Migration
+=========
+
+Replace the function call by a regular :php:`GeneralUtility::makeInstance(Locales::class);` call
+or use Dependency Injection (Constructor Injection or ObjectManager) to fetch an instance of
+the Locales class.
+
+.. index:: PHP-API, FullyScanned
\ No newline at end of file
index c136f1d..7e9b9c0 100644 (file)
@@ -1929,8 +1929,6 @@ class TypoScriptFrontendController implements LoggerAwareInterface
             GeneralUtility::callUserFunction($_funcRef, $_params, $this);
         }
 
-        Locales::initialize();
-
         $siteLanguage = $this->getCurrentSiteLanguage();
         if (!$siteLanguage) {
             throw new PageNotFoundException('Frontend cannot be displayed, as there is no language available', 1557924417);
index 3e7895f..bbd9dd8 100644 (file)
@@ -910,4 +910,11 @@ return [
             'Breaking-87957-DoNotMagicallyRegisterValidators.rst',
         ],
     ],
+    'TYPO3\CMS\Core\Localization\Locales::initialize' => [
+        'numberOfMandatoryArguments' => 0,
+        'maximumNumberOfArguments' => 0,
+        'restFiles' => [
+            'Deprecation-88569-LocalesinitializeInFavorOfRegularSingletonInstance.rst',
+        ],
+    ],
 ];