Files
portal-api/app/Support/MailPlaceholders.php

82 lines
2.5 KiB
PHP

<?php
namespace App\Support;
use App\Models\Customer;
final class MailPlaceholders
{
public const PATTERN = '/\{\{\s*\$?([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/';
private const CONDITIONAL = '/\{\{\s*#if\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}(.*?)(?:\{\{\s*else\s*\}\}(.*?))?\{\{\s*\/if\s*\}\}/s';
private const LAYOUT_SLOT = 'content';
public const RECIPIENT_FIELDS = [
'client_name' => 'name',
'customer_name' => 'name',
'full_name' => 'name',
'fullname' => 'name',
'name' => 'name',
'customer_email' => 'email',
'email' => 'email',
'account_email' => 'email',
'customer_phone' => 'phone',
'phone' => 'phone',
];
/**
* @return array<int, string>
*/
public static function extract(?string ...$contents): array
{
preg_match_all(self::PATTERN, implode("\n", array_map('strval', $contents)), $matches);
return array_values(array_diff(array_unique($matches[1]), [self::LAYOUT_SLOT, 'else']));
}
/**
* @param array<string, string|null> $values
*/
public static function resolveConditionals(string $content, array $values): string
{
return preg_replace_callback(
self::CONDITIONAL,
fn (array $match) => trim((string) ($values[$match[1]] ?? '')) !== '' ? $match[2] : ($match[3] ?? ''),
$content,
) ?? $content;
}
/**
* @param array<string, string|null> $values
*/
public static function fill(string $content, array $values, bool $escapeHtml = true): string
{
$content = self::resolveConditionals($content, $values);
return preg_replace_callback(self::PATTERN, function (array $match) use ($values, $escapeHtml) {
if ($match[1] === self::LAYOUT_SLOT) {
return $match[0];
}
$value = (string) ($values[$match[1]] ?? '');
return $escapeHtml ? nl2br(htmlspecialchars($value, ENT_QUOTES, 'UTF-8')) : $value;
}, $content) ?? $content;
}
/**
* @return array<string, string>
*/
public static function recipientValues(?Customer $customer, string $email): array
{
$fields = [
'name' => $customer?->fullname ?: $email,
'email' => $email,
'phone' => (string) ($customer?->phone ?? ''),
];
return array_map(fn (string $field) => $fields[$field], self::RECIPIENT_FIELDS);
}
}