mail send

This commit is contained in:
2025-12-07 01:40:21 +01:00
parent 98298e2b23
commit cb9deabe91
4 changed files with 208 additions and 7 deletions

View File

@@ -1,6 +1,8 @@
<?php
declare(strict_types=1);
use TijsVerkoyen\CssToInlineStyles\CssToInlineStyles;
// 💡 NEUE KORREKTUR: Starte Output Buffering so früh wie möglich, um Whitespace/Errors
// von inkludierten Dateien (AuthService.php, config.php) abzufangen.
ob_start();
@@ -617,6 +619,118 @@ class ApiKernel
$this->respond(['ok' => true, 'kind' => $kind, 'id' => $id, 'deleted' => true]);
}
/**
* Sendet einen Testversand für Templates.
*/
private function handleTemplateTestSend(): void
{
$auth = $this->requireAuth();
$templateId = (int)$this->val($this->in, ['template_id', 'id', 'template'], 0);
if ($templateId <= 0) {
$this->fail('template_id required', null, 422);
}
$recipient = trim((string)$this->val($this->in, ['to', 'email', 'recipient'], ''));
if ($recipient === '' || !filter_var($recipient, FILTER_VALIDATE_EMAIL)) {
$this->fail('Valid recipient required', null, 422);
}
$subject = trim((string)$this->val($this->in, ['subject'], 'Testversand'));
if ($subject === '') {
$subject = 'Testversand';
}
$t = $this->tableMap['templates'];
[$idCol, $allCols] = $this->resolveIdCol('templates');
[$tw, $tp] = $this->tenantWhere($auth);
$sql = "SELECT * FROM `$t` WHERE `$idCol` = :id" . $tw . " LIMIT 1";
$stmt = $this->pdo->prepare($sql);
$stmt->bindValue(':id', $templateId);
foreach ($tp as $k => $v) $stmt->bindValue($k, $v);
$stmt->execute();
$row = $stmt->fetch();
if (!$row) {
$this->fail('Template not found', ['id' => $templateId], 404);
}
$htmlCol = $this->firstExisting($allCols, ['html', 'body', 'markup', 'content']);
$html = ($htmlCol && isset($row[$htmlCol])) ? (string)$row[$htmlCol] : '';
if ($html === '' && !empty($row['json_content'])) {
$html = '<p>(Dieses Template enthält noch keine HTML-Inhalte.)</p>';
}
$html = $this->prepareEmailHtml($html);
if (!$this->dispatchTestMail($recipient, $subject, $html)) {
$this->fail('Send failed', null, 500);
}
$this->respond([
'ok' => true,
'template_id' => $templateId,
'to' => $recipient,
'subject' => $subject,
]);
}
private function prepareEmailHtml(string $html): string
{
$html = trim($html);
if ($html === '') {
return '<p>(Kein Inhalt vorhanden)</p>';
}
if (!class_exists(CssToInlineStyles::class)) {
return $html;
}
try {
$inliner = new CssToInlineStyles();
return $inliner->convert($html);
} catch (Throwable $e) {
return $html;
}
}
private function dispatchTestMail(string $to, string $subject, string $html): bool
{
if (!function_exists('mail')) {
return false;
}
$smtp = $this->conf['smtp'] ?? [];
$fromEmail = $smtp['from_email'] ?? 'no-reply@example.com';
$fromName = $smtp['from_name'] ?? 'EmailTemplate';
$headers = [
'MIME-Version: 1.0',
'Content-Type: text/html; charset=UTF-8',
'From: ' . $this->formatEmailAddress($fromEmail, $fromName),
];
$encodedSubject = function_exists('mb_encode_mimeheader')
? mb_encode_mimeheader($subject, 'UTF-8')
: $subject;
return @mail($to, $encodedSubject, $html, implode("\r\n", $headers));
}
private function formatEmailAddress(string $email, string $name): string
{
$email = trim($email);
if ($email === '') {
return 'no-reply@example.com';
}
$name = trim($name);
if ($name === '') {
return $email;
}
$encoded = function_exists('mb_encode_mimeheader')
? mb_encode_mimeheader($name, 'UTF-8')
: $name;
return sprintf('%s <%s>', $encoded, $email);
}
// =================================================================
// 💡 Öffentliche run()-Methode (KORRIGIERT)
// =================================================================
@@ -649,6 +763,9 @@ class ApiKernel
$this->authService->logout();
$this->respond(['ok' => true]);
break;
case 'templates.test_send':
$this->handleTemplateTestSend();
break;
/* ---------- CRUD HANDLER ---------- */
default: