For coders TYPO3 Tech Corner

[TYPO3] Mit rector alte Extensions automatisch erneuern lassen

[TYPO3] Mit rector alte Extensions automatisch erneuern lassen

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.

Zurück

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