Skip to content

Booker emails

A booker hears about their order by email when it is confirmed, released (a hold abandoned before confirmation), canceled or rejected. The emails are yoyaku's: yoyaku_order decides what they say and when they go, and a delivery module sends them, with or without a workflow.

Who sends what

OrderNotifierInterface::notifyMilestone($order, $milestone, $refunded, $variant) (service yoyaku_order.order_notifier) is the one entry point. Orchestra's "Notify about an order" action calls it, and so can any module. The notifier writes the sentences in the language the booker booked in, and dispatches OrderNotificationEvent in the order's booking channel, so every link, site name and file in the email is the front the booker used.

yoyaku_order_easy_email delivers the event through an Easy Email template named after the message:

Message Template
Confirmed yoyaku_booking_confirmed
Confirmed, with a self-service cancel link yoyaku_booking_cancellable
Canceled yoyaku_booking_canceled
Released yoyaku_booking_released
Rejected yoyaku_booking_rejected

The first of these that exists is sent, so one tenant, or one variant a caller asks for, gets a template of its own by adding one: yoyaku_<tenant>_<type>_<variant>, yoyaku_<tenant>_<type>, yoyaku_<type>_<variant>, then yoyaku_<type>.

In French

The five templates ship with their French, as configuration translation in yoyaku_order_easy_email/config/install/language/fr. They are translated as configuration rather than in the .po catalog because their bodies are laid out with inline styles, which locale refuses to import.

Locale keeps a configuration translation only if it was saved through the translation API, which is what the Configuration translation form does; a module's shipped translation is not, and locale's next refresh would delete it. So ShippedConfigTranslationHooks saves the shipped French again when the module is installed on a French site and when French is added later, and from then on it survives every refresh like one a person made. A site that edits the French in the Configuration translation form keeps its own version.

Easy Email sends in the site's default language, so a site whose default is French sends these words in French to every booker.

Tokens

  • [yoyaku-notification:label]: a sentence saying what the email is about, for its subject.
  • [yoyaku-notification:message]: the message to the booker.
  • [yoyaku-notification:link]: the cancel link of a cancellable booking.
  • [yoyaku-notification:section:NAME]: a section of HTML a module added, such as section:tickets with yoyaku_ticket; empty when no module added it.
  • [yoyaku-order:*]: the order itself (number, bookings, amount due and more), see the yoyaku_order README.

Adding to an email

Any subscriber of OrderNotificationEvent at the default priority adds to the email before it is sent; delivery modules subscribe at OrderNotificationEvent::DELIVERY_PRIORITY, after them.

  • addAttachment($filename, $mime_type, $content): a file.
  • addInlineImage($filename, $mime_type, $content): an image shown in the body, through the cid: URL it returns. Symfony Mailer shows it in place; Mime Mail does once mimemail #3144592 and #3626119 are in; any other mailer sends it as an attachment. An image the rendered body does not show is not sent at all.
  • addSection($name, $markup): HTML a template places with [yoyaku-notification:section:NAME].

A delivery module that fails to send calls reportDeliveryFailure($reason), and the email is sent again later. yoyaku_ticket adds the tickets section (one row per ticket with its QR code, and a link to the ticket page) and the ticket PDFs, within the limits of its own settings: see Tickets.

When they are sent

The notifier queues the email rather than sending it where the milestone happens, so nobody waits for it to be built and sent. By default it goes once the response has been sent, and cron sends whatever is left: an email whose process died, or one that failed, which is tried five times in all, the retries 1, 2, 4 then 8 minutes apart. The emails of one order go out in order and once each, and one that a newer email about the order follows is not sent at all: a confirmation queued just before the order was canceled never reaches the booker after the cancellation.

An email is sent as the account that reached the milestone, and on the base URL the milestone was reached on, so it reads the same whether it went after the response or from cron.

Administration › Booking › Order settings chooses when:

  • Once the page has been sent (the default). On a server whose PHP does not run under PHP-FPM, the page may still wait for it.
  • By cron only: the email waits as long as cron does.
  • Before the page is sent: the page waits for it, as it did before the queue.

and an optional wait in minutes, after which cron sends it.