Upload via GUI (360 Dateien)

This commit is contained in:
2026-10-30 21:49:53 +00:00
parent 2837074176
commit 07295c8b77
4 changed files with 111 additions and 10 deletions
+95
View File
@@ -1850,6 +1850,101 @@ function run_migrations(PDO $pdo, bool $verbose = false): array
}
}
// Anmelde-Wächter: Protokoll der Anmeldungen sowie gemerkte Geräte und Orte je Mitarbeiter
if (!isset($done['php_0065_login_guard'])) {
try {
$drv = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
$ai = $drv === 'sqlite' ? 'INTEGER PRIMARY KEY AUTOINCREMENT' : 'INT AUTO_INCREMENT PRIMARY KEY';
$eng = $drv === 'sqlite' ? '' : ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4';
$pdo->exec("CREATE TABLE IF NOT EXISTS login_events (
id $ai,
staff_id INT NULL,
email VARCHAR(255) NOT NULL DEFAULT '',
event VARCHAR(20) NOT NULL,
channel VARCHAR(10) NOT NULL DEFAULT 'web',
ip VARCHAR(64) NOT NULL DEFAULT '',
place VARCHAR(100) NOT NULL DEFAULT '',
device VARCHAR(160) NOT NULL DEFAULT '',
detail VARCHAR(255) NOT NULL DEFAULT '',
token_hash VARCHAR(64) NULL,
token_used TINYINT NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL
)$eng");
$pdo->exec('CREATE INDEX idx_login_events_created ON login_events (created_at)');
$pdo->exec('CREATE INDEX idx_login_events_staff ON login_events (staff_id, created_at)');
$pdo->exec('CREATE INDEX idx_login_events_token ON login_events (token_hash)');
$pdo->exec("CREATE TABLE IF NOT EXISTS login_devices (
id $ai,
staff_id INT NOT NULL,
device_hash VARCHAR(64) NOT NULL,
label VARCHAR(160) NOT NULL DEFAULT '',
channel VARCHAR(10) NOT NULL DEFAULT 'web',
first_ip VARCHAR(64) NOT NULL DEFAULT '',
last_ip VARCHAR(64) NOT NULL DEFAULT '',
place VARCHAR(100) NOT NULL DEFAULT '',
first_seen DATETIME NOT NULL,
last_seen DATETIME NOT NULL,
UNIQUE (staff_id, device_hash)
)$eng");
$pdo->exec("CREATE TABLE IF NOT EXISTS login_places (
id $ai,
staff_id INT NOT NULL,
place_key VARCHAR(80) NOT NULL,
label VARCHAR(100) NOT NULL DEFAULT '',
first_seen DATETIME NOT NULL,
last_seen DATETIME NOT NULL,
UNIQUE (staff_id, place_key)
)$eng");
$pdo->prepare('INSERT INTO schema_migrations (migration) VALUES (?)')->execute(['php_0065_login_guard']);
$result['applied']++;
if ($verbose) $result['log'][] = ' [OK] php_0065_login_guard';
} catch (Throwable $e) {
$result['errors'][] = 'php_0065_login_guard: ' . $e->getMessage();
if ($verbose) $result['log'][] = ' [FAIL] php_0065_login_guard - ' . $e->getMessage();
}
}
// Abwesenheit im Profil: Welche Tickets an die Vertretung weitergegeben wurden (für die Rückgabe nach dem Urlaub)
if (!isset($done['php_0066_vacation_moves'])) {
try {
$drv = $pdo->getAttribute(PDO::ATTR_DRIVER_NAME);
$ai = $drv === 'sqlite' ? 'INTEGER PRIMARY KEY AUTOINCREMENT' : 'INT AUTO_INCREMENT PRIMARY KEY';
$eng = $drv === 'sqlite' ? '' : ' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4';
$pdo->exec("CREATE TABLE IF NOT EXISTS vacation_moves (
id $ai,
ticket_id INT NOT NULL,
from_staff_id INT NOT NULL,
to_staff_id INT NOT NULL,
created_at DATETIME NOT NULL,
returned_at DATETIME NULL
)$eng");
$pdo->exec('CREATE INDEX idx_vacation_moves_from ON vacation_moves (from_staff_id, returned_at)');
$pdo->prepare('INSERT INTO schema_migrations (migration) VALUES (?)')->execute(['php_0066_vacation_moves']);
$result['applied']++;
if ($verbose) $result['log'][] = ' [OK] php_0066_vacation_moves';
} catch (Throwable $e) {
$result['errors'][] = 'php_0066_vacation_moves: ' . $e->getMessage();
if ($verbose) $result['log'][] = ' [FAIL] php_0066_vacation_moves - ' . $e->getMessage();
}
}
// Reparatur: Entwarnungs-Notizen der öffentlichen API waren doppelt maskiert (" statt ")
if (!isset($done['php_0067_fix_api_resolve_notes'])) {
try {
$rows = $pdo->query("SELECT t.id, t.message FROM ticket_threads t JOIN tickets k ON k.id = t.ticket_id
WHERE k.source = 'api' AND t.author_type = 'system' AND t.is_internal_note = 1
AND (t.message LIKE '%"%' OR t.message LIKE '%&%' OR t.message LIKE '%'%')")->fetchAll();
$upd = $pdo->prepare('UPDATE ticket_threads SET message = ? WHERE id = ?');
foreach ($rows as $r) $upd->execute([html_entity_decode((string) $r['message'], ENT_QUOTES | ENT_HTML5, 'UTF-8'), $r['id']]);
$pdo->prepare('INSERT INTO schema_migrations (migration) VALUES (?)')->execute(['php_0067_fix_api_resolve_notes']);
$result['applied']++;
if ($verbose) $result['log'][] = ' [OK] php_0067_fix_api_resolve_notes (' . count($rows) . ' Notizen repariert)';
} catch (Throwable $e) {
$result['errors'][] = 'php_0067_fix_api_resolve_notes: ' . $e->getMessage();
if ($verbose) $result['log'][] = ' [FAIL] php_0067_fix_api_resolve_notes - ' . $e->getMessage();
}
}
return $result;
}