diff --git a/tools/maintenance.php b/tools/maintenance.php index 33c0a4d4..abf53361 100644 --- a/tools/maintenance.php +++ b/tools/maintenance.php @@ -5,6 +5,56 @@ require dirname(__FILE__) . '/inc/cli.php'; +function get_reports_by_board(): array { + $query = prepare("SELECT `board`, `post`, `id` FROM ``reports``"); + $query->execute() or error(db_error($query)); + return $query->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_NUM); +} + +function post_ids_by_board(array $reports): array { + $ret = []; + foreach ($reports as $board => $values) { + foreach ($values as $value) { + $ret[$board] ??= []; + $ret[$board][] = $value[0]; + } + } + return $ret; +} + +function filter_invalid_reports(array $board_post_ids, array $reports): array { + $invalid_reports = []; + + foreach ($board_post_ids as $board => $post_ids) { + $query = query(sprintf('SELECT `id` FROM ``posts_%s`` WHERE `id` = ' . implode(' OR `id` = ', $post_ids), $board)); + $existing_posts = $query->fetchAll(PDO::FETCH_COLUMN); + + foreach ($reports[$board] as $values) { + list($post_id, $report_id) = $values; + if (!in_array($post_id, $existing_posts)) { + $invalid_reports[] = $report_id; + } + } + } + + return $invalid_reports; +} + +function get_report_ids(array $reports): array { + $ret = []; + foreach ($reports as $_board => $values) { + foreach ($values as $value) { + $report_id = $value[0]; + $ret[] = $report_id; + } + } + return $ret; +} + +function delete_reports(array $report_ids): int { + return query('DELETE FROM ``reports`` WHERE `id` = ' . implode(' OR `id` = ', $report_ids))->rowCount(); +} + echo "Clearing expired bans...\n"; $start = microtime(true); $deleted_count = Bans::purge($config['require_ban_view'], $config['purge_bans']); @@ -19,7 +69,23 @@ $deleted_count = purge_old_antispam(); $delta = microtime(true) - $start; echo "Deleted $deleted_count expired antispam in $delta seconds!\n"; $time_tot = $delta; -$deleted_tot = $deleted_count; +$deleted_tot += $deleted_count; + +echo "Clearing invalid reports...\n"; +$start = microtime(true); +$reports = get_reports_by_board(); +$report_ids = get_report_ids($reports); +$board_post_ids = post_ids_by_board($reports); +$invalid_reports = filter_invalid_reports($board_post_ids, $reports); +if (!empty($invalid_reports)) { + $deleted_count = delete_reports($invalid_reports); +} else { + $deleted_count = 0; +} +$delta = microtime(true) - $start; +echo "Deleted $deleted_count invalid reports in $delta seconds!\n"; +$time_tot += $delta; +$deleted_tot += $deleted_count; $time_tot = number_format((float)$time_tot, 4, '.', ''); modLog("Deleted $deleted_tot expired entries in {$time_tot}s with maintenance tool");