From c67c2d8a9263c127f075d7c587eb5387a1c16fc2 Mon Sep 17 00:00:00 2001 From: ECYaz Date: Fri, 31 Jul 2026 07:30:44 -0400 Subject: [PATCH] Guard each author counter on its own when decrementing The decrement update subtracted from author_contribs and from the per-type counter in one statement, guarded only by author_contribs being above zero. The columns are unsigned, so once a per-type counter has drifted to zero the subtraction fails and the whole action dies with an SQL error: changing the contribution status, changing its owner or deleting it. Each counter now stops at zero on its own, which also lets a drifted counter correct itself over time instead of the skipped update pushing them further apart. --- includes/objects/contribution.php | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/includes/objects/contribution.php b/includes/objects/contribution.php index 47d45a10e..e2d431952 100644 --- a/includes/objects/contribution.php +++ b/includes/objects/contribution.php @@ -1998,12 +1998,31 @@ private function change_author_contrib_count($user_id, $action = '+', $force = f $user_id = (int) $user_id; $action = ($action == '-') ? '-' : '+'; + if ($action == '-') + { + // Guard each counter on its own; the columns are unsigned, so a + // counter that is already at zero must not fail the whole update. + $sql_set = 'author_contribs = CASE WHEN author_contribs > 0 THEN author_contribs - 1 ELSE 0 END'; + + if (isset($this->type->author_count)) + { + $sql_set .= ', ' . $this->type->author_count . ' = CASE WHEN ' . $this->type->author_count . ' > 0 THEN ' . $this->type->author_count . ' - 1 ELSE 0 END'; + } + } + else + { + $sql_set = 'author_contribs = author_contribs + 1'; + + if (isset($this->type->author_count)) + { + $sql_set .= ', ' . $this->type->author_count . ' = ' . $this->type->author_count . ' + 1'; + } + } + // Increment/Decrement the contrib counter for the new owner $sql = 'UPDATE ' . TITANIA_AUTHORS_TABLE . " - SET author_contribs = author_contribs $action 1" . - ((isset($this->type->author_count)) ? ', ' . $this->type->author_count . ' = ' . $this->type->author_count . " $action 1" : '') . " - WHERE user_id = $user_id " . - (($action == '-') ? 'AND author_contribs > 0' : ''); + SET $sql_set + WHERE user_id = $user_id"; phpbb::$db->sql_query($sql);