Newsletter Management: Erweiterbarkeit
Newsletter-Plugin für Sylius erweitern - PRE_SUBSCRIBE-Event für Spam-Schutz, Formular-Erweiterung per FormTypeExtension, Template-Overrides und Hinweise zum Ersetzen von Services
Newsletter Management: Erweiterbarkeit
Diese Dokumentation bezieht sich immer auf die aktuellste veröffentlichte Version.
Das Plugin bietet zwei dokumentierte Erweiterungspunkte für Dritte: das Event PRE_SUBSCRIBE, mit dem ein Listener Anmeldungen ablehnen kann, und das Anmeldeformular NewsletterSignupType, an das sich per FormTypeExtension Felder hängen lassen. Beides nutzt das ALTCHA-Plugin für den Spam-Schutz. Dazu kommen Template-Overrides für das Aussehen.
Das Event PRE_SUBSCRIBE
| Eigenschaft | Wert |
|---|---|
| Konstante | Mmd\SyliusNewsletterManagementPlugin\Event\NewsletterSubscriptionEvents::PRE_SUBSCRIBE |
| Event-Name | mmd_sylius_newsletter_management_plugin.newsletter_subscription.pre_subscribe |
| Payload | Mmd\SyliusNewsletterManagementPlugin\Event\NewsletterSubscriptionPreSubscribeEvent |
| Zeitpunkt | Bevor etwas gespeichert oder verschickt wird, direkt nach der Prüfung, ob der Newsletter im Channel aktiv ist |
Der NewsletterSubscriptionManager löst das Event bei jeder Anmeldung aus, die über ihn läuft: Anmeldeseite (/newsletter), die Anmeldung über die Shop API und die Newsletter-Checkbox bei Registrierung und Profil. Das Footer-Teaser-Formular löst es nicht selbst aus, es leitet nur auf die Anmeldeseite weiter. Abmeldung, Bestätigung und Einstellungen ändern lösen das Event nicht aus.
Der Payload bietet:
| Methode | Beschreibung |
|---|---|
getEmail() |
Die Adresse, bereits klein geschrieben und getrimmt |
getChannel() |
Der Channel der Anmeldung |
getRequest() |
Der aktuelle Request, etwa für Header, Body-Felder oder die Client-Adresse |
getSource() |
Der Einstiegsweg als NewsletterSubscriptionSource: Storefront, Api, Registration oder Admin |
reject(?string $reason = null) |
Lehnt die Anmeldung ab. $reason ist ein Übersetzungsschlüssel, der dem Kunden angezeigt wird, oder null für den Standardtext |
isRejected(), getRejectionReason() |
Zustand abfragen, etwa für weitere Listener |
Eine Ablehnung zeigt im Storefront eine Fehlermeldung (Flash) und beantwortet die Shop-API-Anfrage mit 422.
Beispiel: Listener, der Wegwerf-Domains ablehnt
<?php
declare(strict_types=1);
namespace App\Newsletter;
use Mmd\SyliusNewsletterManagementPlugin\Entity\NewsletterSubscriptionSource;
use Mmd\SyliusNewsletterManagementPlugin\Event\NewsletterSubscriptionEvents;
use Mmd\SyliusNewsletterManagementPlugin\Event\NewsletterSubscriptionPreSubscribeEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
#[AsEventListener(event: NewsletterSubscriptionEvents::PRE_SUBSCRIBE)]
final class BlockDisposableDomains
{
private const BLOCKED = ['mailinator.com', 'trashmail.com'];
public function __invoke(NewsletterSubscriptionPreSubscribeEvent $event): void
{
// Die Registrierung hat ihren eigenen Schutz.
if ($event->getSource() === NewsletterSubscriptionSource::Registration) {
return;
}
$domain = substr((string) strrchr($event->getEmail(), '@'), 1);
if (\in_array($domain, self::BLOCKED, true)) {
$event->reject('app.newsletter.disposable_domain');
}
}
}
Mit dem Attribut #[AsEventListener] und aktiviertem Autoconfigure reicht die Klasse im Projekt. Alternativ registrierst du den Listener per Tag:
services:
App\Newsletter\BlockDisposableDomains:
tags:
- { name: kernel.event_listener, event: 'mmd_sylius_newsletter_management_plugin.newsletter_subscription.pre_subscribe' }
Den Übersetzungsschlüssel aus dem Beispiel legst du in deiner eigenen Übersetzungsdatei an, etwa in translations/flashes.de.yaml. Im Storefront wird der Schlüssel als Flash-Nachricht übersetzt. Gibst du null an, erscheint der Standardtext des Plugins.
Die Newsletter-Checkbox im Sylius-Kern (Registrierung und Profil) löst das Event mit der Quelle
Registrationaus. Sylius' eigene Shop-API-Registrierung (POST /shop/customers) setzt das Kern-Flag ohne Event und ohne Anmeldung durch das Plugin. Headless-Clients melden sich überPOST /shop/newsletter-subscriptionsan.
Formular erweitern
Mmd\SyliusNewsletterManagementPlugin\Form\Type\NewsletterSignupType ist bewusst nicht final. Damit kannst du per Symfony FormTypeExtension Felder an das Anmeldeformular hängen. So bindet das ALTCHA-Plugin sein Proof-of-Work-Widget ein, während die serverseitige Prüfung auf PRE_SUBSCRIBE lauscht.
<?php
declare(strict_types=1);
namespace App\Form\Extension;
use Mmd\SyliusNewsletterManagementPlugin\Form\Type\NewsletterSignupType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
final class NewsletterSignupExtension extends AbstractTypeExtension
{
public static function getExtendedTypes(): iterable
{
return [NewsletterSignupType::class];
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('companyWebsite', TextType::class, ['mapped' => false, 'required' => false]);
}
}
Ein nicht gemapptes Feld landet nicht im Datenmodell NewsletterSignup; du liest es in deinem PRE_SUBSCRIBE-Listener aus $event->getRequest().
Die Anmeldeseite rendert nach der Einwilligungs-Checkbox und vor dem Absenden-Button den Twig Hook mmd_altcha.widget.newsletter. Er gehört dem ALTCHA-Plugin und bleibt leer, solange dieses Plugin fehlt oder das Schutzziel nicht aktiviert ist. Wie du das Schutzziel einschaltest, steht unter ALTCHA: Konfiguration.
Templates überschreiben
Das Aussehen von Anmeldeseite, Bestätigung, Einstellungen, Abmeldung, Footer-Teaser und Mails passt du mit dem normalen Sylius-Mechanismus an: Lege ein Template mit demselben Pfad unter templates/bundles/MmdSyliusNewsletterManagementPlugin/ in deinem Projekt oder Theme ab. Welche Templates und Hooks es gibt, steht unter Storefront-Integration. Die Admin-Templates sind Oberflächen-Interna des Plugins und nicht zum Überschreiben gedacht.
Welche Platzhalter Newsletter-Autoren im Editor verwenden dürfen, beschreibt die Seite Newsletter.
Services ersetzen
Die Services des Plugins sind über Interfaces verdrahtet (zum Beispiel NewsletterSubscriptionManagerInterface, NewsletterMailerInterface, NewsletterMailSenderInterface). Du kannst sie mit der normalen Symfony-Service-Dekoration ersetzen oder erweitern.
Technisch ist das möglich, aber nicht als stabile öffentliche API zugesagt. Die dokumentierten Erweiterungspunkte sind
PRE_SUBSCRIBEundNewsletterSignupType. Interface-Methoden können sich ändern, prüfe eine Dekoration deshalb bei jedem Update.