$details)
{
$templates[$context] = self::template($trigger, $context);
}
return $templates;
}
/**
* @return mixed[]
*/
public static function blankTemplates(string $trigger): array
{
$templates = [];
foreach (Registry::contexts($trigger) as $context => $details)
{
$templates[$context] = self::blankTemplate($trigger, $context);
}
return $templates;
}
/**
* @return mixed[]
*/
public static function template(string $trigger, string $context, ?bool $include_portal_link = null): array
{
return self::baseTemplate([
'active' => in_array($context, [Registry::CONTEXT_ADMIN, Registry::CONTEXT_PRIMARY_BOOKER], true) ? 1 : 0,
'subject' => self::subject($trigger, $context),
'content' => self::content($trigger, $context, $include_portal_link),
]);
}
/**
* @return mixed[]
*/
public static function blankTemplate(string $trigger, string $context): array
{
return self::baseTemplate();
}
/**
* @return string[]
*/
public static function collectionTemplates(): array
{
return [
'participant_list' => '
{participant_name}
{participant_email}
{participant_fields}
',
'option_list' => '{option_title} x {option_quantity}',
'session_list' => '{session_item}',
];
}
/**
* @param mixed[] $overrides
* @return mixed[]
*/
private static function baseTemplate(array $overrides = []): array
{
return array_replace([
'active' => 0,
'subject' => '',
'content' => '',
'to' => self::emptyPicker(),
'cc_enabled' => 1,
'cc' => self::emptyPicker(),
'bcc_enabled' => 1,
'bcc' => self::emptyPicker(),
'attach_ical' => 0,
'attachments' => [],
'collections' => self::collectionTemplates(),
], $overrides);
}
/**
* @return mixed[]
*/
public static function emptyPicker(): array
{
return [
'users' => [],
'roles' => [],
'emails' => '',
];
}
public static function subject(string $trigger, string $context): string
{
if ($trigger === Registry::TRIGGER_CUSTOMER_PORTAL_VERIFICATION_CODE)
{
return esc_html__('[{site_name}] Your booking verification code', 'daytidy');
}
$title = self::triggerTitle($trigger);
if ($context === Registry::CONTEXT_ADMIN || $context === Registry::CONTEXT_OFFERING_HOST)
{
// translators: Placeholder values.
return sprintf(esc_html__('[{site_name}] %s: {offering_title}', 'daytidy'), $title);
}
// translators: Placeholder values.
return sprintf(esc_html__('%s for {offering_title}', 'daytidy'), $title);
}
public static function content(string $trigger, string $context, ?bool $include_portal_link = null): string
{
if ($trigger === Registry::TRIGGER_CUSTOMER_PORTAL_VERIFICATION_CODE)
{
return self::renderContent([
self::paragraph(
__(
'Your DayTidy verification code is {booking_verification_code}. It expires in {booking_verification_code_expiry_minutes} minutes.',
'daytidy'
)
),
]);
}
$blocks = self::bookerContent(
$trigger,
$context === Registry::CONTEXT_PRIMARY_BOOKER ? $include_portal_link : false
);
if ($context === Registry::CONTEXT_ADMIN || $context === Registry::CONTEXT_OFFERING_HOST)
{
$blocks = self::adminContent($trigger);
}
return self::renderContent($blocks);
}
public static function triggerTitle(string $trigger): string
{
$triggers = Registry::triggers();
return $triggers[$trigger]['label'] ?? esc_html__('Booking Notification', 'daytidy');
}
/**
* @return mixed[]
*/
private static function adminContent(string $trigger): array
{
return [
self::paragraph(self::intro($trigger, true)),
self::field(__('Booking Ref', 'daytidy'), '{booking_ref}'),
self::field(__('Booker', 'daytidy'), '{booking_first_name} {booking_last_name} <{booking_email}>'),
self::field(__('Offering', 'daytidy'), '{offering_title}'),
self::section(__('Sessions', 'daytidy'), '{session_list}', 'ul'),
self::section(__('Options', 'daytidy'), '{option_list}', 'ul'),
self::section(__('Participants', 'daytidy'), '{participant_list}'),
self::field(__('Total', 'daytidy'), '{booking_total}'),
];
}
/**
* @return mixed[]
*/
private static function bookerContent(string $trigger, ?bool $include_portal_link = null): array
{
$blocks = [
self::paragraph(self::intro($trigger, false)),
self::field(__('Booking Ref', 'daytidy'), '{booking_ref}'),
self::field(__('Offering', 'daytidy'), '{offering_title}'),
self::section(__('Sessions', 'daytidy'), '{session_list}', 'ul'),
self::section(__('Options', 'daytidy'), '{option_list}', 'ul'),
self::field(__('Total', 'daytidy'), '{booking_total}'),
];
if ($include_portal_link ?? self::hasPortalPage()) $blocks[] = self::field(__('Manage Booking', 'daytidy'), '{booking_portal_url}');
return $blocks;
}
private static function hasPortalPage(): bool
{
$page_id = PortalSettings::pageId();
return $page_id > 0 && PageSetup::isUsablePortalPage($page_id);
}
private static function intro(string $trigger, bool $admin): string
{
$message = [
Registry::TRIGGER_BOOKING_CREATED => $admin
? __('A new booking has been created.', 'daytidy')
: __('Your booking has been received.', 'daytidy'),
Registry::TRIGGER_BOOKING_PAID => $admin
? __('A booking has been marked as paid.', 'daytidy')
: __('Your booking payment has been received.', 'daytidy'),
Registry::TRIGGER_BOOKING_REFUNDED => $admin
? __('A booking has been refunded.', 'daytidy')
: __('Your booking has been refunded.', 'daytidy'),
Registry::TRIGGER_BOOKING_RESCHEDULED => $admin
? __('A booking has been rescheduled.', 'daytidy')
: __('Your booking has been rescheduled.', 'daytidy'),
Registry::TRIGGER_BOOKING_REMINDER_BEFORE_START => $admin
? __('A booking session is coming up soon.', 'daytidy')
: __('Your booking session is coming up soon.', 'daytidy'),
Registry::TRIGGER_BOOKING_CONFIRMED => $admin
? __('A booking has been confirmed.', 'daytidy')
: __('Your booking has been confirmed.', 'daytidy'),
Registry::TRIGGER_BOOKING_DECLINED => $admin
? __('A booking has been declined.', 'daytidy')
: __('Your booking has been declined.', 'daytidy'),
Registry::TRIGGER_BOOKING_CANCELLED => $admin
? __('A booking has been cancelled.', 'daytidy')
: __('Your booking has been cancelled.', 'daytidy'),
Registry::TRIGGER_BOOKING_COMPLETED => $admin
? __('A booking has been completed.', 'daytidy')
: __('Your booking has been completed.', 'daytidy'),
Registry::TRIGGER_BOOKING_PAYMENT_FAILED => $admin
? __('A booking payment has failed.', 'daytidy')
: __('Your booking payment could not be completed.', 'daytidy'),
Registry::TRIGGER_CUSTOMER_PORTAL_VERIFICATION_CODE => __('Your booking verification code is ready.', 'daytidy'),
];
return $message[$trigger] ?? __('A booking notification has been triggered.', 'daytidy');
}
/**
* @param mixed[] $blocks
*/
private static function renderContent(array $blocks): string
{
$html = [];
foreach ($blocks as $block)
{
if (!is_array($block)) continue;
$rendered = self::renderBlock($block);
if ($rendered) $html[] = $rendered;
}
return implode('
', $html);
}
/**
* @param mixed[] $block
*/
private static function renderBlock(array $block): string
{
$type = (string) ($block['type'] ?? '');
if ($type === 'paragraph')
{
return '' . esc_html((string) ($block['text'] ?? '')) . '
';
}
if ($type === 'field')
{
return sprintf(
'%s: %s
',
esc_html((string) ($block['label'] ?? '')),
(string) ($block['value'] ?? '')
);
}
if ($type === 'section')
{
$content = (string) ($block['content'] ?? '');
$wrapper = (string) ($block['wrapper'] ?? '');
if ($wrapper) $content = sprintf('<%1$s>%2$s%1$s>', esc_attr($wrapper), $content);
return sprintf(
'%s:
%s',
esc_html((string) ($block['label'] ?? '')),
$content
);
}
return '';
}
/**
* @return mixed[]
*/
private static function paragraph(string $text): array
{
return [
'type' => 'paragraph',
'text' => $text,
];
}
/**
* @return mixed[]
*/
private static function field(string $label, string $value): array
{
return [
'type' => 'field',
'label' => $label,
'value' => $value,
];
}
/**
* @return mixed[]
*/
private static function section(string $label, string $content, string $wrapper = ''): array
{
return [
'type' => 'section',
'label' => $label,
'content' => $content,
'wrapper' => in_array($wrapper, ['ol', 'ul'], true) ? $wrapper : '',
];
}
}