- Patch #39432 by c960657, chx, Gábor Hojtsy: fixed problems with anonymous users voting.

merge-requests/26/head
Dries Buytaert 2010-04-22 23:59:04 +00:00
parent 257a5b8ef5
commit e82edd5758
2 changed files with 61 additions and 17 deletions

View File

@ -478,17 +478,17 @@ function poll_load($nodes) {
$poll->allowvotes = FALSE;
if (user_access('vote on polls') && $poll->active) {
if ($user->uid) {
$result = db_query('SELECT chid FROM {poll_vote} WHERE nid = :nid AND uid = :uid', array(':nid' => $node->nid, ':uid' => $user->uid))->fetchObject();
$poll->vote = db_query('SELECT chid FROM {poll_vote} WHERE nid = :nid AND uid = :uid', array(':nid' => $node->nid, ':uid' => $user->uid))->fetchField();
if (empty($poll->vote)) {
$poll->vote = -1;
$poll->allowvotes = TRUE;
}
}
elseif (!empty($_SESSION['poll_vote'][$node->nid])) {
$poll->vote = $_SESSION['poll_vote'][$node->nid];
}
else {
$result = db_query("SELECT chid FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname", array(':nid' => $node->nid, ':hostname' => ip_address()))->fetchObject();
}
if ($result) {
$poll->vote = $result->chid;
}
else {
$poll->vote = -1;
$poll->allowvotes = TRUE;
$poll->allowvotes = !db_query("SELECT 1 FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname", array(':nid' => $node->nid, ':hostname' => ip_address()))->fetchField();
}
}
foreach ($poll as $key => $value) {
@ -730,6 +730,16 @@ function poll_vote($form, &$form_state) {
->execute();
cache_clear_all();
if (!$user->uid) {
// The vote is recorded so the user gets the result view instead of the
// voting form when viewing the poll. Saving a value in $_SESSION has the
// convenient side effect of preventing the user from hitting the page
// cache. When anonymous voting is allowed, the page cache should only
// contain the voting form, not the results.
$_SESSION['poll_vote'][$node->nid] = $choice;
}
drupal_set_message(t('Your vote was recorded.'));
// Return the user to whatever page they voted from.
@ -911,6 +921,8 @@ function poll_cancel($form, &$form_state) {
->condition('chid', $node->vote)
->execute();
unset($_SESSION['poll_vote'][$node->nid]);
drupal_set_message(t('Your vote was cancelled.'));
}

View File

@ -370,8 +370,13 @@ class PollVoteCheckHostname extends PollTestCase {
user_role_change_permissions(DRUPAL_ANONYMOUS_RID, array(
'access content' => TRUE,
'vote on polls' => TRUE,
'cancel own vote' => TRUE,
));
// Enable page cache to verify that the result page is not saved in the
// cache when anonymous voting is allowed.
variable_set('cache', CACHE_NORMAL);
// Create poll.
$title = $this->randomName();
$choices = $this->_generateChoices(3);
@ -380,7 +385,7 @@ class PollVoteCheckHostname extends PollTestCase {
$this->drupalLogout();
// Create web users.
$this->web_user1 = $this->drupalCreateUser(array('access content', 'vote on polls'));
$this->web_user1 = $this->drupalCreateUser(array('access content', 'vote on polls', 'cancel own vote'));
$this->web_user2 = $this->drupalCreateUser(array('access content', 'vote on polls'));
}
@ -405,19 +410,32 @@ class PollVoteCheckHostname extends PollTestCase {
$this->drupalGet('node/' . $this->poll_nid);
$elements = $this->xpath('//input[@value="Vote"]');
$this->assertTrue(empty($elements), t("%user is not able to vote again.", array('%user' => $this->web_user1->name)));
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
// Logout User1.
$this->drupalLogout();
// Fill the page cache by requesting the poll.
$this->drupalGet('node/' . $this->poll_nid);
$this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', t('Page was cacheable but was not in the cache.'));
$this->drupalGet('node/' . $this->poll_nid);
$this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'HIT', t('Page was cached.'));
// Anonymous user vote on Poll.
$this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
$this->drupalPost(NULL, $edit, t('Vote'));
$this->assertText(t('Your vote was recorded.'), t('Anonymous vote was recorded.'));
$this->assertText(t('Total votes: @votes', array('@votes' => 2)), t('Vote count updated correctly.'));
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
// Check to make sure Anonymous user cannot vote again.
$this->drupalGet('node/' . $this->poll_nid);
$this->assertFalse($this->drupalGetHeader('x-drupal-cache'), t('Page was not cacheable.'));
$elements = $this->xpath('//input[@value="Vote"]');
$this->assertTrue(empty($elements), t("Anonymous is not able to vote again."));
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
// Login User2.
$this->drupalLogin($this->web_user2);
@ -426,6 +444,8 @@ class PollVoteCheckHostname extends PollTestCase {
$this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
$this->assertText(t('Your vote was recorded.'), t('%user vote was recorded.', array('%user' => $this->web_user2->name)));
$this->assertText(t('Total votes: @votes', array('@votes' => 3)), 'Vote count updated correctly.');
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(empty($elements), t("'Cancel your vote' button does not appear."));
// Logout User2.
$this->drupalLogout();
@ -433,20 +453,30 @@ class PollVoteCheckHostname extends PollTestCase {
// Change host name for anonymous users.
db_update('poll_vote')
->fields(array(
'hostname' => '123.456.789.20',
'hostname' => '123.456.789.1',
))
->condition('hostname', '', '!=')
->condition('hostname', '', '<>')
->execute();
// Check to make sure Anonymous user can vote again after hostname change.
$this->drupalPost('node/' . $this->poll_nid, $edit, t('Vote'));
// Check to make sure Anonymous user can vote again with a new session after
// a hostname change.
$this->drupalGet('node/' . $this->poll_nid);
$this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', t('Page was cacheable but was not in the cache.'));
$this->drupalPost(NULL, $edit, t('Vote'));
$this->assertText(t('Your vote was recorded.'), t('%user vote was recorded.', array('%user' => $this->web_user2->name)));
$this->assertText(t('Total votes: @votes', array('@votes' => 4)), 'Vote count updated correctly.');
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
// Check to make sure Anonymous user cannot vote again.
// Check to make sure Anonymous user cannot vote again with a new session,
// and that the vote from the previous session cannot be cancelledd.
$this->curlClose();
$this->drupalGet('node/' . $this->poll_nid);
$this->assertEqual($this->drupalGetHeader('x-drupal-cache'), 'MISS', t('Page was cacheable but was not in the cache.'));
$elements = $this->xpath('//input[@value="Vote"]');
$this->assertTrue(empty($elements), t("Anonymous is not able to vote again."));
$this->assertTrue(empty($elements), t('Anonymous is not able to vote again.'));
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(empty($elements), t("'Cancel your vote' button does not appear."));
// Login User1.
$this->drupalLogin($this->web_user1);
@ -455,6 +485,8 @@ class PollVoteCheckHostname extends PollTestCase {
$this->drupalGet('node/' . $this->poll_nid);
$elements = $this->xpath('//input[@value="Vote"]');
$this->assertTrue(empty($elements), t("%user is not able to vote again.", array('%user' => $this->web_user1->name)));
$elements = $this->xpath('//input[@value="Cancel your vote"]');
$this->assertTrue(!empty($elements), t("'Cancel your vote' button appears."));
}
}