Composer tauscht die Systemextension aus
AustauschDer Fork deklariert replace: typo3/cms-form. Eine Erweiterung, die typo3/cms-form verlangt, bleibt damit erfüllt. Beides nebeneinander lehnt Composer ab, und so ist es gemeint.
Dass Paketname und Extension-Key auseinandergehen, ist Absicht: Auf der Platte heißt die Erweiterung weiter form. Alles, was auf EXT:form/… zeigt — Fluid-Pfade, FAL-Konfiguration, das JavaScript des Formulareditors — findet sein Ziel.
Jede Ergänzung ist rückwärtskompatibel. Jede bleibt aus, bis Sie sie einschalten.
Vier Schichten, kein Rätselbild
SpamschutzAlle vier Prüfungen laufen auf dem Server und entscheiden allein aus dem, was die Einsendung mitbringt — der Besucher muss sich vor keinem Bilderrätsel beweisen. Alles bleibt dabei auf Ihrer Maschine: kein fremder Dienst, nichts fürs Einwilligungsbanner. Und alle vier arbeiten auf vollständig zwischengespeicherten Seiten — daran scheitern die meisten selbstgebauten Versuche.
- Honeypot — ein per CSS verstecktes Feld mit zufälligem Namen je Sitzung. Fängt Ausfüller, die jedes Feld bedienen, das sie finden. Kommt aus dem TYPO3-Core.
- Entropiefilter — ein Shannon-Band über die Freitextfelder plus eine Prüfung je Wort auf Kauderwelsch. Fängt maschinell erzeugten Text, von
aaaaaaabisvOYhcWlrcTafTMSelBkM. - JavaScript-Prüfung — ein signierter Token, im Markup verschleiert, vom Browser zurückgerechnet.
- Mindestausfüllzeit — im Browser gemessen und gegen das Alter der Auslieferung gegengerechnet.
Dazu ein Protokoll jedes Fehlschlags: Es hält Zeitpunkt, Regel und Herkunft fest und verwirft die Eingaben selbst.
Gemessen
Ein Kontaktformular im Betrieb, 27 Tage, mit Honeypot und Entropiefilter: 15.332 abgewiesene Einsendungen, davon 15.139 mit Bot-Signatur — 98,7 %. 125 angreifende Sitzungen standen 10 echten gegenüber, getaktet auf 7 Sekunden, in Schüben von einer Viertelstunde.
Sichtbar wird dabei auch das andere Prozent: Von den zehn echten Besuchern, die an einem Validator hängenblieben, hatten neun die Nachricht leer gelassen und sieben das Formular ganz ohne Eingaben abgeschickt. Das ist ein Befund über die Bedienung, nicht über Spam — und er fällt nur auf, wenn man misst.
Was das nicht leistet
Ein Angreifer, der einen echten Browser fernsteuert, kommt an Schicht 3 und 4 vorbei; die beiden verteuern einen Angriff, sie verhindern ihn nicht. Die Verschleierung in Schicht 3 ist keine Verschlüsselung — der Algorithmus geht an jeden Besucher mit raus. Und die Zeitmessung behauptet der Browser: Der Server kann damit belegen, dass eine Einsendung zu schnell war, nie dass sie schnell genug war.
Schicht 3 und 4 kosten außerdem Barrierefreiheit. Beide weisen Clients ab, die schweigen, und dazu gehört jeder Besucher ohne JavaScript. Schicht 4 lässt sich dafür nachsehen (allowMissingTimingData); Schicht 3 bleibt streng.
Das steht hier, weil ein Spamschutz, dessen Grenzen Sie kennen, mehr wert ist als einer, an den Sie glauben.
Was bisher nur im YAML ging
FormulareditorVarianten und Bedingungen sind im Formulareditor für jedes Element, jede Seite, die Form selbst und jeden Finisher zu bearbeiten: Ausdruck, Sichtbarkeit und bedingte Pflichtangabe. Vorher warf Öffnen und Speichern im Editor handgeschriebene Varianten still weg — jetzt überstehen sie den Umlauf.
Ein Bedingungsbauer klickt Ausdrücke zusammen: Regelzeilen aus Feld, Operator und Wert, verschachtelte UND/ODER-Gruppen, Vorschau des Ausdrucks beim Bauen. Bestehende Ausdrücke liest er in den Baum zurück; was ihm fremd ist, bleibt als Text stehen.
Der E-Mail-Inhaltseditor öffnet pro Finisher ein großes Fenster mit Vorlagenauswahl, einem Fließtext-Editor für die HTML-Fassung und einer getrennten Fassung als reiner Text. Dazu eine serverseitige Vorschau im echten Fluid-Layout, mit Beispielwerten gefüllt, und ein Testversand. Ein Auswahlfeld setzt Feldmarken wie {formValues} an die Schreibmarke, damit die Schreibweise stimmt.


