From cf790b5a096a154cee6f22688b4c9d2dbc14d76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Hojtsy?= Date: Mon, 17 Dec 2007 21:58:38 +0000 Subject: [PATCH] #67895 patch by myself, tested by JirkaRybka and blackdog: move poll votes with poll options, when an option is removed, instead of dropping all old votes, solving an old data loss bug --- modules/poll/poll.module | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/modules/poll/poll.module b/modules/poll/poll.module index a21c0db9b8f..b8fde337eb4 100644 --- a/modules/poll/poll.module +++ b/modules/poll/poll.module @@ -396,15 +396,15 @@ function poll_validate($node) { function poll_load($node) { global $user; - // Load the appropriate choices into the $node object $poll = db_fetch_object(db_query("SELECT runtime, active FROM {poll} WHERE nid = %d", $node->nid)); + // Load the appropriate choices into the $poll object. $result = db_query("SELECT chtext, chvotes, chorder FROM {poll_choices} WHERE nid = %d ORDER BY chorder", $node->nid); while ($choice = db_fetch_array($result)) { $poll->choice[$choice['chorder']] = $choice; } - // Determine whether or not this user is allowed to vote + // Determine whether or not this user is allowed to vote. $poll->allowvotes = FALSE; if (user_access('vote on polls') && $poll->active) { if ($user->uid) { @@ -450,18 +450,32 @@ function poll_insert($node) { * Implementation of hook_update(). */ function poll_update($node) { + // Update poll settings. db_query('UPDATE {poll} SET runtime = %d, active = %d WHERE nid = %d', $node->runtime, $node->active, $node->nid); + // Clean poll choices. db_query('DELETE FROM {poll_choices} WHERE nid = %d', $node->nid); - db_query('DELETE FROM {poll_votes} WHERE nid = %d', $node->nid); - $i = 0; - foreach ($node->choice as $choice) { + // Poll choices come in the same order with the same numbers as they are in + // the database, but some might have an empty title, which signifies that + // they should be removed. We remove all votes to the removed options, so + // people who voted on them can vote again. + $new_chorder = 0; + foreach ($node->choice as $old_chorder => $choice) { $chvotes = isset($choice['chvotes']) ? (int)$choice['chvotes'] : 0; $chtext = $choice['chtext']; - if ($chtext != '') { - db_query("INSERT INTO {poll_choices} (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $chtext, $chvotes, $i++); + if (!empty($chtext)) { + db_query("INSERT INTO {poll_choices} (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $chtext, $chvotes, $new_chorder); + if ($new_chorder != $old_chorder) { + // We can only remove items in the middle, not add, so + // new_chorder is always <= old_chorder, making this safe. + db_query("UPDATE {poll_votes} SET chorder = %d WHERE nid = %d AND chorder = %d", $new_chorder, $node->nid, $old_chorder); + } + $new_chorder++; + } + else { + db_query("DELETE FROM {poll_votes} WHERE nid = %d AND chorder = %d", $node->nid, $old_chorder); } } }