Files
deskhub/DeskHub-Webseite/staff/email_addresses.php
T
2026-10-28 07:54:42 +00:00

390 lines
23 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require_once __DIR__ . '/../includes/bootstrap.php';
$admin = require_admin_or_permission('manage_email_addresses');
$pdo = get_db();
$errors = [];
$departments = departments_for_select($pdo, array_map('intval', $pdo->query('SELECT department_id FROM email_addresses')->fetchAll(PDO::FETCH_COLUMN)));
$priorities = $pdo->query('SELECT * FROM priorities ORDER BY sort_order')->fetchAll();
$topics = help_topic_options($pdo, false, false);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'create' || $action === 'update') {
$id = $action === 'update' ? (int) ($_POST['id'] ?? 0) : 0;
try {
$newId = email_address_save($pdo, $id, [
'email' => $_POST['email'] ?? '', 'label' => $_POST['label'] ?? '',
'department_id' => $_POST['department_id'] ?? 0, 'priority_id' => $_POST['priority_id'] ?? null,
'help_topic_id' => $_POST['help_topic_id'] ?? null, 'is_default' => !empty($_POST['is_default']),
'is_active' => ($_POST['status'] ?? 'active') === 'active', 'notes' => $_POST['notes'] ?? '',
'imap_enabled' => !empty($_POST['imap_enabled']), 'imap_host' => $_POST['host'] ?? '', 'imap_port' => $_POST['port'] ?? 993,
'imap_encryption' => $_POST['encryption'] ?? 'ssl', 'imap_username' => $_POST['username'] ?? '', 'imap_password' => $_POST['password'] ?? '',
'imap_folder' => $_POST['folder'] ?? '', 'imap_after_fetch' => $_POST['after_fetch'] ?? 'seen',
'imap_archive_folder' => $_POST['archive_folder'] ?? '', 'imap_spam_folder' => $_POST['spam_folder'] ?? '',
'smtp_enabled' => !empty($_POST['smtp_enabled']), 'smtp_host' => $_POST['smtp_host'] ?? '', 'smtp_port' => $_POST['smtp_port'] ?? 587,
'smtp_encryption' => $_POST['smtp_encryption'] ?? 'tls', 'smtp_username' => $_POST['smtp_username'] ?? '', 'smtp_password' => $_POST['smtp_password'] ?? '',
]);
audit_log($admin['id'], ($action === 'create' ? 'E-Mail-Adresse erstellt: ' : 'E-Mail-Adresse aktualisiert: ') . strtolower(trim($_POST['email'] ?? '')));
flash('success', $action === 'create' ? 'E-Mail-Adresse erstellt.' : 'Änderungen gespeichert.');
redirect('/staff/email_addresses.php');
} catch (EmailAddressException $e) {
$errors[] = $e->getMessage();
}
}
if ($action === 'delete') {
$delEmail = email_address_delete($pdo, (int) $_POST['id']);
audit_log($admin['id'], "E-Mail-Adresse gelöscht: {$delEmail}");
flash('success', 'E-Mail-Adresse gelöscht.');
redirect('/staff/email_addresses.php');
}
if (in_array($action, ['send_test', 'test', 'test_smtp'], true)) {
$id = (int) $_POST['id'];
try {
$msg = match ($action) {
'send_test' => email_address_send_test($pdo, $id, $admin['email']),
'test' => email_address_test_imap($pdo, $id),
default => email_address_test_smtp($pdo, $id),
};
flash('success', $msg);
} catch (EmailAddressException $e) {
flash('error', $e->getMessage());
}
redirect('/staff/email_addresses.php?edit=' . $id . ($action === 'test' ? '&tab=imap' : ($action === 'test_smtp' ? '&tab=smtp' : '')));
}
if ($action === 'bulk_add') {
$raw = trim($_POST['bulk_emails'] ?? '');
$deptId = (int) ($_POST['bulk_department_id'] ?? 0);
$prioId = ($_POST['bulk_priority_id'] ?? '') !== '' ? (int) $_POST['bulk_priority_id'] : null;
if (!in_array($deptId, array_map('intval', array_column($departments, 'id')), true)) {
$errors[] = 'Bitte eine gültige Abteilung wählen.';
} else {
// Eine Adresse pro Zeile, optional mit Komma getrennter Bezeichnung: "email@x.de, Bezeichnung"
$lines = array_filter(array_map('trim', preg_split('/[\r\n]+/', $raw)));
$added = 0;
$skipped = 0;
foreach ($lines as $line) {
$parts = array_map('trim', explode(',', $line, 2));
try {
email_address_save($pdo, 0, ['email' => $parts[0] ?? '', 'label' => $parts[1] ?? '', 'department_id' => $deptId, 'priority_id' => $prioId]);
$added++;
} catch (EmailAddressException $e) {
$skipped++;
}
}
audit_log($admin['id'], "E-Mail-Adressen Massen-Import: $added hinzugefügt, $skipped übersprungen");
flash('success', "$added Adresse(n) hinzugefügt, $skipped übersprungen (ungültig oder bereits vorhanden).");
redirect('/staff/email_addresses.php');
}
}
}
// --- Anzeige: Formular (neu/bearbeiten) oder Liste ---------------------------------------
$isNew = isset($_GET['new']);
$editId = (int) ($_GET['edit'] ?? 0);
$showForm = $isNew || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true));
$editAddress = null;
$editImap = null;
if ($editId) {
$stmt = $pdo->prepare('SELECT * FROM email_addresses WHERE id = ?');
$stmt->execute([$editId]);
$editAddress = $stmt->fetch() ?: null;
if ($editAddress) $editImap = email_address_imap($pdo, $editId);
}
$f = fn(string $k, $default = '') => $_POST[$k] ?? $default;
$tab = in_array($_GET['tab'] ?? '', ['imap', 'smtp'], true) ? $_GET['tab'] : 'account';
if ($errors && !empty($_POST['smtp_enabled'])) $tab = 'smtp';
elseif ($errors && !empty($_POST['imap_enabled'])) $tab = 'imap';
$addresses = $pdo->query(
'SELECT ea.*, d.name AS department_name, p.name AS priority_name,
(SELECT COUNT(*) FROM imap_accounts ia WHERE ia.email_address_id = ea.id AND ia.is_active = 1) AS imap_active
FROM email_addresses ea
JOIN departments d ON d.id = ea.department_id
LEFT JOIN priorities p ON p.id = ea.priority_id
ORDER BY d.name, ea.email'
)->fetchAll();
$fmt = fn(?string $dt) => $dt ? date('d.m.Y H:i', strtotime($dt)) : '–';
$pageTitle = 'E-Mail-Adressen';
$activePage = 'email_addresses';
require __DIR__ . '/_header.php';
?>
<?php foreach ($errors as $err): ?>
<div class="flash error"><?= e($err) ?></div>
<?php endforeach; ?>
<?php if ($showForm): ?>
<?php
$v = fn(string $k, string $col, $default = '') => $f($k, $editAddress[$col] ?? $default);
$imapV = fn(string $k, string $col, $default = '') => $f($k, $editImap[$col] ?? $default);
$curStatus = $_POST ? ($_POST['status'] ?? 'active') : (($editAddress['is_active'] ?? 1) ? 'active' : 'inactive');
$imapEnabled = $_POST ? !empty($_POST['imap_enabled']) : ($editImap && $editImap['is_active']);
$smtpEnabled = $_POST ? !empty($_POST['smtp_enabled']) : !empty($editAddress['smtp_enabled']);
$afterFetchVal = $imapV('after_fetch', 'after_fetch', 'seen');
$hasSmtpPass = !empty($editAddress['smtp_password_enc']);
?>
<h1>
<?= $editAddress ? 'E-Mail-Adresse' : 'Neue E-Mail-Adresse' ?>
<?php if ($editAddress): ?><span class="muted" style="font-size:1rem;font-weight:400">— <?= e($editAddress['label'] ?: '') ?> &lt;<?= e($editAddress['email']) ?>&gt;</span><?php endif; ?>
</h1>
<form method="post" class="card" style="padding:0" autocomplete="off">
<?= csrf_field() ?>
<input type="hidden" name="action" value="<?= $editAddress ? 'update' : 'create' ?>">
<?php if ($editAddress): ?><input type="hidden" name="id" value="<?= (int) $editAddress['id'] ?>"><?php endif; ?>
<div class="tabs" style="display:flex;gap:4px;padding:10px 12px 0;border-bottom:1px solid var(--border)">
<button type="button" class="tab-btn" data-tab="account">Konto</button>
<button type="button" class="tab-btn" data-tab="imap">Entferntes Postfach</button>
<button type="button" class="tab-btn" data-tab="smtp">Abgehend (SMTP)</button>
</div>
<div class="tab-pane" data-pane="account" style="padding:16px 20px">
<h3 style="margin-top:0">E-Mail-Informationen und Einstellungen</h3>
<p class="muted" style="font-size:.82rem">Eingehende Mails an diese Adresse landen automatisch in der gewählten Abteilung; ausgehende Antworten dieser Abteilung werden mit dieser Adresse als Absender verschickt.</p>
<label for="email">E-Mail-Adresse *</label>
<input type="email" id="email" name="email" value="<?= e($v('email', 'email')) ?>" required>
<label for="label">Anzeigename</label>
<input type="text" id="label" name="label" value="<?= e($v('label', 'label')) ?>" placeholder="z. B. Windelgeschichten">
<label>Status</label>
<div style="display:flex;gap:18px;margin:4px 0 10px">
<label style="display:flex;align-items:center;gap:6px;margin:0"><input type="radio" name="status" value="active" style="width:auto" <?= $curStatus === 'active' ? 'checked' : '' ?>> <strong>Aktiv</strong></label>
<label style="display:flex;align-items:center;gap:6px;margin:0"><input type="radio" name="status" value="inactive" style="width:auto" <?= $curStatus !== 'active' ? 'checked' : '' ?>> Deaktiviert</label>
</div>
<p class="muted" style="font-size:.78rem;margin-top:-6px">Eine deaktivierte Adresse wird weder für das Routing noch als Absender verwendet; der Abruf pausiert.</p>
<h3>Einstellungen bei neuem Ticket</h3>
<label for="department_id">Abteilung *</label>
<select name="department_id" id="department_id" required>
<?php foreach ($departments as $d): ?>
<option value="<?= $d['id'] ?>" <?= (string) $v('department_id', 'department_id') === (string) $d['id'] ? 'selected' : '' ?>><?= e($d['name']) ?><?= ($d['is_active'] ?? 1) ? '' : ' (deaktiviert)' ?></option>
<?php endforeach; ?>
</select>
<label for="priority_id">Priorität</label>
<select name="priority_id" id="priority_id">
<option value="">— Systemstandard —</option>
<?php foreach ($priorities as $p): ?>
<option value="<?= $p['id'] ?>" <?= (string) $v('priority_id', 'priority_id') === (string) $p['id'] ? 'selected' : '' ?>><?= e($p['name']) ?></option>
<?php endforeach; ?>
</select>
<label for="help_topic_id">Hilfethema</label>
<select name="help_topic_id" id="help_topic_id">
<option value="">— Systemstandard —</option>
<?php foreach ($topics as $t): ?>
<option value="<?= $t['id'] ?>" <?= (string) $v('help_topic_id', 'help_topic_id') === (string) $t['id'] ? 'selected' : '' ?>><?= e($t['path']) ?></option>
<?php endforeach; ?>
</select>
<label style="display:flex; align-items:center; gap:8px; margin-top:14px">
<input type="checkbox" name="is_default" style="width:auto" <?= $_POST ? (!empty($_POST['is_default']) ? 'checked' : '') : (!empty($editAddress['is_default']) ? 'checked' : '') ?>>
Standard-Absenderadresse dieser Abteilung
</label>
<h3>Interne Notizen <span class="muted" style="font-weight:400;font-size:.85rem">– Sei offen, sie sind vertraulich</span></h3>
<textarea name="notes" rows="5"><?= e($v('notes', 'notes')) ?></textarea>
</div>
<div class="tab-pane" data-pane="imap" style="padding:16px 20px;display:none">
<h3 style="margin-top:0">Mails per IMAP abrufen</h3>
<label style="display:flex; align-items:center; gap:8px">
<input type="checkbox" name="imap_enabled" id="imap_enabled" style="width:auto" <?= $imapEnabled ? 'checked' : '' ?>>
Abruf für diese Adresse aktivieren
</label>
<p class="muted" style="font-size:.8rem">Abteilung, Priorität und Hilfethema stammen aus dem Reiter „Konto“.
<?php if ($editImap): ?>Letzter Abruf: <?= e(cron_last_run_label($editImap['last_run_at'] ?? null)) ?>.<?php endif; ?></p>
<div id="imap-fields">
<div style="display:grid;grid-template-columns:1fr 100px;gap:10px">
<div><label for="host">Server</label>
<input type="text" id="host" name="host" value="<?= e($imapV('host', 'host')) ?>" placeholder="imap.beispiel.de"></div>
<div><label for="port">Port</label>
<input type="number" id="port" name="port" value="<?= e($imapV('port', 'port', '993')) ?>"></div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">
<div><label for="username">Benutzername</label>
<input type="text" id="username" name="username" value="<?= e($imapV('username', 'username')) ?>" placeholder="leer = E-Mail-Adresse" autocomplete="off"></div>
<div><label for="password">Passwort</label>
<input type="password" id="password" name="password" placeholder="<?= $editImap ? '(unverändert)' : '' ?>" autocomplete="new-password"></div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">
<div><label for="encryption">Verschlüsselung</label>
<select id="encryption" name="encryption">
<?php $encVal = $imapV('encryption', 'encryption', 'ssl'); ?>
<option value="ssl" <?= $encVal === 'ssl' ? 'selected' : '' ?>>SSL/TLS (993)</option>
<option value="tls" <?= $encVal === 'tls' ? 'selected' : '' ?>>STARTTLS (143)</option>
<option value="none" <?= $encVal === 'none' ? 'selected' : '' ?>>Keine</option>
</select></div>
<div><label for="folder">Ordner</label>
<input type="text" id="folder" name="folder" value="<?= e($imapV('folder', 'folder', 'INBOX')) ?>"></div>
</div>
<label for="after_fetch" style="margin-top:10px">Aktion nach Abruf</label>
<select id="after_fetch" name="after_fetch">
<option value="seen" <?= $afterFetchVal === 'seen' ? 'selected' : '' ?>>Als gelesen markieren</option>
<option value="archive" <?= $afterFetchVal === 'archive' ? 'selected' : '' ?>>In Ordner verschieben</option>
<option value="delete" <?= $afterFetchVal === 'delete' ? 'selected' : '' ?>>Löschen</option>
</select>
<div id="archive-row" style="margin-top:10px">
<label for="archive_folder">Zielordner</label>
<input type="text" id="archive_folder" name="archive_folder" value="<?= e($imapV('archive_folder', 'archive_folder', 'Processed')) ?>">
</div>
<label for="spam_folder" style="margin-top:10px">Spam-/Junk-Ordner</label>
<input type="text" id="spam_folder" name="spam_folder" value="<?= e($imapV('spam_folder', 'spam_folder', 'Junk')) ?>">
</div>
</div>
<div class="tab-pane" data-pane="smtp" style="padding:16px 20px;display:none">
<h3 style="margin-top:0">Ausgehende Mails (SMTP)</h3>
<label style="display:flex; align-items:center; gap:8px">
<input type="checkbox" name="smtp_enabled" id="smtp_enabled" style="width:auto" <?= $smtpEnabled ? 'checked' : '' ?>>
Eigenen SMTP-Server für diese Adresse verwenden
</label>
<p class="muted" style="font-size:.8rem">Ohne eigenen Server werden Mails mit dieser Absenderadresse über den globalen SMTP aus den <a href="/staff/settings.php">Einstellungen</a> verschickt.</p>
<div id="smtp-fields">
<div style="display:grid;grid-template-columns:1fr 100px;gap:10px">
<div><label for="smtp_host">Server</label>
<input type="text" id="smtp_host" name="smtp_host" value="<?= e($v('smtp_host', 'smtp_host')) ?>" placeholder="smtp.beispiel.de"></div>
<div><label for="smtp_port">Port</label>
<input type="number" id="smtp_port" name="smtp_port" value="<?= e($v('smtp_port', 'smtp_port', '587')) ?>"></div>
</div>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px">
<div><label for="smtp_username">Benutzername</label>
<input type="text" id="smtp_username" name="smtp_username" value="<?= e($v('smtp_username', 'smtp_username')) ?>" autocomplete="off"></div>
<div><label for="smtp_password">Passwort</label>
<input type="password" id="smtp_password" name="smtp_password" placeholder="<?= $hasSmtpPass ? '(unverändert)' : '' ?>" autocomplete="new-password"></div>
</div>
<label for="smtp_encryption" style="margin-top:10px">Verschlüsselung</label>
<select id="smtp_encryption" name="smtp_encryption" style="max-width:260px">
<?php $smtpEnc = $v('smtp_encryption', 'smtp_encryption', 'tls'); ?>
<option value="tls" <?= $smtpEnc === 'tls' ? 'selected' : '' ?>>STARTTLS (587)</option>
<option value="ssl" <?= $smtpEnc === 'ssl' ? 'selected' : '' ?>>SSL/TLS (465)</option>
<option value="none" <?= $smtpEnc === 'none' ? 'selected' : '' ?>>Keine</option>
</select>
</div>
</div>
<div class="btn-row" style="padding:0 20px 18px">
<button type="submit" class="btn"><?= $editAddress ? 'Änderungen speichern' : 'Erstellen' ?></button>
<a href="/staff/email_addresses.php" class="btn secondary">Abbrechen</a>
</div>
</form>
<?php if ($editAddress): ?>
<div style="display:flex;gap:10px;margin-top:12px;flex-wrap:wrap">
<?php
$tests = [['send_test', 'Test-Mail senden (an ' . $admin['email'] . ')', true]];
if ($editImap) $tests[] = ['test', 'Postfach-Verbindung testen', true];
if (!empty($editAddress['smtp_enabled'])) $tests[] = ['test_smtp', 'SMTP-Server testen', true];
foreach ($tests as [$act, $lbl]): ?>
<form method="post">
<?= csrf_field() ?>
<input type="hidden" name="action" value="<?= $act ?>">
<input type="hidden" name="id" value="<?= (int) $editAddress['id'] ?>">
<button type="submit" class="btn secondary"><?= e($lbl) ?></button>
</form>
<?php endforeach; ?>
</div>
<p class="muted" style="font-size:.78rem">Tests verwenden die gespeicherten Werte.</p>
<?php endif; ?>
<style>
.tab-btn{background:none;border:1px solid transparent;border-bottom:none;padding:8px 16px;cursor:pointer;border-radius:6px 6px 0 0;color:var(--muted)}
.tab-btn.active{background:var(--card-bg,#fff);border-color:var(--border);color:inherit;font-weight:600;position:relative;top:1px}
</style>
<script>
(function () {
var btns = document.querySelectorAll('.tab-btn'), panes = document.querySelectorAll('.tab-pane');
function show(t) {
btns.forEach(function (b) { b.classList.toggle('active', b.dataset.tab === t); });
panes.forEach(function (p) { p.style.display = p.dataset.pane === t ? '' : 'none'; });
}
btns.forEach(function (b) { b.addEventListener('click', function () { show(b.dataset.tab); }); });
show(<?= json_encode($tab) ?>);
function toggler(checkId, boxId) {
var on = document.getElementById(checkId), box = document.getElementById(boxId);
function sync() { box.style.opacity = on.checked ? '1' : '.5'; box.querySelectorAll('input,select').forEach(function (i) { i.disabled = !on.checked; }); }
on.addEventListener('change', sync); sync();
}
toggler('imap_enabled', 'imap-fields'); toggler('smtp_enabled', 'smtp-fields');
// Verschlüsselung gewählt: Port passend setzen (nur wenn dort noch ein Standardport steht, eigene Ports bleiben)
var enc = document.getElementById('smtp_encryption'), prt = document.getElementById('smtp_port');
if (enc && prt) enc.addEventListener('change', function () {
var std = { tls: '587', ssl: '465', none: '25' };
if (['25', '465', '587', ''].indexOf(String(prt.value).trim()) !== -1) prt.value = std[enc.value] || prt.value;
});
var af = document.getElementById('after_fetch'), ar = document.getElementById('archive-row');
function syncAf() { ar.style.display = af.value === 'archive' ? '' : 'none'; }
af.addEventListener('change', syncAf); syncAf();
})();
</script>
<?php else: ?>
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px">
<h1 style="margin:0">E-Mail-Adressen</h1>
<a href="/staff/email_addresses.php?new=1" class="btn">Neue E-Mail-Adresse</a>
</div>
<p class="muted">Eine Adresse = Abteilung + Priorität + Hilfethema + (optional) Postfach zum Abruf und eigener SMTP-Server. DeskHub wertet beim Abruf den „An:“- und „CC:“-Header aus und legt das Ticket in der passenden Abteilung ab. Ist keine Adresse passend, greift die Standardabteilung aus den <a href="/staff/settings.php">Einstellungen</a>.</p>
<div class="card">
<table>
<thead><tr><th>E-Mail-Adresse</th><th>Anzeigename</th><th>Status</th><th>Abteilung</th><th>Priorität</th><th>Abruf</th><th>Eigener SMTP</th><th>Zuletzt aktualisiert</th><th></th></tr></thead>
<tbody>
<?php foreach ($addresses as $a): ?>
<tr>
<td><a href="/staff/email_addresses.php?edit=<?= (int) $a['id'] ?>"><?= e($a['email']) ?></a><?= $a['is_default'] ? ' <span class="muted">(Standard)</span>' : '' ?></td>
<td><?= e($a['label'] ?: '–') ?></td>
<td><strong><?= ($a['is_active'] ?? 1) ? 'Aktiv' : 'Deaktiviert' ?></strong></td>
<td><?= e($a['department_name']) ?></td>
<td><?= e($a['priority_name'] ?? 'Systemstandard') ?></td>
<td><?= $a['imap_active'] ? '✓' : '–' ?></td>
<td><?= !empty($a['smtp_enabled']) ? '✓' : '–' ?></td>
<td class="muted" style="font-size:.82rem"><?= e($fmt($a['updated_at'] ?? null)) ?></td>
<td style="white-space:nowrap">
<a href="/staff/email_addresses.php?edit=<?= (int) $a['id'] ?>">Bearbeiten</a> ·
<form method="post" style="display:inline" onsubmit="return confirm('E-Mail-Adresse wirklich löschen?');">
<?= csrf_field() ?>
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= (int) $a['id'] ?>">
<button type="submit" style="background:none;border:none;color:#dc2626;cursor:pointer;padding:0;font-size:.9rem">Löschen</button>
</form>
</td>
</tr>
<?php endforeach; ?>
<?php if (!$addresses): ?>
<tr><td colspan="9" class="muted">Noch keine E-Mail-Adressen angelegt.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
<details class="card" style="margin-top:20px">
<summary style="cursor:pointer;font-weight:600">Mehrere Adressen auf einmal anlegen</summary>
<p class="muted" style="font-size:.82rem;margin:10px 0">Eine Adresse pro Zeile, optional mit Anzeigename nach einem Komma (z. B. <code>technik@firma.de, Technik-Support</code>).</p>
<form method="post">
<?= csrf_field() ?>
<input type="hidden" name="action" value="bulk_add">
<textarea name="bulk_emails" rows="5" required style="font-family:monospace;font-size:.82rem"></textarea>
<label style="margin-top:10px">Abteilung</label>
<select name="bulk_department_id" required>
<?php foreach ($departments as $d): ?><option value="<?= $d['id'] ?>"><?= e($d['name']) ?></option><?php endforeach; ?>
</select>
<label style="margin-top:10px">Priorität</label>
<select name="bulk_priority_id">
<option value="">— Systemstandard —</option>
<?php foreach ($priorities as $p): ?><option value="<?= $p['id'] ?>"><?= e($p['name']) ?></option><?php endforeach; ?>
</select>
<div class="btn-row"><button type="submit" class="btn">Alle anlegen</button></div>
</form>
</details>
<?php endif; ?>
<?php require __DIR__ . '/_footer.php'; ?>