For coders TYPO3 Tech Corner

[TYPO3] Use rector to automatically update old extensions

[TYPO3] Use rector to automatically update old extensions

In the TYPO3 world everyone is talking about rector right now. Therefore, of course, our blog post is not the first on the topic. Nevertheless, we see a lot of potential in this piece of software and want to show you how we use it.

Note: Post last updated on September 10, 2022

I think that many of us have already faced the hurdle of getting an old extension that is no longer maintained for a new TYPO3 version to work again. Sometimes this is a lot of manual work. There is an automated solution for this with the PHP package ssch/rector, which can make changes to the code of extensions directly.

Rector: Installation and configuration

You can simply install rector for TYPO3 via composer:

composer require --dev ssch/typo3-rector

Then you can have a configuration file for TYPO3 created automatically:

cp ./vendor/ssch/typo3-rector/templates/rector.php.dist rector.php

This file (rector.php) is now in your project root directory. Here you can still set which changes in the code of your extension should be checked for. The set lists and the individual services that can be loaded are particularly important. The following is a greatly simplified example of a configuration of a TYPO3 extension that was created for TYPO3 8, but is now required in TYPO3 10:

<?php // rector.php declare(strict_types=1); use Rector\Config\RectorConfig; use Rector\Core\Configuration\Option; use Rector\Core\ValueObject\PhpVersion; use Ssch\TYPO3Rector\Configuration\Typo3Option; use Ssch\TYPO3Rector\FileProcessor\Composer\Rector\ExtensionComposerRector; use Ssch\TYPO3Rector\Rector\General\ConvertImplicitVariablesToExplicitGlobalsRector; use Ssch\TYPO3Rector\Rector\General\ExtEmConfRector; use Ssch\TYPO3Rector\Set\Typo3LevelSetList; return static function (RectorConfig $rectorConfig): void { $rectorConfig->sets([ Typo3LevelSetList::UP_TO_TYPO3_11 ]); // In order to have a better analysis from phpstan we teach it here some more things $rectorConfig->phpstanConfig(Typo3Option::PHPSTAN_FOR_RECTOR_PATH); // FQN classes are not imported by default. If you don't do it manually after every Rector run, enable it by: $rectorConfig->importNames(); // Disable parallel otherwise non php file processing is not working i.e. typoscript $rectorConfig->disableParallel(); // this will not import root namespace classes, like \DateTime or \Exception $rectorConfig->disableImportShortClasses(); // Define your target version which you want to support $rectorConfig->phpVersion(PhpVersion::PHP_74); // If you only want to process one/some TYPO3 extension(s), you can specify its path(s) here. // If you use the option --config change __DIR__ to getcwd() // $rectorConfig->paths([ // __DIR__ . '/packages/acme_demo/', // ]); // When you use rector there are rules that require some more actions like creating UpgradeWizards for outdated TCA types. // To fully support you we added some warnings. So watch out for them. // If you use importNames(), you should consider excluding some TYPO3 files. $rectorConfig->skip([ // @see <a href="https://github.com/sabbelasichon/typo3-rector/issues/2536" target="_blank" rel="noreferrer">github.com/sabbelasichon/typo3-rector/issues/2536</a> __DIR__ . '/**/Configuration/ExtensionBuilder/*', // We skip those directories on purpose as there might be node_modules or similar // that include typescript which would result in false positive processing __DIR__ . '/**/Resources/**/node_modules/*', __DIR__ . '/**/Resources/**/NodeModules/*', __DIR__ . '/**/Resources/**/BowerComponents/*', __DIR__ . '/**/Resources/**/bower_components/*', __DIR__ . '/**/Resources/**/build/*', __DIR__ . '/vendor/*', __DIR__ . '/Build/*', __DIR__ . '/public/*', __DIR__ . '/.github/*', __DIR__ . '/.Build/*', ]); // If you have trouble that rector cannot run because some TYPO3 constants are not defined add an additional constants file // @see <a href="https://github.com/sabbelasichon/typo3-rector/blob/master/typo3.constants.php" target="_blank" rel="noreferrer">github.com/sabbelasichon/typo3-rector/blob/master/typo3.constants.php</a> // @see <a href="https://github.com/rectorphp/rector/blob/main/docs/static_reflection_and_autoload.md#include-files" target="_blank" rel="noreferrer">github.com/rectorphp/rector/blob/main/docs/static_reflection_and_autoload.md</a> // $rectorConfig->bootstrapFiles([ // __DIR__ . '/typo3.constants.php' //]); // register a single rule // $rectorConfig->rule(\Ssch\TYPO3Rector\Rector\v9\v0\InjectAnnotationRector::class); /** * Useful rule from RectorPHP itself to transform i.e. GeneralUtility::makeInstance('TYPO3\CMS\Core\Log\LogManager') * to GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\LogManager::class) calls. * But be warned, sometimes it produces false positives (edge cases), so watch out */ // $rectorConfig->rule(\Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class); // Optional non-php file functionalities: // @see <a href="https://github.com/sabbelasichon/typo3-rector/blob/main/docs/beyond_php_file_processors.md" target="_blank" rel="noreferrer">github.com/sabbelasichon/typo3-rector/blob/main/docs/beyond_php_file_processors.md</a> // Adapt your composer.json dependencies to the latest available version for the defined SetList // $rectorConfig->sets([ // Typo3SetList::COMPOSER_PACKAGES_104_CORE, // Typo3SetList::COMPOSER_PACKAGES_104_EXTENSIONS, // ]); // Rewrite your extbase persistence class mapping from typoscript into php according to official docs. // This processor will create a summarized file with all the typoscript rewrites combined into a single file. /* $rectorConfig->ruleWithConfiguration(\Ssch\TYPO3Rector\FileProcessor\TypoScript\Rector\v10\v0\ExtbasePersistenceTypoScriptRector::class, [ \Ssch\TYPO3Rector\FileProcessor\TypoScript\Rector\v10\v0\ExtbasePersistenceTypoScriptRector::FILENAME => __DIR__ . '/packages/acme_demo/Configuration/Extbase/Persistence/Classes.php', ]); */ // Add some general TYPO3 rules $rectorConfig->rule(ConvertImplicitVariablesToExplicitGlobalsRector::class); $rectorConfig->ruleWithConfiguration(ExtEmConfRector::class, [ ExtEmConfRector::ADDITIONAL_VALUES_TO_BE_REMOVED => [] ]); $rectorConfig->ruleWithConfiguration(ExtensionComposerRector::class, [ ExtensionComposerRector::TYPO3_VERSION_CONSTRAINT => '' ]); // Modernize your TypoScript include statements for files and move from <INCLUDE /> to @import use the FileIncludeToImportStatementVisitor (introduced with TYPO3 9.0) // $rectorConfig->rule(\Ssch\TYPO3Rector\FileProcessor\TypoScript\Rector\v9\v0\FileIncludeToImportStatementTypoScriptRector::class); };

