From 7f45f31aa82b87384fa09d8a7e8d074c78f703e0 Mon Sep 17 00:00:00 2001 From: fowr <89118232+perdedora@users.noreply.github.com> Date: Tue, 6 Aug 2024 11:49:51 -0300 Subject: [PATCH] fix: proper delete posts in a cyclical thread --- post.php | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/post.php b/post.php index 0a0dd94a..98eb0a06 100644 --- a/post.php +++ b/post.php @@ -185,6 +185,41 @@ function strip_image_metadata(string $img_path): int { return $ret; } +/** + * Delete posts in a cyclical thread. + * + * @param string $boardUri The URI of the board. + * @param int $threadId The ID of the thread. + * @param int $cycleLimit The number of most recent posts to retain. + */ +function delete_cyclical_posts(string $boardUri, int $threadId, int $cycleLimit): void +{ + $query = prepare(sprintf(' + SELECT p.`id` + FROM ``posts_%s`` p + LEFT JOIN ( + SELECT `id` + FROM ``posts_%s`` + WHERE `thread` = :thread + ORDER BY `id` DESC + LIMIT :limit + ) recent_posts ON p.id = recent_posts.id + WHERE p.thread = :thread + AND recent_posts.id IS NULL', + $boardUri, $boardUri + )); + + $query->bindValue(':thread', $threadId, PDO::PARAM_INT); + $query->bindValue(':limit', $cycleLimit, PDO::PARAM_INT); + + $query->execute() or error(db_error($query)); + $ids = $query->fetchAll(PDO::FETCH_COLUMN); + + foreach ($ids as $id) { + deletePost($id, false); + } +} + /** * Method handling functions */ @@ -1282,11 +1317,7 @@ if (isset($_POST['delete'])) { // Handle cyclical threads if (!$post['op'] && isset($thread['cycle']) && $thread['cycle']) { - // Query is a bit weird due to "This version of MariaDB doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'" (MariaDB Ver 15.1 Distrib 10.0.17-MariaDB, for Linux (x86_64)) - $query = prepare(sprintf('DELETE FROM ``posts_%s`` WHERE `thread` = :thread AND `id` NOT IN (SELECT `id` FROM (SELECT `id` FROM ``posts_%s`` WHERE `thread` = :thread ORDER BY `id` DESC LIMIT :limit) i)', $board['uri'], $board['uri'])); - $query->bindValue(':thread', $post['thread']); - $query->bindValue(':limit', $config['cycle_limit'], PDO::PARAM_INT); - $query->execute() or error(db_error($query)); + delete_cyclical_posts($board['uri'], $post['thread'], $config['cycle_limit']); } if (isset($post['antispam_hash'])) {