philippurbschat.de/home/app/controllers/AdminController.php

230 lines
No EOL
9 KiB
PHP

<?php
require_once __DIR__ . '/../../core/Controller.php';
require_once __DIR__ . '/../services/HealthService.php';
class AdminController extends Controller {
// Auth-Check
public function __construct() {
if (session_status() === PHP_SESSION_NONE) { session_start(); }
if (!isset($_SESSION['is_admin']) || $_SESSION['is_admin'] !== true) {
header('Location: ' . Config::get('BASE_URL', '/'));
exit;
}
}
// Dashboard
public function index() {
$report = HealthService::getHealthReport();
$this->view('admin/dashboard', [
'title' => 'Admin Dashboard',
'health' => $report
]);
}
// Settings
public function settings() {
$this->view('admin/settings', [
'title' => 'Einstellungen'
]);
}
// User & Invite Management
public function users() {
$userModel = $this->model('User');
$invitationModel = $this->model('Invitation');
$users = $userModel->getAll();
$invitations = $invitationModel->getAll();
$allModules = ModuleService::getAll();
$activeTab = $_GET['tab'] ?? 'users';
$this->view('admin/users', [
'title' => 'Benutzer- & Zugangsverwaltung',
'users' => $users,
'invitations' => $invitations,
'allModules' => $allModules,
'activeTab' => $activeTab
]);
}
// User Form
public function user_form($id = null) {
$user = null;
if ($id) {
$userModel = $this->model('User');
$user = $userModel->getById($id);
if (!$user) {
Flash::set('Nutzer nicht gefunden.', 'error');
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users');
exit;
}
}
$this->view('admin/user_form', [
'title' => $id ? 'Benutzer bearbeiten' : 'Neuen Benutzer anlegen',
'user' => $user,
'allModules' => ModuleService::getAll()
]);
}
// Save User
public function user_save() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users');
exit;
}
try {
Security::checkCsrf($_POST['csrf_token'] ?? '');
$id = !empty($_POST['id']) ? (int)$_POST['id'] : null;
$userModel = $this->model('User');
if (empty($_POST['name']) || empty($_POST['email'])) {
throw new Exception("Name und E-Mail sind Pflichtfelder.");
}
// Projects from checkboxes
$projects = isset($_POST['projects']) && is_array($_POST['projects']) ? $_POST['projects'] : [];
$postData = $_POST;
$postData['projects'] = $projects;
$userModel->save($postData, $id);
Flash::set('Nutzer erfolgreich gespeichert!', 'success');
} catch (Exception $e) {
Flash::set($e->getMessage(), 'error');
}
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users');
exit;
}
// Quick toggle user status (Active / Inactive)
public function user_toggle_status($id) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
Security::checkCsrf($_POST['csrf_token'] ?? '');
$userModel = $this->model('User');
$user = $userModel->getById($id);
if (!$user) {
throw new Exception("Nutzer nicht gefunden.");
}
$newStatus = ($user['status'] === 'Active') ? 'Inactive' : 'Active';
$user['status'] = $newStatus;
$userModel->save($user, $id);
Flash::set('Status für ' . htmlspecialchars($user['name']) . ' geändert auf: ' . $newStatus, 'success');
} catch (Exception $e) {
Flash::set('Fehler: ' . $e->getMessage(), 'error');
}
}
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users');
exit;
}
// Delete User
public function user_delete($id) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
Security::checkCsrf($_POST['csrf_token'] ?? '');
$userModel = $this->model('User');
$userModel->delete($id);
Flash::set('Nutzer wurde gelöscht.', 'success');
} catch (Exception $e) {
Flash::set('Fehler beim Löschen: ' . $e->getMessage(), 'error');
}
}
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users');
exit;
}
// Create Invitation Link
public function invite_create() {
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users?tab=invites');
exit;
}
try {
Security::checkCsrf($_POST['csrf_token'] ?? '');
$invitationModel = $this->model('Invitation');
$userModel = $this->model('User');
$assignedProjects = isset($_POST['projects']) && is_array($_POST['projects']) ? $_POST['projects'] : [];
$note = trim($_POST['note'] ?? '');
$maxUses = !empty($_POST['max_uses']) ? max(1, (int)$_POST['max_uses']) : 1;
$recipientEmail = trim(strtolower($_POST['recipient_email'] ?? ''));
$sendEmailNow = !empty($_POST['send_email_now']);
if (!empty($recipientEmail)) {
if (!filter_var($recipientEmail, FILTER_VALIDATE_EMAIL)) {
throw new Exception('Bitte gib eine gültige E-Mail-Adresse an.');
}
$existingUser = $userModel->findByEmail($recipientEmail);
if ($existingUser) {
throw new Exception("Ein Benutzer mit der E-Mail '{$recipientEmail}' existiert bereits.");
}
}
$expiresAt = null;
if (!empty($_POST['days_valid']) && (int)$_POST['days_valid'] > 0) {
$days = (int)$_POST['days_valid'];
$expiresAt = (new DateTime("+{$days} days"))->format('Y-m-d H:i:s');
}
$token = $invitationModel->create($assignedProjects, $note ?: null, $maxUses, $expiresAt, $recipientEmail ?: null);
$baseUrl = rtrim(Config::get('BASE_URL', 'https://philippurbschat.de/'), '/');
$inviteUrl = $baseUrl . '/register?token=' . $token;
$mailSentNotice = '';
if (!empty($recipientEmail) && $sendEmailNow) {
require_once __DIR__ . '/../services/MailService.php';
MailService::sendInvitation($recipientEmail, $token, $assignedProjects, $note ?: null);
$mailSentNotice = " und E-Mail an {$recipientEmail} gesendet";
}
Flash::set('Einladungslink erfolgreich erstellt' . $mailSentNotice . ': ' . $inviteUrl, 'success');
} catch (Exception $e) {
Flash::set('Fehler beim Erstellen des Einladungslinks: ' . $e->getMessage(), 'error');
}
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users?tab=invites');
exit;
}
// Resend Invitation Email
public function invite_resend($id) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
Security::checkCsrf($_POST['csrf_token'] ?? '');
$invitationModel = $this->model('Invitation');
$inv = $invitationModel->getById((int)$id);
if (!$inv) {
throw new Exception('Einladung nicht gefunden.');
}
if (empty($inv['recipient_email'])) {
throw new Exception('Dieser Einladungslink ist keiner konkreten E-Mail-Adresse zugewiesen.');
}
require_once __DIR__ . '/../services/MailService.php';
MailService::sendInvitation($inv['recipient_email'], $inv['token'], $inv['assigned_projects'], $inv['note'] ?? null);
Flash::set("Einladungs-E-Mail erfolgreich erneut an {$inv['recipient_email']} gesendet.", 'success');
} catch (Exception $e) {
Flash::set('Fehler beim Senden der E-Mail: ' . $e->getMessage(), 'error');
}
}
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users?tab=invites');
exit;
}
// Delete Invitation Link
public function invite_delete($id) {
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
try {
Security::checkCsrf($_POST['csrf_token'] ?? '');
$invitationModel = $this->model('Invitation');
$invitationModel->delete((int)$id);
Flash::set('Einladungslink wurde gelöscht.', 'success');
} catch (Exception $e) {
Flash::set('Fehler beim Löschen: ' . $e->getMessage(), 'error');
}
}
header('Location: ' . Config::get('BASE_URL', '/') . 'admin/users?tab=invites');
exit;
}
}