web - refactor core modules, harden authorization, simplify endpoints
This commit is contained in:
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 2.3 MiB |
@@ -1,16 +1,7 @@
|
||||
<?php
|
||||
/* Name: brandschutz_cron.php
|
||||
Beschreibung: Monatlicher Cron-Job (am 1. des Monats) für Brandschutz-Schulungserinnerungen
|
||||
|
||||
Aufgaben:
|
||||
1. Einen Monat vor Ablauf: Erste Erinnerungsmail an den Nutzer
|
||||
2. Nach Ablauf der Frist: Monatliche Erinnerungsmail an den Nutzer
|
||||
3. 4+ Monate nach Ablauf: Eskalation an Admins (aktive Systemnachricht + Mail)
|
||||
|
||||
Aufruf: php brandschutz_cron.php (via Cron: 0 8 1 * *)
|
||||
*/
|
||||
/* Name: brandschutz_cron.php
|
||||
Beschreibung: Monatlicher Job für Brandschutz-Schulungserinnerungen */
|
||||
|
||||
// Initialisierung
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
http_response_code(403);
|
||||
exit('Forbidden');
|
||||
@@ -21,128 +12,131 @@ $_SERVER['HTTP_HOST'] = getenv('INTRANET_FQDN') ?: 'localhost';
|
||||
|
||||
$pdo = require $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/database.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/intranet_repo/general_files/ini/send_mail.php';
|
||||
require_once __DIR__ . '/util/brandschutz_helpers.php';
|
||||
|
||||
$today = date('Y-m-d');
|
||||
$today = brandschutz_today();
|
||||
$log = [];
|
||||
$brandschutzUrl = brandschutz_training_url();
|
||||
|
||||
// Alle Nutzer mit Brandschutz-Rolle laden
|
||||
$sql = "SELECT ugi.user_id, ugi.first_name, ugi.last_name, ugi.mail,
|
||||
bt.last_training_date, bt.reminder_count, bt.admin_reminder_count
|
||||
FROM user_permissions up
|
||||
INNER JOIN user_general_information ugi ON up.user_id = ugi.user_id
|
||||
LEFT JOIN brandschutz_training bt ON ugi.user_id = bt.user_id
|
||||
WHERE up.\"Brandschutz\" = 1";
|
||||
$result = $pdo->query($sql);
|
||||
$users = $result->fetchAll(PDO::FETCH_ASSOC);
|
||||
// Tracking-Zeilen gesammelt anlegen statt einmal pro Nutzer im Loop.
|
||||
$pdo->exec(
|
||||
'INSERT INTO brandschutz_training (user_id) '
|
||||
. 'SELECT user_id FROM user_permissions WHERE "Brandschutz" = 1 '
|
||||
. 'ON CONFLICT (user_id) DO NOTHING'
|
||||
);
|
||||
|
||||
$users = $pdo->query(
|
||||
'SELECT ugi.user_id, ugi.first_name, ugi.last_name, ugi.mail, '
|
||||
. 'bt.last_training_date, bt.reminder_count, bt.admin_reminder_count '
|
||||
. 'FROM user_permissions up '
|
||||
. 'INNER JOIN user_general_information ugi ON up.user_id = ugi.user_id '
|
||||
. 'INNER JOIN brandschutz_training bt ON ugi.user_id = bt.user_id '
|
||||
. 'WHERE up."Brandschutz" = 1'
|
||||
)->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$incrementReminder = $pdo->prepare(
|
||||
'UPDATE brandschutz_training SET reminder_count = reminder_count + 1 WHERE user_id = ?'
|
||||
);
|
||||
$incrementAdminReminder = $pdo->prepare(
|
||||
'UPDATE brandschutz_training SET admin_reminder_count = admin_reminder_count + 1 WHERE user_id = ?'
|
||||
);
|
||||
|
||||
foreach ($users as $bsUser) {
|
||||
$userId = (int)$bsUser['user_id'];
|
||||
$firstName = $bsUser['first_name'] ?? '';
|
||||
$lastName = $bsUser['last_name'] ?? '';
|
||||
$mail = $bsUser['mail'] ?? '';
|
||||
$fullName = trim("{$firstName} {$lastName}");
|
||||
if (empty($fullName)) $fullName = $mail;
|
||||
$greeting = !empty($firstName) ? "Hallo {$firstName}" : "Hallo";
|
||||
$userId = (int) $bsUser['user_id'];
|
||||
$mail = trim((string) ($bsUser['mail'] ?? ''));
|
||||
$fullName = brandschutz_display_name($bsUser, $mail !== '' ? $mail : 'Unbekannt');
|
||||
$greeting = brandschutz_greeting($bsUser);
|
||||
$reminderCount = (int) ($bsUser['reminder_count'] ?? 0);
|
||||
$adminReminderCount = (int) ($bsUser['admin_reminder_count'] ?? 0);
|
||||
$status = brandschutz_training_status($bsUser['last_training_date'] ?? null, $today);
|
||||
$actions = brandschutz_reminder_actions($status, $reminderCount);
|
||||
|
||||
$lastTraining = $bsUser['last_training_date'];
|
||||
$reminderCount = (int)($bsUser['reminder_count'] ?? 0);
|
||||
$adminReminderCount = (int)($bsUser['admin_reminder_count'] ?? 0);
|
||||
|
||||
// Sicherstellen dass ein Tracking-Eintrag existiert
|
||||
$stmtEnsure = $pdo->prepare("INSERT INTO brandschutz_training (user_id) VALUES (?) ON CONFLICT (user_id) DO NOTHING");
|
||||
$stmtEnsure->execute([$userId]);
|
||||
|
||||
// Fälligkeit berechnen
|
||||
if (empty($lastTraining)) {
|
||||
// Nie geschult = sofort fällig
|
||||
$dueDate = $today;
|
||||
$daysUntilDue = -1; // Bereits fällig
|
||||
$daysOverdue = 1;
|
||||
} else {
|
||||
$dueDate = date('Y-m-d', strtotime($lastTraining . ' +365 days'));
|
||||
$daysUntilDue = (int)((strtotime($dueDate) - strtotime($today)) / 86400);
|
||||
$daysOverdue = $daysUntilDue < 0 ? abs($daysUntilDue) : 0;
|
||||
}
|
||||
|
||||
// Szenario 1: Einen Monat vor Ablauf (0-30 Tage verbleibend) - Erste Erinnerung
|
||||
if ($daysUntilDue >= 0 && $daysUntilDue <= 30 && $reminderCount === 0) {
|
||||
$dueDateFormatted = date('d.m.Y', strtotime($dueDate));
|
||||
if ($actions['pre_due']) {
|
||||
$dueDateFormatted = (string) $status['due_date_display'];
|
||||
$subject = "Erinnerung: Brandschutzunterweisung bis {$dueDateFormatted} fällig";
|
||||
$message = "{$greeting},\n\nIhre Brandschutzunterweisung läuft am {$dueDateFormatted} ab.\n\n";
|
||||
$message .= "Die Schulung dauert nur etwa 20 Minuten und kann bequem vom Handy oder PC aus durchgeführt werden.\n\n";
|
||||
$message .= "Bitte absolvieren Sie die Unterweisung innerhalb der nächsten zwei Monate über das Intranet.\n\n";
|
||||
$message .= "Vielen Dank!";
|
||||
$message = "{$greeting},\n\nIhre Brandschutzunterweisung läuft am {$dueDateFormatted} ab.\n\n"
|
||||
. "Die Schulung dauert nur etwa 20 Minuten und kann bequem vom Handy oder PC aus durchgeführt werden.\n\n"
|
||||
. "Bitte absolvieren Sie die Unterweisung innerhalb der nächsten zwei Monate über das Intranet.\n\n"
|
||||
. 'Vielen Dank!';
|
||||
|
||||
$brandschutzUrl = "https://" . $_SERVER['HTTP_HOST'] . "/intranet_repo/projects/brandschutz/brandschutz.php";
|
||||
send_intranet_mail($mail, $subject, $message, null, "intranet@nak-reinickendorf.de", "Zur Brandschutzunterweisung", $brandschutzUrl);
|
||||
|
||||
// Zähler erhöhen
|
||||
$stmtUpdate = $pdo->prepare("UPDATE brandschutz_training SET reminder_count = reminder_count + 1 WHERE user_id = ?");
|
||||
$stmtUpdate->execute([$userId]);
|
||||
|
||||
// Log in erledigte Nachrichten
|
||||
$sysSubject = "Brandschutz-Erinnerung gesendet: {$fullName}";
|
||||
$sysMessage = "Automatische Erinnerungsmail an {$fullName} ({$mail}) gesendet. Schulung fällig am {$dueDateFormatted}.";
|
||||
$stmtLog = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', 'System', ?, ?, ?, 'done', NOW(), NOW())");
|
||||
$stmtLog->execute([$mail, $sysSubject, $sysMessage]);
|
||||
send_intranet_mail(
|
||||
$mail,
|
||||
$subject,
|
||||
$message,
|
||||
null,
|
||||
'intranet@nak-reinickendorf.de',
|
||||
'Zur Brandschutzunterweisung',
|
||||
$brandschutzUrl
|
||||
);
|
||||
$incrementReminder->execute([$userId]);
|
||||
|
||||
brandschutz_log_admin_message(
|
||||
$pdo,
|
||||
'System',
|
||||
$mail,
|
||||
"Brandschutz-Erinnerung gesendet: {$fullName}",
|
||||
"Automatische Erinnerungsmail an {$fullName} ({$mail}) gesendet. Schulung fällig am {$dueDateFormatted}."
|
||||
);
|
||||
$log[] = "Erste Erinnerung an {$fullName} gesendet (fällig am {$dueDateFormatted}).";
|
||||
}
|
||||
|
||||
// Szenario 2: Frist überschritten - Monatliche Erinnerung an Nutzer
|
||||
if ($daysOverdue > 0) {
|
||||
$dueDateFormatted = !empty($lastTraining) ? date('d.m.Y', strtotime($dueDate)) : 'sofort';
|
||||
$monthsOverdue = (int)ceil($daysOverdue / 30);
|
||||
|
||||
if ($actions['overdue']) {
|
||||
$daysOverdue = (int) $status['days_overdue'];
|
||||
$dueDateFormatted = $status['due_date'] === null ? 'sofort' : (string) $status['due_date_display'];
|
||||
$reminderNumber = $reminderCount + 1;
|
||||
$subject = "Überfällig: Brandschutzunterweisung ({$daysOverdue} Tage)";
|
||||
$message = "{$greeting},\n\nIhre Brandschutzunterweisung ist seit {$daysOverdue} Tagen überfällig";
|
||||
if ($dueDateFormatted !== 'sofort') {
|
||||
$message .= " (Frist war der {$dueDateFormatted})";
|
||||
}
|
||||
$message .= ".\n\nDie Schulung dauert nur etwa 20 Minuten und kann bequem vom Handy oder PC aus durchgeführt werden.\n\n";
|
||||
$message .= "Bitte absolvieren Sie die Unterweisung umgehend über das Intranet.\n\n";
|
||||
$message .= "Dies ist die {$reminderCount}. Erinnerung zu dieser Schulung.";
|
||||
$message .= ".\n\nDie Schulung dauert nur etwa 20 Minuten und kann bequem vom Handy oder PC aus durchgeführt werden.\n\n"
|
||||
. "Bitte absolvieren Sie die Unterweisung umgehend über das Intranet.\n\n"
|
||||
. "Dies ist die {$reminderNumber}. Erinnerung zu dieser Schulung.";
|
||||
|
||||
$brandschutzUrl = "https://" . $_SERVER['HTTP_HOST'] . "/intranet_repo/projects/brandschutz/brandschutz.php";
|
||||
send_intranet_mail($mail, $subject, $message, null, "intranet@nak-reinickendorf.de", "Zur Brandschutzunterweisung", $brandschutzUrl);
|
||||
send_intranet_mail(
|
||||
$mail,
|
||||
$subject,
|
||||
$message,
|
||||
null,
|
||||
'intranet@nak-reinickendorf.de',
|
||||
'Zur Brandschutzunterweisung',
|
||||
$brandschutzUrl
|
||||
);
|
||||
$incrementReminder->execute([$userId]);
|
||||
|
||||
// Zähler erhöhen
|
||||
$stmtUpdate = $pdo->prepare("UPDATE brandschutz_training SET reminder_count = reminder_count + 1 WHERE user_id = ?");
|
||||
$stmtUpdate->execute([$userId]);
|
||||
brandschutz_log_admin_message(
|
||||
$pdo,
|
||||
'System',
|
||||
$mail,
|
||||
"Brandschutz-Erinnerung gesendet: {$fullName} ({$daysOverdue} Tage überfällig)",
|
||||
"Automatische Erinnerungsmail (Nr. {$reminderNumber}) an {$fullName} ({$mail}) gesendet. Schulung seit {$daysOverdue} Tagen überfällig."
|
||||
);
|
||||
$log[] = "Erinnerung Nr.{$reminderNumber} an {$fullName} ({$daysOverdue} Tage überfällig).";
|
||||
|
||||
// Log in erledigte Nachrichten
|
||||
$sysSubject = "Brandschutz-Erinnerung gesendet: {$fullName} ({$daysOverdue} Tage überfällig)";
|
||||
$sysMessage = "Automatische Erinnerungsmail (Nr. " . ($reminderCount + 1) . ") an {$fullName} ({$mail}) gesendet. Schulung seit {$daysOverdue} Tagen überfällig.";
|
||||
$stmtLog = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', 'System', ?, ?, ?, 'done', NOW(), NOW())");
|
||||
$stmtLog->execute([$mail, $sysSubject, $sysMessage]);
|
||||
|
||||
$log[] = "Erinnerung Nr." . ($reminderCount + 1) . " an {$fullName} ({$daysOverdue} Tage überfällig).";
|
||||
|
||||
// Szenario 3: 4+ Monate überfällig - Eskalation an Brandschutzbeauftragte + Admins
|
||||
if ($daysOverdue >= 120) {
|
||||
if ($actions['escalate']) {
|
||||
$nextAdminReminder = $adminReminderCount + 1;
|
||||
$adminSubject = "ESKALATION: Brandschutzunterweisung überfällig – {$fullName}";
|
||||
$adminMessage = "Die Brandschutzunterweisung von {$fullName} ({$mail}) ist seit {$daysOverdue} Tagen überfällig (mehr als 4 Monate).\n\n";
|
||||
$adminMessage .= "Bitte erinnern Sie die Person persönlich an die ausstehende Schulung.\n\n";
|
||||
$adminMessage .= "Bisherige Erinnerungsmails an den Nutzer: " . ($reminderCount + 1) . "\n";
|
||||
$adminMessage .= "Bisherige Admin-Eskalationen: " . ($adminReminderCount + 1);
|
||||
$adminMessage = "Die Brandschutzunterweisung von {$fullName} ({$mail}) ist seit {$daysOverdue} Tagen überfällig (mehr als 4 Monate).\n\n"
|
||||
. "Bitte erinnern Sie die Person persönlich an die ausstehende Schulung.\n\n"
|
||||
. "Bisherige Erinnerungsmails an den Nutzer: {$reminderNumber}\n"
|
||||
. "Bisherige Admin-Eskalationen: {$nextAdminReminder}";
|
||||
|
||||
// Mail an Brandschutzbeauftragte
|
||||
send_brandschutzbeauftragter_mail($pdo, $adminSubject, $adminMessage);
|
||||
|
||||
// Aktive (pending) Systemnachricht im Postfach
|
||||
$dataJson = json_encode([
|
||||
'action' => 'brandschutz_escalation',
|
||||
'user_id' => $userId,
|
||||
'user_name' => $fullName,
|
||||
'days_overdue' => $daysOverdue
|
||||
]);
|
||||
$stmtAdmin = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, created_at, data_json) VALUES ('system', 'System', ?, ?, ?, 'pending', NOW(), ?)");
|
||||
$stmtAdmin->execute([$mail, $adminSubject, $adminMessage, $dataJson]);
|
||||
|
||||
// Admin-Zähler erhöhen
|
||||
$stmtAdminCount = $pdo->prepare("UPDATE brandschutz_training SET admin_reminder_count = admin_reminder_count + 1 WHERE user_id = ?");
|
||||
$stmtAdminCount->execute([$userId]);
|
||||
|
||||
brandschutz_log_admin_message(
|
||||
$pdo,
|
||||
'System',
|
||||
$mail,
|
||||
$adminSubject,
|
||||
$adminMessage,
|
||||
'pending',
|
||||
[
|
||||
'action' => 'brandschutz_escalation',
|
||||
'user_id' => $userId,
|
||||
'user_name' => $fullName,
|
||||
'days_overdue' => $daysOverdue,
|
||||
]
|
||||
);
|
||||
$incrementAdminReminder->execute([$userId]);
|
||||
$log[] = "ESKALATION an Brandschutzbeauftragte für {$fullName} ({$daysOverdue} Tage überfällig).";
|
||||
}
|
||||
}
|
||||
@@ -150,13 +144,8 @@ foreach ($users as $bsUser) {
|
||||
|
||||
$pdo = null;
|
||||
|
||||
// Ausgabe/Logging
|
||||
$output = "Brandschutz-Cron ausgeführt am " . date('d.m.Y H:i:s') . "\n";
|
||||
$output = 'Brandschutz-Cron ausgeführt am ' . date('d.m.Y H:i:s') . "\n";
|
||||
$output .= count($users) . " Nutzer mit Brandschutz-Rolle geprüft.\n";
|
||||
if (!empty($log)) {
|
||||
$output .= "\nAktionen:\n" . implode("\n", $log);
|
||||
} else {
|
||||
$output .= "\nKeine Aktionen erforderlich.";
|
||||
}
|
||||
$output .= $log === [] ? "\nKeine Aktionen erforderlich." : "\nAktionen:\n" . implode("\n", $log);
|
||||
|
||||
echo $output . "\n";
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
const BRANDSCHUTZ_VALIDITY_DAYS = 365;
|
||||
|
||||
function brandschutz_csrf_token(): string
|
||||
{
|
||||
if (empty($_SESSION['brandschutz_csrf'])) {
|
||||
$_SESSION['brandschutz_csrf'] = bin2hex(random_bytes(32));
|
||||
}
|
||||
|
||||
return (string) $_SESSION['brandschutz_csrf'];
|
||||
}
|
||||
|
||||
function brandschutz_verify_csrf($postedToken): void
|
||||
{
|
||||
$sessionToken = $_SESSION['brandschutz_csrf'] ?? '';
|
||||
if (!is_string($postedToken) || $sessionToken === '' || !hash_equals((string) $sessionToken, $postedToken)) {
|
||||
throw new InvalidArgumentException('Ungültige Anfrage. Bitte laden Sie die Seite neu.');
|
||||
}
|
||||
}
|
||||
|
||||
function brandschutz_is_valid_date(string $value): bool
|
||||
{
|
||||
$date = DateTimeImmutable::createFromFormat('!Y-m-d', $value);
|
||||
$errors = DateTimeImmutable::getLastErrors();
|
||||
|
||||
return $date !== false
|
||||
&& ($errors === false || ($errors['warning_count'] === 0 && $errors['error_count'] === 0))
|
||||
&& $date->format('Y-m-d') === $value;
|
||||
}
|
||||
|
||||
function brandschutz_today(?DateTimeImmutable $today = null): DateTimeImmutable
|
||||
{
|
||||
if ($today !== null) {
|
||||
return $today->setTime(0, 0);
|
||||
}
|
||||
|
||||
return new DateTimeImmutable('today', new DateTimeZone('Europe/Berlin'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet den fachlichen Schulungsstatus an einer Stelle für Intranet,
|
||||
* Adminpanel und Erinnerungsjob.
|
||||
*/
|
||||
function brandschutz_training_status(?string $lastTraining, ?DateTimeImmutable $today = null): array
|
||||
{
|
||||
$today = brandschutz_today($today);
|
||||
$lastTraining = trim((string) $lastTraining);
|
||||
|
||||
if ($lastTraining === '' || !brandschutz_is_valid_date($lastTraining)) {
|
||||
return [
|
||||
'last_training' => null,
|
||||
'last_training_display' => 'Nie',
|
||||
'due_date' => null,
|
||||
'due_date_display' => 'Sofort fällig',
|
||||
'days_until_due' => -1,
|
||||
'days_overdue' => 1,
|
||||
'is_due' => true,
|
||||
'status_key' => 'never',
|
||||
'status_text' => 'Nie geschult',
|
||||
'status_class' => 'bs-status-overdue',
|
||||
'overdue_text' => 'Keine Schulung hinterlegt – sofort fällig',
|
||||
'overdue_class' => 'overdue',
|
||||
];
|
||||
}
|
||||
|
||||
$trainingDate = new DateTimeImmutable($lastTraining, new DateTimeZone('Europe/Berlin'));
|
||||
$dueDate = $trainingDate->modify('+' . BRANDSCHUTZ_VALIDITY_DAYS . ' days');
|
||||
// Bestehende 24h-Tagesberechnung bewusst beibehalten (inkl. DST-Verhalten).
|
||||
$daysUntilDue = (int) (($dueDate->getTimestamp() - $today->getTimestamp()) / 86400);
|
||||
$daysOverdue = $daysUntilDue <= 0 ? abs($daysUntilDue) : 0;
|
||||
|
||||
if ($daysUntilDue > 30) {
|
||||
$statusKey = 'current';
|
||||
$statusText = 'Aktuell';
|
||||
$statusClass = 'bs-status-ok';
|
||||
} elseif ($daysUntilDue > 0) {
|
||||
$statusKey = 'warning';
|
||||
$statusText = 'Bald fällig';
|
||||
$statusClass = 'bs-status-warning';
|
||||
} elseif ($daysUntilDue > -120) {
|
||||
$statusKey = 'overdue';
|
||||
$statusText = $daysOverdue . ' Tage überfällig';
|
||||
$statusClass = 'bs-status-overdue';
|
||||
} else {
|
||||
$statusKey = 'critical';
|
||||
$statusText = $daysOverdue . ' Tage überfällig';
|
||||
$statusClass = 'bs-status-critical';
|
||||
}
|
||||
|
||||
return [
|
||||
'last_training' => $lastTraining,
|
||||
'last_training_display' => $trainingDate->format('d.m.Y'),
|
||||
'due_date' => $dueDate->format('Y-m-d'),
|
||||
'due_date_display' => $dueDate->format('d.m.Y'),
|
||||
'days_until_due' => $daysUntilDue,
|
||||
'days_overdue' => $daysOverdue,
|
||||
'is_due' => $daysUntilDue <= 0,
|
||||
'status_key' => $statusKey,
|
||||
'status_text' => $statusText,
|
||||
'status_class' => $statusClass,
|
||||
'overdue_text' => $daysUntilDue > 0
|
||||
? 'Nicht überfällig (' . $daysUntilDue . ' Tage verbleibend)'
|
||||
: $daysOverdue . ' Tage überfällig',
|
||||
'overdue_class' => $daysUntilDue > 0 ? 'ok' : 'overdue',
|
||||
];
|
||||
}
|
||||
|
||||
function brandschutz_reminder_actions(array $status, int $reminderCount): array
|
||||
{
|
||||
$daysUntilDue = (int) ($status['days_until_due'] ?? 0);
|
||||
$daysOverdue = (int) ($status['days_overdue'] ?? 0);
|
||||
|
||||
return [
|
||||
'pre_due' => $daysUntilDue >= 0 && $daysUntilDue <= 30 && $reminderCount === 0,
|
||||
'overdue' => $daysOverdue > 0,
|
||||
'escalate' => $daysOverdue >= 120,
|
||||
];
|
||||
}
|
||||
|
||||
function brandschutz_display_name(array $user, string $fallback = 'Unbekannt'): string
|
||||
{
|
||||
$fullName = trim((string) ($user['first_name'] ?? '') . ' ' . (string) ($user['last_name'] ?? ''));
|
||||
if ($fullName !== '') {
|
||||
return $fullName;
|
||||
}
|
||||
|
||||
$mail = trim((string) ($user['mail'] ?? ''));
|
||||
return $mail !== '' ? $mail : $fallback;
|
||||
}
|
||||
|
||||
function brandschutz_greeting(array $user): string
|
||||
{
|
||||
$firstName = trim((string) ($user['first_name'] ?? ''));
|
||||
return $firstName !== '' ? 'Hallo ' . $firstName : 'Hallo';
|
||||
}
|
||||
|
||||
function brandschutz_training_url(?string $host = null): string
|
||||
{
|
||||
$host = trim((string) ($host ?? ($_SERVER['HTTP_HOST'] ?? '')));
|
||||
$host = $host !== '' ? $host : 'localhost';
|
||||
|
||||
return 'https://' . $host . '/intranet_repo/projects/brandschutz/brandschutz.php';
|
||||
}
|
||||
|
||||
function brandschutz_store_training_date(PDO $pdo, int $userId, string $date, bool $resetCounters): void
|
||||
{
|
||||
if ($userId <= 0 || !brandschutz_is_valid_date($date)) {
|
||||
throw new InvalidArgumentException('Ungültiges Schulungsdatum.');
|
||||
}
|
||||
|
||||
if ($resetCounters) {
|
||||
$sql = 'INSERT INTO brandschutz_training '
|
||||
. '(user_id, last_training_date, reminder_count, admin_reminder_count) '
|
||||
. 'VALUES (?, ?, 0, 0) '
|
||||
. 'ON CONFLICT (user_id) DO UPDATE SET '
|
||||
. 'last_training_date = EXCLUDED.last_training_date, reminder_count = 0, admin_reminder_count = 0';
|
||||
} else {
|
||||
$sql = 'INSERT INTO brandschutz_training '
|
||||
. '(user_id, last_training_date, reminder_count, admin_reminder_count) '
|
||||
. 'VALUES (?, ?, 0, 0) '
|
||||
. 'ON CONFLICT (user_id) DO UPDATE SET last_training_date = EXCLUDED.last_training_date';
|
||||
}
|
||||
|
||||
$statement = $pdo->prepare($sql);
|
||||
$statement->execute([$userId, $date]);
|
||||
}
|
||||
|
||||
function brandschutz_log_admin_message(
|
||||
PDO $pdo,
|
||||
string $senderName,
|
||||
string $senderEmail,
|
||||
string $subject,
|
||||
string $message,
|
||||
string $status = 'done',
|
||||
?array $data = null
|
||||
): void {
|
||||
if (!in_array($status, ['done', 'pending'], true)) {
|
||||
throw new InvalidArgumentException('Ungültiger Nachrichtenstatus.');
|
||||
}
|
||||
|
||||
$dataJson = $data === null ? null : json_encode($data, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
|
||||
|
||||
if ($status === 'done') {
|
||||
$statement = $pdo->prepare(
|
||||
"INSERT INTO admin_messages "
|
||||
. "(type, sender_name, sender_email, subject, message, status, processed_at, created_at, data_json) "
|
||||
. "VALUES ('system', ?, ?, ?, ?, 'done', NOW(), NOW(), ?)"
|
||||
);
|
||||
} else {
|
||||
$statement = $pdo->prepare(
|
||||
"INSERT INTO admin_messages "
|
||||
. "(type, sender_name, sender_email, subject, message, status, processed_at, created_at, data_json) "
|
||||
. "VALUES ('system', ?, ?, ?, ?, 'pending', NULL, NOW(), ?)"
|
||||
);
|
||||
}
|
||||
|
||||
$statement->execute([$senderName, $senderEmail, $subject, $message, $dataJson]);
|
||||
}
|
||||
Reference in New Issue
Block a user