? .svn
? 737274-b.patch
? 737274.patch
? cvs.diff
? dec.diff
? decisions.hold
? latest-cvs.diff
? latest-svn.diff
? latest.diff
? ranking.module.patch
? scratch.php
? selection.hold
? modes/.svn
? po/.svn
? tests/.svn
? translations/.svn
Index: decisions.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/decisions/decisions.module,v
retrieving revision 1.239
diff -u -p -r1.239 decisions.module
--- decisions.module	8 Mar 2010 15:01:19 -0000	1.239
+++ decisions.module	15 Mar 2010 15:30:37 -0000
@@ -591,9 +591,55 @@ function decisions_algorithms($mode) {
 }
 
 /*
- * Return the decisions votes for a nid from a particular user (or IP address).
+ * Return the decisions vote for a nid from a particular user (or IP address).
  */
-function decisions_get_votes($nid, $uid = 0) {
+function decisions_get_vote($nid, $uid = 0) {
+  $fallback = variable_get('decisions_voted_cache_fallback', 1);
+  $vote_cache = decisions_get_vote_cache($nid, $uid);
+
+  if (empty($vote_cache)) {
+    if ($fallback) {
+      return decisions_get_vote_direct($nid, $uid);
+    }
+    else {
+      return FALSE;
+    }
+  }
+  return $vote_cache;
+}
+
+/*
+ * Check whether the user voted on a Decisions node
+ * according to the decisions cache.
+ * See decisions_votingapi_insert() for more information.
+ */
+function decisions_get_vote_cache($nid, $uid) {
+  $identifier = $uid > 0 ? $uid : ip_address();
+  $cache = cache_get('decisions-'. $nid . '-' . $identifier, 'cache_decisions');
+  if (empty($cache) || !is_object($cache)) {
+    return FALSE;
+  }
+  if ($uid == 0) {
+    //Respect the VotingAPI anonymous window.
+    $in_window = time() <= $cache->created + variable_get('votingapi_anonymous_window', 3600);
+    if (!$in_window) {
+      return FALSE;
+    }
+  }
+  return unserialize($cache->data);
+}
+
+/*
+ * Convenience wrapper around votingapi_select_votes.
+ * @param int $nid
+ *   The node id voted upon.
+ * @param int $uid.
+ *   The user id of the user who voted.
+ * @return array $vote
+ *   The VotingAPI vote array, if one exists.
+ */
+function decisions_get_vote_direct($nid, $uid) {
+
   $criteria['content_id'] = $nid;
   $criteria['content_type'] = 'decisions';
   //We include the UID for both authenticated an anonymous users so that voting and then logging out doesn't preclude anons from voting.
@@ -602,9 +648,9 @@ function decisions_get_votes($nid, $uid 
   if ($uid == 0) {
     $criteria['vote_source'] = ip_address();
   }
-  return votingapi_select_votes($criteria);
+  $vote = votingapi_select_votes($criteria);
+  return array_shift($vote);
 }
-
 /*
  * Return results for a given nid.
  */
@@ -622,7 +668,7 @@ function decisions_get_results($nid) {
  */
 function decisions_cancel($nid) {
   if ($node = node_load($nid)) {
-    if ($node->voted && $node->active) {
+    if (!empty($node->vote) && $node->active) {
       $criteria = votingapi_current_user_identifier();
       $criteria['content_type'] = 'decisions';
       $criteria['content_id'] = $node->nid;
@@ -802,7 +848,7 @@ function _decisions_is_open($node) {
 function _decisions_can_vote($node, $user = NULL) {
   return (_decisions_is_open($node) &&
     // user should not have already voted
-    !$node->voted &&
+    empty($node->vote) &&
     // user must be eligible to vote
     _decisions_eligible($node, $user));
 }
@@ -1103,9 +1149,8 @@ function decisions_load($node) {
     $decision->choice[$choice['vote_offset']] = $choice;  
   }
   $decision->choices = count($decision->choice);
-
-  // See if user has voted
-  $decision->voted = decisions_voted($node->nid, $user->uid);
+  $vote = decisions_get_vote($node->nid, $user->uid);
+  $decision->vote = $vote;
   return $decision;
 }
 
@@ -1327,7 +1372,6 @@ function decisions_view(&$node, $teaser 
   }
   $node->content['decisions']['status']['#value'] = $status_messages;
   $node->content['decisions']['#weight'] = 1;
-
   if (arg(2) != 'results' && _decisions_can_vote($node)) {
     // User hasn't voted and we're not on the results tab
     $mode = _decisions_get_mode($node);
@@ -1342,7 +1386,7 @@ function decisions_view(&$node, $teaser 
   else {
     $node->content['decisions']['#value'] = theme('decisions_view_own_result');
   }
-  if (isset($node->voted) && $node->voted && user_access('cancel own vote') && $node->active) {
+  if (!empty($node->vote) && user_access('cancel own vote') && $node->active) {
     $node->content['decisions']['cancel']['#value'] = drupal_get_form('decisions_cancel_form', $node->nid);
   }
 
@@ -1713,46 +1757,6 @@ function _decisions_randomize_options($c
 }
 
 /*
- * Check whether the user voted on a Decisions node
- * according to the decisions cache.
- * See decisions_votingapi_insert() for more information.
- */
-function decisions_voted_cache($nid, $uid) {
-  $identifier = $uid > 0 ? $uid : ip_address();
-  $cache = cache_get('decisions-'. $nid . '-' . $identifier, 'cache_decisions');
-  if (!isset($cache) || !is_object($cache)) {
-    return FALSE;
-  }
-  if ($uid == 0) {
-    //Respect the VotingAPI anonymous window.
-    $in_window = time() <= $cache->created + variable_get('votingapi_anonymous_window', 3600);
-    if (!$in_window) {
-      return FALSE;
-    }
-  }
-  return TRUE;
-}
-
-/*
- * Check whether the given user voted on a particular node.
- */
-function decisions_voted($nid, $uid) {
-  $fallback = variable_get('decisions_voted_cache_fallback', 1);
-  $voted_cache = decisions_voted_cache($nid, $uid);
-  if ($voted_cache) {
-    return TRUE;
-  }
-  else {
-    if ($fallback) {
-      $votes = decisions_get_votes($nid, $uid);
-      return empty($votes) ? FALSE : TRUE;
-    }
-    else {
-      return FALSE;
-    }
-  }
-}
-/*
  * Implementation of hook_votingapi_insert().
  * Sets a simple cache item that we can use to check if a user voted.
  * This can be more performant on sites that use a fast cache store, like Memcache.
@@ -1761,8 +1765,8 @@ function decisions_votingapi_insert($vot
   foreach ($votes as $vote) {
     if (isset($vote['content_type']) && $vote['content_type'] == 'decisions' ) {
       $identifier = $vote['uid'] > 0 ? $vote['uid'] : ip_address();
+      cache_set('decisions-'. $vote['content_id'] . '-' . $identifier, serialize($vote), 'cache_decisions');
     }
-    cache_set('decisions-'. $vote['content_id'] . '-' . $identifier, $vote['vote_id'], 'cache_decisions');
   }
 }
 
Index: modes/selection.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/decisions/modes/selection.module,v
retrieving revision 1.28
diff -u -p -r1.28 selection.module
--- modes/selection.module	8 Mar 2010 15:01:19 -0000	1.28
+++ modes/selection.module	15 Mar 2010 15:30:37 -0000
@@ -10,9 +10,10 @@
  * Implementation of hook_menu().
  */
 function selection_menu() {
-  $items['decisions_selection/vote'] = array(
+  $items['decisions_selection/vote/%node'] = array(
     'title' => 'Vote',
     'page callback' => 'selection_vote',
+    'page arguments' => array(2),
     'access arguments' => array('vote on decisions'),
     'type' => MENU_CALLBACK,
   );
@@ -64,10 +65,11 @@ function selection_decisions_algorithms(
  * @return
  * Returns HTML for AHAH voting, or redirects to the destination for synchronous voting.
  */
-function selection_vote($nid, $cid) {
+function selection_vote($node, $cid) {
   global $user;
-  if (selection_check_token($_REQUEST['token'], $nid, $cid)) {
-    $valid_cid = db_result(db_query("SELECT label FROM {decisions_choices} WHERE nid = %d AND vote_offset = %d", $nid, $cid));
+  $new_vote = array();
+  if (selection_check_token($_REQUEST['token'], $node->nid, $cid)) {
+    $valid_cid = !empty($node->choice[$cid]['label']);
     if (empty($valid_cid)) {
       if (empty($_REQUEST['ajax'])) {
         drupal_goto(drupal_get_destination());
@@ -76,18 +78,18 @@ function selection_vote($nid, $cid) {
         exit();
       }
     }
-    $voted = decisions_voted($nid, $user->uid);
+    $voted = !empty($node->voted);
     if (!$voted) {
-      $vote = array(
+      $new_vote = array(
         'value' => 1,
         'tag' => $cid,
         'value_type' => 'option',
         'content_type' => 'decisions',
-        'content_id' => $nid,
+        'content_id' => $node->nid,
       );
-      $votes[] = $vote;
+      $votes[] = $new_vote;
       votingapi_add_votes($votes);
-      votingapi_recalculate_results('decisions', $nid);
+      votingapi_recalculate_results('decisions', $node->nid);
     }
     else {
       if (empty($_REQUEST['ajax'])) {
@@ -98,19 +100,19 @@ function selection_vote($nid, $cid) {
         exit();
       }
     }
-    //Render the results
+    // Render the results
     if (empty($_REQUEST['ajax'])) {
-      //Vote confirmation is displayed in the results so that the degradable behavior matches the AHAH behavior.
+      // Vote confirmation is displayed in the results so that the degradable behavior matches the AHAH behavior.
       drupal_goto(drupal_get_destination());
     }
     else {
-      //Sadly, we must reload the node.
-      $node = node_load($nid);
-      print theme('selection_decisions_view_results', $node, FALSE, FALSE, $votes);
+      // We pass along the vote cast in this request so that the user's choice
+      // can be displayed along with the results.
+      print theme('selection_decisions_view_results', $node, FALSE, FALSE, $new_vote);
       exit();
     }
   }
-  //Invalid token.
+  // Invalid token.
   if (empty($_REQUEST['ajax'])) {
     drupal_set_message(t("Invalid token. Please try voting again."));
     drupal_goto(drupal_get_destination());
@@ -231,8 +233,9 @@ function decisions_selection_voting_form
  * Display the selection results.
  * TODO: implement (http://drupal.org/node/48249)
  */
-function selection_decisions_view_results($node, $teaser, $page, $this_vote = array()) {
+function selection_decisions_view_results($node, $teaser, $page, $new_vote = array()) {
   global $user;
+  $vote = !empty($new_vote) ? $new_vote : $node->vote;
   $output = "";
   $results = votingapi_select_results(array('content_id' => $node->nid, 'content_type' => 'decisions'));
   // Count the votes for each choice
@@ -265,12 +268,11 @@ function selection_decisions_view_result
 
     //If AHAH and 1click are enabled, ensure that the fallback behavior shows the same vote confirmation.
     if (variable_get('decisions_1click', 0) && ($node->maxchoices == 1)) {
-      if (empty($this_vote)) {
+      if (!empty($new_vote)) {
         //Fallback behavior.
-        $this_vote = decisions_get_votes($node->nid, $user->uid);
+        $vote = $new_vote;
       }
-      $this_vote = array_shift($this_vote);
-      $vote_label = $node->choice[$this_vote['tag']]['label'];
+      $vote_label = $node->choice[$vote['tag']]['label'];
       $output .= '<span class="status">' . t('You voted: @vote_tag', array('@vote_tag' => $vote_label)) . '</span>';
     }
     $output .= '<div class="poll">';
@@ -390,6 +392,6 @@ function decisions_selection_voting_form
   }
 }
 
-function theme_selection_decisions_view_results($node = NULL, $teaser = FALSE, $page = FALSE, $this_vote = array()) {
-  return selection_decisions_view_results($node, $teaser, $page, $this_vote);
+function theme_selection_decisions_view_results($node = NULL, $teaser = FALSE, $page = FALSE, $new_vote = array()) {
+  return selection_decisions_view_results($node, $teaser, $page, $new_vote);
 }
\ No newline at end of file
Index: tests/selection.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/decisions/tests/selection.test,v
retrieving revision 1.2
diff -u -p -r1.2 selection.test
--- tests/selection.test	8 Mar 2010 15:01:19 -0000	1.2
+++ tests/selection.test	15 Mar 2010 15:30:37 -0000
@@ -1,20 +1,17 @@
 <?php
+// $Id$
 
-// $Id:
 /**
  * @file
  * Tests for the Decisions Module.
  *
- * 
  */
 
 class SelectionTestCase extends DrupalWebTestCase {
   /**
-  * Implementation of getInfo().
-  */
-
+   * Implementation of getInfo().
+   */
   public static function getInfo() {
-
     return array(
       'name' => t('Decisions Selections CRUD'),
       'description' => t('Create, edit, delete a new selection node with two choices'),
@@ -23,14 +20,14 @@ class SelectionTestCase extends DrupalWe
   }
 
   /**
-  * Implementation of setUp().
-  */
+   * Implementation of setUp().
+   */
   function setUp() {
     parent::setUp('selection', 'decisions', 'votingapi');
     variable_set('decisions_1click', 1);
   }
 
-  /*
+  /**
    * Submit a closed 1-click decision, then open it, then close it again,
    * and testing voting as a non administrative user.
    */
@@ -54,12 +51,13 @@ class SelectionTestCase extends DrupalWe
     $selection["choice[2][label]"] = $choice2;
     $selection['settings[active]'] = 0;
     $selection['settings[date][startdate][date][year]'] = '1900';
-    $selection['settings[date][startdate][date][year]'] = '1900';
     $selection['settings[date][noenddate]'] = 1;
     $selection['settings[maxchoices]'] = 1;
     $this->drupalPost('node/add/decisions-selection', $selection, t('Save'));
     $this->assertRaw(t("@type %title has been created.", array('@type' => $type_name, '%title' => $title)), t("@type %title has been created.", array('@type' => $type_name, '%title' => $title)));
-    // We look for "This decision is" because that is the beginning of all closed/inactive text.
+
+    // We look for "This decision is" because that is the beginning of all
+    // closed/inactive text.
     $this->assertText(t('This decision is currently closed'), t("Decision closed text is displayed."));
 
     // Open the decision.
@@ -72,7 +70,8 @@ class SelectionTestCase extends DrupalWe
     $this->assertText($choice1, t("Choice 1 appears for administrators."));
     $this->asserttext($choice2, t("Choice 2 appears for administrators."));
 
-    // Close the decision. Depending on how results are displayed, the choices may or may not appear.
+    // Close the decision. Depending on how results are displayed, the choices
+    // may or may not appear.
     $selection['settings[active]'] = 0;
     $this->drupalPost('node/'. $nid . '/edit', $selection, t('Save'));
     $this->assertRaw(t('This decision is currently closed'), t("Decision closed text is displayed."));
@@ -101,6 +100,7 @@ class SelectionTestCase extends DrupalWe
     $uid = isset($this->loggedInUser->uid) ? $this->loggedInUser->uid : 0;
     $this->drupalGet('node/'. $nid);
     $random = rand(3, 100);
+
     // Verify that the choices appear when the decision is open.
     $this->assertText($choice1, t("Choice 1 appears."));
     $this->asserttext($choice2, t("Choice 2 appears."));
@@ -111,47 +111,47 @@ class SelectionTestCase extends DrupalWe
      // Verify that the vote confirmaton appears
     $this->assertText(t("You voted: @tag", array('@tag' => $choice1)), t("Vote confirmation text appears referencing the selected tag."));
 
-    // Test decisions_voted().
-    // Verify decisions_voted() returns TRUE with the cache fallback on.
+    // Test decisions_get_vote() and the functions it relies upon.
+    // Verify decisions_get_vote() returns an array with the proper vote tag with the cache fallback on.
     variable_set('decisions_cache_fallback', 1);
-    $votedFallback = decisions_voted($nid, $uid);
-    $this->assertTrue($votedFallback, t('decisions_voted() correctly returns TRUE with the cache fallback on.'));
+    $voteFallback = decisions_get_vote($nid, $uid);
+    $this->assertTrue(isset($voteFallback['tag']) && $voteFallback['tag'] == 1, t('decisions_get_vote() correctly returns TRUE with the cache fallback on.'));
 
-    // Verify decisions_voted() returns TRUE with the cache fallback turned off.
+    // Verify decisions_get_vote() returns an array with the proper vote tag with the cache fallback turned off.
     variable_set('decisions_cache_fallback', 0);
-    $votedFallbackOff = decisions_voted($nid, $uid);
-    $this->assertTrue($votedFallbackOff, t('decisions_voted() correctly returns TRUE with the cache fallback off.'));
+    $voteFallbackOff = decisions_get_vote($nid, $uid);
+    $this->assertTrue(isset($voteFallbackOff['tag']) && $voteFallbackOff['tag'] == 1, t('decisions_get_vote() correctly returns TRUE with the cache fallback off.'));
 
-    // Verify decisions_voted() returns FALSE with the cache fallback on.
+    // Verify decisions_get_vote() returns FALSE with the cache fallback on.
     variable_set('decisions_cache_fallback', 1);
-    $votedFallbackFalse = decisions_voted($random, $uid + $random);
-    $this->assertFalse($votedFallbackFalse, t('decisions_voted() correctly returns FALSE with the cache fallback on.'));
+    $voteFallbackFalse = decisions_get_vote($random, $uid + $random);
+    $this->assertFalse($voteFallbackFalse, t('decisions_get_vote() correctly returns FALSE with the cache fallback on.'));
 
-    // Verify decisions_voted() returns FALSE with the cache fallback turned off.
+    // Verify decisions_get_vote() returns FALSE with the cache fallback turned off.
     variable_set('decisions_cache_fallback', 0);
-    $votedFallbackOffFalse = decisions_voted($random, $uid + $random);
-    $this->assertFalse($votedFallbackOffFalse, t('decisions_voted() correctly returns FALSE with the cache fallback off.'));
+    $voteFallbackOffFalse = decisions_get_vote($random, $uid + $random);
+    $this->assertFalse($voteFallbackOffFalse, t('decisions_get_vote() correctly returns FALSE with the cache fallback off.'));
 
     // Verify that the proper Decisions cache item was created when the user voted.
-    $cache = decisions_voted_cache($nid, $uid);
-    $this->assertTrue($cache, t("The Decisions vote cache item was created."));
-    // Pass random values to ensure that decisions_voted_cache() returns FALSE
-    // when the expected cache item does not exist.
-    $noCache = decisions_voted_cache($choice1, 0);
-    $this->assertFalse($noCache, t('decisions_cache correctly returns FALSE.'));
+    $cache = decisions_get_vote_cache($nid, $uid);
+    $this->assertTrue(isset($cache['tag']) && $cache['tag'] == 1, t("The Decisions vote cache item was created with the proper vote tag."));
 
-    // Verify that a vote was registered with the VotingAPI and is returned
-    // by decisions_get_votes().
-    $votes = array();
-    $votes = decisions_get_votes($nid, $uid);
-    $this->assertTrue(isset($votes['0']['vote_id']) && is_numeric($votes['0']['vote_id']), t("decisions_get_votes() returns the VotingAPI vote cast."));
-    $this->assertTrue(isset($votes['0']['tag']) && $votes['0']['tag'] == 1, t("The vote contains the correct VotingAPI tag."));
+    // Pass random values to ensure that decisions_get_vote_cache() returns FALSE
+    // when the expected cache item does not exist.
+    $noCache = decisions_get_vote_cache($choice1, 0);
+    $this->assertFalse($noCache, t('decisions_get_vote_cache() correctly returns FALSE.'));
+    
+    $voteDirect = decisions_get_vote_direct($nid, $uid);
+    $this->assertTrue(isset($voteDirect['tag']) && $voteDirect['tag'] == 1, t("decisions_get_vote_direct() returned a vote with the proper tag."));
   }
+
   /**
    * Set permission.
    *
-   * @param string $role User role to set permissions for.
-   * @param array $permissions Key-value array of permissions to set.
+   * @param string $role
+   *   User role to set permissions for.
+   * @param array $permissions
+   *   Key-value array of permissions to set.
    */
   function setPermission($role, $permissions) {
     // Get role id (rid) for specified role.
