? updown.patch
Index: updown-active-widget.tpl.php
===================================================================
RCS file: updown-active-widget.tpl.php
diff -N updown-active-widget.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ updown-active-widget.tpl.php	22 Aug 2008 01:52:12 -0000
@@ -0,0 +1,71 @@
+<?php
+// $Id$
+
+/**
+ * @file updown-active-widget.tpl.php
+ * Default theme implementation to display the active updown widget.
+ *
+ * Available variables:
+ * - $node: The node object.
+ * - $user: The user object.
+ * - $current_score: The current score.
+ * - $user_voted: Whether this user has voted.
+ * - $teaser: Whether this is displayed as a teaser.
+ * - $can_unvote: Whether the user can undo their vote.
+ *
+ * @see template_preprocess_updown_active_widget()
+ */
+?>
+<?php
+  $vote_up_uri = base_path() .'node/'. $node->nid .'/vote/'.UPDOWN_VALUE_HIGH;
+  $vote_down_uri = base_path() .'node/'. $node->nid .'/vote/'.UPDOWN_VALUE_LOW;
+  $vote_undo_uri = base_path() .'node/'. $node->nid .'/vote/'.UPDOWN_VALUE_UNVOTE;
+  $vote_class = $user_voted ? 'voted' : 'voting';
+?>
+<script type="text/javascript">
+  jQuery(document).ready(function() {
+    currentScore = $('#updown-widget-<?php print $node->nid ?>').children('.updown-score').children('.updown-current-score');
+    voteElement = $('#updown-widget-<?php print $node->nid ?>').children('.updown-vote');
+    <?php if ($can_unvote) : ?>
+      voteUndoElement = $('#updown-widget-<?php print $node->nid ?>').children('.updown-voteundo');
+    <?php endif; ?>
+    
+    // clicking on the '+' or '-' buttons
+    voteElement.children().children('a').click(function() {
+      $.get($(this).attr('href'), function(data) {
+       currentScore.html(data);
+       voteElement.hide();
+       <?php if ($can_unvote) : ?>
+        voteUndoElement.show();
+       <?php endif; ?>
+      });
+      
+      // disable the normal link
+      return false;
+    });
+    
+    // clicking on the 'undo' button
+    voteUndoElement.children('a').click(function() {
+      $.get($(this).attr('href'), function(data) {
+        currentScore.html(data);
+        <?php if ($can_unvote) : ?>
+          voteUndoElement.hide();
+        <?php endif; ?>
+        voteElement.show();
+      });
+      
+      // disable the normal link
+      return false;
+    });
+  });
+</script>
+<div class="updown-widget updown-widget-<?php print $vote_class ?>" id="updown-widget-<?php print $node->nid ?>">
+  <div class="updown-score"><span class="updown-current-score"><?php print $current_score ?></span> score</div>
+  <div class="updown-vote">
+    <div class="updown-voteup"><a href="<?php print $vote_up_uri ?>">+</a></div>
+    <div class="updown-votedown"><a href="<?php print $vote_down_uri ?>">-</a></div>
+  </div>
+  <?php if ($can_unvote) : ?>
+    <div class="updown-voteundo"><a href="<?php print $vote_undo_uri ?>">undo</a></div>
+  <?php endif; ?>
+</div>
Index: updown-inactive-widget.tpl.php
===================================================================
RCS file: updown-inactive-widget.tpl.php
diff -N updown-inactive-widget.tpl.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ updown-inactive-widget.tpl.php	22 Aug 2008 01:52:13 -0000
@@ -0,0 +1,21 @@
+<?php
+// $Id$
+
+/**
+ * @file updown-inactive-widget.tpl.php
+ * Default theme implementation to display the inactive updown widget.
+ *
+ * Available variables:
+ * - $node: The node object.
+ * - $user: The user object.
+ * - $current_score: The current score.
+ * - $user_voted: Whether this user has voted.
+ * - $teaser: Whether this is displayed as a teaser.
+ * - $can_unvote: Whether the user can undo their vote.
+ *
+ * @see template_preprocess_updown_inactive_widget()
+ */
+?>
+<div class="updown-widget">
+  <div class="updown-score"><span class="updown-current-score"><?php print $current_score ?></span> score</div>
+</div>
Index: updown.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/updown/updown.module,v
retrieving revision 1.1
diff -u -p -r1.1 updown.module
--- updown.module	20 Aug 2008 23:35:09 -0000	1.1
+++ updown.module	22 Aug 2008 01:52:13 -0000
@@ -7,52 +7,212 @@
  * ========================================================================
  */
 
+define('UPDOWN_VALUE_HIGH',   100);
+define('UPDOWN_VALUE_LOW',    0);
+define('UPDOWN_VALUE_UNVOTE', 'undo');
+
+/**
+ * Implementation of hook_perm().
+ */
 function updown_perm() {
-  return array('vote on logo');
+  return array('rate content with updown');
 }
 
