query('SELECT * FROM departments ORDER BY name')->fetchAll(); $customRoles = $pdo->query('SELECT * FROM roles ORDER BY name')->fetchAll(); $teams = $pdo->query('SELECT id, name, is_active FROM teams ORDER BY name')->fetchAll(); $permLabels = [ 'reply_ticket' => 'Tickets beantworten', 'close_ticket' => 'Tickets schließen/lösen', 'delete_ticket' => 'Tickets löschen', 'transfer_ticket' => 'Tickets übertragen', 'post_note' => 'Interne Notizen schreiben', 'assign_ticket' => 'Tickets zuweisen', 'manage_canned' => 'Textbausteine verwalten', 'view_reports' => 'Berichte einsehen', 'manage_kb' => 'Wissensdatenbank verwalten', 'create_ticket' => 'Tickets im Namen von Kunden erstellen', ] + array_diff_key(admin_section_permissions(), ['manage_kb' => 1]); /** Setzt die zusätzlichen Abteilungen (Erweiterter Zugriff) neu. */ function save_staff_access(PDO $pdo, int $id, ?int $primaryDeptId, array $post): void { $selected = array_unique(array_filter(array_map('intval', $post['extra_departments'] ?? []))); $pdo->prepare('DELETE FROM staff_department WHERE staff_id = ?')->execute([$id]); $ins = $pdo->prepare('INSERT INTO staff_department (staff_id, department_id, notify, role_id) VALUES (?,?,?,?)'); $validRoles = array_map('intval', $pdo->query('SELECT id FROM roles')->fetchAll(PDO::FETCH_COLUMN)); foreach ($selected as $dId) { if ($dId === (int) $primaryDeptId) continue; // Hauptabteilung wird nicht doppelt gespeichert $rid = (int) ($post['role_' . $dId] ?? 0); $ins->execute([$id, $dId, !empty($post['notify_' . $dId]) ? 1 : 0, in_array($rid, $validRoles, true) ? $rid : null]); } } /** Setzt die Team-Mitgliedschaften eines Mitarbeiters neu. */ function save_staff_teams(PDO $pdo, int $id, array $teamIds): void { $pdo->prepare('DELETE FROM team_members WHERE staff_id = ?')->execute([$id]); $ins = $pdo->prepare('INSERT INTO team_members (team_id, staff_id) VALUES (?,?)'); foreach (array_unique(array_filter(array_map('intval', $teamIds))) as $tid) $ins->execute([$tid, $id]); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { verify_csrf(); $action = $_POST['action'] ?? ''; if ($action === 'create' || $action === 'update') { $id = (int) ($_POST['id'] ?? 0); $name = trim($_POST['name'] ?? ''); $email = trim($_POST['email'] ?? ''); // Nur echte Administratoren dürfen die Administrator-Rolle vergeben – sonst könnte sich ein // per Co-Admin-Recht (nur manage_staff) berechtigter Agent selbst (oder andere) zum // Vollzugriff-Admin machen. Beim Bearbeiten durch einen Co-Admin bleibt die vorhandene // Rolle des Ziel-Kontos unverändert, statt sie stillschweigend auf "Mitarbeiter" zu setzen. if ($isFullAdmin) { $role = ($_POST['role'] ?? '') === 'admin' ? 'admin' : 'agent'; } elseif ($action === 'update') { $currentRoleStmt = $pdo->prepare('SELECT role FROM staff WHERE id = ?'); $currentRoleStmt->execute([$id]); $role = $currentRoleStmt->fetchColumn() === 'admin' ? 'admin' : 'agent'; } else { $role = 'agent'; } $roleId = ($_POST['role_id'] ?? '') !== '' ? (int) $_POST['role_id'] : null; $deptId = ($_POST['department_id'] ?? '') !== '' ? (int) $_POST['department_id'] : null; $isActive = ($_POST['status'] ?? 'active') === 'active' ? 1 : 0; $password = $_POST['password'] ?? ''; $signature = sanitize_staff_html(trim($_POST['signature'] ?? '')); if ($name === '') $errors[] = 'Bitte einen Namen angeben.'; if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = 'Bitte eine gültige E-Mail-Adresse angeben.'; if ($action === 'create' || $password !== '') { $pwErr = validate_password_strength($password); if ($pwErr) $errors[] = $pwErr; } if ($action === 'update' && $id === (int) $me['id'] && !$isActive) $errors[] = 'Sie können Ihr eigenes Konto nicht deaktivieren.'; $dup = $pdo->prepare('SELECT COUNT(*) FROM staff WHERE LOWER(email) = LOWER(?) AND id <> ?'); $dup->execute([$email, $id]); if ($dup->fetchColumn() > 0) $errors[] = 'Ein Mitarbeiter mit dieser E-Mail-Adresse existiert bereits.'; if (!$errors) { if ($action === 'create') { $pdo->prepare('INSERT INTO staff (name, email, password_hash, role, role_id, department_id, signature, is_active, created_at) VALUES (?,?,?,?,?,?,?,?,?)') ->execute([$name, $email, password_hash($password, PASSWORD_DEFAULT), $role, $roleId, $deptId, $signature ?: null, $isActive, db_now()]); $id = (int) $pdo->lastInsertId(); audit_log($me['id'], "Mitarbeiter angelegt: {$name} ({$email})"); flash('success', 'Mitarbeiter angelegt.'); } else { $sql = 'UPDATE staff SET name=?, email=?, role=?, role_id=?, department_id=?, signature=?, is_active=?'; $params = [$name, $email, $role, $roleId, $deptId, $signature ?: null, $isActive]; if ($password !== '') { $sql .= ', password_hash=?'; $params[] = password_hash($password, PASSWORD_DEFAULT); } $params[] = $id; $pdo->prepare($sql . ' WHERE id=?')->execute($params); audit_log($me['id'], "Mitarbeiter aktualisiert: {$name} ({$email})"); flash('success', 'Änderungen gespeichert.'); } save_staff_access($pdo, $id, $deptId, $_POST); if ($canManageTeams) save_staff_teams($pdo, $id, (array) ($_POST['teams'] ?? [])); redirect('/staff/staff_manage.php'); } } // Eigenständiger Zugriffs-Speicher-Aufruf (Rückwärtskompatibilität) if ($action === 'save_access') { $id = (int) $_POST['id']; $stmt = $pdo->prepare('SELECT department_id FROM staff WHERE id = ?'); $stmt->execute([$id]); save_staff_access($pdo, $id, (int) $stmt->fetchColumn(), $_POST); audit_log($me['id'], "Abteilungszugriff geändert für Mitarbeiter #{$id}"); flash('success', 'Abteilungszugriff gespeichert.'); redirect('/staff/staff_manage.php?edit=' . $id . '&tab=access'); } if ($action === 'delete') { $id = (int) $_POST['id']; if ($id === (int) $me['id']) { flash('error', 'Sie können Ihr eigenes Konto nicht löschen.'); } else { $pdo->prepare('UPDATE tickets SET assigned_staff_id = NULL WHERE assigned_staff_id = ?')->execute([$id]); $pdo->prepare('DELETE FROM staff WHERE id = ?')->execute([$id]); audit_log($me['id'], "Mitarbeiter gelöscht: #{$id}"); flash('success', 'Mitarbeiter gelöscht.'); } redirect('/staff/staff_manage.php'); } } $isNew = isset($_GET['new']); $editId = (int) ($_GET['edit'] ?? 0); $showForm = $isNew || $editId || ($errors && in_array($_POST['action'] ?? '', ['create', 'update'], true)); $editStaff = null; $extraAccess = []; // department_id => ['notify' => 0/1, 'role_id' => ?int] $memberTeams = []; if ($editId) { $stmt = $pdo->prepare('SELECT * FROM staff WHERE id = ?'); $stmt->execute([$editId]); $editStaff = $stmt->fetch() ?: null; if ($editStaff) { $stmt = $pdo->prepare('SELECT department_id, notify, role_id FROM staff_department WHERE staff_id = ?'); $stmt->execute([$editId]); foreach ($stmt->fetchAll() as $row) $extraAccess[(int) $row['department_id']] = ['notify' => (int) $row['notify'], 'role_id' => $row['role_id'] !== null ? (int) $row['role_id'] : null]; $stmt = $pdo->prepare('SELECT team_id FROM team_members WHERE staff_id = ?'); $stmt->execute([$editId]); $memberTeams = array_map('intval', $stmt->fetchAll(PDO::FETCH_COLUMN)); } } if ($_POST && $errors) { // eingegebene Auswahl bei Fehlern erhalten $extraAccess = []; foreach (array_filter(array_map('intval', $_POST['extra_departments'] ?? [])) as $dId) { $extraAccess[$dId] = ['notify' => !empty($_POST['notify_' . $dId]) ? 1 : 0, 'role_id' => ($_POST['role_' . $dId] ?? '') !== '' ? (int) $_POST['role_' . $dId] : null]; } $memberTeams = array_map('intval', (array) ($_POST['teams'] ?? [])); } $allStaff = $pdo->query( 'SELECT s.*, d.name AS department_name, (SELECT COUNT(*) FROM team_members tm WHERE tm.staff_id = s.id) AS team_count FROM staff s LEFT JOIN departments d ON d.id = s.department_id ORDER BY s.name' )->fetchAll(); $fmt = fn(?string $dt) => $dt ? date('d.m.Y', strtotime($dt)) : '–'; $pageTitle = 'Mitarbeiter'; $activePage = 'staff'; require __DIR__ . '/_header.php'; ?>
$_POST[$k] ?? $default; $v = fn(string $k, string $col, $default = '') => $f($k, $editStaff[$col] ?? $default); $curStatus = $_POST ? ($_POST['status'] ?? 'active') : (($editStaff['is_active'] ?? 1) ? 'active' : 'locked'); $curRole = (string) $v('role', 'role', 'agent'); $curRoleId = (string) $v('role_id', 'role_id'); $curDept = (string) $v('department_id', 'department_id'); $startTab = in_array($_GET['tab'] ?? '', ['account', 'access', 'perms', 'teams'], true) ? $_GET['tab'] : 'account'; $rolePerms = []; foreach ($customRoles as $r) $rolePerms[$r['id']] = json_decode($r['permissions'], true) ?: []; $agentDefaults = default_permissions('agent'); $adminDefaults = default_permissions('admin'); ?>

—

Kontoinformationen

>
Abbrechen

Mitarbeiter

Neuen Agenten hinzufügen
NameE-MailTypStatusHauptabteilungTeamsErstellt
Bearbeiten ·