Editing a poll clears votes but not "Cancel your vote" option

ahaapaka - January 21, 2009 - 21:32
Project:Drupal
Version:6.14
Component:poll.module
Category:bug report
Priority:normal
Assigned:danielhonrade
Status:active
Issue tags:poll patch
Description

Editing an existing poll clears all existing votes, but for some reason the "Cancel your vote" button is still available. And if "Cancel your vote" button is selected, the vote count will go to -1!

Steps to reproduce:
1. Create a poll with two choices
2. Vote for the first choice -> now it has 1 vote
3. Click "Edit" tab, add a third choice and click "Save" button
4. You'll return to the poll results -> now all choices have 0 votes
5. Click "Cancel your vote" button
6. Click "Results" tab -> now the first choice has -100% (-1 votes) and Total votes is -1!

This seems to be somehow related to permissions, because I could not reproduce this with the admin (user 1) account. With admin user the editing does not automatically clear existing votes in step 3.

Anyway this is reproducible with an authenticated user that has permissions to "delete own poll content", "edit own poll content" and "vote on polls", but no other permissions related to the Poll module.

AttachmentSizeStatusTest resultOperations
votes_cleared_but_cancel_option_not.png8.76 KBIgnoredNoneNone
negative_vote_count.png7.74 KBIgnoredNoneNone

#1

ahaapaka - February 10, 2009 - 19:29
Title:Editing a poll clears votes but not "Cancel your vote" option» Studied this issue a bit

First of all, editing a poll is not intended to clear all votes. This is revealed in the following comment inside the poll_update() function:

We remove all votes to the removed options, so people who voted on them can vote again.

Then the reason why votes disappear (when editing a poll):

1. Form data contains votes only if the user has permission to 'administer nodes'

<?php
function poll_form(&$node, $form_state) {
...
 
// Add the current choices to the form.
 
for ($delta = 0; $delta < $choice_count; $delta++) {
...
   
$form['choice_wrapper']['choice'][$delta] = _poll_choice_form($delta, $text, $votes);
  }
...
}
?>

<?php
function _poll_choice_form($delta, $value = '', $votes = 0) {
 
$admin = user_access('administer nodes');
...
  if (
$admin) {
   
$form['chvotes'] = array(
     
'#type' => 'textfield',
     
'#title' => t('Votes for choice @n', array('@n' => ($delta + 1))),
     
'#default_value' => $votes,
     
'#size' => 5,
     
'#maxlength' => 7,
     
'#parents' => array('choice', $delta, 'chvotes'),
    );
  }

  return
$form;
}
?>

2. poll_update() function assumes that the $node contains all data (not just updated data)