And you can have your files updated automatically:

# Test which files can be changed ./vendor/bin/rector process private/typo3conf/ext/extensionkey --dry-run # Change files now ./vendor/bin/rector process private/typo3conf/ext/extensionkey

Rector: Best practice

Without a doubt, Rector is a great piece of software that is being improved every day. Using it can save you hours of tinkering, research and, above all, trial and error.

Nevertheless, it is possible that tomorrow a new rule will be added that is still missing today. In addition, you may have to live with the fact that not every line of code can be converted automatically. For some methods, there may be several ways in which manual intervention is required. Other substitutions may not be as perfect as you would like them to be.

We therefore suggest a combination of automated and manual revision. With the help of GIT you can, for example, commit your changes in the extension. So if automatic adjustments are made afterwards, you can control the changes in your IDE and accept or roll back. For example, PhpStorm shows you exactly what has been changed.

"Code faster, look at the time" - does this sound familiar to you?

How about time and respect for code quality? Working in a team? Automated tests?

Join us

Lesson cancellation - and now? New portal for the Bavarian school system.

For the Bavarian school system, we developed a new web app based on an existing but very outdated portal. The portal reports lesson cancellations throughout Bavaria and registered users are informed...

Go to news

SQL: Show all tables sorted by size in descending order

Lately I've been using the SQL command more often to find out which tables in the TYPO3 database are the largest. I've published the snippet once.

Go to news

TYPO3 12 with CKEditor 5: Styles in a single selection

If you set a link in the RTE in TYPO3, you may have to choose between different link classes, for example to create buttons in the frontend. What's new in TYPO3 12 is that you can select not just one...

Go to news

Null-Safe Operator in the TYPO3 area

With the introduction of PHP8, problems with undefined arrays or variables in general can arise in many places. Here are a few examples and simple solutions.

Go to news

Delete the first/last lines of a (SQL) file

There isn't much to say about the following commands. Sometimes it can be useful to delete the first (or last) X lines from a file. And if the file is too large to open with a conventional program, a...

Go to news

b13/container: Add and modify child elements in edit view

Unlike gridelements, you cannot manage the child elements in the B13 Container extension when you open the container in the editing view. I would be happy to show you how you can quickly install this...

Go to news