97 lines
4.7 KiB
PHP
97 lines
4.7 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
require_once __DIR__ . '/common.php';
|
||
|
||
api_require_method('GET', 'POST');
|
||
$staff = api_require_staff();
|
||
api_require_admin_or_permission($staff, 'manage_roles');
|
||
$pdo = get_db();
|
||
|
||
// Ticket-Rechte + alle Adminportal-Bereichsrechte (admin_section_permissions(), includes/functions.php) –
|
||
// zusammen ergeben sie das vollständige Set, das über eine benutzerdefinierte Rolle vergeben werden kann.
|
||
$rolePermissionKeys = array_keys(permission_labels());
|
||
|
||
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
|
||
$roles = $pdo->query(
|
||
'SELECT r.*, (SELECT COUNT(*) FROM staff s WHERE s.role_id=r.id) + (SELECT COUNT(*) FROM staff_department sd WHERE sd.role_id=r.id) AS staff_count FROM roles r ORDER BY r.name'
|
||
)->fetchAll();
|
||
|
||
api_json([
|
||
'permissionKeys' => $rolePermissionKeys,
|
||
'permissionLabels' => permission_labels(),
|
||
'permissionGroups' => array_values(array_map(fn($g) => ['title' => $g['title'], 'keys' => array_keys($g['items'])], permission_catalog())),
|
||
'defaultAgentPermissions' => default_permissions('agent'),
|
||
'items' => array_map(fn(array $r) => [
|
||
'id' => (int) $r['id'],
|
||
'name' => $r['name'],
|
||
'permissions' => json_decode($r['permissions'] ?? '{}', true) ?? [],
|
||
'effectivePermissions' => permission_effective(json_decode($r['permissions'] ?? '{}', true) ?? []),
|
||
'staffCount' => (int) $r['staff_count'],
|
||
'isActive' => (bool) ($r['is_active'] ?? 1),
|
||
'notes' => $r['notes'] ?? null,
|
||
'createdAt' => $r['created_at'] ?? null,
|
||
'updatedAt' => $r['updated_at'] ?? null,
|
||
], $roles),
|
||
]);
|
||
}
|
||
|
||
$body = api_request_body();
|
||
$action = $body['action'] ?? '';
|
||
|
||
if ($action === 'save') {
|
||
$id = (int) ($body['id'] ?? 0);
|
||
$name = trim((string) ($body['name'] ?? ''));
|
||
if ($name === '') api_error(422, 'NAME_REQUIRED', 'Bitte einen Namen angeben.');
|
||
|
||
$incoming = (array) ($body['permissions'] ?? []);
|
||
// Rechte, die eine ältere App-Version nicht kennt (und deshalb nicht mitschickt), bleiben unverändert bzw. bekommen den Standardwert
|
||
$existingPerms = default_permissions('agent');
|
||
if ($id) {
|
||
$ep = $pdo->prepare('SELECT permissions FROM roles WHERE id = ?');
|
||
$ep->execute([$id]);
|
||
$existingPerms = array_merge($existingPerms, json_decode((string) $ep->fetchColumn(), true) ?: []);
|
||
}
|
||
$perms = [];
|
||
foreach ($rolePermissionKeys as $p) {
|
||
$want = array_key_exists($p, $incoming) ? !empty($incoming[$p]) : !empty($existingPerms[$p]);
|
||
// Wer kein echter Administrator ist, kann keine Rechte vergeben, die er selbst nicht hat
|
||
if ($staff['role'] !== 'admin' && $want && !has_permission($staff, $p)) $want = !empty($existingPerms[$p]) && $id > 0;
|
||
$perms[$p] = $want;
|
||
}
|
||
$json = json_encode($perms);
|
||
$dup = $pdo->prepare('SELECT COUNT(*) FROM roles WHERE LOWER(name) = LOWER(?) AND id <> ?');
|
||
$dup->execute([$name, $id]);
|
||
if ((int) $dup->fetchColumn() > 0) api_error(422, 'NAME_TAKEN', 'Eine Rolle mit diesem Namen existiert bereits.');
|
||
// Fehlende Schlüssel (ältere App-Version) lassen Status/Notizen unverändert
|
||
$cur = null;
|
||
if ($id) {
|
||
$c = $pdo->prepare('SELECT is_active, notes FROM roles WHERE id = ?');
|
||
$c->execute([$id]);
|
||
$cur = $c->fetch() ?: null;
|
||
}
|
||
$isActive = array_key_exists('isActive', $body) ? (!empty($body['isActive']) ? 1 : 0) : (int) ($cur['is_active'] ?? 1);
|
||
$notes = array_key_exists('notes', $body) ? (trim((string) $body['notes']) ?: null) : ($cur['notes'] ?? null);
|
||
|
||
if ($id === 0) {
|
||
$pdo->prepare('INSERT INTO roles (name, permissions, is_active, notes, created_at, updated_at) VALUES (?,?,?,?,?,?)')->execute([$name, $json, $isActive, $notes, db_now(), db_now()]);
|
||
$newId = (int) $pdo->lastInsertId();
|
||
audit_log($staff['id'], "Rolle erstellt: {$name} (Mobile App)");
|
||
} else {
|
||
$pdo->prepare('UPDATE roles SET name=?, permissions=?, is_active=?, notes=?, updated_at=? WHERE id=?')->execute([$name, $json, $isActive, $notes, db_now(), $id]);
|
||
$newId = $id;
|
||
audit_log($staff['id'], "Rolle aktualisiert: {$name} (Mobile App)");
|
||
}
|
||
api_json(['id' => $newId]);
|
||
}
|
||
|
||
if ($action === 'delete') {
|
||
$id = (int) ($body['id'] ?? 0);
|
||
$pdo->prepare('UPDATE staff SET role_id = NULL WHERE role_id = ?')->execute([$id]);
|
||
$pdo->prepare('UPDATE staff_department SET role_id = NULL WHERE role_id = ?')->execute([$id]);
|
||
$pdo->prepare('DELETE FROM roles WHERE id = ?')->execute([$id]);
|
||
audit_log($staff['id'], "Rolle gelöscht: #{$id} (Mobile App)");
|
||
api_json(['ok' => true]);
|
||
}
|
||
|
||
api_error(422, 'INVALID_ACTION', 'Unbekannte Aktion.');
|