Skip to content
Corex

NotificationDispatcher

Corex\Forms\Submission\NotificationDispatcher · class · Forms layer

Sends a submission notification through the best transport available, with a wp_mail() floor. The detect-and-defer ladder — RoutedMailer → AttemptingMailer → Mailer → wp_mail() — used to live only in the legacy event listener; the flow path had nothing below RoutedMailer, so a site with CoreX Mail inactive saved the submission and sent no notification at all, silently. This service is that ladder, extracted and shared, so both paths reach the floor. It never throws: a transport failure is a failed/not_attempted {@see NotificationDelivery}, never an exception that could roll back an already-saved submission (FR-013). The mailers are injected as nullable collaborators (resolved conditionally by the provider), not looked up from a container — domain logic holds no service locator (Principle IV). It is also where a notification’s own words are written: a caller hands over what writes them, and they are written in the email’s language ({@see EmailLanguage}).

__construct(EmailLanguage $language, ?RoutedMailer $routed, ?Mailer $mailer, ?MailPath $paths)

Section titled “__construct(EmailLanguage $language, ?RoutedMailer $routed, ?Mailer $mailer, ?MailPath $paths)”

dispatch(string $trigger, array $context, Closure $write): NotificationDelivery

Section titled “dispatch(string $trigger, array $context, Closure $write): NotificationDelivery”

The plain-text body for a fallback notification: one label: value line per field. Shared by both callers of the ladder so the floor format lives in one place.

The same answers, marked up, for the transports that declare text/html. {@see plainTextBody()} separates fields with newlines, and every CoreX mail transport sets Content-Type: text/html. HTML collapses whitespace, so the notification arrived as one unbroken run of text — every field on a single line, in an email whose header promised markup. Reported from a real build (issue #138, item 4). Kept as a second method rather than a change to the first: a genuinely plain-text transport would still want the plain-text form, and silently returning HTML from a method named plainTextBody is how the mismatch happened in the first place.