Skip to content

Latest commit

 

History

History
3437 lines (2546 loc) · 101 KB

all_rectors_overview.md

File metadata and controls

3437 lines (2546 loc) · 101 KB

155 Rules Overview


Categories


CodeQuality

AddErrorCodeToExceptionRector

Add timestamp error code to exceptions

-throw new \RuntimeException('my message');
+throw new \RuntimeException('my message', 1729021897);

ConvertImplicitVariablesToExplicitGlobalsRector

Convert $TYPO3_CONF_VARS to $GLOBALS['TYPO3_CONF_VARS']

-$TYPO3_CONF_VARS['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postUserLookUp']['foo'] = 'FooBarBaz->handle';
+$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['postUserLookUp']['foo'] = 'FooBarBaz->handle';

ExtEmConfRector

Refactor file ext_emconf.php

🔧 configure it!

 $EM_CONF[$_EXTKEY] = [
     'title' => 'Package Extension',
     'description' => 'Package Extension',
     'category' => 'fe',
-    'shy' => 0,
     'version' => '2.0.1',
-    'dependencies' => '',
-    'conflicts' => '',
-    'priority' => '',
-    'loadOrder' => '',
-    'module' => '',
     'state' => 'stable',
-    'uploadfolder' => 0,
-    'createDirs' => '',
-    'modify_tables' => '',
-    'clearcacheonload' => 0,
-    'lockType' => '',
     'author' => 'Max Mustermann',
     'author_email' => '[email protected]',
     'author_company' => 'Mustermann GmbH',
-    'CGLcompliance' => '',
-    'CGLcompliance_note' => '',
     'constraints' => [
         'depends' => [
             'php' => '5.6.0-0.0.0',
             'typo3' => '7.6.0-8.99.99',
         ],
         'conflicts' => [],
         'suggests' => [],
     ],
     'autoload' => [
         'psr-4' => [
             'Foo\\Bar\\' => 'Classes/',
         ],
     ],
-    '_md5_values_when_last_written' => 'a:0:{}',
 ];

InjectMethodToConstructorInjectionRector

Replace inject method to constructor injection

 namespace App\Service;

 use \TYPO3\CMS\Core\Cache\CacheManager;

 class Service
 {
     private CacheManager $cacheManager;

-    public function injectCacheManager(CacheManager $cacheManager): void
+    public function __construct(CacheManager $cacheManager)
     {
         $this->cacheManager = $cacheManager;
     }
 }

MethodGetInstanceToMakeInstanceCallRector

Use GeneralUtility::makeInstance instead of getInstance call

🔧 configure it!

-$instance = TYPO3\CMS\Core\Resource\Index\ExtractorRegistry::getInstance();
+use TYPO3\CMS\Core\Resource\Index\ExtractorRegistry;
+
+$instance = GeneralUtility::makeInstance(ExtractorRegistry::class);

MoveExtensionManagementUtilityAddStaticFileIntoTCAOverridesRector

Move ExtensionManagementUtility::addStaticFile into Configuration/TCA/Overrides/sys_template.php

-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('extensionKey', 'Configuration/TypoScript', 'Title');
+// Move to file Configuration/TCA/Overrides/sys_template.php

MoveExtensionManagementUtilityAddToAllTCAtypesIntoTCAOverridesRector

Move ExtensionManagementUtility::addToAllTCAtypes into table specific Configuration/TCA/Overrides file

-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('table', 'new_field', '', 'after:existing_field');
+// Move to table specific Configuration/TCA/Overrides/table.php file

MoveExtensionUtilityRegisterPluginIntoTCAOverridesRector

Move ExtensionUtility::registerPlugin into Configuration/TCA/Overrides/tt_content.php

-\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin('extension_key', 'Pi1', 'Title');
+// Move to file Configuration/TCA/Overrides/tt_content.php

RenameClassMapAliasRector

Replaces defined classes by new ones.

🔧 configure it!

 namespace App;

-use t3lib_div;
+use TYPO3\CMS\Core\Utility\GeneralUtility;

 function someFunction()
 {
-    t3lib_div::makeInstance(\tx_cms_BackendLayout::class);
+    GeneralUtility::makeInstance(\TYPO3\CMS\Backend\View\BackendLayoutView::class);
 }

UseExtensionKeyInLocalizationUtilityRector

Replace the second parameter of LocalizationUtility::translate to the extension name

-LocalizationUtility::translate('key', 'extension_key');
+LocalizationUtility::translate('key', 'ExtensionName');

General

ConstantsToBackedEnumValueRector

Migrate all FILETYPE_* constants from AbstractFile to FileType enum class

🔧 configure it!

-\TYPO3\CMS\Core\Resource\AbstractFile::FILETYPE_UNKNOWN;
+\TYPO3\CMS\Core\Resource\FileType::UNKNOWN;

RenameAttributeRector

Rename Attribute

🔧 configure it!

-#[Controller]
+#[AsController]

TYPO310

BackendUtilityEditOnClickRector

Migrate the method BackendUtility::editOnClick() to use UriBuilder API

 $pid = 2;
 $params = '&edit[pages][' . $pid . ']=new&returnNewPageId=1';
-$url = BackendUtility::editOnClick($params);
+$url = GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute('record_edit') . $params . '&returnUrl=' . rawurlencode(GeneralUtility::getIndpEnv('REQUEST_URI'));;

BackendUtilityGetViewDomainToPageRouterRector

Refactor method call BackendUtility::getViewDomain() to PageRouter

-use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Site\SiteFinder;
+use TYPO3\CMS\Core\Utility\GeneralUtility;

-$domain1 = BackendUtility::getViewDomain(1);
+$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId(1);
+$domain1 = $site->getRouter()->generateUri(1);

ChangeDefaultCachingFrameworkNamesRector

Use new default cache names like core instead of cache_core)

 $cacheManager = GeneralUtility::makeInstance(CacheManager::class);
-$cacheManager->getCache('cache_core');
-$cacheManager->getCache('cache_hash');
-$cacheManager->getCache('cache_pages');
-$cacheManager->getCache('cache_pagesection');
-$cacheManager->getCache('cache_runtime');
-$cacheManager->getCache('cache_rootline');
-$cacheManager->getCache('cache_imagesizes');
+$cacheManager->getCache('core');
+$cacheManager->getCache('hash');
+$cacheManager->getCache('pages');
+$cacheManager->getCache('pagesection');
+$cacheManager->getCache('runtime');
+$cacheManager->getCache('rootline');
+$cacheManager->getCache('imagesizes');

ConfigurationManagerAddControllerConfigurationMethodRector

Add additional method getControllerConfiguration for AbstractConfigurationManager

 final class MyExtbaseConfigurationManager extends AbstractConfigurationManager
 {
     protected function getSwitchableControllerActions($extensionName, $pluginName)
     {
         $switchableControllerActions = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions'][$extensionName]['modules'][$pluginName]['controllers'] ?? false;
         if ( ! is_array($switchableControllerActions)) {
             $switchableControllerActions = [];
         }

         return $switchableControllerActions;
     }
+
+    protected function getControllerConfiguration($extensionName, $pluginName): array
+    {
+        return $this->getSwitchableControllerActions($extensionName, $pluginName);
+    }
 }

ExcludeServiceKeysToArrayRector

Change parameter $excludeServiceKeys explicitly to an array

-GeneralUtility::makeInstanceService('serviceType', 'serviceSubType', 'key1, key2');
-ExtensionManagementUtility::findService('serviceType', 'serviceSubType', 'key1, key2');
+GeneralUtility::makeInstanceService('serviceType', 'serviceSubType', ['key1', 'key2']);
+ExtensionManagementUtility::findService('serviceType', 'serviceSubType', ['key1', 'key2']);

ForceTemplateParsingInTsfeAndTemplateServiceRector

Force template parsing in tsfe is replaced with context api and aspects

-$myVariable = $GLOBALS['TSFE']->forceTemplateParsing;
-$myVariable2 = $GLOBALS['TSFE']->tmpl->forceTemplateParsing;
+$myVariable = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Context\Context::class)->getPropertyFromAspect('typoscript', 'forcedTemplateParsing');
+$myVariable2 = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Context\Context::class)->getPropertyFromAspect('typoscript', 'forcedTemplateParsing');

-$GLOBALS['TSFE']->forceTemplateParsing = true;
-$GLOBALS['TSFE']->tmpl->forceTemplateParsing = true;
+\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Context\Context::class)->setAspect('typoscript', \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Context\TypoScriptAspect::class, true));
+\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Context\Context::class)->setAspect('typoscript', \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Context\TypoScriptAspect::class, true));

InjectEnvironmentServiceIfNeededInResponseRector

Inject EnvironmentService if needed in subclass of Response

 class MyResponse extends Response
 {
+    /**
+     * @var \TYPO3\CMS\Extbase\Service\EnvironmentService
+     */
+    protected $environmentService;
+
     public function myMethod()
     {
         if ($this->environmentService->isEnvironmentInCliMode()) {

         }
+    }
+
+    public function injectEnvironmentService(\TYPO3\CMS\Extbase\Service\EnvironmentService $environmentService)
+    {
+        $this->environmentService = $environmentService;
     }
 }

 class MyOtherResponse extends Response
 {
     public function myMethod()
     {

     }
 }

MoveApplicationContextToEnvironmentApiRector

Use Environment API to fetch application context

-GeneralUtility::getApplicationContext();
+Environment::getContext();

RefactorCHashArrayOfTSFERector

Refactor Internal public property cHash_array

