Files
deskhub/DeskHub-Webseite/staff/custom_fields.php
T
2026-10-19 18:06:00 +00:00

195 lines
10 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();
$pdo = get_db();
$errors = [];
$fieldTypes = [
'text' => 'Einzeiliger Text',
'textarea' => 'Mehrzeiliger Text',
'select' => 'Dropdown-Auswahl',
'radio' => 'Radio-Auswahl (Punkte)',
'checkbox' => 'Checkbox (Ja/Nein)',
'number' => 'Zahl',
'date' => 'Datum',
];
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$action = $_POST['action'] ?? '';
if ($action === 'create' || $action === 'update') {
$label = trim($_POST['label'] ?? '');
$type = array_key_exists($_POST['field_type'] ?? '', $fieldTypes) ? $_POST['field_type'] : 'text';
$optionsRaw = trim($_POST['options'] ?? '');
$helpTopicId = ($_POST['help_topic_id'] ?? '') !== '' ? (int) $_POST['help_topic_id'] : null;
$isRequired = !empty($_POST['is_required']) ? 1 : 0;
$isActive = !empty($_POST['is_active']) ? 1 : 0;
$sort = (int) ($_POST['sort_order'] ?? 0);
$radioInline = !empty($_POST['radio_inline']) ? 1 : 0;
$helpText = form_help_compose((string) ($_POST['help_text'] ?? ''), (string) ($_POST['link_url'] ?? ''), (string) ($_POST['link_word'] ?? ''), $label);
if ($label === '') $errors[] = 'Bitte eine Bezeichnung angeben.';
if (in_array($type, ['select', 'radio'], true) && $optionsRaw === '') $errors[] = 'Bitte mindestens eine Option angeben (eine pro Zeile).';
if (!$errors) {
if ($action === 'create') {
$pdo->prepare('INSERT INTO custom_fields (label, field_type, options, help_topic_id, is_required, is_active, sort_order, radio_inline, help_text, created_at) VALUES (?,?,?,?,?,?,?,?,?,?)')
->execute([$label, $type, $optionsRaw ?: null, $helpTopicId, $isRequired, $isActive, $sort, $radioInline, $helpText ?: null, db_now()]);
audit_log($admin['id'], "Ticket-Feld erstellt: {$label}");
flash('success', 'Feld erstellt.');
} else {
$id = (int) $_POST['id'];
$pdo->prepare('UPDATE custom_fields SET label=?, field_type=?, options=?, help_topic_id=?, is_required=?, is_active=?, sort_order=?, radio_inline=?, help_text=? WHERE id=?')
->execute([$label, $type, $optionsRaw ?: null, $helpTopicId, $isRequired, $isActive, $sort, $radioInline, $helpText ?: null, $id]);
audit_log($admin['id'], "Ticket-Feld aktualisiert: {$label}");
flash('success', 'Feld aktualisiert.');
}
redirect('/staff/custom_fields.php');
}
}
if ($action === 'delete') {
$id = (int) $_POST['id'];
$labelStmt = $pdo->prepare('SELECT label FROM custom_fields WHERE id = ?');
$labelStmt->execute([$id]);
$delLabel = $labelStmt->fetchColumn();
$pdo->prepare('DELETE FROM custom_fields WHERE id = ?')->execute([$id]);
audit_log($admin['id'], "Ticket-Feld gelöscht: {$delLabel}");
flash('success', 'Feld gelöscht (bereits erfasste Werte bleiben in bestehenden Tickets sichtbar).');
redirect('/staff/custom_fields.php');
}
}
$fields = $pdo->query(
'SELECT cf.*, ht.name AS help_topic_name FROM custom_fields cf
LEFT JOIN help_topics ht ON ht.id = cf.help_topic_id
WHERE cf.department_id IS NULL ORDER BY cf.sort_order, cf.label'
)->fetchAll();
$helpTopics = $pdo->query('SELECT * FROM help_topics ORDER BY name')->fetchAll();
$editId = $_GET['edit'] ?? null;
$editField = null;
if ($editId) {
$stmt = $pdo->prepare('SELECT * FROM custom_fields WHERE id = ?');
$stmt->execute([$editId]);
$editField = $stmt->fetch();
}
$pageTitle = 'Ticket-Felder';
$activePage = 'custom_fields';
require __DIR__ . '/_header.php';
?>
<h1>Individuelle Ticket-Felder</h1>
<p class="muted">Diese Felder erscheinen zusätzlich zu Name, E-Mail, Betreff und Beschreibung auf dem Formular „Neues Ticket erstellen“. Die eingegebenen Werte werden im Ticket angezeigt.</p>
<?php foreach ($errors as $err): ?>
<div class="flash error"><?= e($err) ?></div>
<?php endforeach; ?>
<div style="display:flex; gap:24px; align-items:flex-start">
<div style="flex:2">
<div class="card">
<table>
<thead><tr><th>Bezeichnung</th><th>Typ</th><th>Hilfe-Thema</th><th>Pflichtfeld</th><th>Aktiv</th><th></th></tr></thead>
<tbody>
<?php foreach ($fields as $f): ?>
<tr>
<td><?= e($f['label']) ?></td>
<td><?= e($fieldTypes[$f['field_type']] ?? $f['field_type']) ?></td>
<td class="muted"><?= $f['help_topic_name'] ? e($f['help_topic_name']) : 'Alle Themen' ?></td>
<td><?= $f['is_required'] ? '✓' : '–' ?></td>
<td><?= $f['is_active'] ? '✓' : '–' ?></td>
<td>
<a href="/staff/custom_fields.php?edit=<?= $f['id'] ?>">Bearbeiten</a> ·
<form method="post" style="display:inline" onsubmit="return confirm('Feld wirklich löschen? Bereits erfasste Werte in bestehenden Tickets bleiben erhalten.');">
<?= csrf_field() ?>
<input type="hidden" name="action" value="delete">
<input type="hidden" name="id" value="<?= $f['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 (!$fields): ?>
<tr><td colspan="6" class="muted">Noch keine individuellen Felder angelegt.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<div style="flex:1; min-width:300px">
<div class="card">
<h3><?= $editField ? 'Feld bearbeiten' : 'Neues Feld' ?></h3>
<form method="post">
<?= csrf_field() ?>
<input type="hidden" name="action" value="<?= $editField ? 'update' : 'create' ?>">
<?php if ($editField): ?><input type="hidden" name="id" value="<?= $editField['id'] ?>"><?php endif; ?>
<label for="label">Bezeichnung</label>
<input type="text" id="label" name="label" value="<?= e($editField['label'] ?? '') ?>" placeholder="z. B. Vertragsnummer" required>
<label for="field_type">Feldtyp</label>
<select name="field_type" id="field_type" onchange="document.getElementById('options-row').style.display = (this.value==='select' || this.value==='radio') ? 'block' : 'none'; document.getElementById('radio-row').style.display = this.value==='radio' ? 'block' : 'none'">
<?php foreach ($fieldTypes as $val => $lbl): ?>
<option value="<?= $val ?>" <?= ($editField['field_type'] ?? 'text') === $val ? 'selected' : '' ?>><?= e($lbl) ?></option>
<?php endforeach; ?>
</select>
<div id="options-row" style="display:<?= in_array($editField['field_type'] ?? '', ['select', 'radio'], true) ? 'block' : 'none' ?>">
<label for="options">Optionen (eine pro Zeile)</label>
<textarea id="options" name="options" placeholder="Option 1&#10;Option 2&#10;Option 3"><?= e($editField['options'] ?? '') ?></textarea>
</div>
<?php $__rt = $editField['field_type'] ?? ''; $__ri = $editField['radio_inline'] ?? 0; ?>
<div id="radio-row" style="display:<?= ($__rt === 'radio') ? 'block' : 'none' ?>">
<label for="radio_inline">Anordnung der Optionen</label>
<select id="radio_inline" name="radio_inline">
<option value="0" <?= empty($__ri) ? 'selected' : '' ?>>Untereinander</option>
<option value="1" <?= !empty($__ri) ? 'selected' : '' ?>>Nebeneinander</option>
</select>
</div>
<?php $__hStored = $editField['help_text'] ?? ''; ?>
<?php [$__hPlain, $__hUrl, $__hWord] = form_help_split($__hStored); ?>
<label for="help_text">Hinweistext (optional)</label>
<textarea id="help_text" name="help_text" rows="3" placeholder="z. B. Ich habe die Nutzerbedingungen gelesen und akzeptiert."><?= e($__hPlain) ?></textarea>
<div class="field-row">
<div><label for="link_word">Verlinkter Teil des Textes</label><input type="text" id="link_word" name="link_word" value="<?= e($__hWord) ?>" placeholder="z. B. Nutzerbedingungen"></div>
<div><label for="link_url">Link-Adresse</label><input type="text" id="link_url" name="link_url" value="<?= e($__hUrl) ?>" placeholder="https://…"></div>
</div>
<p class="muted" style="font-size:.78rem;margin:3px 0 0">Bei einer <strong>Checkbox</strong> steht der Text neben dem Kästchen, bei anderen Feldern unter dem Feld. Das Wort aus „Verlinkter Teil“ wird im Text zum Link auf die Adresse. Eine Checkbox als <strong>Pflichtfeld</strong> muss angehakt werden.</p>
<label for="help_topic_id">Gilt für Hilfe-Thema</label>
<select name="help_topic_id" id="help_topic_id">
<option value="">Alle Themen (oder Formular ohne Themenauswahl)</option>
<?php foreach ($helpTopics as $t): ?>
<option value="<?= $t['id'] ?>" <?= (string) ($editField['help_topic_id'] ?? ($_GET['topic'] ?? '')) === (string) $t['id'] ? 'selected' : '' ?>><?= e($t['name']) ?></option>
<?php endforeach; ?>
</select>
<p class="muted" style="font-size:.78rem">Auf „Alle Themen“ belassen, damit das Feld unabhängig vom gewählten Anliegen erscheint.</p>
<label for="sort_order">Sortierung</label>
<input type="text" id="sort_order" name="sort_order" value="<?= e((string) ($editField['sort_order'] ?? '0')) ?>">
<label style="display:flex; align-items:center; gap:8px; margin-top:14px">
<input type="checkbox" name="is_required" style="width:auto" <?= !empty($editField['is_required']) ? 'checked' : '' ?>>
Pflichtfeld
</label>
<label style="display:flex; align-items:center; gap:8px; margin-top:8px">
<input type="checkbox" name="is_active" style="width:auto" <?= ($editField['is_active'] ?? 1) ? 'checked' : '' ?>>
Aktiv (auf dem Ticket-Formular sichtbar)
</label>
<div class="btn-row">
<button type="submit" class="btn"><?= $editField ? 'Speichern' : 'Erstellen' ?></button>
<?php if ($editField): ?><a href="/staff/custom_fields.php" class="btn secondary">Abbrechen</a><?php endif; ?>
</div>
</form>
</div>
</div>
</div>
<?php require __DIR__ . '/_footer.php'; ?>