Index: modules/poll/poll.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/poll/poll.module,v
retrieving revision 1.239
diff -u -p -r1.239 poll.module
--- modules/poll/poll.module	26 Aug 2007 07:46:11 -0000	1.239
+++ modules/poll/poll.module	26 Aug 2007 17:44:02 -0000
@@ -99,8 +99,8 @@ function poll_menu() {
 /**
  * Callback function to see if a node is acceptable for poll menu items.
  */
-function _poll_menu_access($node, $perm, $inspect_allowvotes) {
-  return user_access($perm) && ($node->type == 'poll') && ($node->allowvotes || !$inspect_allowvotes);
+function _poll_menu_access(&$node, $perm, $inspect_allowvotes) {
+  return user_access($perm) && ($node->type == 'poll') && (!$inspect_allowvotes || poll_allow_votes($node));
 }
 
 /**
@@ -360,28 +360,12 @@ function poll_delete($node) {
  *   An extra parameter that adapts the hook to display a block-ready
  *   rendering of the poll.
  */
-function poll_view($node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
+function poll_view(&$node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
   global $user;
   $output = '';
-
   // Determine whether or not this user is allowed to vote
-  $poll->allowvotes = FALSE;
-  if (user_access('vote on polls') && $poll->active) {
-    if ($user->uid) {
-      $result = db_fetch_object(db_query('SELECT chorder FROM {poll_votes} WHERE nid = %d AND uid = %d', $node->nid, $user->uid));
-    }
-    else {
-      $result = db_fetch_object(db_query("SELECT chorder FROM {poll_votes} WHERE nid = %d AND hostname = '%s'", $node->nid, ip_address()));
-    }
-    if (isset($result->chorder)) {
-      $poll->vote = $result->chorder;
-    }
-    else {
-      $poll->vote = -1;
-      $poll->allowvotes = TRUE;
-    }
-  }
-
+  // We do this early because it sets the user's vote on the node object.
+  $allow_votes = poll_allow_votes($node);
 
   // Special display for side-block
   if ($block) {
@@ -390,14 +374,14 @@ function poll_view($node, $teaser = FALS
 
     $links = module_invoke_all('link', 'node', $node, 1);
     $links[] = array('title' => t('Older polls'), 'href' => 'poll', 'attributes' => array('title' => t('View the list of polls on this site.')));
-    if ($node->allowvotes && $block) {
+    if ($allow_votes && $block) {
       $links[] = array('title' => t('Results'), 'href' => 'node/'. $node->nid .'/results', 'attributes' => array('title' => t('View the current poll results.')));
     }
 
     $node->links = $links;
   }
 
-  if (!empty($node->allowvotes) && ($block || empty($node->show_results))) {
+  if (!empty($allow_votes) && ($block || empty($node->show_results))) {
     $node->content['body'] = array(
       '#value' => drupal_get_form('poll_view_voting', $node, $block),
     );
@@ -411,6 +395,52 @@ function poll_view($node, $teaser = FALS
 }
 
 /**
+ * Determine if the given user has the right to vote on this poll.
+ */
+function poll_allow_votes($node, $account = NULL) {
+  if (empty($account)) {
+    global $user;
+    $account = $user;
+  }
+
+  if (user_access('vote on polls', $account) && $node->active) {
+    // If the user can vote, has the user already voted?
+    if (poll_fetch_vote($node, $account) == -1) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * Determine the given user's vote on the poll.
+ */
+function poll_fetch_vote($node, $account = NULL) {
+  static $cache = array();
+  if (empty($account)) {
+    global $user;
+    $account = $user;
+  }
+  if (!isset($cache[$account->uid])) {
+    if ($account->uid) {
+      $result = db_fetch_object(db_query('SELECT chorder FROM {poll_votes} WHERE nid = %d AND uid = %d', $node->nid, $account->uid));
+    }
+    else {
+      $result = db_fetch_object(db_query("SELECT chorder FROM {poll_votes} WHERE nid = %d AND hostname = '%s'", $node->nid, ip_address()));
+    }
+    if (isset($result->chorder)) {
+      $cache[$account->uid] = $result->chorder;
+    }
+    else {
+      $cache[$account->uid] = -1;
+    }
+  }
+
+  return $cache[$account->uid];
+}
+
+/**
  * Menu callback to provide a simple list of all polls available.
  */
 function poll_page() {
@@ -501,7 +531,7 @@ function poll_vote($form, &$form_state) 
   // Add one to the votes.
   db_query("UPDATE {poll_choices} SET chvotes = chvotes + 1 WHERE nid = %d AND chorder = %d", $node->nid, $choice);
 
-  cache_clear_all();
+  cache_clear_all($node->nid, 'cache_node');
   drupal_set_message(t('Your vote was recorded.'));
 
   // Return the user to whatever page they voted from.
@@ -534,13 +564,16 @@ function poll_view_results(&$node, $teas
   }
 
   $poll_results = '';
+  
+  // get the user's vote
+  $vote = poll_fetch_vote($node);
   foreach ($node->choice as $i => $choice) {
     if ($choice['chtext'] != '') {
-      $poll_results .= theme('poll_bar', $choice['chtext'], $choice['chvotes'], $total_votes, isset($node->vote) && $node->vote == $i, $block);
+      $poll_results .= theme('poll_bar', $choice['chtext'], $choice['chvotes'], $total_votes, $vote == $i, $block);
     }
   }
 
-  return theme('poll_results', $node->title, $poll_results, $total_votes, isset($node->links) ? $node->links : array(), $block, $node->nid, isset($node->vote) ? $node->vote : NULL);
+  return theme('poll_results', $node->title, $poll_results, $total_votes, isset($node->links) ? $node->links : array(), $block, $node->nid, $vote);
 }
 
 /**
@@ -614,6 +647,8 @@ function poll_cancel($form, &$form_state
   $node = node_load($form['#nid']);
   global $user;
 
+  $vote = poll_fetch_vote($node);
+
   if ($user->uid) {
     db_query('DELETE FROM {poll_votes} WHERE nid = %d and uid = %d', $node->nid, $user->uid);
   }
@@ -622,7 +657,8 @@ function poll_cancel($form, &$form_state
   }
 
   // Subtract from the votes.
-  db_query("UPDATE {poll_choices} SET chvotes = chvotes - 1 WHERE nid = %d AND chorder = %d", $node->nid, $node->vote);
+  db_query("UPDATE {poll_choices} SET chvotes = chvotes - 1 WHERE nid = %d AND chorder = %d", $node->nid, $vote);
+  cache_clear_all($node->nid, 'cache_node');
 }
 
 /**
