For coders TYPO3 Tech Corner

[TYPO3] Mit rector alte Extensions automatisch erneuern lassen

[TYPO3] Mit rector alte Extensions automatisch erneuern lassen

In der TYPO3-Welt ist rector aktuell in aller Munde. Daher ist unser Blogpost natürlich auch nicht der Erste zu dem Thema. Dennoch sehen wir sehr viel Potenzial in dem Stück Software und wollen euch zeigen, wie wir es nutzen.

Hinweis: Beitrag zuletzt aktualisiert am 10. September 2022

Ich denke, dass viele von uns schon einmal vor der Hürde standen, eine alte Extension, die nicht mehr gepflegt wird, für eine neue TYPO3-Version wieder zum Laufen zu bekommen. Das ist mitunter sehr viel händische Arbeit. Hierzu gibt es mit dem PHP-Paket ssch/rector eine automatisierte Lösung, die direkt Änderungen im Code von Extensions vornehmen kann.

Rector installieren und konfigurieren

Installieren lässt sich rector für TYPO3 über composer ganz leicht:

composer require --dev ssch/typo3-rector

Anschließend kann man eine Konfigurationsdatei für TYPO3 von der Vorlage ins Projekt-Root kopieren:

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

Diese Datei (rector.php) liegt nun in eurem Projekt-Root-Verzeichnis. Hier könnt ihr noch einstellen, auf welche Änderungen im Code eurer Extension geprüft werden soll. Wichtig dabei sind vor allem die SetLists und die einzelnen Services, die man dazu laden kann. Nachfolgend ein stark vereinfachtes Beispiel für eine Konfiguration einer TYPO3-Extension die für TYPO3 7 erstellt wurde, aber jetzt in TYPO3 11 benötigt wird:

<?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); };

Und schon könnt ihr eure Dateien automatisch modernisieren lassen:

# 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

Best practice mit rector

Rector ist zweifeillos ein tolles Stück Software, das auch noch täglich verbessert wird. Der Einsatz kann euch viele Stunden Bastelei, Recherche und vor allem "Trial and Error" ersparen.

Dennoch kann es aber sein, dass morgen schon eine neue Regel dazukommt, die heute noch vermisst wird. Darüber hinaus muss man vielleicht auch damit leben, dass nicht jede Zeile Code automatisch umgewandelt werden kann. Für einige Methoden gibt es eventuell mehrere Wege, bei denen händisch eingegriffen werden muss. Andere Ersetzungen sind vielleicht nicht ganz so perfekt, wie man sich das selber wünscht.

Daher schlagen wir eine Kombination aus automatisierter und manueller Überarbeitung vor. Mit Hilfe von GIT könnt ihr beispielsweise eure Änderungen in der Extension commiten. Wenn also im Anschluss automatische Anpassungen gemacht werden, könnt ihr in eurer IDE die Änderungen kontrollieren und akzeptieren oder zurückrollen. Beispielsweise zeigt euch PhpStorm ganz genau was geändert wurde.

Kennst du das: Immer nur schnell schnell?

Wie wäre es einmal mit Zeit und Respekt für Codequalität? Arbeiten im Team? Automatisierte Tests?

Komm zu uns

Unterrichtsausfall - und nun? Neues Portal für das Bayerische Staatsministerium für Unterricht und Kultus

Für das Bayerische Staatsministerium für Unterricht und Kultus durften wir eine neue WebApp bzw. ein neues Portal auf Basis eines bereits bestehenden, aber stark veralteten Portals entwickeln. Das...

Zum Beitrag

SQL: Zeige alle Tabellen absteigend nach Größe sortiert

Ich brauche in letzter Zeit häufiger den SQL-Befehl, um herauszufinden, welche Tabellen in der TYPO3-Datenbank am größten sind. Ich habe das Snippet einmal veröffentlicht.

Zum Beitrag

TYPO3 12 mit CKEditor 5: Stile als Einfachauswahl

Wenn man im RTE in TYPO3 einen Link setzt, kann es sein, dass man zwischen verschiedenen Link-Klassen auswählen muss, um beispielsweise Buttons im Frontend zu erzeugen. Neu ist in TYPO3 12 dass man...

Zum Beitrag

Null-Safe Operator im TYPO3-Bereich

Spätestens mit dem Einzug von PHP8 kann es an vielen Stellen zu Problemen mit undefinierten Arrays oder Variablen im Allgemeinen kommen. Hier ein paar Beispiele und einfache Lösung dafür.

Zum Beitrag

Die ersten/letzten Zeilen einer (SQL)-Datei löschen

Zu den nachfolgenden Befehlen gibt es eigentlich nicht viel zu sagen. Manchmal kann es nützlich sein, die ersten (bzw. letzten) X Zeilen aus einer Datei zu löschen. Und wenn die Datei zu groß zum...

Zum Beitrag

b13/container: Kindelemente in der Bearbeitungsansicht hinzufügen und ändern

Anders als in gridelements kann man in der Extension Container von B13 die Kindelemente nicht verwalten, wenn man den Container in der Bearbeitungsansicht öffnet. Wie man das schnell selber einbauen...

Zum Beitrag