Checkout Field Feedback Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Validierungsfehler der Bestellformulare direkt unter den zugehörigen Eingabefeldern anzeigen, mit der vorhandenen JavaScript-Zuordnung.
Architecture: Der Checkout behält seinen bestehenden Auto-Submit mit anschließendem Redirect. PHP stellt die Validierungsantworten pro Formular beim Rendern der Bestätigungsseite bereit. Der vorhandene MoorlFbFormValidatorPlugin verarbeitet diese initialen Antworten genauso wie seine bisherigen onFormResponse-Ereignisse und nutzt weiterhin window.formValidation.
Tech Stack: Shopware 6.7, Symfony Validator und Session, Twig, Shopware Storefront JavaScript.
Spec: Nutzeranforderung vom 09.11.2026: feldbezogene Fehlermeldungen im Checkout; vorhandene Feedback-Elemente und JavaScript-Zuordnung wiederverwenden. Umsetzung vom Nutzer freigegeben; Ausführungsstand siehe unten.
Rahmen und Entscheidungen
- Auto-Submit, Uploads, Session-Payload, Redirect mit
scrollTound serverseitige Bestellsperre bleiben erhalten. - Keine Umstellung des Checkouts auf den normalen AJAX-Submit von
MoorlFbFormPlugin: Dieser setzt unter anderem einen Submit-Button voraus und leert das Formular nach Erfolg. - Kein paralleler Twig-Renderer für Feldfehler: bestehende
.form-field-feedback-Elemente und Shopware-Validierung verwenden. - Formularglobale Fehler bleiben im allgemeinen Feedback sichtbar. Feldfehler erscheinen unter den Feldern; der allgemeine Warenkorbhinweis bleibt als Zusammenfassung bestehen.
- Bei aktiver
checkoutLockbleibt der bisherige Validierungszeitpunkt erhalten, einschließlich der Prüfung beim Laden der Seite. Ohne Sperre werden Fehler erst nach einer tatsächlichen Formularübermittlung angezeigt. - Mehrere Formulare und verschachtelte Felder müssen korrekt zugeordnet werden. Keine Änderung an bestehenden Formularnamen.
- Zwei getrennte Plugin-Repositories sind betroffen:
MoorlFormsOrderundMoorlForms. Gemeinsame Auslieferung beziehungsweise eine Mindestversion vonmoorl/formsvor Release berücksichtigen.
Betroffene Produktdateien
Alle Pfade relativ zu custom/plugins/:
| Datei | Geplante Änderung |
|---|---|
MoorlFormsOrder/src/Core/Service/FbOrderService.php |
Ergebnisse aller übermittelten Formulare erfassen; Fehler pro Formular für Redirect und Rendering bereitstellen; Sperrvalidierung erhalten. |
MoorlFormsOrder/src/Storefront/Controller/FormController.php |
Alle Ergebnisse berücksichtigen; Feldfehler nicht zusätzlich als globale Flash-Nachrichten ausgeben. |
MoorlFormsOrder/src/Resources/views/storefront/page/checkout/confirm/index.html.twig |
Initiale Validierungsantworten sicher als Validator-Optionen ausgeben; vorhandenen Formular-Loop und Auto-Submit erhalten. |
MoorlForms/src/Resources/app/storefront/src/fb-form-validator/fb-form-validator.plugin.js |
Initiale Antworten und bestehende Events über dieselbe Feldzuordnung verarbeiten; Suchbereich je Formular beachten. |
form-feedback.html.twig, die einzelnen Feldtemplates, fb-form.plugin.js, main.js, FormSubmitResponse.php und CheckoutFormError.php benötigen nach diesem Ansatz keine Änderung. Die bestehende Plugin-Registrierung des Validators auf form reicht aus. Gebaute Storefront-Artefakte erst beim üblichen Build aktualisieren.
Prüfschwerpunkte
- Fehler im ersten von mehreren Formularen bleiben sichtbar, auch wenn das letzte gültig ist.
- Gleichnamige Felder in unterschiedlichen Formularen erhalten nur ihre eigenen Meldungen.
- Repeater, Checkbox-Gruppen und Mehrfachauswahl behalten ihre korrekte Feldzuordnung.
- Korrigierte oder entfernte Formulare hinterlassen keine alten Meldungen; leere Fehlerlisten werden berücksichtigt.
- Formularglobale Fehler und Meldungen mit Sonderzeichen werden sicher angezeigt; normale Formulare behalten ihre bisherige Event-Verarbeitung.
Aufgabe 1: Validierungsantworten vollständig durch den Checkout führen
Dateien:
- Ändern: src/Core/Service/FbOrderService.php
- Ändern: src/Storefront/Controller/FormController.php
- Neu: tests/Unit/Core/Service/FbOrderServiceValidationTest.php
- Neu: tests/Unit/Storefront/Controller/FormControllerValidationTest.php
Schnittstellen:
- FbOrderService::changeCart(Request $request, Cart $cart, SalesChannelContext $salesChannelContext): array liefert array<string, FormSubmitResponse>, indiziert nach Formular-ID. Der einzige gefundene Aufrufer ist der zu ändernde Controller.
- JSON-Nutzlast weiterhin über FormSubmitResponse::getJsonResponse() erzeugen; keine zweite Pfadkonvertierung in PHP einführen.
- Session-Schlüssel MoorlFormsOrder.validation als Konstante in FbOrderService; Inhalt: Antworten nach Formular-ID, ausschließlich serialisierbare Feedbackdaten, keine Validatorobjekte.
- Cart-Extension MoorlFormsOrderValidation als ArrayStruct(['forms' => $responses]) für Twig. Nur aktuell relevante Formulare aufnehmen.
- [ ] Tests zuerst schreiben: erstes Formular ungültig/letztes gültig; alle gültig; wiederholter Submit korrigiert Fehler; entfernte Formulare werden herausgefiltert; Sperre an/aus; globale und feldbezogene Meldungen im Controller unterscheiden.
- [ ] Tests ausführen und den erwarteten Fehler vor der Implementierung bestätigen.
- [ ] In
changeCart()alle Antworten unmittelbar pro Formular erzeugen und erfassen. Validatorzustand je Formular isolieren;reset()nicht zwischen Schritten einsetzen, die noch dessen Tree-Zustand benötigen. Bestehende Uploadverarbeitung und Payload-Speicherung erhalten. Fehlende/unbekannte Formular-IDs kontrolliert behandeln. - [ ] Nach jedem Submit den Session-Fehlerstand vollständig ersetzen, auch bei Erfolg. Ergebnisse nicht aus der letzten Schleifeniteration ableiten.
- [ ] In
enrichCart()bei aktiver Sperre pro Formular frisch validieren, Ergebnisse vor dem Reset kopieren und einen gemeinsamen Sperrfehler setzen, sobald mindestens ein Formular ungültig ist. Bei deaktivierter Sperre nur gespeicherte Submit-Antworten für die aktuell sichtbaren Formulare bereitstellen. Bei fehlenden Formularen alte Extension entfernen und veraltete Sessioneinträge bereinigen. - [ ] Im Controller alle Antworten auswerten. Nur globale Violations als Flash-Nachrichten ausgeben; feldbezogene Meldungen kommen über die Extension. Redirect und bisherige Bestelllogik erhalten. Keine zusätzliche Bestellsperre allein durch die neue Feedbackanzeige einführen.
- [ ] Die neuen Tests und die vorhandenen
MoorlFormsOrder/testsmit PHPUnit ausführen. Bootstrap analog zu den vorhandenen Unit-Tests verwenden; PHP passend zur installierten Shopware-Version verwenden.
Aufgabe 2: Bestehenden JavaScript-Validator um initiale Antworten ergänzen
Dateien im Repository MoorlForms:
- Ändern: src/Resources/app/storefront/src/fb-form-validator/fb-form-validator.plugin.js
- Neu: tests/Storefront/fb-form-validator.test.mjs
Schnittstellen:
- Neue optionale Plugin-Option initialResponses: [].
- Ein Eintrag hat {scopeSelector: '#fb-<formId>', violations: [...]}; Violations behalten das bestehende Schema name, path, message, global.
- Bestehendes onFormResponse mit event.detail.violations bleibt kompatibel.
- Gemeinsame Methode _applyViolations(violations, scope = this._form) für Event-Antworten und Initialdaten. Initialdaten nach Registrierung der Listener verarbeiten.
- [ ] Fokussierte Tests zuerst schreiben: initiale Antwort erreicht
window.formValidation; Event-Antwort funktioniert weiter; gleiche Namen in zwei Formularbereichen bleiben getrennt; mehrere Meldungen je Feld bleiben erhalten; leere Antworten und globale Violations werden übersprungen. - [ ] Tests mit
node --test tests/Storefront/fb-form-validator.test.mjsausführen; produktive Methode testen, nicht eine kopierte Implementierung. Shopware-Imports im Test isoliert laden, entsprechend der vorhandenen Toolchain. - [ ] Gemeinsame Zuordnung implementieren. Felder im angegebenen Formularbereich suchen; Gruppen und
name[]berücksichtigen. Für komplexe Namen keine ungeprüfte Stringinterpolation in CSS-Selektoren verwenden. - [ ] Meldungen pro Feld sammeln und über
addErrorMessage()/setFieldInvalid()gemeinsam setzen, damit mehrere Fehler nicht gegenseitig überschrieben werden. Schlüssel für Fehlermeldungen je Formular/Feld eindeutig halten. - [ ] Eigene frühere Serverfehlermarkierungen bei erneuter Verarbeitung entfernen, ohne andere Validierungsergebnisse pauschal zu löschen. Globale Fehler nicht als fehlendes Eingabefeld protokollieren.
- [ ] Neue Tests und die vorhandenen MoorlForms-Tests ausführen. Beim DOM-Test zusätzlich Rückmeldung unter dem richtigen
aria-describedby-Ziel prüfen.
Aufgabe 3: Checkout-Template anbinden
Datei im Repository MoorlFormsOrder:
- Ändern: src/Resources/views/storefront/page/checkout/confirm/index.html.twig
- [ ] Aus
page.cart.extensions.MoorlFormsOrderValidation.formsdie ListeinitialResponsesaufbauen: pro Formular ID-basierter Bereich#fb-<formId>und dessen Violations. - [ ] Die Liste als
data-moorl-fb-form-validator-optionsam bestehenden#checkoutFormübergeben.json_encodeund HTML-Attribut-Escaping verwenden, kein ungefiltertesraw. - [ ] Vorhandene Feedback-Container und
aria-describedby-Verbindungen nutzen. Keine Initialisierung vonMoorlFbFormPluginam Checkout-Formular ergänzen; keine konkurrierenden Submit-Handler. - [ ] Template mit installierter Shopware-Umgebung linten und das gerenderte JSON mit Meldungen prüfen, die Anführungszeichen, HTML-Zeichen und Umlaute enthalten.
Aufgabe 4: Integration und Auslieferung prüfen
- [ ] Storefront über das bestehende Shopware-Buildverfahren neu bauen; keine neue Build-Toolchain einführen.
- [ ] Im Browser bei aktivierter Sperre ein leeres Pflichtfeld prüfen: Meldung direkt darunter,
is-invalid,aria-invalid, Warenkorbzusammenfassung und gesperrte Bestellung. - [ ] Feld korrigieren und Auto-Submit abwarten: Wert erhalten, Feldmeldung verschwunden, Bestellbarkeit entsprechend dem gesamten Formularzustand aktualisiert.
- [ ] Zwei Formulare testen: Fehler im ersten, zweites gültig; gleichnamige Felder; verschachtelte Felder, Repeater, Checkboxen, Mehrfachauswahl und Upload.
- [ ] Mit deaktivierter Sperre prüfen: keine neue Sofortvalidierung beim ersten Seitenaufruf, feldbezogenes Feedback nach Submit, unveränderte Bestellbarkeit.
- [ ] Reguläres AJAX-Formular außerhalb des Checkouts prüfen: Feedbackbereich und
onFormResponsefunktionieren weiter; kein doppeltes Feedback. - [ ] Mit deaktiviertem JavaScript prüfen, dass serverseitige Bestellsperre und allgemeine Meldungen weiterhin tragen.
- [ ] Versionsanforderung für
moorl/formsanhand der tatsächlichen Release-Version festlegen; falls nötigMoorlFormsOrder/composer.jsonbeim Release anpassen. Keine Versionsnummer während der Planung erfinden.
Ergebnis der Planung
Vier Produktdateien in zwei Plugins, drei neue gezielte Testdateien sowie übliche Build-Artefakte bei der Umsetzung. Eine Composer-Anpassung ist nur für die Release-Abhängigkeit vorgesehen.
Ausführungsstand 09.11.2026
- Aufgaben 1–3 implementiert, Änderungen bleiben uncommitted in den bestehenden Plugin-Checkouts. Zusätzlich
MoorlFormsOrder/tests/bootstrap.phpfür die Autoloads beider Plugins ergänzt. - Schnittstellenprüfung:
changeCart()hat einen Aufrufer, den Controller; dessen Verarbeitung ist auf das Antwortarray umgestellt. Template und Validator verwenden dieselbeinitialResponses-Struktur. - Entscheidung: Die Feedback-Funktion darf bei deaktivierter
checkoutLockkeine zusätzliche Bestellsperre erzeugen. Der bisher im Controller direkt hinzugefügte Sperrfehler entfällt; die konfigurierte Sperrvalidierung bleibt im Service. - Entscheidung: Fehlerhafte oder nicht zum aktuellen Warenkorb gehörende Formular-IDs werden als Bad Request abgewiesen; Validierungszustand wird dabei nicht verändert. Ein bereits gesetzter
IGNORE_VALIDATION_EVENT-Zustand bleibt erhalten. - Entscheidung: Checkbox-/Radiofelder mit gemeinsamem Feedback werden gesammelt zurückgesetzt, bevor ihr gemeinsamer Meldungstext gelöscht wird. Später hinzugefügte native Validierungsmeldungen werden erhalten.
- Review-Korrektur: Switch-/AGB-Templates enthalten teilweise kein
aria-describedby. Der Validator ergänzt den Verweis auf den bereits vorhandenen<field.id>-feedback-Container und erhält andere Beschreibungsverweise. Keine zusätzlichen Produktdateien nötig. - Tests:
php vendor/bin/phpunit --bootstrap custom/plugins/MoorlFormsOrder/tests/bootstrap.php custom/plugins/MoorlFormsOrder/tests— 8 Tests, 26 Assertions, erfolgreich. - Tests:
node --test custom/plugins/MoorlForms/tests/Storefront/fb-form-validator.test.mjs— 6 Tests erfolgreich. Produktions-Plugin und originale Shopware-Feedback-Hilfe werden mit einer kleinen DOM-Testumgebung ausgeführt. - Vorbestehender Befund: Die MoorlForms-PHP-Suite hat unverändert einen Fehler in
ElementValueRuleTest::testConfiguresATranslatedLabelForTheTechnicalNameField(fehlendes übersetztes Label); bereits vor den Änderungen reproduziert. - Prüfung: PHP-Syntax und eigenständiges Twig-Rendering einschließlich JSON-Attribut-Escaping mit Anführungszeichen, HTML-Zeichen und Umlauten erfolgreich. Für diesen isolierten Rendercheck nur die Shopware-Namensauflösung durch normale Twig-Tags ersetzt.
- Build: MoorlForms mit der originalen Shopware-Webpack-Konfiguration und temporärem Plugin-Manifest separat kompiliert. Keine Änderung am Projekt-Manifest oder an anderen Plugins. Ausgabe im üblichen ignorierten
dist/storefront-Verzeichnis. - Unabhängige Codeprüfung abgeschlossen; keine verbleibenden kritischen oder wichtigen Befunde.
- Offen für die lauffähige Shopumgebung: Browserabnahme der Checkout-, Upload- und Repeater-Abläufe, vollständiger Shop-Build/Asset-Installation und Festlegung der Release-Mindestversion von
moorl/forms. Lokaler Kernelstart ist bereits durch den fehlenden Containerparametermcp.servers.unassignedblockiert.