Commit cb355fa5 authored by Benni Mack's avatar Benni Mack
Browse files

[TASK] Do not use custom "getInstance()" methods on Singleton interfaces

There was a time when new code for TYPO3 Core was introduced
by using "MyClass::getInstance()" to act as a factory for this
class, which _would_ be OK if these classes are actually prototypes
and not services (or singleton services), as GeneralUtility::makeInstance()
or DI via Services.yaml works as well.

This change deprecates all getInstance methods around such code
with GeneralUtility::makeInstance() calls. At a later point, proper DI
can be introduced in these cases.

* TYPO3\CMS\Core\Resource\Index\ExtractorRegistry::getInstance()
* TYPO3\CMS\Core\Resource\Index\FileIndexRepository::getInstance()
* TYPO3\CMS\Core\Resource\Index\MetaDataRepository::getInstance()
* TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry::getInstance()
* TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::getInstance()
* TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry::getInstance()
* TYPO3\CMS\Form\Service\TranslationService::getInstance()
* TYPO3\CMS\T3editor\Registry\AddonRegistry::getInstance()
* TYPO3\CMS\T3editor\Registry\ModeRegistry::getInstance()

Resolves: #95326
Releases: master
Change-Id: Ie3160c67792e115cf5488dc800bd717c0b913ab9
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/71178

