context = $ctx; } public function getName(): string { return 'cron'; } public function getSummary(): string { return 'Runs scheduled tasks and cleanups.'; } public function dispatch(CommandArgs $args): void { $runSlow = $args->hasFlag('slow'); foreach(self::TASKS as $task) { if($runSlow || empty($task['slow'])) { echo $task['name'] . PHP_EOL; switch($task['type']) { case 'sql': DB::exec($task['command']); break; case 'func': call_user_func([$this, $task['command']]); break; } } } } private function syncForumStats(): void { forum_count_synchronise(); } private const TASKS = [ [ 'name' => 'Ensures main role exists.', 'type' => 'sql', 'slow' => true, 'command' => " INSERT IGNORE INTO `msz_roles` (`role_id`, `role_name`, `role_hierarchy`, `role_colour`, `role_description`, `role_created`) VALUES (1, 'Member', 1, 1073741824, NULL, NOW()) ", ], [ 'name' => 'Ensures all users are in the main role.', 'type' => 'sql', 'slow' => true, 'command' => " INSERT INTO `msz_user_roles` (`user_id`, `role_id`) SELECT `user_id`, 1 FROM `msz_users` as u WHERE NOT EXISTS ( SELECT 1 FROM `msz_user_roles` as ur WHERE `role_id` = 1 AND u.`user_id` = ur.`user_id` ) ", ], [ 'name' => 'Ensures all display_role values are correct with `msz_user_roles`.', 'type' => 'sql', 'slow' => true, 'command' => " UPDATE `msz_users` as u SET `display_role` = ( SELECT ur.`role_id` FROM `msz_user_roles` as ur LEFT JOIN `msz_roles` as r ON r.`role_id` = ur.`role_id` WHERE ur.`user_id` = u.`user_id` ORDER BY `role_hierarchy` DESC LIMIT 1 ) WHERE NOT EXISTS ( SELECT 1 FROM `msz_user_roles` as ur WHERE ur.`role_id` = u.`display_role` AND `ur`.`user_id` = u.`user_id` ) ", ], [ 'name' => 'Remove expired sessions.', 'type' => 'sql', 'command' => " DELETE FROM `msz_sessions` WHERE `session_expires` < NOW() ", ], [ 'name' => 'Remove old password reset records.', 'type' => 'sql', 'command' => " DELETE FROM `msz_users_password_resets` WHERE `reset_requested` < NOW() - INTERVAL 1 WEEK ", ], [ 'name' => 'Clean up login history.', 'type' => 'sql', 'command' => " DELETE FROM `msz_login_attempts` WHERE `attempt_created` < NOW() - INTERVAL 1 MONTH ", ], [ 'name' => 'Clean up audit log.', 'type' => 'sql', 'command' => " DELETE FROM `msz_audit_log` WHERE `log_created` < NOW() - INTERVAL 3 MONTH ", ], [ 'name' => 'Remove stale forum tracking entries.', 'type' => 'sql', 'command' => " DELETE tt FROM `msz_forum_topics_track` as tt LEFT JOIN `msz_forum_topics` as t ON t.`topic_id` = tt.`topic_id` WHERE t.`topic_bumped` < NOW() - INTERVAL 1 MONTH ", ], [ 'name' => 'Synchronise forum_id.', 'type' => 'sql', 'slow' => true, 'command' => " UPDATE `msz_forum_posts` AS p INNER JOIN `msz_forum_topics` AS t ON t.`topic_id` = p.`topic_id` SET p.`forum_id` = t.`forum_id` ", ], [ 'name' => 'Recount forum topics and posts.', 'type' => 'func', 'slow' => true, 'command' => 'syncForumStats', ], [ 'name' => 'Clean up expired tfa tokens.', 'type' => 'sql', 'command' => " DELETE FROM `msz_auth_tfa` WHERE `tfa_created` < NOW() - INTERVAL 15 MINUTE ", ], ]; }