+/**
+ * Implementation of hook_menu().
+ */
 function updown_menu() {
-  $items['node/%/vote/%'] = array(
+  $items['node/%node/vote/%'] = array(
     'title' => 'Up/Down Vote',
     'type' => MENU_CALLBACK,
-    'page callback' => '_updown_vote',
+    'page callback' => 'updown_node_vote',
     'page arguments' => array(1, 3),
     'access callback' => 'user_access',
-    'access arguments' => array('vote on logo'),
+    'access arguments' => array('rate content with updown'),
   );
   
   return $items;
 }
 
-function _updown_vote($nid, $vote) {
-  if ($vote == 'undo') {
-    _updown_delete_vote($nid);
-  }
-  elseif (is_numeric($nid)) {
-    $node = node_load($nid);
+/**
+ * Implementation of hook_form_alter
+ * Adds updown enaable and position to the node-type configuration form.
+ * 
+ */
+function updown_form_alter(&$form, &$form_state, $form_id) {
+  if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
+    // Goofy hack to get the buttons at the end of the array.
+    $form['workflow']['#weight'] = isset($form['workflow']['#weight']) ? $form['workflow']['#weight'] + 1 : 1;
+    $form['submit']['#weight'] = isset($form['submit']['#weight']) ? $form['submit']['#weight'] + 1 : 1;
+    $form['delete']['#weight'] = isset($form['delete']['#weight']) ? $form['delete']['#weight'] + 1 : 1;
+
+    $form['updown'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('UpDown ratings'),
+      '#collapsible' => TRUE,
+      '#collapsed' => !variable_get('updown_'. $form['#node_type']->type, 0),
+      '#description' => t('To rate this content, enable UpDown rating below.'),
+      //'#theme' => 'updown_node_type_form',
+      '#attributes' => array('id' => 'updown-node-type-form'),
+    );
+
+    $form['updown']['updown'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enable UpDown rating'),
+      '#default_value' => variable_get('updown_'. $form['#node_type']->type, 0),
+      '#return_value' => 1,
+      '#weight' => -5,
+    );
+    
+    $form['updown']['updown_unvote'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Allow users to undo their votes'),
+      '#default_value' => variable_get('updown_unvote_'. $form['#node_type']->type, 0),
+      '#return_value' => 1,
+    );
     
+    $form['updown']['updown_position_teaser'] = array(
+      '#type' => 'select',
+      '#title' => t('Teaser display'),
+      '#default_value' => variable_get('updown_position_teaser_'. $form['#node_type']->type, 'hidden'),
+      '#options' => array(
+        'above' => t('Clickable widget above teaser'),
+        'below' => t('Clickable widget below teaser'),
+        'above_static' => t('Static display above teaser'),
+        'below_static' => t('Static display below teaser'),
+        'link' => t('Teaser link to full node widget'),
+        'hidden' => t('<Hidden>'),
+      ),
+    );
+
+    $form['updown']['updown_position'] = array(
+      '#type' => 'select',
+      '#title' => t('Full node display'),
+      '#default_value' => variable_get('updown_position_'. $form['#node_type']->type, 'below'),
+      '#options' => array(
+        'above' => t('Clickable widget above node body'),
+        'below' => t('Clickable widget below node body'),
+        'above_static' => t('Static display above node body'),
+        'below_static' => t('Static display below node body'),
+        'hidden' => t('<Hidden>'),
+      ),
+    );
+    
+    $form['#submit'][] = 'updown_node_type_form_submit';
+  }
+}
+
+/**
+ * Additional submit handler for the node type form.
+ */
+function updown_node_type_form_submit($form, &$form_state) {
+  // Do not save any updown variables if updown is disabled.
+  if (isset($form_state['values']['updown']) && $form_state['values']['updown'] === 0) {
+    foreach ($form_state['values'] as $key => $value) {
+      if (strpos($key, 'updown') === 0) {
+        variable_del($key .'_'. $form_state['values']['type']);
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_node_types().
+ */
+function updown_node_type($op, $info) {
+  $type = $info->type;
+  $variables = array(
+    'updown',
+  );
+
+  // Be responsible and cleanup unneeded variables.
+  if ($op == 'delete') {
+    foreach ($variables as $variable) {
+      variable_del($variable .'_'. $type);
+    }
+  }
+  // When changing the type name, update the variables.
+  elseif ($op == 'update' && !empty($info->old_type) && $info->old_type != $info->type) {
+    foreach ($variables as $variable) {
+      $value = variable_get($variable .'_'. $type, -1);
+      if ($value != -1) {
+        variable_del($variable .'_'. $type);
+        variable_set($variable .'_'. $type, $value);
+      }
+    }
+  }
+}
+
+/**
+ * Implementation of hook_nodeapi()
+ * 
+ * Adds the updown widget to the node view.
+ */
+function updown_nodeapi(&$node, $op, $teaser, $page) {
+  switch ($op) {
+    case 'view':
+      if ($node->build_mode != NODE_BUILD_PREVIEW && !isset($node->modr8_form_teaser) && variable_get('updown_'. $node->type, 0)) {
+        if ($teaser) {
+          $position = variable_get('updown_position_teaser_'. $node->type, 'above');
+        }
+        else {
+          $position = variable_get('updown_position_'. $node->type, 'above');
+        }
+        switch ($position) {
+          case 'above':
+          case 'below':
+            if (user_access('rate content with updown')) {
+              $node->content['updown_widget'] = array(
+                '#value' => theme('updown_active_widget', $node, $teaser),
+                '#weight' => $position == 'above' ? -10 : 50,
+              );
+              break;
+            } // Fall through to static if not allowed to rate.
+          case 'above_static':
+          case 'below_static':
+            $node->content['updown_widget'] = array(
+              '#value' => theme('updown_inactive_widget', $node, $teaser),
+              '#weight' => $position == 'above_static' ? -10 : 50,
+            );
+            break;
+          default:
+            // We'll do nothing.
+            break;
+        }
+      }
+      break;
+  }
+}
+
+function updown_node_vote($node, $vote) {
+  if ($vote == UPDOWN_VALUE_UNVOTE) {
+    if (variable_get('updown_unvote_'. $node->type, 0)) {
+      _updown_delete_vote($node);
+    }
+  }
+  else {
     // additional validity check
-    if (($node->type == 'logo' || $node->type = 'session_proposal') && is_numeric($vote) && $vote <= 100 && $vote >= 0) {
+    if (variable_get('updown_'. $node->type, 0) && is_numeric($vote) && $vote <= UPDOWN_VALUE_HIGH && $vote >= UPDOWN_VALUE_LOW) {
       global $user;
       
       // assemble the vote array
-      $vote = array(array(
+      $vote_info = array(array(
         'content_type' => 'node',
-        'content_id' => $nid,
+        'content_id' => $node->nid,
         'value_type' => 'percent',
         'value' => $vote,
         'uid' => $user->uid,
       ));
       
       // log the vote
-      votingapi_set_votes($vote);
+      votingapi_set_votes($vote_info);
     }
   }
   
   // if the request came from a link, return the user to the page they were on;
   // otherwise, return the new score
   if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
-    exit(print(_updown_get_current_score($nid)));
+    exit(print(_updown_get_current_score($node)));
   }
   else {
     header('Location: '. $_SERVER['HTTP_REFERER']);
@@ -60,45 +220,40 @@ function _updown_vote($nid, $vote) {
   }
 }
 
-function _updown_delete_vote($nid) {
-  // check the nid for validity
-  if (is_numeric($nid)) {
-    $node = node_load($nid);
+function _updown_delete_vote($node) {
+  // additional validity check 
+  if (variable_get('updown_'. $node->type, 0)) {
+    global $user;
     
-    // additional validity check 
-    if (in_array($node->type, array('logo', 'session_proposal'))) {
-      global $user;
-      
-      $votes = array();
-      $criteria = array(
-        'content_type' => 'node',
-        'content_id' => $nid,
-        'uid' => $user->uid,
-      );
-      
-      $votes = votingapi_select_votes($criteria);
-      votingapi_delete_votes($votes);
-    }
+    $votes = array();
+    $criteria = array(
+      'content_type' => 'node',
+      'content_id' => $nid,
+      'uid' => $user->uid,
+    );
+    
+    $votes = votingapi_select_votes($criteria);
+    votingapi_delete_votes($votes);
   }
   
-  return _updown_get_current_score($nid);
+  return _updown_get_current_score($node);
 }
 
-function _updown_get_current_score($nid) {
+function _updown_get_current_score($node) {
   $current_score = 0;
   
   $criteria = array(
     'content_type' => 'node',
-    'content_id' => $nid,
+    'content_id' => $node->nid,
   );
   
   $votes = votingapi_select_votes($criteria);
   
   foreach ($votes as $vote) {
-    if ($vote['value'] == 100) {
+    if ($vote['value'] == UPDOWN_VALUE_HIGH) {
       ++$current_score;
     }
-    elseif ($vote['value'] == 0) {
+    elseif ($vote['value'] == UPDOWN_VALUE_LOW) {
       --$current_score;
     }
   }
@@ -106,13 +261,17 @@ function _updown_get_current_score($nid)
   return $current_score;
 }
 
-function _updown_user_voted($nid) {
+function _updown_user_voted($node, $account=NULL) {
   global $user;
   
+  if (empty($account)) {
+    $account = $user;
+  }
+  
   $criteria = array(
     'content_type' => 'node',
-    'content_id' => $nid,
-    'uid' => $user->uid,
+    'content_id' => $node->nid,
+    'uid' => $account->uid,
   );
   
   return count(votingapi_select_votes($criteria));
@@ -128,85 +287,47 @@ function _updown_user_voted($nid) {
 
 function updown_theme() {
   return array(
-    'updown_widget' => array(
-      'arguments' => array('nid' => NULL, 'type' => NULL),
-    ),
     'updown_inactive_widget' => array(
-      'arguments' => array('nid' => NULL),
+      'template' => 'updown-inactive-widget',
+      'arguments' => array('node' => NULL, 'teaser' => NULL, 'user' => NULL),
     ),
     'updown_active_widget' => array(
-      'arguments' => array('nid' => NULL),
+      'template' => 'updown-active-widget',
+      'arguments' => array('node' => NULL, 'teaser' => NULL, 'user' => NULL),
     ),
   );
 }
 
-function theme_updown_widget($nid, $type) {
-  // no voting for anonymous users
+/**
+ * Process variables for updown-active-widget.tpl.php.
+ */
+function template_preprocess_updown_active_widget(&$variables) {
   global $user;
-  if (!$user->uid || $type == 'logo') {
-    return theme('updown_inactive_widget', $nid);
-  }
-  else {
-    return theme('updown_active_widget', $nid);
+  
+  $node = $variables['node'];
+  
+  if (empty($variables['user'])) {
+    $variables['user'] = $user;
   }
-}
-
-function theme_updown_inactive_widget($nid) {
-  $current_score = _updown_get_current_score($nid);
   
-  return <<<MARKUP
-<div class="updown-widget">
-  <div class="updown-score"><span class="updown-current-score">{$current_score}</span> score</div>
-</div>
-MARKUP;
+  $variables['current_score'] = _updown_get_current_score($node->nid);
+  $variables['user_voted'] = _updown_user_voted($node->nid);
+  $variables['can_unvote'] = variable_get('updown_unvote_'. $node->type, 0);
 }
 
-function theme_updown_active_widget($nid) {
-  $current_score = _updown_get_current_score($nid);
-  $vote_up_uri = base_path() .'node/'. $nid .'/vote/100';
-  $vote_down_uri = base_path() .'node/'. $nid .'/vote/0';
-  $vote_undo_uri = base_path() .'node/'. $nid .'/vote/undo';
-  $vote_class = _updown_user_voted($nid) ? 'voted' : 'voting';
+/**
+ * Process variables for updown-inactive-widget.tpl.php.
+ */
+function template_preprocess_updown_inactive_widget(&$variables) {
+  global $user;
   
-  return <<<MARKUP
-<script type="text/javascript">
-  jQuery(document).ready(function() {
-    currentScore = $('#updown-widget-{$nid}').children('.updown-score').children('.updown-current-score');
-    voteElement = $('#updown-widget-{$nid}').children('.updown-vote');
-    voteUndoElement = $('#updown-widget-{$nid}').children('.updown-voteundo');
-    
-    // clicking on the '+' or '-' buttons
-    voteElement.children().children('a').click(function() {
-      $.get($(this).attr('href'), function(data) {
-       currentScore.html(data);
-       voteElement.hide();
-       voteUndoElement.show();
-      });
-      
-      // disable the normal link
-      return false;
-    });
-    
-    // clicking on the 'undo' button
-    voteUndoElement.children('a').click(function() {
-      $.get($(this).attr('href'), function(data) {
-        currentScore.html(data);
-        voteUndoElement.hide();
-        voteElement.show();
-      });
-      
-      // disable the normal link
-      return false;
-    });
-  });
-</script>
-<div class="updown-widget updown-widget-{$vote_class}" id="updown-widget-{$nid}">
-  <div class="updown-score"><span class="updown-current-score">{$current_score}</span> score</div>
-  <div class="updown-vote">
-    <div class="updown-voteup"><a href="{$vote_up_uri}">+</a></div>
-    <div class="updown-votedown"><a href="{$vote_down_uri}">-</a></div>
-  </div>
-  <div class="updown-voteundo"><a href="{$vote_undo_uri}">undo</a></div>
-</div>
-MARKUP;
+  $node = $variables['node'];
+  
+  if (empty($variables['user'])) {
+    $variables['user'] = $user;
+  }
+  
+  $variables['current_score'] = _updown_get_current_score($node->nid);
+  $variables['user_voted'] = _updown_user_voted($node->nid);
+  $variables['can_unvote'] = variable_get('updown_unvote_'. $node->type, 0);
 }
