Neuerungen für Entwickler in WoltLab Suite 5.5

Einige der bisher vorgestellten Anpassungen erfolgten als Nebenprodukt der bereits vorgestellten verbesserten Benutzeroberfläche, dem Ignorieren von Themen und der modernisierten Suche. Wir setzen mit WoltLab Suite 5.5 allerdings auch die konsequente Modernisierung von Kernkomponenten fort, die in WoltLab Suite 5.2 mit dem FormBuilder, WoltLab Suite 5.3 mit Guzzle als Ersatz für HTTPRequest und WoltLab Suite 5.4 mit dem Sitzungs-System und TypeScript begonnen wurde.

Im Laufe der Entwicklung von WoltLab Suite 5.5 haben wir die Entwickler-Dokumentation bereits fortlaufend gepflegt. In diesem Artikel möchten wir noch einmal eine Übersicht über die Verbesserungen zur Developer Experience (DX) in WoltLab Suite 5.5 geben und kurz anreißen, wo die Reise in Zukunft weiter gehen wird.

PSR-7-Controller

Beim Aufruf einer Seite, beispielsweise der Startseite des Forums, wird die HTTP-Anfrage durch eine Controller-Klasse verarbeitet, welche üblicherweise auf AbstractPage, AbstractForm oder AbstractAction basiert. Die Parameter für den Aufruf, beispielsweise eine ID, wird dabei über die Superglobals ($_GET, $_POST und co) ermittelt. Für die Antwort zurück an den Browser kommt (indirekt) PHPs echo sowie teilweise die header()-Funktion zum Einsatz, etwa für Umleitungen.

Dieses Vorgehen hat mehrere Nachteile: Bei der Verarbeitung der Anfrage-Header muss beispielsweise bekannt sein, wie diese im $_SERVER-Array kodiert werden. Bei der Erzeugung der Antwort werden die einzelnen Antwort-Header an vielen unterschiedlichen Stellen gesetzt und das notwendige exit; nach einer Weiterleitung sorgt dafür, dass Logik am Ende der Verarbeitung unter Umständen nicht ausgeführt wird. Auch wenn es in der Regel gut funktioniert, stößt man als Entwickler hin und wieder an die Grenzen dieser Architektur und kann die eigenen Ideen nicht oder nur unter viel Mehraufwand realisieren.

Als Lösung für diese Probleme führen wir beginnend mit WoltLab Suite 5.5 eine Unterstützung für die strukturierte Verarbeitung von HTTP-Anfragen und -Antworten auf Basis des PSR-7-Standards ein. Anfragen und Antworten werden, mit allem was dazu gehört, als PHP-Objekt repräsentiert. Das erlaubt im Falle von HTTP-Antworten beispielsweise zuverlässig die bereits gesetzten Antwort-Header zu lesen, erweitern, verändern und zu entfernen, bevor die Antwort am Ende der Verarbeitung an zentraler Stelle durch WoltLab Suite Core an den Client gesendet wird.

WoltLab Suite 5.5 liefert standardmäßig laminas-diactoros als PSR-7-Implementierung mit. Diactoros stellt viele Antwort-Klassen für gängige Anwendungsfälle zur Verfügung. So gibt es beispielsweise eine JsonResponse, an die ein PHP-Array übergeben werden kann. Dieses wird durch Diactoros automatisch als JSON kodiert und auch der notwendige content-type-Header wird automatisch gesetzt.

In WoltLab Suite 5.5 erlaubt die PSR-7-Integration als ersten Schritt die Rückgabe des PSR-7-ResponseInterface im eigenen Controller. Wir haben die Beispiele in unserer Entwickler-Dokumentation erklärt: https://docs.woltlab.com/5.5/migration/…l-psr-7-support

In der nächsten Version soll die PSR-7-Integration um eine Unterstützung für das PSR-7-ServerRequestInterface erweitert werden. Dieses erlaubt dann die Entgegennahme der Anfrage-Parameter auf strukturierte Weise.

Dedizierte Event-Klassen

Das Event-System von WoltLab Suite ist seit der Einführung des IParameterizedEventListener-Interfaces in WoltLab Suite 2.1 im Wesentlichen unverändert. Das zeigt, dass es grundsätzlich sehr gut funktioniert. Es gibt dabei allerdings ein wesentliches Kernproblem, dass die Arbeit mit Events unnötig erschwert: Es ist nicht immer ersichtlich, welche Events zur Verfügung stehen und vor allem, welche Daten diese zum jeweiligen Zeitpunkt zur Verfügung haben. Das ziemlich unstrukturierte $parameters-Array macht die Arbeit in der IDE zudem unnötig kompliziert, nicht zuletzt die Verwendung von isset($parameters[…]) zur Behandlung optionaler Werte in Kombination mit einem Tippfehler sorgt für unnötigen Frust bei der Entwicklung.

