-
CodeQuality (10)
-
General (2)
-
TYPO310 (37)
-
TYPO311 (30)
-
TYPO312 (55)
-
TYPO313 (20)
-
TypeDeclaration (1)
Add timestamp error code to exceptions
-throw new \RuntimeException('my message');
+throw new \RuntimeException('my message', 1729021897);
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';
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:{}',
];
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;
}
}
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);
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
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
Move ExtensionUtility::registerPlugin into Configuration/TCA/Overrides/tt_content.php
- class:
Ssch\TYPO3Rector\CodeQuality\General\MoveExtensionUtilityRegisterPluginIntoTCAOverridesRector
-\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin('extension_key', 'Pi1', 'Title');
+// Move to file Configuration/TCA/Overrides/tt_content.php
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);
}
Replace the second parameter of LocalizationUtility::translate to the extension name
-LocalizationUtility::translate('key', 'extension_key');
+LocalizationUtility::translate('key', 'ExtensionName');
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;
Rename Attribute
🔧 configure it!
-#[Controller]
+#[AsController]
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'));;
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);
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');
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);
+ }
}
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']);
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));
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()
{
}
}
Use Environment API to fetch application context
-GeneralUtility::getApplicationContext();
+Environment::getContext();
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;
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);
Refactor Internal public TSFE properties
-$domainStartPage = $GLOBALS['TSFE']->domainStartPage;
+$cHash = $GLOBALS['REQUEST']->getAttribute('routing')->getArguments()['cHash'];
Remove vendor name from registerPlugin call
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
- 'TYPO3.CMS.Form',
+ 'Form',
'Formframework',
'Form',
'content-form'
);
Remove "enableMultiSelectFilterTextfield" => true as its default
return [
'columns' => [
'foo' => [
'label' => 'foo',
'config' => [
'type' => 'select',
'renderType' => 'selectMultipleSideBySide',
- 'enableMultiSelectFilterTextfield' => true,
],
],
],
];
transOrigPointerField is not longer allowed to be excluded
return [
'ctrl' => [
'transOrigPointerField' => 'l10n_parent',
],
'columns' => [
'l10n_parent' => [
- 'exclude' => true,
'config' => [
'type' => 'select',
],
],
],
];
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);
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();
}
}
TCA option "selicon_field_path" removed
return [
'ctrl' => [
'selicon_field' => 'icon',
- 'selicon_field_path' => 'uploads/media'
],
];
Remove showRecordFieldList inside section interface
return [
'ctrl' => [
],
- 'interface' => [
- 'showRecordFieldList' => 'foo,bar,baz',
- ],
'columns' => [
],
];
Remove showRemovedLocalizationRecords from inline TCA configurations.
return [
'columns' => [
'falFileRelation' => [
'config' => [
'type' => 'inline',
'appearance' => [
'showPossibleLocalizationRecords' => false,
- 'showRemovedLocalizationRecords' => false,
],
],
],
],
];
TCA option setToDefaultOnCopy removed
return [
'ctrl' => [
- 'selicon_field' => 'icon',
- 'setToDefaultOnCopy' => 'foo'
+ 'selicon_field' => 'icon'
],
'columns' => [
],
];
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;
+}
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());
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);
Substitute ResourceFactory::getInstance()
through GeneralUtility::makeInstance(ResourceFactory::class)
-$resourceFactory = ResourceFactory::getInstance();
+$resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
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();
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)
{
}
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
{
}
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;
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();
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();
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
);
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();
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',
]
);
Use $fileObject->getMetaData()->get()
instead of $fileObject->_getMetaData()
$fileObject = new File();
-$fileObject->_getMetaData();
+$fileObject->getMetaData()->get();
Turns TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::hex2bin calls to native php hex2bin
-TYPO3\CMS\Extbase\Utility\TypeHandlingUtility::hex2bin("6578616d706c65206865782064617461");
+hex2bin("6578616d706c65206865782064617461");
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());
}
Migrate the method BackendUtility::TYPO3_copyRightNotice()
to use Typo3Information API
-$copyright = BackendUtility::TYPO3_copyRightNotice();
+$copyright = GeneralUtility::makeInstance(Typo3Information::class)->getCopyrightNotice();
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;
}
}
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');
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();
}
}
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);
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');
}
}
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');
Removes deprecated params of the ContentObjectRenderer->getATagParams()
method
$cObjRenderer = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class);
-$bar = $cObjRenderer->getATagParams([], false);
+$bar = $cObjRenderer->getATagParams([]);
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,
+ ]
]
]
Migrate the iframe based file tree to SVG
-'navigationFrameModule' => 'file_navframe'
+'navigationComponentId' => 'TYPO3/CMS/Backend/Tree/FileStorageTreeContainer'
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);
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',
],
],
],
];
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'
],
],
],
],
];
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',
],
],
],
];
Replaces public $cObj
with protected and set via method
class Foo
{
- public $cObj;
+ protected $cObj;
+
+ public function setContentObjectRenderer(ContentObjectRenderer $cObj): void
+ {
+ $this->cObj = $cObj;
+ }
}
Remove the default type for internal_type
return [
'columns' => [
'foobar' => [
'config' => [
'type' => 'group',
- 'internal_type' => 'db',
],
],
],
];
Remove
-protected function initializeView(ViewInterface $view)
+protected function initializeView($view)
removeWorkspacePlaceholderShadowColumnsConfiguration
return [
'ctrl' => [
- 'shadowColumnsForNewPlaceholders' => '',
- 'shadowColumnsForMovePlaceholders' => '',
],
];
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;
+}
Replaces all direct calls to $GLOBALS['TSFE']->ATagParams.
-$foo = $GLOBALS['TSFE']->ATagParams;
+$foo = $GLOBALS['TSFE']->config['config']['ATagParams'] ?? '';
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,
],
],
],
],
],
];
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());
}
}
Substitute TYPO3_MODE and TYPO3_REQUESTTYPE constants
-defined('TYPO3_MODE') or die();
+defined('TYPO3') or die();
Substitute class EnvironmentService with ApplicationType class"
-if ($this->environmentService->isEnvironmentInFrontendMode()) {
+if (ApplicationType::fromRequest($GLOBALS['TYPO3_REQUEST'])->isFrontend())
...
}
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();
Use PageRenderer and IconFactory directly instead of getting them from the ModuleTemplate
- class:
Ssch\TYPO3Rector\TYPO311\v5\SubstituteGetIconFactoryAndGetPageRendererFromModuleTemplateRector
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());
}
}
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;
+}));
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([], []);
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');
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);
Use normalized params to get the request url
-$requestUri = $this->request->getRequestUri();
+$requestUri = $this->request->getAttribute('normalizedParams')->getRequestUrl();
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;
+ }
}
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;
}
}
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
{
}
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');
}
}
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;
}
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;
+ }
}
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'
+ ],
+ ],
+ ],
+];
Migrates option cols to size for TCA type none
return [
'columns' => [
'aColumn' => [
'config' => [
'type' => 'none',
- 'cols' => 20,
+ 'size' => 20,
],
],
],
];
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');
}
}
Migrate ContentObjectRenderer->getTypoLink_URL to ContentObjectRenderer->createUrl
-$contentObjectRenderer->typoLink_URL(12);
+$contentObjectRenderer->createUrl(['parameter' => 12]);
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()];
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',
],
],
],
];
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();
Migrate ->fetchColumn(0) to ->fetchOne()
$result = $queryBuilder
->select(...)
->from(...)
->executeQuery()
- ->fetchColumn(0);
+ ->fetchOne(0);
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();
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']
- ),
+ ],
],
],
];
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']);
}
}
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;
}
}
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,
],
],
],
];
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',
],
],
],
],
];
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'],
],
],
],
],
];
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']);
Migrate null flag
return [
'columns' => [
'nullable_column' => [
'config' => [
- 'eval' => 'null',
+ 'nullable' => true,
],
],
],
];
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,
],
],
],
];
Replace Querybuilder::execute()
with fitting methods
$rows = $queryBuilder
->select(...)
->from(...)
- ->execute()
+ ->executeQuery()
->fetchAllAssociative();
$deletedRows = $queryBuilder
->delete(...)
- ->execute();
+ ->executeStatement();
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>';
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'],
],
],
],
],
],
];
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',
],
],
],
];
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');
Migrate required flag
return [
'columns' => [
'required_column' => [
'config' => [
- 'eval' => 'trim,required',
+ 'eval' => 'trim',
+ 'required' => true,
],
],
],
];
Migrate required flag
$GLOBALS['SiteConfiguration']['site']['columns']['required_column1'] = [
'required_column' => [
'config' => [
- 'eval' => 'trim,required',
+ 'eval' => 'trim',
+ 'required' = true,
],
],
];
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',
],
],
],
];
Migrate TypoScriptFrontendController->type
-$GLOBALS['TSFE']->type;
+$GLOBALS['TSFE']->getPageArguments()->getPageType();
Move method ExtensionManagementUtility::allowTableOnStandardPages to TCA configuration
-use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
-ExtensionManagementUtility::allowTableOnStandardPages('my_table');
+$GLOBALS['TCA']['my_table']['ctrl']['security']['ignorePageTypeRestriction']
Remove the TCA option cruser_id
return [
'ctrl' => [
'label' => 'foo',
- 'cruser_id' => 'cruser_id',
],
'columns' => [
],
];
Refactor AdditionalFieldProvider classes
-class RemoveMailerAdapterInterfaceFixture implements TYPO3\CMS\Mail\MailerAdapterInterface
+class RemoveMailerAdapterInterfaceFixture
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',
- ],
],
],
],
],
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);
Remove ['interface']['always_description']
return [
- 'interface' => [
- 'always_description' => 'foo,bar,baz',
- ],
'columns' => [
],
];
Removes usages of TSFE->convOutputCharset(...)
$tsfe = GeneralUtility::makeInstance(TypoScriptFrontendController::class);
-$foo = $GLOBALS['TSFE']->convOutputCharset($content);
-$bar = $tsfe->convOutputCharset('content');
+$foo = $content;
+$bar = 'content';
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';
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']
),
],
],
];
Remove unused TemplateService->updateRootlineData()
calls
-$templateService = GeneralUtility::makeInstance(TemplateService::class);
-$templateService->updateRootlineData();
+$templateService = GeneralUtility::makeInstance(TemplateService::class);
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);
Replaces ExpressionBuilder methods orX()
& andX()
$rows = $queryBuilder
->select(...)
->from(...)
->where(
- $queryBuilder->expr()->andX(...),
- $queryBuilder->expr()->orX(...)
+ $queryBuilder->expr()->and(...),
+ $queryBuilder->expr()->or(...)
)
->executeQuery()
->fetchAllAssociative();
Replace PageRepository->getRecordOverlay()
with ->getLanguageOverlay()
-$pageRepo->getRecordOverlay('', [], '');
+$pageRepo->getLanguageOverlay('', []);
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());
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);
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')
),
]
);
Migrate TemplateService to ServerRequest frontend.typsocript attribute
-$setup = $GLOBALS['TSFE']->tmpl->setup;
+$setup = $GLOBALS['TYPO3_REQUEST']->getAttribute('frontend.typoscript')->getSetupArray();
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([]);
Use config array of TSFE instead of properties
-$fileTarget = $GLOBALS['TSFE']->fileTarget;
+$fileTarget = $GLOBALS['TSFE']->config['config']['fileTarget'];
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' => '*',
-];
+]);
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;
}
}
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;
}
}
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());
+ }
}
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();
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);
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
{
}
}
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;
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
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
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)
);
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');
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');
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');
Swap arguments for ExtensionManagementUtility::addPiFlexFormValue
ExtensionManagementUtility::addPiFlexFormValue(
+ '*',
+ 'FILE:EXT:examples/Configuration/Flexforms/HtmlParser.xml',
$pluginSignature,
- 'FILE:EXT:examples/Configuration/Flexforms/HtmlParser.xml',
);
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',
+);
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();
}
}
Unset the value in the config mmHasUidField
return [
'columns' => [
'nullable_column' => [
'config' => [
'type' => 'group',
- 'MM_hasUidField' => false,
],
],
],
];
Remove subtypes_excludelist from list type
-$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['my_plugin'] = 'layout,select_key,pages';
+-
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;
Substitute itemFormElID key with custom generator
-$attributeId = htmlspecialchars($this->data['parameterArray']['itemFormElID']);
+$attributeId = htmlspecialchars(StringUtility::getUniqueId(self::class . '-'));
$html[] = '<input id="' . $attributeId . '">';
Use strict types in Extbase AbstractDomainObject
abstract class AbstractDomainObject
{
- protected $uid;
- protected $pid;
+ protected ?int $uid = null;
+ protected ?int $pid = null;
}
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';
}
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;
}