XCLASS-Drift: warum ein Diff zum Original nicht reicht

Wer eine fremde Methode per XCLASS ersetzt, kopiert ihren Rumpf. Ändert der Hersteller später etwas darin – eine zusätzliche Prüfung, einen Bugfix –, läuft die eigene Fassung weiter und lässt die Änderung einfach aus. Ein Diff hilft dabei erstaunlich wenig, denn die beiden Fassungen weichen ja absichtlich voneinander ab.

Ein XCLASS auf eine fremde Extension ist selten eine kleine Ergänzung. Meist wird eine Methode vollständig kopiert und an einer Stelle abgewandelt. Von da an führen beide Fassungen ein Eigenleben – und die eigene erfährt nie, was im Original passiert.

Ein Abgleich nach zwei Jahren förderte in einem Projekt drei Dinge zutage, die im Original hinzugekommen waren und in der Kopie fehlten: eine Prüfung eingehender E-Mail-Adressen mit GeneralUtility::validEmail(), das Registrieren der Seiten-Cache-Tags (ohne die wurde eine Übersichtsseite bei Änderungen nicht mehr verworfen) und eine korrigierte Jahresberechnung für Kalenderwochen, die über den Jahreswechsel reichen.

Der naheliegende Gedanke – regelmäßig ein diff laufen lassen – trägt nicht weit. Die Fassungen unterscheiden sich absichtlich; bei einer Methode, die den Rumpf komplett ersetzt, waren es über fünfzig Zeilen. Das ist Rauschen, kein Signal. Die nützliche Frage lautet nicht „worin unterscheiden sie sich", sondern „hat sich das Original geändert, seit ich zuletzt hingesehen habe".

Prüfsumme über die überschriebenen Methodenrümpfe

extract() { sed -n "/function $2(/,/^    }/p" "$1"; }

extract vendor/hersteller/ext/Classes/Service/Foo.php machMal \
  | shasum -a 256 | cut -d' ' -f1

Diese Prüfsummen legt man einmal als Baseline ab. Der nächste Lauf vergleicht und meldet nur die Methoden, deren Original sich bewegt hat. Dann schaut man sich genau diese an, übernimmt die Änderung bei Bedarf und schreibt die Baseline fort. Aufwand: ein Aufruf nach jedem composer update der fremden Extension.

Ein zweiter Baustein gehört dazu: ein Test, der zusichert, dass der XCLASS überhaupt greift. Wird der Dienst per Konstruktor-Injection aus dem DI-Container bezogen, ist keineswegs offensichtlich, ob die Registrierung über $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'] noch wirkt. Ohne diese Zusicherung prüfen alle anderen Tests im Zweifel die Originalklasse – und sind trotzdem grün.


Erstellt am: