Markus Michalski FAQ

Support Form: Erweiterbarkeit

Support Form für Sylius - Anfragen per Event vor dem Speichern ablehnen, Formular per FormTypeExtension erweitern, austauschbare Services sowie Hooks und Templates der Admin-Oberfläche

English Version

Zurück zur Übersicht

Support Form: Erweiterbarkeit

Live Demo: Teste dieses und weitere Plugins live — ohne Installation, ohne Risiko: demo.markus-michalski.net

Das Plugin bringt zwei Stellen mit, an denen sich eigener Code einklinken kann, ohne das Plugin zu verändern. Beide sind für Spam-Schutz gedacht, taugen aber für jede Prüfung vor dem Speichern.

Anfragen vor dem Speichern ablehnen

Bevor eine Anfrage gespeichert wird, löst die Verarbeitung das Event mmd_sylius_support_form_plugin.support_request.pre_persist aus. Die Konstante dafür ist SupportRequestEvents::PRE_PERSIST. Das passiert auf beiden Wegen, also im Shop und über die Shop API. Ein Listener bekommt ein SupportRequestPrePersistEvent mit der Anfrage und dem aktuellen Request und kann die Anfrage ablehnen.

<?php

declare(strict_types=1);

namespace App\EventListener;

use Mmd\SyliusSupportFormPlugin\Event\SupportRequestEvents;
use Mmd\SyliusSupportFormPlugin\Event\SupportRequestPrePersistEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;

#[AsEventListener(event: SupportRequestEvents::PRE_PERSIST)]
final class RejectBlockedSubjects
{
    public function __invoke(SupportRequestPrePersistEvent $event): void
    {
        $subject = $event->getSupportRequest()->getSubject() ?? '';

        if (str_contains(strtolower($subject), 'casino')) {
            $event->reject('app.support_form.rejected');
        }
    }
}

reject() nimmt einen optionalen Grund entgegen:

Weg Wirkung von reject()
Storefront Der Kunde sieht den Grund als Fehlermeldung. Der Grund ist ein Übersetzungsschlüssel. Ohne Grund erscheint die Standardmeldung „Deine Anfrage konnte nicht verarbeitet werden. Bitte versuche es erneut.“
Shop API Die API antwortet mit 422. Der Grund steht unverändert in der Fehlermeldung, ohne Grund steht dort „Submission rejected.“

Lehnt ein Listener die Anfrage ab, wird sie weder gespeichert noch verschickt. Das gilt für beide Mails.

Der Listener läuft, nachdem die Anfrage gültig ist. Er sieht also nur Anfragen, die schon alle Pflichtangaben erfüllen. Zu Prüfungen auf dem Request gehören etwa Rate-Limiting, ein Honeypot-Feld oder die Auswertung eines Proof-of-Work-Tokens.

Das Formular um Felder erweitern

SupportRequestType ist ein gewöhnlicher Symfony-Formulartyp und nicht final. Eine FormTypeExtension, die auf SupportRequestType::class zeigt, kann daher eigene Felder ergänzen, zum Beispiel für ein Spam-Schutz-Widget.

<?php

declare(strict_types=1);

namespace App\Form\Extension;

use Mmd\SyliusSupportFormPlugin\Form\Type\SupportRequestType;
use Symfony\Component\Form\AbstractTypeExtension;

final class SupportRequestTypeExtension extends AbstractTypeExtension
{
    public static function getExtendedTypes(): iterable
    {
        return [SupportRequestType::class];
    }
}

Zusätzlich steht im Storefront-Template der Hook mmd_altcha.widget.support_form vor dem Absenden-Button bereit (siehe Storefront).

Eine Erweiterung des Formulartyps wirkt nur in der Storefront. Die Shop API baut keine Formularfelder auf. Eine Prüfung, die für beide Wege gelten soll, gehört deshalb in einen Listener auf PRE_PERSIST.

Austauschbare Services

Diese Services sind über ein Interface als Alias registriert. Du kannst sie in deiner Anwendung durch eine eigene Implementierung ersetzen, indem du den Alias umlenkst:

Interface Aufgabe
SupportRequestSubmissionHandlerInterface Löst PRE_PERSIST aus, speichert und benachrichtigt
SupportRequestMailerInterface Verschickt Benachrichtigung und Bestätigung
SupportFormSubjectResolverInterface Liefert die Betreff-Auswahl eines Channels und löst einen Code in seine Bezeichnung auf
SupportFormPrivacyPolicyLinkProviderInterface Liefert den Datenschutz-Link für die Einwilligung
SupportRequestAnswersApplierInterface Prüft die Antworten der Shop API und übernimmt sie in die Anfrage

Die Entities (SupportRequest, SupportFormField, SupportFormChannelConfiguration, dazu SupportFormFieldTranslation für die Übersetzungen eines Feldes) sind Sylius-Ressourcen. Du kannst sie über die Sylius-Ressourcen-Konfiguration durch eigene Klassen ersetzen, wie bei jeder anderen Sylius-Ressource.

# config/services.yaml
services:
    Mmd\SyliusSupportFormPlugin\Mailer\SupportRequestMailerInterface:
        alias: App\Mailer\MySupportRequestMailer

Admin-Oberfläche anpassen

Das Plugin hängt seine Admin-Seiten über Twig Hooks in die Sylius-Oberfläche. Du kannst eigene Einträge an denselben Hooks registrieren oder die Templates überschreiben.

Hooks:

Templates (Kopie unter templates/bundles/MmdSyliusSupportFormPlugin/ ablegen, mit demselben Pfad ohne das führende templates/):