blur business close up code
TYPO3 Blog

TYPO3 Version 9: Core-Patches mit Composer verwalten 

Seit TYPO3 Version 9 wird jede System-Extension separat via composer installiert. Das bedeutet, dass man nicht mehr einfach das typo3/cms Paket mit composer installieren kann.

Und es bedeutet auch, dass man nicht mehr so einfach core Patches einbinden kann. Wie es doch klappt, erfahrt ihr in diesem Beitrag.

Statt dessen können wir zum Beispiel auf das composer Paket typo3/minimal zurückgreifen. Schauen wir uns einmal die Sourcen dazu auf https://github.com/TYPO3/minimal an, so stellen wir fest, dass es sich bei dem Paket im Wesentlichen nur um ein Meta-Paket handelt, das folgende TYPO3 System Extensions einbindet:

typo3/cms-backend
typo3/cms-core
typo3/cms-extbase
typo3/cms-extensionmanager
typo3/cms-filelist
typo3/cms-fluid
typo3/cms-frontend
typo3/cms-install
typo3/cms-recordlist

Dieses Vorgehen hat viele Vorteile: Es wird nur Code geladen, der auch wirklich verwendet wird. D.h. die Sourcen werden kleiner und es entstehen weniger Sicherheitslücken durch Code, der gar nicht verwendet wird. Die Motivation dahinter wird in diesem Blogartikel sehr gut beschrieben.

Doch nun zu unserem eigentlichen Problem: Stellen wir uns den unwahrscheinlichen Fall vor, dass es einen Bug in der von uns verwendeten TYPO3-Version gibt, für den es zwar schon einen Patch gibt, der aber noch nicht in die aktuelle Version gemergt wurde und den wir gerne in unserer TYPO3 Installation verwenden möchten.

Das geht mit Hilfe des composer Pluginscweagans/composer-patches und ist in diesem Blog-Artikel über das Patchen von TYPO3 und Extensions bis zur Version 8.7 sehr gut und anschaulich beschrieben.

Nur leider gibt es das eine große Paket typo3/cms nicht mehr und daher lassen sich auch nicht ohne weiteres die auf https://review.typo3.org bereitgestellten Patches verwenden. Statt dessen muss man nun genau schauen, auf welche System Extensions sich die Änderungen in den Patches beziehen. Bezieht sich ein Patch auf Dateien aus verschiedenen System Extensions, so muss man den Patch aufteilen in eine Patch-Datei pro System Extension. Und anschließend muss man pro Extension eine composer Konfiguration unter extra/patches erstellen.

Ein Beispiel dazu:

Nehmen wir mal den Patch https://review.typo3.org/#/c/58979/ für TYPO3 Version 9.5.1, der ein Problem mit dem alias Feld in den Seiteneigenschaften bei mehrsprachigen Websites behebt (Stand Dezember 2018).

Lädt man sich die zugehörige Patch-Datei herunter und entpackt die darin enthaltene Diff-Datei, so stellt man fest, dass folgende Dateien verändert werden:

  • /typo3/sysext/core/Classes/DataHandling/DataHandler.php
  • /typo3/sysext/core/Tests/Functional/DataHandling/DataHandler/GetUniqueTranslationTest.php
  • /typo3/sysext/frontend/Classes/Page/PageRepository.php

Der Patch bezieht sich also auf die System Extension core einerseits und auf frontend andererseits.

Wir müssen aus der Diff-Datei also zwei Diff-Dateien machen, in denen sich ausschließlich die Änderungen für jeweils eine einzelne System Extension befinden.

In unseren neuen Diff-Dateien lassen wir einfach den gesamten Prolog der originalen Diff-Datei weg, der mit FROM in Zeile 1 beginnt und mit aufhört vor dem ersten diff.

Die einzelnen diff-Bereiche beginnend vom diff bis zur letzten Zeile vor dem nächsten diff kopieren wir in neue Diff-Dateien.

Da in den composer Paketen von TYPO3 keine Tests mitgeliefert werden, müssen wir die Änderung an der Datei GetUniqueTranslationTest.php weg lassen. Das gilt generell für Dateien im Unterverzeichnis Tests unterhalb einer System-Extension. Denn diese sind nicht Teil der composer Pakete von TYPO3 und daher könnte der Patch nicht fehlerfrei angewendet werden.

Wir erstellen also 2 diff-Dateien für diesen Patch:

  • Build
    • Patches
      • c1ce767_core.diff
      • c1ce767_frontend.diff

Um diese Patches dann via composer einzubinden, erweitern wir unsere composer.json wie folgt:

"extra": {
    "patches": {
        "typo3/cms-core": {
            "BUGFIX unique for fields with l10n_mode=exclude": "Build/Patches/c1ce767_core.diff"
        },
        "typo3/cms-frontend": {
            "BUGFIX unique for fields with l10n_mode=exclude": "Build/Patches/c1ce767_frontend.diff"
        }
    }
},

Die Namen der composer Pakete ergeben sich aus dem Namen der System-Extension mit dem Präfix typo3/cms-. Also z.B. typo3/cms-core für die System-Extension core.

Damit die Patches auch eingepielt werden, dürfen wir natürlich das dafür erforderliche composer Paket nicht vergessen:

composer require cweagans/composer-patches

Anschließend können wir die Patches installieren:

composer install

Zu beachten ist, dass nachträgliche lokale Änderungen an den Patches bei einem erneuten composer install nicht berücksichtigt werden. Das Plugin cweagans/composer-patches bietet noch eine Reihe weiterer Konfigurationsmöglichkeiten, die auf github gut dokumentiert sind.