-$cHash_array = $GLOBALS['TSFE']->cHash_array;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\HttpUtility;
+use TYPO3\CMS\Frontend\Page\CacheHashCalculator;
+
+$relevantParametersForCachingFromPageArguments = [];
+$pageArguments = $GLOBALS['REQUEST']->getAttribute('routing');
+$queryParams = $pageArguments->getDynamicArguments();
+if (!empty($queryParams) && ($pageArguments->getArguments()['cHash'] ?? false)) {
+    $queryParams['id'] = $pageArguments->getPageId();
+    $relevantParametersForCachingFromPageArguments = GeneralUtility::makeInstance(CacheHashCalculator::class)->getRelevantParameters(HttpUtility::buildQueryString($queryParams));
+}
+$cHash_array = $relevantParametersForCachingFromPageArguments;

RefactorIdnaEncodeMethodToNativeFunctionRector

Use native function idn_to_ascii instead of GeneralUtility::idnaEncode

-$domain = GeneralUtility::idnaEncode('domain.com');
-$email = GeneralUtility::idnaEncode('[email protected]');
+$domain = idn_to_ascii('domain.com', IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);
+$email = 'email@' . idn_to_ascii('domain.com', IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46);

RefactorInternalPropertiesOfTSFERector

Refactor Internal public TSFE properties

-$domainStartPage = $GLOBALS['TSFE']->domainStartPage;
+$cHash = $GLOBALS['REQUEST']->getAttribute('routing')->getArguments()['cHash'];

RegisterPluginWithVendorNameRector

Remove vendor name from registerPlugin call

 \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
-   'TYPO3.CMS.Form',
+   'Form',
    'Formframework',
    'Form',
    'content-form'
 );

RemoveEnableMultiSelectFilterTextfieldRector

Remove "enableMultiSelectFilterTextfield" => true as its default

 return [
     'columns' => [
         'foo' => [
             'label' => 'foo',
             'config' => [
                 'type' => 'select',
                 'renderType' => 'selectMultipleSideBySide',
-                'enableMultiSelectFilterTextfield' => true,
             ],
         ],
     ],
 ];

RemoveExcludeOnTransOrigPointerFieldRector

transOrigPointerField is not longer allowed to be excluded

 return [
     'ctrl' => [
         'transOrigPointerField' => 'l10n_parent',
     ],
     'columns' => [
         'l10n_parent' => [
-            'exclude' => true,
             'config' => [
                 'type' => 'select',
             ],
         ],
     ],
 ];

RemoveFormatConstantsEmailFinisherRector

Remove constants FORMAT_PLAINTEXT and FORMAT_HTML of class TYPO3\CMS\Form\Domain\Finishers\EmailFinisher

-$this->setOption(self::FORMAT, EmailFinisher::FORMAT_HTML);
+$this->setOption('addHtmlPart', true);

RemovePropertyExtensionNameRector

Use method getControllerExtensionName from $request property instead of removed property $extensionName

 class MyCommandController extends CommandController
 {
     public function myMethod()
     {
-        if ($this->extensionName === 'whatever') {
+        if ($this->request->getControllerExtensionName() === 'whatever') {

         }

-        $extensionName = $this->extensionName;
+        $extensionName = $this->request->getControllerExtensionName();
     }
 }

RemoveSeliconFieldPathRector

TCA option "selicon_field_path" removed

 return [
     'ctrl' => [
         'selicon_field' => 'icon',
-        'selicon_field_path' => 'uploads/media'
     ],
 ];

RemoveShowRecordFieldListInsideInterfaceSectionRector

Remove showRecordFieldList inside section interface

 return [
     'ctrl' => [
     ],
-    'interface' => [
-        'showRecordFieldList' => 'foo,bar,baz',
-    ],
     'columns' => [
     ],
 ];

RemoveShowRemovedLocalizationRecordsRector

Remove showRemovedLocalizationRecords from inline TCA configurations.

 return [
     'columns' => [
         'falFileRelation' => [
             'config' => [
                 'type' => 'inline',
                 'appearance' => [
                     'showPossibleLocalizationRecords' => false,
-                    'showRemovedLocalizationRecords' => false,
                 ],
             ],
         ],
     ],
 ];

RemoveTcaOptionSetToDefaultOnCopyRector

TCA option setToDefaultOnCopy removed

 return [
     'ctrl' => [
-        'selicon_field' => 'icon',
-        'setToDefaultOnCopy' => 'foo'
+        'selicon_field' => 'icon'
     ],
     'columns' => [
     ],
 ];

SendNotifyEmailToMailApiRector

Refactor ContentObjectRenderer::sendNotifyEmail to MailMessage-API

-$GLOBALS['TSFE']->cObj->sendNotifyEmail("Subject\nMessage", '[email protected]', '[email protected]', '[email protected]');
+use Symfony\Component\Mime\Address;
+use TYPO3\CMS\Core\Mail\MailMessage;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\MailUtility;$success = false;
+
+$mail = GeneralUtility::makeInstance(MailMessage::class);
+$message = trim("Subject\nMessage");
+$senderName = trim(null);
+$senderAddress = trim('[email protected]');
+
+if ($senderAddress !== '') {
+    $mail->from(new Address($senderAddress, $senderName));
+}
+
+if ($message !== '') {
+    $messageParts = explode(LF, $message, 2);
+    $subject = trim($messageParts[0]);
+    $plainMessage = trim($messageParts[1]);
+    $parsedRecipients = MailUtility::parseAddresses('[email protected]');
+    if (!empty($parsedRecipients)) {
+        $mail->to(...$parsedRecipients)->subject($subject)->text($plainMessage);
+        $mail->send();
+    }
+    $success = true;
+}

SetSystemLocaleFromSiteLanguageRector

Refactor TypoScriptFrontendController->settingLocale() to Locales::setSystemLocaleFromSiteLanguage()

+use TYPO3\CMS\Core\Localization\Locales;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

 $controller = GeneralUtility::makeInstance(TypoScriptFrontendController::class, null, 0, 0);
-$controller->settingLocale();
+Locales::setSystemLocaleFromSiteLanguage($controller->getLanguage());

SubstituteGeneralUtilityMethodsWithNativePhpFunctionsRector

Substitute deprecated method calls of class GeneralUtility

 use TYPO3\CMS\Core\Utility\GeneralUtility;

 $hex = '127.0.0.1';
-GeneralUtility::IPv6Hex2Bin($hex);
+inet_pton($hex);
 $bin = $packed = chr(127) . chr(0) . chr(0) . chr(1);
-GeneralUtility::IPv6Bin2Hex($bin);
+inet_ntop($bin);
 $address = '127.0.0.1';
-GeneralUtility::compressIPv6($address);
-GeneralUtility::milliseconds();
+inet_ntop(inet_pton($address));
+round(microtime(true) * 1000);

SubstituteResourceFactoryRector

Substitute ResourceFactory::getInstance() through GeneralUtility::makeInstance(ResourceFactory::class)

-$resourceFactory = ResourceFactory::getInstance();
+$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);

SwiftMailerBasedMailMessageToMailerBasedMessageRector

New Mail API based on symfony/mailer and symfony/mime

-use Swift_Attachment;
 use TYPO3\CMS\Core\Mail\MailMessage;
 use TYPO3\CMS\Core\Utility\GeneralUtility;

 $mail = GeneralUtility::makeInstance(MailMessage::class);

 $mail
     ->setSubject('Your subject')
     ->setFrom(['[email protected]' => 'John Doe'])
     ->setTo(['[email protected]', '[email protected]' => 'A name'])
-    ->setBody('Here is the message itself')
-    ->addPart('<p>Here is the message itself</p>', 'text/html')
-    ->attach(Swift_Attachment::fromPath('my-document.pdf'))
+    ->text('Here is the message itself')
+    ->html('<p>Here is the message itself</p>')
+    ->attachFromPath('my-document.pdf')
     ->send();

UnifiedFileNameValidatorRector

GeneralUtility::verifyFilenameAgainstDenyPattern GeneralUtility::makeInstance(FileNameValidator::class)->isValid($filename)

+use TYPO3\CMS\Core\Resource\Security\FileNameValidator;
 use TYPO3\CMS\Core\Utility\GeneralUtility;

 $filename = 'somefile.php';
-if (!GeneralUtility::verifyFilenameAgainstDenyPattern($filename)) {
+if (!GeneralUtility::makeInstance(FileNameValidator::class)->isValid($filename)) {
 }

-if ($GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] != FILE_DENY_PATTERN_DEFAULT)
+if ($GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] != FileNameValidator::DEFAULT_FILE_DENY_PATTERN)
 {
 }

UseActionControllerRector

Use ActionController class instead of AbstractController if used

-class MyController extends AbstractController
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+
+class MyController extends ActionController
 {
 }

UseClassTypo3InformationRector

Use class Typo3Information

-$urlGeneral = TYPO3_URL_GENERAL;
-$urlLicense = TYPO3_URL_LICENSE;
-$urlException = TYPO3_URL_EXCEPTION;
-$urlDonate = TYPO3_URL_DONATE;
-$urlOpcache = TYPO3_URL_WIKI_OPCODECACHE;
+use TYPO3\CMS\Core\Information\Typo3Information;
+$urlGeneral = Typo3Information::TYPO3_URL_GENERAL;
+$urlLicense = Typo3Information::TYPO3_URL_LICENSE;
+$urlException = Typo3Information::TYPO3_URL_EXCEPTION;
+$urlDonate = Typo3Information::TYPO3_URL_DONATE;
+$urlOpcache = Typo3Information::TYPO3_URL_WIKI_OPCODECACHE;

UseClassTypo3VersionRector

Use class Typo3Version instead of the constants

-$typo3Version = TYPO3_version;
-$typo3Branch = TYPO3_branch;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Information\Typo3Version;
+$typo3Version = GeneralUtility::makeInstance(Typo3Version::class)->getVersion();
+$typo3Branch = GeneralUtility::makeInstance(Typo3Version::class)->getBranch();

UseConstantsFromTYPO3DatabaseConnection

Use strict types in Extbase ActionController

+use TYPO3\CMS\Core\Database\Connection;
+
 $queryBuilder = $this->connectionPool->getQueryBuilderForTable('table');
 $result = $queryBuilder
     ->select('uid')
     ->from('table')
     ->where(
-        $queryBuilder->expr()->eq('bodytext', $queryBuilder->createNamedParameter('lorem', \PDO::PARAM_STR)),
-        $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(42, \PDO::PARAM_INT)),
-        $queryBuilder->expr()->eq('available', $queryBuilder->createNamedParameter(true, \PDO::PARAM_BOOL)),
-        $queryBuilder->expr()->eq('foo', $queryBuilder->createNamedParameter(true, \PDO::PARAM_NULL))
+        $queryBuilder->expr()->eq('bodytext', $queryBuilder->createNamedParameter('lorem', Connection::PARAM_STR)),
+        $queryBuilder->expr()->eq('pid', $queryBuilder->createNamedParameter(42, Connection::PARAM_INT)),
+        $queryBuilder->expr()->eq('available', $queryBuilder->createNamedParameter(true, Connection::PARAM_BOOL)),
+        $queryBuilder->expr()->eq('foo', $queryBuilder->createNamedParameter(true, Connection::PARAM_NULL))
     )
     ->executeQuery();

UseControllerClassesInExtbasePluginsAndModulesRector

Use controller classes when registering extbase plugins/modules

-use TYPO3\CMS\Extbase\Utility\ExtensionUtility;
-ExtensionUtility::configurePlugin(
-    'TYPO3.CMS.Form',
+use TYPO3\CMS\Extbase\Utility\ExtensionUtility;ExtensionUtility::configurePlugin(
+    'Form',
     'Formframework',
-    ['FormFrontend' => 'render, perform'],
-    ['FormFrontend' => 'perform'],
+    [\TYPO3\CMS\Form\Controller\FormFrontendController::class => 'render, perform'],
+    [\TYPO3\CMS\Form\Controller\FormFrontendController::class => 'perform'],
     ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT
 );

UseFileGetContentsForGetUrlRector

Rewrite Method Calls of GeneralUtility::getUrl("somefile.csv") to @file_get_contents

-use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Http\RequestFactory;

-GeneralUtility::getUrl('some.csv');
+@file_get_contents('some.csv');
 $externalUrl = 'https://domain.com';
-GeneralUtility::getUrl($externalUrl);
+GeneralUtility::makeInstance(RequestFactory::class)->request($externalUrl)->getBody()->getContents();

UseIconsFromSubFolderInIconRegistryRector

Use icons from subfolder in IconRegistry

 \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class)
         ->registerIcon(
             'apps-pagetree-reference',
             TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
             [
-                'source' => 'typo3/sysext/core/Resources/Public/Icons/T3Icons/content/content-text.svg',
+                'source' => 'typo3/sysext/core/Resources/Public/Icons/T3Icons/svgs/content/content-text.svg',
             ]
         );

UseMetaDataAspectRector

Use $fileObject->getMetaData()->get() instead of $fileObject->_getMetaData()

 $fileObject = new File();
-$fileObject->_getMetaData();
+$fileObject->getMetaData()->get();

UseNativePhpHex2binMethodRector

Turns TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::hex2bin calls to native php hex2bin

-TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::hex2bin("6578616d706c65206865782064617461");
+hex2bin("6578616d706c65206865782064617461");

UseTwoLetterIsoCodeFromSiteLanguageRector

The usage of the property sys_language_isocode is deprecated. Use method getTwoLetterIsoCode of SiteLanguage

-if ($GLOBALS['TSFE']->sys_language_isocode) {
-    $GLOBALS['LANG']->init($GLOBALS['TSFE']->sys_language_isocode);
+if ($GLOBALS['TSFE']->getLanguage()->getTwoLetterIsoCode()) {
+    $GLOBALS['LANG']->init($GLOBALS['TSFE']->getLanguage()->getTwoLetterIsoCode());
 }

UseTypo3InformationForCopyRightNoticeRector

Migrate the method BackendUtility::TYPO3_copyRightNotice() to use Typo3Information API

-$copyright = BackendUtility::TYPO3_copyRightNotice();
+$copyright = GeneralUtility::makeInstance(Typo3Information::class)->getCopyrightNotice();

TYPO311

AddSetConfigurationMethodToExceptionHandlerRector

Add method setConfiguration to class which implements ExceptionHandlerInterface

 use TYPO3\CMS\Frontend\ContentObject\Exception\ExceptionHandlerInterface;
 use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;

 class CustomExceptionHandler implements ExceptionHandlerInterface
 {
     private array $configuration;

-    public function __construct(array $configuration) {
-        $this->configuration = $configuration;
+    public function handle(\Exception $exception, AbstractContentObject $contentObject = null, $contentObjectConfiguration = [])
+    {
     }

-    public function handle(\Exception $exception, AbstractContentObject $contentObject = null, $contentObjectConfiguration = [])
+    public function setConfiguration(array $configuration): void
     {
+        $this->configuration = $configuration;
     }
 }

DateTimeAspectInsteadOfGlobalsExecTimeRector

Use DateTimeAspect instead of superglobals like $GLOBALS['EXEC_TIME']

-$currentTimestamp = $GLOBALS['EXEC_TIME'];
+use TYPO3\CMS\Core\Context\Context;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+$currentTimestamp = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp');

ExtbaseControllerActionsMustReturnResponseInterfaceRector

Extbase controller actions must return ResponseInterface

🔧 configure it!

+use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyController extends ActionController
 {
-    public function someAction()
+    public function someAction(): ResponseInterface
     {
         $this->view->assign('foo', 'bar');
+        return $this->htmlResponse();
     }
 }

FlexFormToolsArrayValueByPathRector

Replace deprecated FlexFormTools methods with ArrayUtility methods

-use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
+use TYPO3\CMS\Core\Utility\ArrayUtility;

-$flexFormTools = new FlexFormTools();
 $searchArray = [];
-$value = $flexFormTools->getArrayValueByPath('search/path', $searchArray);
+$value = ArrayUtility::getValueByPath($searchArray, 'search/path');

-$flexFormTools->setArrayValueByPath('set/path', $dataArray, $value);
+$dataArray = ArrayUtility::setValueByPath($dataArray, 'set/path', $value);

ForwardResponseInsteadOfForwardMethodRector

Return TYPO3\CMS\Extbase\Http\ForwardResponse instead of TYPO3\CMS\Extbase\Mvc\Controller\ActionController::forward()

+use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+use TYPO3\CMS\Extbase\Http\ForwardResponse;

 class FooController extends ActionController
 {
-   public function listAction()
+   public function listAction(): ResponseInterface
    {
-        $this->forward('show');
+        return new ForwardResponse('show');
    }
 }

GetClickMenuOnIconTagParametersRector

Use BackendUtility::getClickMenuOnIconTagParameters() instead BackendUtility::wrapClickMenuOnIcon() if needed

 use TYPO3\CMS\Backend\Utility\BackendUtility;
 $returnTagParameters = true;
-BackendUtility::wrapClickMenuOnIcon('pages', 1, 'foo', '', '', '', $returnTagParameters);
+BackendUtility::getClickMenuOnIconTagParameters('pages', 1, 'foo');

HandleCObjRendererATagParamsMethodRector

Removes deprecated params of the ContentObjectRenderer->getATagParams() method

 $cObjRenderer = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
-$bar = $cObjRenderer->getATagParams([], false);
+$bar = $cObjRenderer->getATagParams([]);

MigrateFileFolderConfigurationRector

Migrate file folder config

 'aField' => [
    'config' => [
       'type' => 'select',
       'renderType' => 'selectSingle',
-      'fileFolder' => 'EXT:my_ext/Resources/Public/Icons',
-      'fileFolder_extList' => 'svg',
-      'fileFolder_recursions' => 1,
+      'fileFolderConfig' => [
+         'folder' => 'EXT:styleguide/Resources/Public/Icons',
+         'allowedExtensions' => 'svg',
+         'depth' => 1,
+      ]
    ]
 ]

MigrateFrameModuleToSvgTreeRector

Migrate the iframe based file tree to SVG

-'navigationFrameModule' => 'file_navframe'
+'navigationComponentId' => 'TYPO3/CMS/Backend/Tree/FileStorageTreeContainer'

MigrateHttpUtilityRedirectRector

Migrate HttpUtilty::redirect() to responseFactory

+use Psr\Http\Message\ResponseFactoryInterface;
+use TYPO3\CMS\Core\Http\PropagateResponseException;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\HttpUtility;

-HttpUtility::redirect('https://example.com', HttpUtility::HTTP_STATUS_303);
+$response = GeneralUtility::makeInstance(ResponseFactoryInterface::class)
+    ->createResponse(HttpUtility::HTTP_STATUS_303)
+    ->withAddedHeader('location', 'https://example.com');
+throw new PropagateResponseException($response);

MigrateLanguageFieldToTcaTypeLanguageRector

use the new TCA type language instead of foreign_table => sys_language for selecting a records

 return [
     'ctrl' => [
         'languageField' => 'sys_language_uid',
     ],
     'columns' => [
         'sys_language_uid' => [
             'exclude' => 1,
             'label' => 'Language',
             'config' => [
-                'type' => 'select',
-                'renderType' => 'selectSingle',
-                'foreign_table' => 'sys_language',
-                'foreign_table_where' => 'ORDER BY sys_language.title',
-                'eval' => 'int',
-                'items' => [
-                    ['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages', -1],
-                    ['LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.default_value', 0],
-                ],
+                'type' => 'language',
             ],
         ],
     ],
 ];

MigrateRootUidToStartingPointsRector

If a column has [treeConfig][rootUid] defined, migrate to [treeConfig][startingPoints] on the same level.

 return [
     'columns' => [
         'aField' => [
             'config' => [
                 'type' => 'select',
                 'renderType' => 'selectTree',
                 'treeConfig' => [
-                    'rootUid' => 42
+                    'startingPoints' => '42'
                 ],
             ],
         ],
     ],
 ];

MigrateSpecialLanguagesToTcaTypeLanguageRector

use the new TCA type language instead of foreign_table => sys_language for selecting a records

 return [
     'ctrl' => [
         'languageField' => 'sys_language_uid',
     ],
     'columns' => [
         'sys_language_uid' => [
             'exclude' => true,
             'label' => 'Language',
             'config' => [
-                'type' => 'select',
-                'renderType' => 'selectSingle',
-                'special' => 'languages',
-                'items' => [
-                    [
-                        'LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.allLanguages',
-                        -1,
-                        'flags-multiple'
-                    ],
-                ],
-                'default' => 0,
+                'type' => 'language',
             ],
         ],
     ],
 ];

ProvideCObjViaMethodRector

Replaces public $cObj with protected and set via method

 class Foo
 {
-    public $cObj;
+    protected $cObj;
+
+    public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
+    {
+        $this->cObj = $cObj;
+    }
 }

RemoveDefaultInternalTypeDBRector

Remove the default type for internal_type

 return [
     'columns' => [
         'foobar' => [
             'config' => [
                 'type' => 'group',
-                'internal_type' => 'db',
             ],
         ],
     ],
 ];

RemoveTypeHintViewInterfaceRector

Remove

-protected function initializeView(ViewInterface $view)
+protected function initializeView($view)

RemoveWorkspacePlaceholderShadowColumnsConfigurationRector

removeWorkspacePlaceholderShadowColumnsConfiguration

 return [
     'ctrl' => [
-        'shadowColumnsForNewPlaceholders' => '',
-        'shadowColumnsForMovePlaceholders' => '',
     ],
 ];

ReplaceInjectAnnotationWithMethodRector

Turns properties with @TYPO3\CMS\Extbase\Annotation\Inject to setter injection

 /**
  * @var SomeService
- * @TYPO3\CMS\Extbase\Annotation\Inject
  */
-private $someService;
+private $someService;
+
+public function injectSomeService(SomeService $someService)
+{
+    $this->someService = $someService;
+}

ReplaceTSFEATagParamsCallOnGlobalsRector

Replaces all direct calls to $GLOBALS['TSFE']->ATagParams.

-$foo = $GLOBALS['TSFE']->ATagParams;
+$foo = $GLOBALS['TSFE']->config['config']['ATagParams'] ?? '';

SimplifyCheckboxItemsTCARector

Simplify checkbox items TCA

 return [
     'columns' => [
         'enabled' => [
             'label' => 'enabled',
             'config' => [
                 'type' => 'check',
                 'renderType' => 'checkboxToggle',
                 'default' => 1,
-                'items' => [
-                    [
-                        0 => '',
-                        1 => '',
-                    ],
-                ],
             ],
         ],
         'hidden' => [
             'label' => 'hidden',
             'config' => [
                 'type' => 'check',
                 'renderType' => 'checkboxToggle',
                 'default' => 0,
                 'items' => [
                     [
                         0 => '',
-                        1 => '',
                         'invertStateDisplay' => true,
                     ],
                 ],
             ],
         ],
     ],
 ];

SubstituteBackendTemplateViewWithModuleTemplateRector

Use an instance of ModuleTemplate instead of BackendTemplateView

 class MyController extends ActionController
 {
-    protected $defaultViewObjectName = BackendTemplateView::class;
+    protected ModuleTemplateFactory $moduleTemplateFactory;

+    public function __construct(
+        ModuleTemplateFactory $moduleTemplateFactory,
+    ) {
+        $this->moduleTemplateFactory = $moduleTemplateFactory;
+    }
+
     public function myAction(): ResponseInterface
     {
         $this->view->assign('someVar', 'someContent');
-        $moduleTemplate = $this->view->getModuleTemplate();
+        $moduleTemplate = $this->moduleTemplateFactory->create($this->request);
         // Adding title, menus, buttons, etc. using $moduleTemplate ...
-        return $this->htmlResponse();
+        $moduleTemplate->setContent($this->view->render());
+        return $this->htmlResponse($moduleTemplate->renderContent());
     }
 }

SubstituteConstantsModeAndRequestTypeRector

Substitute TYPO3_MODE and TYPO3_REQUESTTYPE constants

-defined('TYPO3_MODE') or die();
+defined('TYPO3') or die();

SubstituteEnvironmentServiceWithApplicationTypeRector

Substitute class EnvironmentService with ApplicationType class"

-if ($this->environmentService->isEnvironmentInFrontendMode()) {
+if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend())
     ...
 }

SubstituteExtbaseRequestGetBaseUriRector

Use PSR-7 compatible request for uri instead of the method getBaseUri

-$baseUri = $this->request->getBaseUri();
+$request = $GLOBALS['TYPO3_REQUEST'];
+/** @var NormalizedParams $normalizedParams */
+$normalizedParams = $request->getAttribute('normalizedParams');
+$baseUri = $normalizedParams->getSiteUrl();

SubstituteGetIconFactoryAndGetPageRendererFromModuleTemplateRector

Use PageRenderer and IconFactory directly instead of getting them from the ModuleTemplate

 class MyController extends ActionController
 {
     protected ModuleTemplateFactory $moduleTemplateFactory;
+    protected IconFactory $iconFactory;
+    protected PageRenderer $pageRenderer;

-    public function __construct(ModuleTemplateFactory $moduleTemplateFactory)
-    {
+    public function __construct(
+        ModuleTemplateFactory $moduleTemplateFactory,
+        IconFactory $iconFactory,
+        PageRenderer $pageRenderer
+    ) {
         $this->moduleTemplateFactory = $moduleTemplateFactory;
+        $this->iconFactory = $iconFactory;
+        $this->pageRenderer = $pageRenderer;
     }

     public function myAction(): ResponseInterface
     {
         $moduleTemplate = $this->moduleTemplateFactory->create($this->request);
-        $moduleTemplate->getPageRenderer()->loadRequireJsModule('Vendor/Extension/MyJsModule');
-        $moduleTemplate->setContent($moduleTemplate->getIconFactory()->getIcon('some-icon', Icon::SIZE_SMALL)->render());
+        $this->pageRenderer->loadRequireJsModule('Vendor/Extension/MyJsModule');
+        $moduleTemplate->setContent($this->iconFactory->getIcon('some-icon', Icon::SIZE_SMALL)->render());
         return $this->htmlResponse($moduleTemplate->renderContent());
     }
 }

SubstituteMethodRmFromListOfGeneralUtilityRector

Use native php functions instead of GeneralUtility::rmFromList

-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
 $element = '1';
 $list = '1,2,3';
-
-$newList = GeneralUtility::rmFromList($element, $list);
+$newList = implode(',', array_filter(explode(',', $list), function($item) use($element) {
+    return $element == $item;
+}));

SwitchBehaviorOfArrayUtilityMethodsRector

Handles the methods arrayDiffAssocRecursive() and arrayDiffKeyRecursive() of ArrayUtility

 $foo = ArrayUtility::arrayDiffAssocRecursive([], [], true);
-$bar = ArrayUtility::arrayDiffAssocRecursive([], [], false);
-$test = ArrayUtility::arrayDiffAssocRecursive([], []);
+$bar = ArrayUtility::arrayDiffKeyRecursive([], []);
+$test = ArrayUtility::arrayDiffKeyRecursive([], []);

UniqueListFromStringUtilityRector

Use StringUtility::uniqueList() instead of GeneralUtility::uniqueList

-use TYPO3\CMS\Core\Utility\GeneralUtility;
-GeneralUtility::uniqueList('1,2,2,3');
+use TYPO3\CMS\Core\Utility\StringUtility;
+StringUtility::uniqueList('1,2,2,3');

UseNativeFunctionInsteadOfGeneralUtilityShortMd5Rector

Use php native function instead of GeneralUtility::shortMd5

-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
 $length = 10;
 $input = 'value';

-$shortMd5 = GeneralUtility::shortMD5($input, $length);
+$shortMd5 = substr(md5($input), 0, $length);

UseNormalizedParamsToGetRequestUrlRector

Use normalized params to get the request url

-$requestUri = $this->request->getRequestUri();
+$requestUri = $this->request->getAttribute('normalizedParams')->getRequestUrl();

TYPO312

AddMethodToWidgetInterfaceClassesRector

Add getOptions() to classes that implement the WidgetInterface

 use TYPO3\CMS\Dashboard\Widgets\WidgetInterface;

 class MyClass implements WidgetInterface
 {
     private readonly array $options;

     public function renderWidgetContent(): string
     {
         return 'foo';
     }
+
+    public function getOptions(): array
+    {
+        return $this->options;
+    }
 }

ChangeExtbaseValidatorsRector

Adapt extbase validators to new interface

 use TYPO3\CMS\Extbase\Validation\Validator\ValidatorInterface;

-final class MyCustomValidatorWithOptions implements ValidatorInterface
+final class MyCustomValidatorWithoutOptions implements ValidatorInterface
 {
     private array $options;
     private \MyDependency $myDependency;

-    public function __construct(array $options, \MyDependency $myDependency)
+    public function __construct(\MyDependency $myDependency)
     {
-        $this->options = $options;
         $this->myDependency = $myDependency;
     }

     public function validate($value)
     {
         // Do something
     }

     public function getOptions(): array
     {
         return $this->options;
+    }
+
+    public function setOptions(array $options): void
+    {
+        $this->options = $options;
     }
 }

CommandConfigurationToAttributeRector

Use Symfony attribute to autoconfigure cli commands

 use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Attribute\AsCommand;
+#[AsCommand(name: 'my_special_command')]
 class MySpecialCommand extends Command
 {
 }

ExtbaseActionsWithRedirectMustReturnResponseInterfaceRector

Extbase controller actions with redirects must return ResponseInterface

+use Psr\Http\Message\ResponseInterface;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyController extends ActionController
 {
-    public function someAction()
+    public function someAction(): ResponseInterface
     {
-        $this->redirect('foo', 'bar');
+        return $this->redirect('foo', 'bar');
     }
 }

ExtbaseAnnotationToAttributeRector

Change annotation to attribute

 use TYPO3\CMS\Extbase\Annotation as Extbase;

 class MyEntity
 {
-    /**
-     * @Extbase\ORM\Lazy()
-     * @Extbase\ORM\Transient()
-     */
+    #[Extbase\ORM\Lazy()]
+    #[Extbase\ORM\Transient()]
     protected string $myProperty;
 }

ImplementSiteLanguageAwareInterfaceRector

Implement SiteLanguageAwareInterface instead of using SiteLanguageAwareTrait

-use TYPO3\CMS\Core\Site\SiteLanguageAwareTrait;
+use TYPO3\CMS\Core\Site\SiteLanguageAwareInterface;
+use TYPO3\CMS\Core\Site\Entity\SiteLanguage;

-class MyClass
+class MyClass implements SiteLanguageAwareInterface
 {
-    use SiteLanguageAwareTrait;
+    protected SiteLanguage $siteLanguage;
+
+    public function setSiteLanguage(SiteLanguage $siteLanguage)
+    {
+        $this->siteLanguage = $siteLanguage;
+    }
+
+    public function getSiteLanguage(): SiteLanguage
+    {
+        return $this->siteLanguage;
+    }
 }

MigrateBackendModuleRegistrationRector

Migrate Backend Module Registration

-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addModule(
-    'web',
-    'example',
-    'top',
-    '',
-    [
-        'routeTarget' => MyExampleModuleController::class . '::handleRequest',
-        'name' => 'web_example',
+// Configuration/Backend/Modules.php
+return [
+    'web_module' => [
+        'parent' => 'web',
+        'position' => ['before' => '*'],
         'access' => 'admin',
-        'workspaces' => 'online',
+        'workspaces' => 'live',
+        'path' => '/module/web/example',
         'iconIdentifier' => 'module-example',
+        'navigationComponent' => 'TYPO3/CMS/Backend/PageTree/PageTreeElement',
         'labels' => 'LLL:EXT:example/Resources/Private/Language/locallang_mod.xlf',
-        'navigationComponentId' => 'TYPO3/CMS/Backend/PageTree/PageTreeElement',
-    ]
-);
-\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerModule(
-    'Extkey',
-    'web',
-    'example',
-    'after:info',
-    [
-        MyExtbaseExampleModuleController::class => 'list, detail',
+        'routes' => [
+            '_default' => [
+                'target' => MyExampleModuleController::class . '::handleRequest',
+            ],
+        ],
     ],
-    [
+    'web_ExtkeyExample' => [
+        'parent' => 'web',
+        'position' => ['after' => 'web_info'],
         'access' => 'admin',
-        'workspaces' => 'online',
+        'workspaces' => 'live',
         'iconIdentifier' => 'module-example',
+        'path' => '/module/web/ExtkeyExample',
         'labels' => 'LLL:EXT:extkey/Resources/Private/Language/locallang_mod.xlf',
-    ]
-);
+        'extensionName' => 'Extkey',
+        'controllerActions' => [
+            MyExtbaseExampleModuleController::class => [
+                'list',
+                'detail'
+            ],
+        ],
+    ],
+];

MigrateColsToSizeForTcaTypeNoneRector

Migrates option cols to size for TCA type none

 return [
     'columns' => [
         'aColumn' => [
             'config' => [
                 'type' => 'none',
-                'cols' => 20,
+                'size' => 20,
             ],
         ],
     ],
 ];

MigrateConfigurationManagerGetContentObjectRector

Migrate ConfigurationManager->getContentObject to use request attribute instead

 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyActionController extends ActionController
 {
     public function myMethod(): void
     {
-        $contentObject = $this->configurationManager->getContentObject();
+        $contentObject = $this->request->getAttribute('currentContentObject');
     }
 }

MigrateContentObjectRendererGetTypoLinkUrlRector

Migrate ContentObjectRenderer->getTypoLink_URL to ContentObjectRenderer->createUrl

-$contentObjectRenderer->typoLink_URL(12);
+$contentObjectRenderer->createUrl(['parameter' => 12]);

MigrateContentObjectRendererLastTypoLinkPropertiesRector

Migrate lastTypoLink properties from ContentObjectRenderer

 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

 $contentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
-$lastTypoLinkUrl = $contentObjectRenderer->lastTypoLinkUrl;
-$lastTypoLinkTarget = $contentObjectRenderer->lastTypoLinkTarget;
-$lastTypoLinkLD = $contentObjectRenderer->lastTypoLinkLD;
+$lastTypoLinkUrl = $contentObjectRenderer->lastTypoLinkResult->getUrl();
+$lastTypoLinkTarget = $contentObjectRenderer->lastTypoLinkResult->getTarget();
+$lastTypoLinkLD = ['target' => htmlspecialchars($contentObjectRenderer->lastTypoLinkResult->getTarget()), 'totalUrl' => $contentObjectRenderer->lastTypoLinkResult->getUrl(), 'type' => $contentObjectRenderer->lastTypoLinkResult->getType()];

MigrateEvalIntAndDouble2ToTypeNumberRector

Migrate eval int and double2 to type number

 return [
     'columns' => [
         'int_field' => [
             'label' => 'int field',
             'config' => [
-                'type' => 'input',
-                'eval' => 'int',
+                'type' => 'number',
             ],
         ],
         'double2_field' => [
             'label' => 'double2 field',
             'config' => [
-                'type' => 'input',
-                'eval' => 'double2',
+                'type' => 'number',
+                'format' => 'decimal',
             ],
         ],
     ],
 ];

MigrateFetchAllToFetchAllAssociativeRector

Migrate ->fetchAll() to ->fetchAllAssociative()

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetchAll();
+  ->fetchAllAssociative();

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetchAll(FetchMode::NUMERIC);
+  ->fetchAllNumeric();

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetchAll(FetchMode::COLUMN);
+  ->fetchFirstColumn();

MigrateFetchColumnToFetchOneRector

Migrate ->fetchColumn(0) to ->fetchOne()

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetchColumn(0);
+  ->fetchOne(0);

MigrateFetchToFetchAssociativeRector

Migrate ->fetch() to ->fetchAssociative()

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetch();
+  ->fetchAssociative();

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetch(FetchMode::NUMERIC);
+  ->fetchNumeric();

 $result = $queryBuilder
   ->select(...)
   ->from(...)
   ->executeQuery()
-  ->fetch(FetchMode::COLUMN);
+  ->fetchOne();

MigrateFileFieldTCAConfigToTCATypeFileRector

Migrate method ExtensionManagementUtility::getFileFieldTCAConfig() to TCA type file

 return [
     'columns' => [
         'image_field' => [
-            'config' => ExtensionManagementUtility::getFileFieldTCAConfig(
-                'logo',
-                [
-                    'maxitems' => 1,
-                    'appearance' => [
-                        'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
-                        'fileUploadAllowed' => 0
-                    ],
-                    'overrideChildTca' => [
-                        'types' => [
-                            '0' => [
-                                'showitem' => '
+            'config' => [
+                'type' => 'file',
+                'allowed' => $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'],
+                'maxitems' => 1,
+                'appearance' => [
+                    'createNewRelationLinkTitle' => 'LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:images.addFileReference',
+                    'fileUploadAllowed' => 0
+                ],
+                'overrideChildTca' => [
+                    'types' => [
+                        '0' => [
+                            'showitem' => '
                             --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
                             --palette--;;filePalette'
-                            ],
-                            AbstractFile::FILETYPE_IMAGE => [
-                                'showitem' => '
+                        ],
+                        AbstractFile::FILETYPE_IMAGE => [
+                            'showitem' => '
                             --palette--;LLL:EXT:core/Resources/Private/Language/locallang_tca.xlf:sys_file_reference.imageoverlayPalette;imageoverlayPalette,
                             --palette--;;filePalette'
-                            ],
                         ],
                     ],
                 ],
-                $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
-            ),
+            ],
         ],
     ],
 ];

MigrateGeneralUtilityGPMergedRector

Migrate GeneralUtility::_GPmerged

 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\ArrayUtility;

-$getMergedWithPost = GeneralUtility::_GPmerged('tx_scheduler');
+$getMergedWithPost = $request->getQueryParams()['tx_scheduler'];
+ArrayUtility::mergeRecursiveWithOverrule($getMergedWithPost, $request->getParsedBody()['tx_scheduler']);

 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyActionController extends ActionController
 {
     public function myMethod(): void
     {
-        $getMergedWithPost = GeneralUtility::_GPmerged('tx_scheduler');
+        $getMergedWithPost = $this->request->getQueryParams()['tx_scheduler'];
+        ArrayUtility::mergeRecursiveWithOverrule($getMergedWithPost, $this->request->getParsedBody()['tx_scheduler']);
     }
 }

MigrateGeneralUtilityGPRector

Migrate GeneralUtility::_GP

 use TYPO3\CMS\Core\Utility\GeneralUtility;

-$value = GeneralUtility::_GP('tx_scheduler');
+$value = $GLOBALS['TYPO3_REQUEST']->getParsedBody()['tx_scheduler'] ?? $GLOBALS['TYPO3_REQUEST']->getQueryParams()['tx_scheduler'] ?? null;

 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyActionController extends ActionController
 {
     public function myMethod(): void
     {
-        $value = GeneralUtility::_GP('tx_scheduler');
+        $value = $this->request->getParsedBody()['tx_scheduler'] ?? $this->request->getQueryParams()['tx_scheduler'] ?? null;
     }
 }

MigrateInputDateTimeRector

Migrate renderType inputDateTime to new TCA type datetime

 return [
     'columns' => [
         'a_datetime_field' => [
              'label' => 'Datetime field',
              'config' => [
-                 'type' => 'input',
-                 'renderType' => 'inputDateTime',
+                 'type' => 'datetime',
+                 'format' => 'date',
                  'required' => true,
                  'size' => 20,
-                 'max' => 1024,
-                 'eval' => 'date,int',
                  'default' => 0,
              ],
         ],
     ],
 ];

MigrateInternalTypeFolderToTypeFolderRector

Migrates TCA internal_type into new new TCA type folder

 return [
     'columns' => [
         'columns' => [
             'aColumn' => [
                 'config' => [
-                    'type' => 'group',
-                    'internal_type' => 'folder',
+                    'type' => 'folder',
                 ],
             ],
             'bColumn' => [
                 'config' => [
                     'type' => 'group',
-                    'internal_type' => 'db',
                 ],
             ],
         ],
     ],
 ];

MigrateItemsIndexedKeysToAssociativeRector

Migrates indexed item array keys to associative for type select, radio and check

 return [
     'columns' => [
         'aColumn' => [
             'config' => [
                 'type' => 'select',
                 'renderType' => 'selectCheckBox',
                 'items' => [
-                    ['My label', 0, 'my-icon', 'group1', 'My Description'],
-                    ['My label 1', 1, 'my-icon', 'group1', 'My Description'],
-                    ['My label 2', 2, 'my-icon', 'group1', 'My Description'],
+                    ['label' => 'My label', 'value' => 0, 'icon' => 'my-icon', 'group' => 'group1', 'description' => 'My Description'],
+                    ['label' => 'My label 1', 'value' => 1, 'icon' => 'my-icon', 'group' => 'group1', 'description' => 'My Description'],
+                    ['label' => 'My label 2', 'value' => 2, 'icon' => 'my-icon', 'group' => 'group1', 'description' => 'My Description'],
                 ],
             ],
         ],
     ],
 ];

MigrateMagicRepositoryMethodsRector

Migrate the magic findBy methods

-$blogRepository->findByFooBar('bar');
-$blogRepository->findOneByFoo('bar');
-$blogRepository->countByFoo('bar');
+$blogRepository->findBy(['fooBar' => 'bar']);
+$blogRepository->findOneBy(['foo' => 'bar']);
+$blogRepository->count(['foo' => 'bar']);

MigrateNullFlagRector

Migrate null flag

 return [
     'columns' => [
         'nullable_column' => [
             'config' => [
-                'eval' => 'null',
+                'nullable' => true,
             ],
         ],
     ],
 ];

MigratePasswordAndSaltedPasswordToPasswordTypeRector

Migrate password and salted password to password type

 return [
     'columns' => [
         'password_field' => [
             'label' => 'Password',
             'config' => [
-                'type' => 'input',
-                'eval' => 'trim,password,saltedPassword',
+                'type' => 'password',
             ],
         ],
         'another_password_field' => [
             'label' => 'Password',
             'config' => [
-                'type' => 'input',
-                'eval' => 'trim,password',
+                'type' => 'password',
+                'hashed' => false,
             ],
         ],
     ],
 ];

MigrateQueryBuilderExecuteRector

Replace Querybuilder::execute() with fitting methods

 $rows = $queryBuilder
   ->select(...)
   ->from(...)
-  ->execute()
+  ->executeQuery()
   ->fetchAllAssociative();
 $deletedRows = $queryBuilder
   ->delete(...)
-  ->execute();
+  ->executeStatement();

MigrateRecordTooltipMethodToRecordIconAltTextMethodRector

Migrate the method BackendUtility::getRecordToolTip() to BackendUtility::getRecordIconAltText()

 use TYPO3\CMS\Backend\Utility\BackendUtility;

-$link = '<a href="#" ' . BackendUtility::getRecordToolTip('tooltip') . '>my link</a>';
+$link = '<a href="#" title="' . BackendUtility::getRecordIconAltText('tooltip') . '">my link</a>';

MigrateRenderTypeColorpickerToTypeColorRector

Migrate renderType colorpicker to type color

 return [
     'columns' => [
         'a_color_field' => [
             'label' => 'Color field',
             'config' => [
-                'type' => 'input',
-                'renderType' => 'colorpicker',
+                'type' => 'color',
                 'required' => true,
                 'size' => 20,
-                'max' => 1024,
-                'eval' => 'trim',
                 'valuePicker' => [
                     'items' => [
                         ['typo3 orange', '#FF8700'],
                     ],
                 ],
             ],
         ],
     ],
 ];

MigrateRenderTypeInputLinkToTypeLinkRector

migrate renderType inputLink to new tca field type link

🔧 configure it!

 return [
     'ctrl' => [],
     'columns' => [
         'full_example' => [
             'config' => [
-                'type' => 'input',
-                'renderType' => 'inputLink',
+                'type' => 'link',
                 'required' => true,
                 'size' => 21,
-                'max' => 1234,
-                'eval' => 'trim,null',
-                'fieldControl' => [
-                    'linkPopup' => [
-                        'disabled' => true,
-                        'options' => [
-                            'title' => 'Browser title',
-                            'allowedExtensions' => 'jpg,png',
-                            'blindLinkFields' => 'class,target,title',
-                            'blindLinkOptions' => 'mail,folder,file,telephone',
-                        ],
-                    ],
+                'eval' => 'null',
+                'allowedTypes' => ['page', 'url', 'record'],
+                'appearance' => [
+                    'enableBrowser' => false,
+                    'browserTitle' => 'Browser title',
+                    'allowedOptions' => ['params', 'rel'],
+                    'allowedFileExtensions' => ['jpg', 'png']
                 ],
-                'softref' => 'typolink',
             ],
         ],
     ],
 ];

MigrateRequestArgumentFromMethodStartRector

Use method setRequest of ContentObjectRenderer instead of third argument of method start

 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;

 $contentObjectRenderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
-$contentObjectRenderer->start([], 'pages', $GLOBALS['TYPO3_REQUEST']);
+$contentObjectRenderer->setRequest($GLOBALS['TYPO3_REQUEST']);
+$contentObjectRenderer->start([], 'pages');

MigrateRequiredFlagRector

Migrate required flag

 return [
     'columns' => [
         'required_column' => [
             'config' => [
-                'eval' => 'trim,required',
+                'eval' => 'trim',
+                'required' => true,
             ],
         ],
     ],
 ];

MigrateRequiredFlagSiteConfigRector

Migrate required flag

 $GLOBALS['SiteConfiguration']['site']['columns']['required_column1'] = [
     'required_column' => [
         'config' => [
-            'eval' => 'trim,required',
+            'eval' => 'trim',
+            'required' = true,
         ],
     ],
 ];

MigrateToEmailTypeRector

Migrates existing input TCA with eval email to new TCA type email

 return [
     'columns' => [
         'email_field' => [
             'label' => 'Email',
             'config' => [
-                'type' => 'input',
-                'eval' => 'trim,email',
-                'max' => 255,
+                'type' => 'email',
             ],
         ],
     ],
 ];

MigrateTypoScriptFrontendControllerTypeRector

Migrate TypoScriptFrontendController->type

-$GLOBALS['TSFE']->type;
+$GLOBALS['TSFE']->getPageArguments()->getPageType();

MoveAllowTableOnStandardPagesToTCAConfigurationRector

Move method ExtensionManagementUtility::allowTableOnStandardPages to TCA configuration

-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
-ExtensionManagementUtility::allowTableOnStandardPages('my_table');
+$GLOBALS['TCA']['my_table']['ctrl']['security']['ignorePageTypeRestriction']

RemoveCruserIdRector

Remove the TCA option cruser_id

 return [
     'ctrl' => [
         'label' => 'foo',
-        'cruser_id' => 'cruser_id',
     ],
     'columns' => [
     ],
 ];

RemoveMailerAdapterInterfaceRector

Refactor AdditionalFieldProvider classes

-class RemoveMailerAdapterInterfaceFixture implements TYPO3\CMS\Mail\MailerAdapterInterface
+class RemoveMailerAdapterInterfaceFixture

RemoveObsoleteAppearanceConfigRector

Removes the obsolete appearance config options within TCA

 return [
     'columns' => [
         'random' => [
             'config' => [
                 'type' => 'group',
-                'appearance' => [
-                    'elementBrowserType' => 'db',
-                    'elementBrowserAllowed' => 'foo',
-                ],
             ],
         ],
         'random-inline' => [
             'config' => [
                 'type' => 'inline',
-                'appearance' => [
-                    'headerThumbnail' => 'db',
-                    'fileUploadAllowed' => 'foo',
-                    'fileByUrlAllowed' => 'foo',
-                ],
             ],
         ],
     ],
 ],

RemoveRelativeToCurrentScriptArgumentsRector

Removes all usages of the relativeToCurrentScript parameter

 /** @var AudioTagRenderer $audioTagRenderer */
 $audioTagRenderer = GeneralUtility::makeInstance(AudioTagRenderer::class);
-$foo = $audioTagRenderer->render($file, $width, $height, $options, $relative);
+$foo = $audioTagRenderer->render($file, $width, $height, $options);

RemoveTCAInterfaceAlwaysDescriptionRector

Remove ['interface']['always_description']

 return [
-    'interface' => [
-        'always_description' => 'foo,bar,baz',
-    ],
     'columns' => [
     ],
 ];

RemoveTSFEConvOutputCharsetCallsRector

Removes usages of TSFE->convOutputCharset(...)

 $tsfe = GeneralUtility::makeInstance(TypoScriptFrontendController::class);
-$foo = $GLOBALS['TSFE']->convOutputCharset($content);
-$bar = $tsfe->convOutputCharset('content');
+$foo = $content;
+$bar = 'content';

RemoveTSFEMetaCharSetCallsRector

Removes calls to metaCharset property or methods of TSFE

 $tsfe = GeneralUtility::makeInstance(TypoScriptFrontendController::class);
-$foo = $GLOBALS['TSFE']->metaCharset;
-$bar = $tsfe->metaCharset;
+$foo = 'utf-8';
+$bar = 'utf-8';

RemoveTableLocalPropertyRector

Remove TCA property table_local in foreign_match_fields

 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;

 return [
     'columns' => [
         'images' => [
             'config' => ExtensionManagementUtility::getFileFieldTCAConfig(
                 'images',
                 [
                     'foreign_match_fields' => [
                         'fieldname' => 'media',
                         'tablenames' => 'tx_site_domain_model_mediacollection',
-                        'table_local' => 'sys_file',
                     ],
                     'maxitems' => 1,
                     'minitems' => 1,
                 ],
                 $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
             ),
         ],
     ],
 ];

RemoveUpdateRootlineDataRector

Remove unused TemplateService->updateRootlineData() calls

-$templateService = GeneralUtility::makeInstance(TemplateService::class);
-$templateService->updateRootlineData();
+$templateService = GeneralUtility::makeInstance(TemplateService::class);

ReplaceContentObjectRendererGetMailToWithEmailLinkBuilderRector

Replace usages of ContentObjectRenderer->getMailTo() with EmailLinkBuilder->processEmailLink()

-$result = $cObj->getMailTo($mailAddress, $linktxt)
+$result = GeneralUtility::makeInstance(EmailLinkBuilder::class, $cObj, $cObj->getTypoScriptFrontendController())
+    ->processEmailLink((string)$mailAddress, (string)$linktxt);

ReplaceExpressionBuilderMethodsRector

Replaces ExpressionBuilder methods orX() & andX()

 $rows = $queryBuilder
   ->select(...)
   ->from(...)
   ->where(
-    $queryBuilder->expr()->andX(...),
-    $queryBuilder->expr()->orX(...)
+    $queryBuilder->expr()->and(...),
+    $queryBuilder->expr()->or(...)
   )
   ->executeQuery()
   ->fetchAllAssociative();

ReplacePageRepoOverlayFunctionRector

Replace PageRepository->getRecordOverlay() with ->getLanguageOverlay()

-$pageRepo->getRecordOverlay('', [], '');
+$pageRepo->getLanguageOverlay('', []);

ReplaceTSFECheckEnableFieldsRector

Replace TSFE calls to checkEnableFields with new RecordAccessVoter->accessGranted method

+use TYPO3\CMS\Core\Domain\Access\RecordAccessVoter\RecordAccessVoter;
 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

 $row = [];

-$foo = $GLOBALS['TSFE']->checkEnableFields($row);
-$foofoo = $GLOBALS['TSFE']->checkPagerecordForIncludeSection($row);
+$foo = GeneralUtility::makeInstance(RecordAccessVoter::class)->accessGranted('pages', $row, $GLOBALS['TSFE']->getContext());
+$foofoo = GeneralUtility::makeInstance(RecordAccessVoter::class)->accessGrantedForPageInRootLine($row, $GLOBALS['TSFE']->getContext());

 /** @var TypoScriptFrontendController $typoscriptFrontendController */
 $typoscriptFrontendController = $GLOBALS['TSFE'];
-$bar = $typoscriptFrontendController->checkEnableFields($row);
-$baz = $typoscriptFrontendController->checkPagerecordForIncludeSection($row);
+$bar = GeneralUtility::makeInstance(RecordAccessVoter::class)->accessGranted('pages', $row, $typoscriptFrontendController->getContext());
+$baz = GeneralUtility::makeInstance(RecordAccessVoter::class)->accessGrantedForPageInRootLine($row, $typoscriptFrontendController->getContext());

ReplaceTSFEWithContextMethodsRector

Replace TSFE with Context methods

-$GLOBALS['TSFE']->initUserGroups();
+$GLOBALS['TSFE']->getContext()->setAspect('frontend.user', $GLOBALS['TSFE']->fe_user->createUserAspect());

-$GLOBALS['TSFE']->isUserOrGroupSet();
+$GLOBALS['TSFE']->getContext()->getAspect('frontend.user')->isUserOrGroupSet();

-$GLOBALS['TSFE']->isBackendUserLoggedIn();
+$GLOBALS['TSFE']->getContext()->getPropertyFromAspect('backend.user', 'isLoggedIn', false);

-$GLOBALS['TSFE']->doWorkspacePreview();
+$GLOBALS['TSFE']->getContext()->getPropertyFromAspect('workspace', 'isOffline', false);

-$GLOBALS['TSFE']->whichWorkspace();
+$GLOBALS['TSFE']->getContext()->getPropertyFromAspect('workspace', 'id', 0);

SubstituteCompositeExpressionAddMethodsRector

Replace add() and addMultiple() of CompositeExpression with with()

 $compositeExpression = CompositeExpression::or();

-$compositeExpression->add(
+$compositeExpression = $compositeExpression->with(
     $queryBuilder->expr()->eq(
         'field',
         $queryBuilder->createNamedParameter('foo')
     )
 );

-$compositeExpression->addMultiple(
-    [
+$compositeExpression = $compositeExpression->with(
+    ...[
         $queryBuilder->expr()->eq(
             'field',
             $queryBuilder->createNamedParameter('bar')
         ),
         $queryBuilder->expr()->eq(
             'field',
             $queryBuilder->createNamedParameter('baz')
         ),
     ]
 );

TemplateServiceToServerRequestFrontendTypoScriptAttributeRector

Migrate TemplateService to ServerRequest frontend.typsocript attribute

-$setup = $GLOBALS['TSFE']->tmpl->setup;
+$setup = $GLOBALS['TYPO3_REQUEST']->getAttribute('frontend.typoscript')->getSetupArray();

UseCompositeExpressionStaticMethodsRector

Use CompositeExpression static methods instead of constructor

-$compositeExpressionAND = new CompositeExpression(CompositeExpression::TYPE_AND, []);
-$compositeExpressionOR = new CompositeExpression(CompositeExpression::TYPE_OR, []);
+$compositeExpressionAND = CompositeExpression::and([]);
+$compositeExpressionOR = CompositeExpression::or([]);

UseConfigArrayForTSFEPropertiesRector

Use config array of TSFE instead of properties

-$fileTarget = $GLOBALS['TSFE']->fileTarget;
+$fileTarget = $GLOBALS['TSFE']->config['config']['fileTarget'];

UsePageDoktypeRegistryRector

Migrate from $GLOBALS['PAGES_TYPES'] to the new PageDoktypeRegistry

-$GLOBALS['PAGES_TYPES'][116] = [
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\DataHandling\PageDoktypeRegistry;
+GeneralUtility::makeInstance(PageDoktypeRegistry::class)->add(116, [
     'type' => 'web',
     'allowedTables' => '*',
-];
+]);

UseServerRequestInsteadOfGeneralUtilityGetRector

Use PSR-7 ServerRequest instead of GeneralUtility::_GET()

 use TYPO3\CMS\Core\Utility\GeneralUtility;

-$value = GeneralUtility::_GET('tx_scheduler');
+$value = $GLOBALS['TYPO3_REQUEST']->getQueryParams()['tx_scheduler'] ?? null;

 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyActionController extends ActionController
 {
     public function myMethod()
     {
-        $value = GeneralUtility::_GET('tx_scheduler');
+        $value = $this->request->getQueryParams()['tx_scheduler'] ?? null;
     }
 }

UseServerRequestInsteadOfGeneralUtilityPostRector

Use PSR-7 ServerRequest instead of GeneralUtility::_POST()

 use TYPO3\CMS\Core\Utility\GeneralUtility;

-$value = GeneralUtility::_POST('tx_scheduler');
+$value = $GLOBALS['TYPO3_REQUEST']->getParsedBody()['tx_scheduler'] ?? null;

 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyActionController extends ActionController
 {
     public function myMethod()
     {
-        $value = GeneralUtility::_POST('tx_scheduler');
+        $value = $this->request->getParsedBody()['tx_scheduler'] ?? null;
     }
 }

TYPO313

AddMethodGetAllPageNumbersToPaginationInterfaceRector

Add new method getAllPageNumbers to classes implementing PaginationInterface

 use TYPO3\CMS\Core\Pagination\PaginationInterface;

 class MySpecialPaginationImplementingPaginationInterface implements PaginationInterface
 {
+    /**
+     * @return int[]
+     */
+    public function getAllPageNumbers(): array
+    {
+        return range($this->getFirstPageNumber(), $this->getLastPageNumber());
+    }
 }

ChangeSignatureForLastInsertIdRector

Remove table argument from lastInsertID() call

 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;

 $connection = GeneralUtility::makeInstance(ConnectionPool::class)
     ->getConnectionForTable('tx_myextension_mytable');

-$uid = $connection->lastInsertId('tx_myextension_mytable');
+$uid = $connection->lastInsertId();

ChangeSignatureOfConnectionQuoteRector

Ensure first parameter is of type string and remove second parameter

 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Utility\GeneralUtility;

 $connection = GeneralUtility::makeInstance(Connection::class);
-$connection->quote(1, 1);
+$connection->quote((string) 1);

EventListenerConfigurationToAttributeRector

Use AsEventListener attribute

 namespace MyVendor\MyExtension\EventListener;
+use TYPO3\CMS\Core\Attribute\AsEventListener;
 use TYPO3\CMS\Core\Mail\Event\AfterMailerInitializationEvent;
+#[AsEventListener(
+    identifier: 'my-extension/null-mailer'
+)]
 final class NullMailer
 {
     public function __invoke(AfterMailerInitializationEvent $event): void
     {
     }
 }

IntroduceCapabilitiesBitSetRector

Introduce capabilities bit set

+use TYPO3\CMS\Core\Resource\Capabilities;
 use TYPO3\CMS\Core\Resource\ResourceStorageInterface;

-echo ResourceStorageInterface::CAPABILITY_BROWSABLE;
-echo ResourceStorageInterface::CAPABILITY_PUBLIC;
-echo ResourceStorageInterface::CAPABILITY_WRITABLE;
-echo ResourceStorageInterface::CAPABILITY_HIERARCHICAL_IDENTIFIERS;
+echo Capabilities::CAPABILITY_BROWSABLE;
+echo Capabilities::CAPABILITY_PUBLIC;
+echo Capabilities::CAPABILITY_WRITABLE;
+echo Capabilities::CAPABILITY_HIERARCHICAL_IDENTIFIERS;

MigrateAddPageTSConfigToPageTsConfigFileRector

Migrate method call ExtensionManagementUtility::addPageTSConfig to page.tsconfig

-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
-    '@import "EXT:extension_key/Configuration/TSconfig/*/*.tsconfig"'
-);
+// Move to file Configuration/page.tsconfig

MigrateAddUserTSConfigToUserTsConfigFileRector

Migrate method call ExtensionManagementUtility::addUserTSConfig to user.tsconfig

-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addUserTSConfig(
-    '@import "EXT:extension_key/Configuration/TSconfig/*/*.tsconfig"'
-);
+// Move to file Configuration/user.tsconfig

MigrateExpressionBuilderTrimMethodSecondParameterRector

Migrate second parameter of trim method to enum

 $queryBuilder = $this->connectionPool->getQueryBuilderForTable('tt_content');
 $queryBuilder->expr()->comparison(
-    $queryBuilder->expr()->trim($fieldName, 1),
+    $queryBuilder->expr()->trim($fieldName, TrimMode::LEADING),
     ExpressionBuilder::EQ,
     $queryBuilder->createNamedParameter('', Connection::PARAM_STR)
 );

MigrateExtbaseHashServiceToUseCoreHashServiceRector

Migrate the class HashService from extbase to the one from TYPO3 core

🔧 configure it!

+use TYPO3\CMS\Core\Crypto\HashService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
-use TYPO3\CMS\Extbase\Security\Cryptography\HashService;

 $hashService = GeneralUtility::makeInstance(HashService::class);

-$generatedHash = $hashService->generateHmac('123');
-$isValidHash = $hashService->validateHmac('123', $generatedHash);
+$generatedHash = $hashService->hmac('123', 'changeMe');
+$isValidHash = $hashService->validateHmac('123', 'changeMe', $generatedHash);

-$stringWithAppendedHash = $hashService->appendHmac('123');
-$validatedStringWithHashRemoved = $hashService->validateAndStripHmac($stringWithAppendedHash);
+$stringWithAppendedHash = $hashService->appendHmac('123', 'changeMe');
+$validatedStringWithHashRemoved = $hashService->validateAndStripHmac($stringWithAppendedHash, 'changeMe');

MigrateGeneralUtilityHmacToHashServiceHmacRector

Migrate GeneralUtility::hmac to HashService::hmac

+use TYPO3\CMS\Core\Crypto\HashService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;

-$hmac = GeneralUtility::hmac('some-input', 'some-secret');
+$hmac = GeneralUtility::makeInstance(HashService::class)->hmac('some-input', 'some-secret');

MigratePluginContentElementAndPluginSubtypesRector

Migrate plugin content element and plugin subtypes (list_type)

-\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin([], 'list_type', 'extension_key');
-\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin('ExtensionName', 'PluginName', [], [], 'list_type');
+\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin([], 'CType', 'extension_key');
+\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin('ExtensionName', 'PluginName', [], [], 'CType');

MigratePluginContentElementAndPluginSubtypesSwapArgsRector

Swap arguments for ExtensionManagementUtility::addPiFlexFormValue

 ExtensionManagementUtility::addPiFlexFormValue(
+    '*',
+    'FILE:EXT:examples/Configuration/Flexforms/HtmlParser.xml',
     $pluginSignature,
-    'FILE:EXT:examples/Configuration/Flexforms/HtmlParser.xml',
 );

MigratePluginContentElementAndPluginSubtypesTCARector

Migrate plugin content element and plugin subtypes (list_type) TCA

-$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist'][$pluginSignature] = 'pi_flexform';
+ExtensionManagementUtility::addToAllTCAtypes(
+    'tt_content',
+    '--div--;Configuration,pi_flexform,',
+    $pluginSignature,
+    'after:subheader',
+);

MigrateViewHelperRenderStaticRector

Migrate static ViewHelpers to object-based ViewHelpers

 class MyViewHelper extends AbstractViewHelper
 {
-    use CompileWithRenderStatic;
-
-    public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext): string
+    public function render(): string
     {
-        return $renderChildrenClosure();
+        return $this->renderChildren();
     }
 }

RemoveMmHasUidFieldRector

Unset the value in the config mmHasUidField

 return [
     'columns' => [
         'nullable_column' => [
             'config' => [
                 'type' => 'group',
-                'MM_hasUidField' => false,
             ],
         ],
     ],
 ];

RemoveTcaSubTypesExcludeListTCARector

Remove subtypes_excludelist from list type

-$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['my_plugin'] = 'layout,select_key,pages';
+-

StrictTypesPersistenceManagerRector

Strict types for PersistenceManager

-protected $newObjects = [];
-protected $changedObjects;
-protected $addedObjects;
-protected $removedObjects;
-protected $queryFactory;
-protected $backend;
-protected $persistenceSession;
+protected array $newObjects = [];
+protected ObjectStorage $changedObjects;
+protected ObjectStorage $addedObjects;
+protected ObjectStorage $removedObjects;
+protected QueryFactoryInterface $queryFactory;
+protected BackendInterface $backend;
+protected Session $persistenceSession;

SubstituteItemFormElIDRector

Substitute itemFormElID key with custom generator

-$attributeId = htmlspecialchars($this->data['parameterArray']['itemFormElID']);
+$attributeId = htmlspecialchars(StringUtility::getUniqueId(self::class . '-'));
 $html[] = '<input id="' . $attributeId . '">';

UseStrictTypesInExtbaseAbstractDomainObjectRector

Use strict types in Extbase AbstractDomainObject

 abstract class AbstractDomainObject
 {
-    protected $uid;
-    protected $pid;
+    protected ?int $uid = null;
+    protected ?int $pid = null;
 }

UseStrictTypesInExtbaseActionControllerRector

Use strict types in Extbase ActionController

 namespace Vendor\MyExtension\Controller;

 use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

 class MyController extends ActionController
 {
-    public $defaultViewObjectName = JsonView::class;
-    public $errorMethodName = 'myAction';
+    public string $defaultViewObjectName = JsonView::class;
+    public string $errorMethodName = 'myAction';
 }

TypeDeclaration

AddPropertyTypeDeclarationWithDefaultNullRector

Add type to property by added rules, mostly public/property by parent type with default value null

🔧 configure it!

 class SomeClass extends ParentClass
 {
-    public $name;
+    public ?string $name = null;
 }