Files
deskhub/DeskHub-Webseite/cron/auto_close_tickets.php
T
2026-10-26 21:19:30 +00:00

75 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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/auto_close_tickets.php
*
* Schließt Tickets automatisch, die seit "Mitarbeiter hat geantwortet, Kunde
* hat sich nicht mehr gemeldet" (Status "answered") länger als die
* eingestellte Anzahl Tage nicht mehr aktualisiert wurden. Abschaltbar
* (Standard: aus) und die Anzahl Tage einstellbar unter Einstellungen →
* Allgemein → "Tickets automatisch schließen".
*
* Einrichtung: Per Cronjob z.B. einmal täglich aufrufen (Crontab-Beispiel siehe README.md):
* /usr/bin/php /pfad/zu/deskhub/cron/auto_close_tickets.php >> /pfad/zu/deskhub/cron/auto_close_tickets.log 2>&1
*
* Kann außerdem manuell aus dem Backend (Einstellungen → Cron-Jobs) ausgeführt werden.
*/
require_once __DIR__ . '/../includes/bootstrap.php';
/**
* Führt das automatische Schließen aus. Kann vom Cron und manuell aus settings.php aufgerufen werden.
*
* @return array{closed: int, log: string[]}
*/
function run_auto_close_tickets(PDO $pdo, bool $verbose = false): array
{
$log = [];
if (get_setting('auto_close_enabled', '0') !== '1') {
$log[] = '[' . date('Y-m-d H:i:s') . '] Automatisches Schließen ist deaktiviert – nichts zu tun.';
return ['closed' => 0, 'log' => $log];
}
$days = max(1, (int) get_setting('auto_close_days', '7'));
$threshold = date('Y-m-d H:i:s', time() - $days * 86400);
// Nur Tickets, bei denen der Mitarbeiter zuletzt geantwortet hat (status='answered')
// und der Kunde sich seitdem nicht mehr gemeldet hat (sonst wäre der Status längst
// wieder 'open') – exakt der in der Anfrage beschriebene Fall "keine Reaktion".
$stmt = $pdo->prepare(
"SELECT id, ticket_number FROM tickets
WHERE status = 'answered' AND is_spam = 0 AND updated_at < ?"
);
$stmt->execute([$threshold]);
$tickets = $stmt->fetchAll();
$now = db_now();
$closed = 0;
foreach ($tickets as $t) {
$pdo->prepare("UPDATE tickets SET status = 'closed', closed_at = ?, updated_at = ? WHERE id = ?")
->execute([$now, $now, $t['id']]);
ticket_sla_status_transition($pdo, (int) $t['id'], (string) $t['status'], 'closed');
log_activity($pdo, (int) $t['id'], null, "Automatisch geschlossen (keine Kundenreaktion seit {$days} Tagen)");
$closed++;
if ($verbose) {
$log[] = "[ok] Ticket #{$t['ticket_number']} automatisch geschlossen";
}
}
set_setting('cron_auto_close_tickets_last_run', $now);
$log[] = '[' . date('Y-m-d H:i:s') . "] Automatisches Schließen abgeschlossen. {$closed} Ticket(s) geschlossen (Schwelle: {$days} Tage).";
return ['closed' => $closed, 'log' => $log];
}
if (php_sapi_name() === 'cli') {
$result = run_auto_close_tickets(get_db(), true);
foreach ($result['log'] as $line) {
echo $line . "\n";
}
}