Tested-by: core-ci's avatarcore-ci <typo3@b13.com>
Tested-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Tested-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Tested-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
Reviewed-by: Wouter Wolters's avatarWouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Oliver Bartsch's avatarOliver Bartsch <bo@cedev.de>
Reviewed-by: Benni Mack's avatarBenni Mack <benni@typo3.org>
parent beb53574
......@@ -129,7 +129,7 @@ class OnlineMediaController
if ($targetFolder === null) {
$targetFolder = $this->getBackendUser()->getDefaultUploadFolder();
}
return OnlineMediaHelperRegistry::getInstance()->transformUrlToFile($url, $targetFolder, $allowedExtensions);
return GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->transformUrlToFile($url, $targetFolder, $allowedExtensions);
}
/**
......
......@@ -535,7 +535,7 @@ class InlineControlContainer extends AbstractContainer
$isDirectFileUploadEnabled = (bool)$backendUser->uc['edit_docModuleUpload'];
$allowedArray = GeneralUtility::trimExplode(',', $allowed, true);
$onlineMediaAllowed = OnlineMediaHelperRegistry::getInstance()->getSupportedFileExtensions();
$onlineMediaAllowed = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getSupportedFileExtensions();
if (!empty($allowedArray)) {
$onlineMediaAllowed = array_intersect($allowedArray, $onlineMediaAllowed);
}
......
......@@ -40,9 +40,11 @@ class ExtractorRegistry implements SingletonInterface
* Returns an instance of this class
*
* @return ExtractorRegistry
* @deprecated will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.
*/
public static function getInstance()
{
trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
return GeneralUtility::makeInstance(self::class);
}
......
......@@ -64,9 +64,11 @@ class FileIndexRepository implements SingletonInterface
* Returns an Instance of the Repository
*
* @return FileIndexRepository
* @deprecated will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.
*/
public static function getInstance()
{
trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
return GeneralUtility::makeInstance(self::class);
}
......
......@@ -398,7 +398,7 @@ class Indexer implements LoggerAwareInterface
*/
protected function getFileIndexRepository()
{
return FileIndexRepository::getInstance();
return GeneralUtility::makeInstance(FileIndexRepository::class);
}
/**
......@@ -408,7 +408,7 @@ class Indexer implements LoggerAwareInterface
*/
protected function getMetaDataRepository()
{
return MetaDataRepository::getInstance();
return GeneralUtility::makeInstance(MetaDataRepository::class);
}
/**
......
......@@ -239,9 +239,11 @@ class MetaDataRepository implements SingletonInterface
/**
* @return MetaDataRepository
* @deprecated will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.
*/
public static function getInstance()
{
trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
return GeneralUtility::makeInstance(self::class);
}
}
......@@ -139,7 +139,7 @@ abstract class AbstractOnlineMediaHelper implements OnlineMediaHelperInterface
*/
protected function getFileIndexRepository()
{
return FileIndexRepository::getInstance();
return GeneralUtility::makeInstance(FileIndexRepository::class);
}
/**
......
......@@ -29,9 +29,11 @@ class OnlineMediaHelperRegistry implements SingletonInterface
* Returns an instance of this class
*
* @return OnlineMediaHelperRegistry
* @deprecated will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.
*/
public static function getInstance()
{
trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
return GeneralUtility::makeInstance(self::class);
}
......
......@@ -17,8 +17,8 @@ namespace TYPO3\CMS\Core\Resource\OnlineMedia\Metadata;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Index\ExtractorInterface;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperInterface;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Class Extractor
......@@ -74,7 +74,7 @@ class Extractor implements ExtractorInterface
*/
public function canProcess(File $file)
{
return OnlineMediaHelperRegistry::getInstance()->getOnlineMediaHelper($file) !== false;
return GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($file) !== false;
}
/**
......@@ -87,8 +87,7 @@ class Extractor implements ExtractorInterface
*/
public function extractMetaData(File $file, array $previousExtractedData = [])
{
/** @var OnlineMediaHelperInterface $helper */
$helper = OnlineMediaHelperRegistry::getInstance()->getOnlineMediaHelper($file);
$helper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($file);
return $helper !== false ? $helper->getMetaData($file) : [];
}
}
......@@ -30,7 +30,7 @@ final class PreviewProcessing implements ProcessorInterface
{
return $task->getType() === 'Image'
&& in_array($task->getName(), ['Preview', 'CropScaleMask'], true)
&& ($helperRegistry = OnlineMediaHelperRegistry::getInstance())->hasOnlineMediaHelper(($sourceFile = $task->getSourceFile())->getExtension())
&& ($helperRegistry = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class))->hasOnlineMediaHelper(($sourceFile = $task->getSourceFile())->getExtension())
&& ($previewImageFile = $helperRegistry->getOnlineMediaHelper($sourceFile)->getPreviewImage($sourceFile))
&& !empty($previewImageFile)
&& file_exists($previewImageFile);
......@@ -42,7 +42,7 @@ final class PreviewProcessing implements ProcessorInterface
GeneralUtility::makeInstance(LocalImageProcessor::class)
->processTaskWithLocalFile(
$task,
OnlineMediaHelperRegistry::getInstance()
GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)
->getOnlineMediaHelper($file)
->getPreviewImage($file)
);
......
......@@ -42,9 +42,11 @@ class RendererRegistry implements SingletonInterface
* Returns an instance of this class
*
* @return RendererRegistry
* @deprecated will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.
*/
public static function getInstance()
{
trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
return GeneralUtility::makeInstance(self::class);
}
......
......@@ -20,6 +20,7 @@ use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Resource\FileReference;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperInterface;
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Vimeo renderer class
......@@ -70,7 +71,7 @@ class VimeoRenderer implements FileRendererInterface
$orgFile = $orgFile->getOriginalFile();
}
if ($orgFile instanceof File) {
$this->onlineMediaHelper = OnlineMediaHelperRegistry::getInstance()->getOnlineMediaHelper($orgFile);
$this->onlineMediaHelper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($orgFile);
} else {
$this->onlineMediaHelper = false;
}
......
......@@ -71,7 +71,7 @@ class YouTubeRenderer implements FileRendererInterface
$orgFile = $orgFile->getOriginalFile();
}
if ($orgFile instanceof File) {
$this->onlineMediaHelper = OnlineMediaHelperRegistry::getInstance()->getOnlineMediaHelper($orgFile);
$this->onlineMediaHelper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($orgFile);
} else {
$this->onlineMediaHelper = false;
}
......
......@@ -509,6 +509,6 @@ class ResourceFactory implements SingletonInterface
*/
protected function getFileIndexRepository()
{
return FileIndexRepository::getInstance();
return GeneralUtility::makeInstance(FileIndexRepository::class);
}
}
......@@ -1377,7 +1377,7 @@ class ResourceStorage implements ResourceStorageInterface
if (
$publicUrl === null
&& $resourceObject instanceof File
&& ($helper = OnlineMediaHelperRegistry::getInstance()->getOnlineMediaHelper($resourceObject)) !== false
&& ($helper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($resourceObject)) !== false
) {
$publicUrl = $helper->getPublicUrl($resourceObject, $relativeToCurrentScript);
}
......@@ -2694,7 +2694,7 @@ class ResourceStorage implements ResourceStorageInterface
*/
protected function getFileIndexRepository()
{
return FileIndexRepository::getInstance();
return GeneralUtility::makeInstance(FileIndexRepository::class);
}
/**
......
......@@ -20,6 +20,7 @@ namespace TYPO3\CMS\Core\Resource\Service;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Index\ExtractorInterface;
use TYPO3\CMS\Core\Resource\Index\ExtractorRegistry;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Service class to extract metadata
......@@ -95,6 +96,6 @@ class ExtractorService
*/
protected function getExtractorRegistry(): ExtractorRegistry
{
return ExtractorRegistry::getInstance();
return GeneralUtility::makeInstance(ExtractorRegistry::class);
}
}
......@@ -42,9 +42,11 @@ class TextExtractorRegistry implements SingletonInterface
* Returns an instance of this class
*
* @return TextExtractorRegistry
* @deprecated will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.
*/
public static function getInstance()
{
trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
return GeneralUtility::makeInstance(__CLASS__);
}
......
.. include:: ../../Includes.txt
====================================================================================
Deprecation: #95326 - Various "getInstance()" static methods on Singleton interfaces
====================================================================================
See :issue:`95326`
Description
===========
A few classes within TYPO3 Core have a static method :php:`getInstance()` which acts as a wrapper
for the constructor which originally was meant as a performance
improvement as pseudo-singleton concept in TYPO3 v6.
With Dependency Injection, these classes can be injected or instantiated directly without any performance penalties.
Therefore the following methods have been marked as deprecated:
* :php:`TYPO3\CMS\Core\Resource\Index\ExtractorRegistry::getInstance()`
* :php:`TYPO3\CMS\Core\Resource\Index\FileIndexRepository::getInstance()`
* :php:`TYPO3\CMS\Core\Resource\Index\MetaDataRepository::getInstance()`
* :php:`TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry::getInstance()`
* :php:`TYPO3\CMS\Core\Resource\Rendering\RendererRegistry::getInstance()`
* :php:`TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry::getInstance()`
* :php:`TYPO3\CMS\Form\Service\TranslationService::getInstance()`
* :php:`TYPO3\CMS\T3editor\Registry\AddonRegistry::getInstance()`
* :php:`TYPO3\CMS\T3editor\Registry\ModeRegistry::getInstance()`
Impact
======
Calling the methods directly in third-party PHP code will trigger a PHP :php:`E_USER_DEPRECATED` error.
Affected Installations
======================
Any TYPO3 installation with custom PHP code calling the methods.
Migration
=========
Check TYPO3's "Extension Scanner" in the Install Tool if you're affected and replace with constructor injection via Dependency
Injection if possible, or use :php:`GeneralUtility::makeInstance()` instead.
.. index:: PHP-API, PartiallyScanned, ext:core
\ No newline at end of file
......@@ -209,7 +209,7 @@ class RendererRegistryTest extends UnitTestCase
public function getRendererReturnsCorrectInstance2(): void
{
$this->resetSingletonInstances = true;
$rendererRegistry = RendererRegistry::getInstance();
$rendererRegistry = new RendererRegistry();
$rendererRegistry->registerRendererClass(AudioTagRenderer::class);
$rendererRegistry->registerRendererClass(VideoTagRenderer::class);
......
......@@ -42,18 +42,18 @@ $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['proc
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['dumpFile'] = FileDumpController::class . '::dumpAction';
$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['requirejs'] = RequireJsController::class . '::retrieveConfiguration';
$rendererRegistry = RendererRegistry::getInstance();
$rendererRegistry = GeneralUtility::makeInstance(RendererRegistry::class);
$rendererRegistry->registerRendererClass(AudioTagRenderer::class);
$rendererRegistry->registerRendererClass(VideoTagRenderer::class);
$rendererRegistry->registerRendererClass(YouTubeRenderer::class);
$rendererRegistry->registerRendererClass(VimeoRenderer::class);
unset($rendererRegistry);
$textExtractorRegistry = TextExtractorRegistry::getInstance();
$textExtractorRegistry = GeneralUtility::makeInstance(TextExtractorRegistry::class);
$textExtractorRegistry->registerTextExtractor(PlainTextExtractor::class);
unset($textExtractorRegistry);
$extractorRegistry = ExtractorRegistry::getInstance();
$extractorRegistry = GeneralUtility::makeInstance(ExtractorRegistry::class);
$extractorRegistry->registerExtractionService(Extractor::class);
unset($extractorRegistry);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment