Upload via GUI (258 Dateien)

This commit is contained in:
2026-10-16 19:12:15 +00:00
parent 491b87f468
commit 56deade877
50 changed files with 23552 additions and 0 deletions
+80
View File
@@ -0,0 +1,80 @@
<?php
// Direkter Web-Zugriff (Browser/URL) wird geblockt. Ausnahmen: echter CLI-Cronjob
// sowie Einbindung per require_once aus dem authentifizierten Backend (staff/settings.php),
// das vor dem require_once die Konstante DESKHUB_CRON_RUNNER definiert.
if (php_sapi_name() !== 'cli' && !defined('DESKHUB_CRON_RUNNER')) { http_response_code(403); exit('Kein Web-Zugriff.'); }
/**
* cron/check_sla.php
*
* Prüft alle offenen Tickets auf überschrittene SLA-Fristen (Erstreaktion
* und Lösung) und markiert sie als überfällig (is_overdue). Optional kann
* bei neu erkannter Überfälligkeit eine Eskalations-E-Mail an die
* zuständige Abteilung gesendet werden.
*
* Einrichtung: Per Cronjob alle 15 Minuten aufrufen (Crontab-Beispiel siehe README.md):
* /usr/bin/php /pfad/zu/deskhub/cron/check_sla.php >> /pfad/zu/deskhub/cron/check_sla.log 2>&1
*
* Kann außerdem manuell aus dem Backend (Einstellungen → Cron-Jobs) ausgeführt werden.
*/
require_once __DIR__ . '/../includes/bootstrap.php';
/**
* Führt die SLA-Prüfung aus. Kann vom Cron und manuell aus settings.php aufgerufen werden.
*
* @return array{overdueTotal: int, newlyOverdue: int, log: string[]}
*/
function run_check_sla(PDO $pdo, bool $verbose = false): array
{
$now = db_now();
$stmt = $pdo->prepare(
"SELECT t.*, d.email AS department_email, d.name AS department_name FROM tickets t
JOIN departments d ON d.id = t.department_id
WHERE t.status NOT IN ('resolved','closed')
AND t.resolution_due_at IS NOT NULL
AND t.resolution_due_at < ?"
);
$stmt->execute([$now]);
$overdue = $stmt->fetchAll();
$newlyOverdue = 0;
$log = [];
foreach ($overdue as $t) {
if (!$t['is_overdue']) {
$pdo->prepare('UPDATE tickets SET is_overdue = 1 WHERE id = ?')->execute([$t['id']]);
log_activity($pdo, $t['id'], null, 'SLA überschritten – Ticket als überfällig markiert');
if ($t['department_email']) {
$subject = "SLA überschritten: Ticket #{$t['ticket_number']}";
$inner = email_p('Das folgende Ticket hat die SLA-Lösungsfrist überschritten und benötigt Aufmerksamkeit:')
. email_badge('Ticket', '#' . $t['ticket_number'], '#b91c1c', '#fee2e2')
. email_p('<strong>Betreff:</strong> ' . e($t['subject']), '24px')
. email_button('Ticket ansehen', e(base_url() . '/staff/ticket_view.php?n=' . urlencode($t['ticket_number'])), '#dc2626');
email_send_and_log($t['department_email'], $subject, email_wrap($inner), null, 'SLA-überschritten-Mail (Abteilung)', $t['ticket_number']);
}
notify_admins_overdue_ticket($t);
$newlyOverdue++;
if ($verbose) {
$log[] = "[ok] Ticket #{$t['ticket_number']} als überfällig markiert";
}
}
}
// Tickets, die nicht mehr überfällig sind (z.B. weil sie gelöst wurden), zurücksetzen
$pdo->exec("UPDATE tickets SET is_overdue = 0 WHERE status IN ('resolved','closed') AND is_overdue = 1");
set_setting('cron_check_sla_last_run', $now);
$log[] = "[" . date('Y-m-d H:i:s') . "] SLA-Prüfung abgeschlossen. " . count($overdue) . " überfällige Tickets insgesamt, davon {$newlyOverdue} neu erkannt.";
return ['overdueTotal' => count($overdue), 'newlyOverdue' => $newlyOverdue, 'log' => $log];
}
if (php_sapi_name() === 'cli') {
$result = run_check_sla(get_db(), true);
foreach ($result['log'] as $line) {
echo $line . "\n";
}
}