<?php
function poll_update($node) {
...
 
// Clean poll choices.
 
db_query('DELETE FROM {poll_choices} WHERE nid = %d', $node->nid);
...
  foreach (
$node->choice as $old_chorder => $choice) {
   
$chvotes = isset($choice['chvotes']) ? (int)$choice['chvotes'] : 0;
   
$chtext = $choice['chtext'];

    if (!empty(
$chtext)) {
     
db_query("INSERT INTO {poll_choices} (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $chtext, $chvotes, $new_chorder);
...
    }
...
  }
}
?>

#2

ahaapaka - February 10, 2009 - 19:30
Title:Studied this issue a bit» Editing a poll clears votes but not "Cancel your vote" option

#3

danielhonrade - June 8, 2009 - 06:17

/* 6/8/09 danielhonrade bug report
*
* Hi, I was hacking the poll core module (which is really bad, I know but
* I only have few days to finish the project (http://pinometro.com) , this is temporary anyway, I am
* planning to create a module that would integrate to poll module with the following
* features:
* - use of google chart
* - add default values for choices
* - allow/disallow users to add choices and change other settings
* - require users to vote before commenting and not otherwise
*
* then I encountered this SAME PROBLEM, which I thought at first was the result of
* my hacking but when I installed a fresh Drupal6 and tested the poll again,
* it's still there, you can check the bug by:
* 1) Install fresh Drupal 6
* 2) Allow authenticated users to vote, create/edit/delete own poll
* 3) Login as a new authenticated user and not as admin, so you don't have node administer perm
* 4) Create a poll, then vote and edit then save
* 5) You'll notice that the vote values become 0
* 5) Cancel your vote, the result becomes -1
*
* PROBLEM: if an authenticated user without node administer permission but
* has a permission to edit his/any poll, everytime he edits his poll or
* any poll the vote values become 0 and when he goes to view tab,
* if has voted, the cancel button still exists even though vote values are 0
* so if he decided to cancel, the result is negative value which
* the validator function doesn't even notice
*
* I created a patch, which I am sure, it's not the best, but it works
*
* SOLUTION 1: I added an else statement where I copied the the content in the
* if($admin) {...} and added '#disabled' => 'disabled', and changed
* '#default_value' => $votes, to '#value' => $votes, because if the
* attribute is disabled #default_value doesn't pass its value
*
* SOLUTION 2: I added an else statement where I copied the the content in the
* if($admin) {...} and just change the '#type' => 'textfield', to '#type' => 'hidden',
* but you'll have nothing under the heading VOTE COUNT which is the original
* state when you create a poll in the original poll module
*/

<?php
// PATCH, just replace this function with this one
function _poll_choice_form($delta, $value = '', $votes = 0) {
 
$admin = user_access('administer nodes');

 
$form = array(
   
'#tree' => TRUE,
  );

 
// We'll manually set the #parents property of these fields so that
  // their values appear in the $form_state['values']['choice'] array.
 
$form['chtext'] = array(
   
'#type' => 'textfield',
   
'#title' => t('Choice @n', array('@n' => ($delta + 1))),
   
'#default_value' => $value,
   
'#parents' => array('choice', $delta, 'chtext'),
  );

  if (
$admin) {
   
$form['chvotes'] = array(
     
'#type' => 'textfield',
     
'#title' => t('Votes for choice @n', array('@n' => ($delta + 1))),
     
'#default_value' => $votes,
     
'#size' => 5,
     
'#maxlength' => 7,
     
'#parents' => array('choice', $delta, 'chvotes'),
    );
  } else {
// <-- add this (daniel's SOLUTION 1 module patch )
   
$form['chvotes'] = array(
     
'#type' => 'textfield',
     
'#title' => t('Votes for choice @n', array('@n' => ($delta + 1))),
     
'#value' => $votes,
     
'#size' => 5,
     
'#maxlength' => 7,
   
'#disabled' => 'disabled',
     
'#parents' => array('choice', $delta, 'chvotes'),
    );
  } 
// <--patch upto here
 
return $form;
}
?>

#4

danielhonrade - June 16, 2009 - 10:15
Assigned to:Anonymous» danielhonrade

I am having problems with getting the right diff program. But here is the patch file, anyway

/* Based on the latest Drupal 6.12-dev
* PROBLEM: if an authenticated user without node administer permission but
* has a permission to edit his/any poll, everytime he edits his poll or
* any poll the vote values become 0 and when he goes to view tab,
* if has voted, the cancel button still exists even though vote values are 0
* so if he decided to cancel, the result is negative value which
* the validator function doesn't even notice
*
* I created a patch, which I am sure, it's not the best, but it works
*
* SOLUTION 1: I added an else statement where I copied the the content in the
* if($admin) {...} and added '#disabled' => 'disabled', and changed
* '#default_value' => $votes, to '#value' => $votes, because if the
* attribute is disabled #default_value doesn't pass its value
*
* SOLUTION 2: I added an else statement where I copied the the content in the
* if($admin) {...} and just change the '#type' => 'textfield', to '#type' => 'hidden',
* but you'll have nothing under the heading VOTE COUNT which is the original
* state when you create a poll in the original poll module
*/

313:   if ($admin) {
314:     $form['chvotes'] = array(
315:       '#type' => 'textfield',
316:       '#title' => t('Votes for choice @n', array('@n' => ($delta + 1))),
317:       '#default_value' => $votes,
318:       '#size' => 5,
319:       '#maxlength' => 7,
320:       '#parents' => array('choice', $delta, 'chvotes'),
321:     );
322
323:   } else { // <-- add this (daniel's solution 1 )
324:       '#type' => 'textfield',
325:       '#title' => t('Votes for choice @n', array('@n' => ($delta + 1))),
326:       '#value' => $votes,
327:       '#size' => 5,
328:       '#maxlength' => 7,
329:   '#disabled' => 'disabled',
330:       '#parents' => array('choice', $delta, 'chvotes'),
331:     );
332:   }  // <--patch upto here

AttachmentSizeStatusTest resultOperations
poll-issue-pollmodulepatch-comment1.patch1.83 KBIgnoredNoneNone

#5

dicreat - June 17, 2009 - 08:06

Solution at #3 works for me.

#6

danielhonrade - June 17, 2009 - 12:25

This should also work for 6.12 and 6.12-dev, I just tested it, now when a user edits his poll, it gives him a disabled number of votes which makes sense since he has no administrative privileges to change the number of votes, if he wants to delete his poll, he can also, thanks for testing. Unlike before, when the user edits his poll, they all become zeros and the vote cancel still appears and when he cancels the vote becomes negative 1.

#7

mikestefff - July 28, 2009 - 18:05
Version:6.9» 6.13

This is still an issue in 6.13. First off, the votes are set back to zero even if you don't change or add any of the vote options. Also, when viewing the poll, if you click the 'Votes' tab, you still get a list of who voted, despite the vote count being zero. Doesn't make any sense to me..

The patch in #3 works ... i think it should be committed.

#8

kiamlaluno - August 27, 2009 - 13:28

I have marked #484878: Poll module bug patch as duplicate of this report.

#9

Pasi - October 2, 2009 - 11:20

And this is still an issue in 6.14. Solution at #3 works also for me.

#10

kiamlaluno - October 2, 2009 - 11:21
Version:6.13» 6.14

#11

Kane - March 15, 2010 - 20:57

Still exists in 6.16.

 
 

Drupal is a registered trademark of Dries Buytaert.