111 lines
7.1 KiB
PHP
111 lines
7.1 KiB
PHP
<?php
|
||
// Seite des Rundmail-Plugins. Verfügbar: $staff, $pdo.
|
||
$isAdmin = ($staff['role'] ?? '') === 'admin';
|
||
$message = null;
|
||
$error = null;
|
||
$form = ['group' => (string) ($_POST['group'] ?? ''), 'subject' => (string) ($_POST['subject'] ?? ''), 'body' => (string) ($_POST['body'] ?? '')];
|
||
$preview = null;
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||
verify_csrf();
|
||
$action = $_POST['action'] ?? '';
|
||
if ($action === 'preview') {
|
||
$g = rundmail_parse_group($pdo, $form['group']);
|
||
$err = rundmail_validate($form['subject'], $form['body']);
|
||
if (!$g) $error = 'Bitte eine Empfängergruppe wählen.';
|
||
elseif ($err) $error = $err;
|
||
else {
|
||
$rcpt = rundmail_recipients($pdo, $staff, $g['type'], $g['id']);
|
||
if (!$rcpt) $error = 'In dieser Gruppe gibt es keine Empfänger (oder Sie dürfen ihr nicht schreiben).';
|
||
else $preview = ['group' => $g, 'rcpt' => $rcpt];
|
||
}
|
||
} elseif ($action === 'send') {
|
||
if (empty($_POST['confirm'])) { $error = 'Bitte bestätigen, dass Text und Empfänger geprüft sind.'; }
|
||
else {
|
||
$r = rundmail_create($pdo, $staff, $form['group'], $form['subject'], $form['body']);
|
||
if ($r['ok']) {
|
||
$message = 'Die Nachricht geht an ' . $r['total'] . ' Empfänger. Der Versand läuft im Hintergrund, den Stand sehen Sie unten.';
|
||
$form = ['group' => '', 'subject' => '', 'body' => ''];
|
||
} else $error = $r['error'];
|
||
}
|
||
} elseif ($action === 'test') {
|
||
$r = rundmail_test($staff, $form['subject'], $form['body']);
|
||
if ($r['ok']) $message = 'Die Probemail ist an ' . $staff['email'] . ' unterwegs.'; else $error = $r['error'];
|
||
} elseif ($action === 'cancel') {
|
||
if (rundmail_cancel($pdo, $staff, (int) ($_POST['id'] ?? 0))) $message = 'Der Versand wurde abgebrochen.'; else $error = 'Dieser Versand lässt sich nicht abbrechen.';
|
||
}
|
||
}
|
||
// Offene Versände weiterschieben, damit der Stand beim Ansehen nicht stehen bleibt
|
||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') rundmail_tick($pdo);
|
||
|
||
$groups = rundmail_groups($pdo, $staff);
|
||
$history = rundmail_history($pdo, $staff);
|
||
$presets = rundmail_presets();
|
||
$statusLabels = ['sending' => 'Läuft', 'done' => 'Fertig', 'cancelled' => 'Abgebrochen'];
|
||
?>
|
||
<h1>Störungsmitteilung und Rundmail</h1>
|
||
<?php if ($message): ?><div class="flash success"><?= e($message) ?></div><?php endif; ?>
|
||
<?php if ($error): ?><div class="flash error"><?= e($error) ?></div><?php endif; ?>
|
||
|
||
<form method="post" class="card" style="max-width:860px;margin-bottom:16px">
|
||
<?= csrf_field() ?>
|
||
<h3>Neue Nachricht</h3>
|
||
<p class="muted" style="font-size:.85rem">Jede Mail geht einzeln an den Kunden (keine sichtbare Empfängerliste). Gedacht für Kunden mit offenen Tickets, etwa bei einer Wartung oder Störung. Mit <code>{name}</code> wird der Name eingesetzt.<?= $isAdmin ? '' : ' Sie sehen nur Gruppen Ihrer Abteilungen.' ?></p>
|
||
<label>Empfänger</label>
|
||
<select name="group" required>
|
||
<option value="">– Gruppe wählen –</option>
|
||
<?php foreach ($groups as $g): ?><option value="<?= e($g['key']) ?>" <?= $form['group'] === $g['key'] ? 'selected' : '' ?>><?= e($g['label']) ?></option><?php endforeach; ?>
|
||
</select>
|
||
<label style="margin-top:8px">Vorlage</label>
|
||
<select id="rm-preset" onchange="var p=window.RM_PRESETS[this.value];if(p){document.getElementById('rm-subject').value=p[0];document.getElementById('rm-body').value=p[1];}">
|
||
<option value="">– eigene Nachricht –</option>
|
||
<?php foreach ($presets as $k => $p): ?><option value="<?= e($k) ?>"><?= e($p[0]) ?></option><?php endforeach; ?>
|
||
</select>
|
||
<script>window.RM_PRESETS = <?= json_encode($presets, JSON_UNESCAPED_UNICODE | JSON_HEX_TAG | JSON_HEX_AMP) ?>;</script>
|
||
<label style="margin-top:8px">Betreff</label>
|
||
<input type="text" id="rm-subject" name="subject" maxlength="150" value="<?= e($form['subject']) ?>" required>
|
||
<label style="margin-top:8px">Text</label>
|
||
<textarea id="rm-body" name="body" rows="9" maxlength="5000" required><?= e($form['body']) ?></textarea>
|
||
<div class="btn-row">
|
||
<button type="submit" name="action" value="preview" class="btn">Empfänger prüfen</button>
|
||
<button type="submit" name="action" value="test" class="btn secondary">Probemail an mich</button>
|
||
</div>
|
||
</form>
|
||
|
||
<?php if ($preview): ?>
|
||
<form method="post" class="card" style="max-width:860px;margin-bottom:16px;border-left:4px solid #b45309">
|
||
<?= csrf_field() ?>
|
||
<input type="hidden" name="action" value="send">
|
||
<input type="hidden" name="group" value="<?= e($form['group']) ?>">
|
||
<input type="hidden" name="subject" value="<?= e($form['subject']) ?>">
|
||
<input type="hidden" name="body" value="<?= e($form['body']) ?>">
|
||
<h3>Vor dem Senden prüfen</h3>
|
||
<p><strong><?= count($preview['rcpt']) ?></strong> Empfänger: <?= e($preview['group']['label']) ?></p>
|
||
<p class="muted" style="font-size:.84rem">Zum Beispiel: <?= e(implode(', ', array_map(fn($r) => $r['email'], array_slice($preview['rcpt'], 0, 5)))) ?><?= count($preview['rcpt']) > 5 ? ' …' : '' ?></p>
|
||
<div style="border:1px solid var(--border,#e3e9ee);border-radius:8px;padding:12px;margin:8px 0;font-size:.9rem"><strong><?= e($form['subject']) ?></strong><br><br><?= nl2br(e(str_replace('{name}', $preview['rcpt'][0]['name'] ?: 'Kunde', $form['body']))) ?></div>
|
||
<label style="font-weight:400"><input type="checkbox" name="confirm" value="1" style="width:auto"> Text und Empfänger sind geprüft, die Nachricht kann nicht zurückgeholt werden.</label>
|
||
<div class="btn-row"><button type="submit" class="btn">An <?= count($preview['rcpt']) ?> Empfänger senden</button></div>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<div class="card">
|
||
<h3><?= $isAdmin ? 'Verlauf aller Nachrichten' : 'Ihre gesendeten Nachrichten' ?></h3>
|
||
<?php if (!$history): ?><p class="muted">Noch nichts gesendet.</p><?php else: ?>
|
||
<table style="width:100%">
|
||
<thead><tr><th>Wann</th><th>Betreff</th><th>Empfänger</th><th>Von</th><th>Stand</th><th></th></tr></thead>
|
||
<tbody>
|
||
<?php foreach ($history as $h): ?>
|
||
<tr>
|
||
<td class="muted" style="white-space:nowrap"><?= e(format_dt((string) $h['created_at'])) ?></td>
|
||
<td><?= e((string) $h['subject']) ?></td>
|
||
<td><?= e((string) $h['group_label']) ?></td>
|
||
<td><?= e((string) $h['sender_name']) ?></td>
|
||
<td><?= e($statusLabels[$h['status']] ?? $h['status']) ?><div class="muted" style="font-size:.76rem"><?= (int) $h['sent'] ?> von <?= (int) $h['total'] ?> gesendet<?= (int) $h['failed'] ? ', <span style="color:#b42318">' . (int) $h['failed'] . ' fehlgeschlagen</span>' : '' ?></div></td>
|
||
<td><?php if ($h['status'] === 'sending' && ($isAdmin || (int) $h['sender_id'] === (int) $staff['id'])): ?><form method="post" onsubmit="return confirm('Versand abbrechen? Noch nicht gesendete Mails entfallen.')"><?= csrf_field() ?><input type="hidden" name="action" value="cancel"><input type="hidden" name="id" value="<?= (int) $h['id'] ?>"><button class="btn secondary" type="submit" style="padding:2px 10px;font-size:.78rem">Abbrechen</button></form><?php endif; ?></td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php endif; ?>
|
||
</div>
|