? pluggable_storage.patch
? votingapi_pluggable.patch
Index: votingapi.api.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/votingapi/Attic/votingapi.api.php,v
retrieving revision 1.1.2.1.2.1
diff -u -p -r1.1.2.1.2.1 votingapi.api.php
--- votingapi.api.php	1 Jul 2009 07:26:12 -0000	1.1.2.1.2.1
+++ votingapi.api.php	21 May 2010 10:14:12 -0000
@@ -160,4 +160,80 @@ function hook_votingapi_views_formatters
   if ($field->field == 'tag') {
     return array('mymodule_funky_tags' => t('MyModule tag formatter'));
   }
-}
\ No newline at end of file
+}
+
+/**
+ * Save a vote in the database.
+ *
+ * @param $vote
+ *   See votingapi_add_votes() for the structure of this array, with the
+ *   defaults loaded from votingapi_prep_vote().
+ */
+function hook_votingapi_storage_add_vote(&$vote) {
+  _mongodb_votingapi_prepare_vote($criteria);
+  mongodb_collection('votingapi_vote')->insert($vote);
+}
+
+/**
+ * Delete votes from the database.
+ *
+ * @param $votes
+ *   An array of votes to delete. Minimally, each vote must have the 'vote_id'
+ *   key set.
+ * @param $vids
+ *   A list of the 'vote_id' values from $voes.
+ */
+function hook_votingapi_storage_delete_votes($votes, $vids) {
+  mongodb_collection('votingapi_vote')->delete(array('vote_id' => array('$in' => array_map('intval', $vids))));
+}
+
+/**
+ * Select invidual votes from the database
+ *
+/**
+ * Select individual votes from the database.
+ *
+ * @param $criteria
+ *   A keyed array used to build the select query. Keys can contain
+ *   a single value or an array of values to be matched.
+ *   $criteria['vote_id']       (If this is set, all other keys are skipped)
+ *   $criteria['entity_id']
+ *   $criteria['entity_type']
+ *   $criteria['value_type']
+ *   $criteria['tag']
+ *   $criteria['uid']
+ *   $criteria['vote_source']
+ *   $criteria['timestamp']   If this is set, records with timestamps
+ *      GREATER THAN the set value will be selected. Defaults to
+ *      REQUEST_TIME - variable_get('votingapi_anonymous_window', 3600); if
+ *      the anonymous window is above zero.
+ * @param $limit
+ *   An integer specifying the maximum number of votes to return. 0 means
+ *   unlimited and is the default.
+ * @return
+ *   An array of votes matching the criteria.
+ */
+function hook_votingapi_storage_select_votes($criteria, $limit) {
+  _mongodb_votingapi_prepare_vote($criteria);
+  $find = array();
+  foreach ($criteria as $key => $value) {
+    $find[$key] = is_array($value) ? array('$in' => $value) : $value;
+  }
+  $cursor = mongodb_collection('votingapi_vote')->find($find);
+  if (!empty($limit)) {
+    $cursor->limit($limit);
+  }
+  $votes = array();
+  foreach ($cursor as $vote) {
+    $votes[] = $vote;
+  }
+  return $votes;
+}
+
+/**
+ * TODO
+ *
+ */
+function hook_votingapi_storage_standard_results($entity_id, $entity) {
+  // TODO
+}
Index: votingapi.drush.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/votingapi/Attic/votingapi.drush.inc,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 votingapi.drush.inc
--- votingapi.drush.inc	27 Jan 2010 01:30:52 -0000	1.1.2.1
+++ votingapi.drush.inc	21 May 2010 10:14:12 -0000
@@ -106,7 +106,7 @@ function votingapi_generate_votes($entit
   $results = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
 
   foreach ($results as $entity) {
-    _votingapi_cast_votes($entity_type, $entity->{$entity_id_column}, $options['age'], $uids, $vote_type);
+    _votingapi_cast_votes($entity_type, $entity[$entity_id_column], $options['age'], $uids, $vote_type);
   }
 }
 
@@ -115,19 +115,22 @@ function votingapi_generate_votes($entit
  */
 function _votingapi_cast_votes($etype, $eid, $timestamp = 0, $uids = array(), $style = 'percent') {
   $votes = array();
+  static $tags;
+  if (!isset($tags)) {
+    $tags = explode(' ', devel_create_greeking(30));
+  }
   foreach ($uids as $uid) {
     switch ($style) {
       case 'percent':
-        if (rand(0, 2)) {
-          $votes[] = array(
-            'uid' => $uid,
-            'entity_type' => $etype,
-            'entity_id' => $eid,
-            'value_type' => 'percent',
-            'timestamp' => REQUEST_TIME - rand(0, REQUEST_TIME - $timestamp),
-            'value' => rand(1, 5) * 20,
-          );
-        }
+        $votes[] = array(
+          'uid' => $uid,
+          'entity_type' => $etype,
+          'entity_id' => $eid,
+          'value_type' => 'percent',
+          'timestamp' => REQUEST_TIME - rand(0, REQUEST_TIME - $timestamp),
+          'value' => mt_rand(1, 5) * 20,
+          'tag' => $tags[mt_rand(0, 30)],
+        );
         break;
       case 'points':
         if (rand(0, 3)) {
@@ -169,7 +172,7 @@ function drush_votingapi_recalculate($en
   }
 
   drush_log($message, 'success');
-} 
+}
 
 
 /**
@@ -179,7 +182,7 @@ function drush_votingapi_flush($entity_t
   if (drush_confirm(dt("Delete @type voting data?", array('@type' => empty($entity_type) ? dt('all') : $entity_type)))) {
     $cache = db_delete('votingapi_cache');
     $votes = db_delete('votingapi_vote');
-  
+
     if (!empty($entity_type)) {
       $cache->condition('entity_type', $entity_type);
       $votes->condition('entity_type', $entity_type);
@@ -188,10 +191,10 @@ function drush_votingapi_flush($entity_t
       $cache->condition('entity_id', $entity_id);
       $votes->condition('entity_id', $entity_id);
     }
-  
+
     $cache->execute();
     $votes->execute();
-  
+
     drush_log(t('Flushed vote data for @type entities.', array('@type' => empty($entity_type) ? t('all') : $entity_type)), 'success');
   }
-}
\ No newline at end of file
+}
Index: votingapi.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/votingapi/votingapi.module,v
retrieving revision 1.46.2.23.2.6
diff -u -p -r1.46.2.23.2.6 votingapi.module
--- votingapi.module	27 Jan 2010 02:39:31 -0000	1.46.2.23.2.6
+++ votingapi.module	21 May 2010 10:14:13 -0000
@@ -183,6 +183,34 @@ function votingapi_current_user_identifi
 }
 
 /**
+ * Implementation of hook_votingapi_storage_add_vote().
+ */
+function votingapi_votingapi_storage_add_vote(&$vote) {
+  drupal_write_record('votingapi_vote', $vote);
+}
+
+/**
+ * Implementation of hook_votingapi_storage_delete_votes().
+ */
+function votingapi_votingapi_storage_delete_votes($votes, $vids) {
+  db_delete('votingapi_vote')->condition('vote_id', $vids, 'IN')->execute();
+}
+
+/**
+ * Implementation of hook_votingapi_storage_select_votes().
+ */
+function votingapi_votingapi_storage_select_votes($criteria, $limit) {
+  $query = db_select('votingapi_vote')->fields('votingapi_vote');
+  foreach ($criteria as $key => $value) {
+    $query->condition($key, $value, is_array($value) ? 'IN' : '=');
+  }
+  if (!empty($limit)) {
+    $query->range(0, $limit);
+  }
+  return $query->execute()->fetchAll(PDO::FETCH_ASSOC);
+}
+
+/**
  * Save a collection of votes to the database.
  *
  * This function does most of the heavy lifting for VotingAPI the main
@@ -213,9 +241,10 @@ function votingapi_add_votes(&$votes) {
   if (!empty($votes['entity_id'])) {
     $votes = array($votes);
   }
+  $function = variable_get('votingapi_storage_module', 'votingapi') . '_votingapi_storage_add_vote';
   foreach ($votes as $key => $vote) {
     _votingapi_prep_vote($vote);
-    drupal_write_record('votingapi_vote', $vote);
+    $function($vote);
     $votes[$key] = $vote;
   }
   module_invoke_all('votingapi_insert', $votes);
@@ -265,7 +294,8 @@ function votingapi_delete_votes($votes =
     foreach ($votes as $vote) {
       $vids[] = $vote['vote_id'];
     }
-    db_delete('votingapi_vote')->condition('vote_id', $vids, 'IN')->execute();
+    $function = variable_get('votingapi_storage_module', 'votingapi') . '_votingapi_storage_delete_votes';
+    $function($votes, $vids);
   }
 }
 
@@ -311,14 +341,8 @@ function votingapi_select_votes($criteri
   if (!empty($criteria['vote_source']) && $anon_window > 0) {
     $criteria['timestamp'] = REQUEST_TIME - $anon_window;
   }
-  $query = db_select('votingapi_vote')->fields('votingapi_vote');
-  foreach ($criteria as $key => $value) {
-    $query->condition($key, $value, is_array($value) ? 'IN' : '=');
-  }
-  if (!empty($limit)) {
-    $query->range(0, $limit);
-  }
-  return $query->execute()->fetchAll(PDO::FETCH_ASSOC);
+  $function = variable_get('votingapi_storage_module', 'votingapi') . '_votingapi_storage_select_votes';
+  return $function($criteria, $limit);
 }
 
 /**
@@ -379,9 +403,10 @@ function votingapi_recalculate_results($
       ->condition('entity_type', $entity_type)
       ->condition('entity_id', $entity_id)
       ->execute();
-      
+
+    $function = variable_get('votingapi_storage_module', 'votingapi') . '_votingapi_storage_standard_results';
     // Bulk query to pull the majority of the results we care about.
-    $cache = _votingapi_get_standard_results($entity_type, $entity_id);
+    $cache = $function($entity_type, $entity_id);
 
     // Give other modules a chance to alter the collection of votes.
     drupal_alter('votingapi_results', $cache, $entity_type, $entity_id);
@@ -479,7 +504,7 @@ function votingapi_metadata($reset = FAL
 /**
  * Builds the default VotingAPI results for the three supported voting styles.
  */
-function _votingapi_get_standard_results($entity_type, $entity_id) {
+function votingapi_votingapi_storage_standard_results($entity_type, $entity_id) {
   $cache = array();
 
   $sql  = "SELECT v.value_type, v.tag, ";
@@ -550,4 +575,4 @@ function _votingapi_prep_vote(&$vote) {
       'prepped' => TRUE
     );
   }
-}
\ No newline at end of file
+}
Index: tests/votingapi.test
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/votingapi/tests/Attic/votingapi.test,v
retrieving revision 1.1.2.3.2.2
diff -u -p -r1.1.2.3.2.2 votingapi.test
--- tests/votingapi.test	20 Jul 2009 22:24:46 -0000	1.1.2.3.2.2
+++ tests/votingapi.test	21 May 2010 10:14:13 -0000
@@ -48,9 +48,9 @@ class VotingAPITestCase extends DrupalWe
     $nid = variable_get('votingapi_nid1', NULL);
     $value = '85';
     // The minimum required fields according to the documentation are
-    // content_id and value.
+    // entity_id and value.
     $vote = array(
-      'content_id' => $nid,
+      'entity_id' => $nid,
       'value' => $value
     );
     try {
@@ -60,7 +60,7 @@ class VotingAPITestCase extends DrupalWe
       $this->assertTrue(REQUEST_TIME - $result[0]['timestamp'] < 2, t('The timestamp should be less than 2 seconds ago.'));
     }
     catch (Exception $e) {
-      $this->fail(t('Could not add a vote with only content_id and value.'));
+      $this->fail(t('Could not add a vote with only entity_id and value.'));
       return;
     }
   }
@@ -72,9 +72,9 @@ class VotingAPITestCase extends DrupalWe
     global $user;
     $value = '7';
     $nid = variable_get('votingapi_nid1', NULL);
-    $vote = array('content_id' => $nid,
+    $vote = array('entity_id' => $nid,
       'value' => $value,
-      'content_type' => 'node');
+      'entity_type' => 'node');
     try {
       $result = votingapi_add_votes($vote);
       // Test that the result has its fields set appropriately.
@@ -104,8 +104,8 @@ class VotingAPITestCase extends DrupalWe
     try {
       for ($index = 0; $index < count($values); $index++) {
         $votes[$index] = array();
-        $votes[$index]['content_type'] = 'node';
-        $votes[$index]['content_id'] = $nid;
+        $votes[$index]['entity_type'] = 'node';
+        $votes[$index]['entity_id'] = $nid;
         $votes[$index]['uid'] = $users[$index]->uid;
         $votes[$index]['value'] = $values[$index];
       }
@@ -122,7 +122,7 @@ class VotingAPITestCase extends DrupalWe
     $this->validateVoteCounts('testAddVote()', $vote_results, $nid, $values);
   }
 
-  function validateVote($prefix, $vote, $content_id, $value, $content_type = 'node',
+  function validateVote($prefix, $vote, $entity_id, $value, $entity_type = 'node',
     $uid = NULL, $value_type = 'percent', $tag = 'vote', $vote_source = NULL) {
     global $user;
     if ($vote_source == NULL) {
@@ -130,9 +130,9 @@ class VotingAPITestCase extends DrupalWe
     }
     $prefix_array = array('@prefix' => $prefix);
     for ($index = 0; $index < count($vote); $index++) {
-      $this->assertTrue($vote[$index]['content_id'] == $content_id, t('@prefix: content_id should match.', $prefix_array));
+      $this->assertTrue($vote[$index]['entity_id'] == $entity_id, t('@prefix: entity_id should match.', $prefix_array));
       $this->assertTrue($vote[$index]['value'] == $value[$index], t('@prefix: value should match.', $prefix_array));
-      $this->assertTrue($vote[$index]['content_type'] == $content_type, t('@prefix: content_type should match, default = "node".', $prefix_array));
+      $this->assertTrue($vote[$index]['entity_type'] == $entity_type, t('@prefix: entity_type should match, default = "node".', $prefix_array));
       $this->assertTrue($vote[$index]['value_type'] == $value_type, t('@prefix: value_type should match, default= "percent".', $prefix_array));
       $this->assertTrue($vote[$index]['tag'] == $tag, t('@prefix: tag should match, default =  "vote".', $prefix_array));
       $this->assertTrue($vote[$index]['vote_source'] == $vote_source, t('@prefix: vote_source should match, default = ip address.', $prefix_array));
@@ -142,7 +142,7 @@ class VotingAPITestCase extends DrupalWe
     }
   }
 
-  function validateVoteCounts($prefix, $votes, $content_id, $values, $content_type = 'node',
+  function validateVoteCounts($prefix, $votes, $entity_id, $values, $entity_type = 'node',
     $value_type = 'percent', $tag = 'vote') {
       $count_summary = 0;
       $average_summary = 1;
@@ -172,10 +172,10 @@ class VotingAPITestCase extends DrupalWe
           $prefix_array['@summary_desc'] = $summary['function'] . ' summary';
           $this->assertFalse(TRUE, t('@prefix: Unknown summary type @summary.', $prefix_array));
         }
-        $this->assertTrue($summary['content_type'] == $content_type,
-          t('@prefix: (@summary_desc) content_type should match, default = "node"', $prefix_array));
-      $this->assertTrue($summary['content_id'] == $content_id,
-        t('@prefix: (@summary_desc) content_id should match', $prefix_array));
+        $this->assertTrue($summary['entity_type'] == $entity_type,
+          t('@prefix: (@summary_desc) entity_type should match, default = "node"', $prefix_array));
+      $this->assertTrue($summary['entity_id'] == $entity_id,
+        t('@prefix: (@summary_desc) entity_id should match', $prefix_array));
       $this->assertTrue($summary['value_type'] == $value_type,
         t('@prefix: (@summary_desc) value_type should match.', $prefix_array));
       $this->assertTrue($summary['tag'] == $tag,
