81 lines
2.4 KiB
PHP
81 lines
2.4 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',
|
|
'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);
|
|
}
|
|
}
|