Upload via GUI (360 Dateien)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user