In WoltLab Suite 5.5 führen wir daher das Konzept dedizierter Event-Klassen ein, die alle notwendigen Informationen über das Event kapseln. Auf diese Weise können logische Events wie etwa „ein Benutzer hat sich eingeloggt“ an mehreren Stellen gefeuert werden, ohne, dass dem EventListener alle Login-Methoden bekannt sein müssen. Innerhalb des Events können die relevanten Informationen wie etwa „Max Mustermann ist der Benutzer, der sich eingeloggt hat“ über Methoden mit voller IDE-Unterstützung abgerufen werden.

Die genaue Funktionsweise ist selbstverständlich in unserem Migration-Guide in der Dokumentation beschrieben: https://docs.woltlab.com/5.5/migration/wsc54/php/#events. Im Standardumfang von WoltLab Suite 5.5 basiert das neue UserLoggedIn-Event auf diesem Konzept, es illustriert die Möglichkeiten des neuen Event-Konzeptes sehr anschaulich.

In den nächsten Versionen werden weitere Event-Klassen nach Bedarf folgen.

Clean-Up-PIPs

Während die meisten XML-basierten PIPs (Package Installation Plugins) bereits die Löschung von Datensätzen unterstützt haben, fehlte die Unterstützung für Sprachvariablen und für alle TAR-basierten PIPs bislang. WoltLab Suite 5.5 schafft hier Abhilfe und erlaubt es neben obsoleten Sprachvariablen auch (PHP-)Dateien und Templates zu löschen.

Die Verwendung der fileDelete, templateDelete und acpTemplateDelete-PIPs haben wir in unserer Dokumentation erklärt: https://docs.woltlab.com/5.5/migration/…/#file-deletion. Die Änderungen am language-PIP sind direkt darunter zu finden: https://docs.woltlab.com/5.5/migration/wsc54/php/#language

Wir empfehlen bei der Aktualisierung der Pakete für WoltLab Suite 5.5 die einmalige Löschung aller Dateien, die irgendwann einmal existierten, aber nicht mehr existieren. Dies stellt sicher, dass auch bei konsequent aktualisierten Installationen keine verwaisten Dateien mehr vorhanden sind. Für die Erzeugung der fileDelete.xml von WoltLab Suite Core haben wir ein PHP-Skript in Kombination mit „git“ verwendet, dass gerne als Basis verwendet werden kann. Es ist im ausführlichen Kommentar der Commit-Nachricht dieses Commits zu finden: https://github.com/WoltLab/WCF/co…e4e014a46fadebd

Polyfills

WoltLab Suite 5.5 liefert die Symfony-Polyfills mit, um – soweit möglich – hilfreiche neue Funktionen aus PHP 7.3 bis PHP 8.0 verfügbar zu machen. Von besonderem Interesse sind beispielsweise str_starts_with, str_ends_with, str_contains, die die Verständlichkeit des Codes deutlich erleichtern können.

Die Details sind in unserer Entwickler-Dokumentation zu finden: https://docs.woltlab.com/5.5/migration/…y-php-polyfills

In den nächsten Versionen, werden die Polyfills jeweils entsprechend der Verfügbarkeit neuer PHP-Versionen aktualisiert (etwa PHP 8.1 und 8.2).

Entfernung von stark veraltetem Code (Deprecations)

Im Zuge der Modernisierungen wurden wieder viele Funktionen, die in die Jahre gekommen sind und Schwächen zeigten durch eine verbesserte Implementierung ersetzt und die alten Varianten als deprecated markiert. Einige Funktionen, die bereits sehr vielen Versionen deprecated sind und im Plugin-Store nicht mehr genutzt wurden, sind entfernt worden.

Die vollständige Liste findet sich in der Dokumentation: https://docs.woltlab.com/5.5/migration/…tions_removals/

In der nächsten Version werden sicherlich weitere Deprecations und weitere Entfernungen von altem Code folgen. Wir empfehlen, bei der Anpassung von Plugins jeweils alle Deprecations zu berücksichtigen, um sicherzustellen, dass die Plugins bereit für die Zukunft sind.

Kommentare 2

Ich bin etwas verblüfft, warum die Polyfills bei 8.0 stoppen. Würde es nicht Sinn ergeben, sie bis zur neusten während der Beta-Phase verfügbaren Version einzubinden?

Der Mehrwert des PHP 8.1-Polyfills ist äußerst gering (nur array_is_list ist sinnvoll verwendbar): https://github.com/symfony/polyfill/tree/main/src/Php81. Wir haben uns dazu entschieden es nicht mitzuliefern, da jedes Polyfill mit Set-Up-Kosten (bspw. für den Autoloader) verbunden ist.