121 lines
3.5 KiB
PHP
121 lines
3.5 KiB
PHP
<?php
|
|
namespace nulib\mail;
|
|
|
|
use nulib\cv;
|
|
use nulib\str;
|
|
use nulib\ValueException;
|
|
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
|
|
|
|
class MailTemplate {
|
|
const SCHEMA = [
|
|
"subject" => "string",
|
|
"body" => "string",
|
|
"exprs" => "array",
|
|
];
|
|
|
|
function __construct(array $mail) {
|
|
$tsubject = $mail["subject"] ?? null;
|
|
$tbody = $mail["body"] ?? null;
|
|
$texprs = $mail["exprs"] ?? [];
|
|
|
|
$this->el = new ExpressionLanguage();
|
|
ValueException::check_null($this->subject = $tsubject, "subject");
|
|
ValueException::check_null($this->body = $tbody, "body");
|
|
$exprs = [];
|
|
# Commencer par extraire les expressions de la forme {name}
|
|
if (preg_match_all('/\{([a-zA-Z_][a-zA-Z0-9_.-]*)}/', $this->body, $mss, PREG_SET_ORDER)) {
|
|
foreach ($mss as $ms) {
|
|
$key = $ms[0];
|
|
$expr = str_replace("'", "\\'", $ms[1]);
|
|
$expr = "_helper.value('$expr')";
|
|
$exprs[$key] = $expr;
|
|
}
|
|
}
|
|
$index = 0;
|
|
foreach ($texprs as $key => $expr) {
|
|
$prefix = null;
|
|
$orig = $expr;
|
|
if (preg_match('/^\[([^]]*)]/', $expr, $ms)) {
|
|
# un préfixe spécifié de la forme [prefix]expr permet de reconnaitre les
|
|
# formes spéciales de expr (+, *, .) qui sont précédées de prefix
|
|
# exemple: [https://]+app.url permettra d'utiliser un texte markdown
|
|
# de la forme <https://+app.url> qui est correctement reconnu comme un
|
|
# url
|
|
$prefix = $ms[1];
|
|
$expr = substr($expr, strlen($ms[0]));
|
|
}
|
|
$mapKey = false;
|
|
if (str::del_prefix($expr, "+")) {
|
|
# config
|
|
$mapKey = "$prefix+$expr";
|
|
$expr = str_replace("'", "\\'", $expr);
|
|
$expr = "_helper.config('$expr')";
|
|
} elseif (str::del_prefix($expr, "*")) {
|
|
# session
|
|
$mapKey = "$prefix*$expr";
|
|
$expr = str_replace("'", "\\'", $expr);
|
|
$expr = "_helper.session('$expr')";
|
|
} elseif (str::del_prefix($expr, ".")) {
|
|
# session
|
|
$mapKey = "$prefix.$expr";
|
|
$expr = str_replace("'", "\\'", $expr);
|
|
$expr = "_helper.value('$expr')";
|
|
} elseif ($prefix !== null) {
|
|
# sinon remettre le préfixe
|
|
$expr = $orig;
|
|
}
|
|
|
|
if ($key === $index) {
|
|
$index++;
|
|
if ($mapKey !== false) {
|
|
$exprs[$mapKey] = $expr;
|
|
} else {
|
|
# clé normale: la correspondance est en minuscule
|
|
$exprs[$expr] = strtolower($expr);
|
|
}
|
|
} else {
|
|
$exprs[$key] = $expr;
|
|
}
|
|
}
|
|
uksort($exprs, function ($a, $b) {
|
|
return -cv::complen($a, $b);
|
|
});
|
|
$this->exprs = $exprs;
|
|
}
|
|
|
|
/** @var ExpressionLanguage */
|
|
protected $el;
|
|
|
|
protected $subject;
|
|
|
|
protected $body;
|
|
|
|
protected $exprs;
|
|
|
|
protected function _eval(string $template, ?array $data): string {
|
|
if ($data === null) return $template;
|
|
$el = $this->el;
|
|
foreach ($this->exprs as $key => $expr) {
|
|
$value = $el->evaluate($expr, $data);
|
|
if (is_array($value)) $value = str::join(" ", $value);
|
|
elseif (!is_string($value)) $value = strval($value);
|
|
$template = str_replace($key, $value, $template);
|
|
}
|
|
return $template;
|
|
}
|
|
|
|
function eval(?array $data, $convertMd=true): array {
|
|
if ($data !== null) {
|
|
$data["_helper"] = new MailTemplateHelper($data);
|
|
}
|
|
$subject = $this->_eval($this->subject, $data);
|
|
$body = $this->body;
|
|
if ($convertMd) $body = mdc::convert($body);
|
|
$body = $this->_eval($body, $data);
|
|
return [
|
|
"subject" => $subject,
|
|
"body" => $body,
|
|
];
|
|
}
|
|
}
|