Übersetzungen ohne XLF
ÜbersetzungDie Übersetzungen liegen in der Formulardefinition, nicht in einer XLF-Datei. Damit funktionieren sie auch für Formulare, die in der Datenbank stehen.
Je Element lassen sich Beschriftung, Platzhalter und Optionsbeschriftungen für jede eingerichtete Sprache pflegen, mit einer Anzeige, wie weit das gediehen ist. Eine zweite Ansicht legt die ganze Form als Matrix aus: jede übersetzbare Zeichenkette mal jede Sprache, Finisher-Optionen eingeschlossen.
Eine Übersetzung behält dabei das Markup, das das Original tragen darf. Eine Beschriftung, die in der Ausgangssprache einen Link enthält, behält ihn in jeder weiteren.

Bedingungen, die schon beim Tippen greifen
FrontendBedingungen, die sich auf Felder derselben Seite beziehen, wertet der Browser live aus: Felder erscheinen und verschwinden, Pflichtangaben kommen und gehen, während der Besucher schreibt. Beim Abschicken entscheidet weiter der Server.
Password und AdvancedPassword zeigen die Passwortrichtlinie live an, auf Wunsch mit Umschalter zum Lesbarmachen und einem Generator, der die Richtlinie einhält. Die Richtlinie holt sich das Feld von einem eigenen Endpunkt, damit Browser und Server dieselbe Regel kennen.
Ein Mehrfach-Upload sammelt die gewählten Dateien, statt die Liste bei jeder Auswahl zu ersetzen, und lässt einzelne vor dem Abschicken wieder entfernen.
Was rausgeht, steht auch im Protokoll
BetriebEin Protokoll für ausgehende Mails, mit Backend-Modul und einer Prüfung für die Kommandozeile. Eine Benachrichtigung, die scheitert oder hängenbleibt, ist damit sichtbar — statt als eine Zeile in var/log zu enden, die ungelesen bleibt.
Daneben zwei Protokolle, die sich je Formular einschalten lassen: die abgewiesenen Einsendungen, ohne die eingegebenen Werte, und die erteilten Einwilligungen. Das zweite beantwortet die Frage, die Art. 7 Abs. 1 DSGVO stellt: Wer hat wann wozu zugestimmt.
Welches Kästchen als Einwilligung zählt, entscheidet genau eine Eigenschaft am Element — kein Raten am Feldnamen. Eine frühere Fassung riet, und von dreizehn Einwilligungen einer Website verfehlte sie drei. Die schlechteste davon hieß schlicht checkbox-1.

Wenn Sie ihn selbst einsetzen
EinbauDer Fork steht unter GPL-2.0-or-later, wie die Systemextension, aus der er stammt. Der Quelltext liegt bei WapplerSystems auf GitHub. Zwei Befehle binden ihn ein — der erste trägt das Repository in die composer.json ein, der zweite holt das Paket:
composer config repositories.form vcs git@github.com:WapplerSystems/form.gitcomposer require wapplersystems/formDanach die Caches leeren: Der kompilierte DI-Container und die zwischengespeicherte Formularkonfiguration halten Klassenverweise fest.
Wir bauen damit die Formulare unserer Projekte, binden ihn in bestehende Installationen ein und entwickeln ihn weiter. Wenn Ihnen etwas fehlt, sagen Sie es uns.
Formulare, die ankommen
KontaktEin Formular, das Spam durchlässt, oder eines, das Anfragen verliert – schreiben Sie uns kurz, woran es hakt. Wir melden uns mit einer Einschätzung.
