plus1.module in Plus 1 6
Same filename and directory in other branches
A simple +1 voting widget module.
File
plus1.moduleView source
<?php
/**
* @file
* A simple +1 voting widget module.
*/
/**
* Implementation of hook_perm().
*/
function plus1_perm() {
return array(
'rate content',
'administer the voting widget',
);
}
/**
* Implementation of hook_menu().
*/
function plus1_menu() {
$items['plus1/vote/%'] = array(
'title' => t('Vote'),
'page callback' => 'plus1_vote',
'page arguments' => array(
2,
),
'access arguments' => array(
'rate content',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/plus1'] = array(
'title' => t('Plus 1'),
'description' => t('Allows readers to vote on content.'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'plus1_settings',
),
'access arguments' => array(
'administer the voting widget',
),
);
return $items;
}
/**
* Menu callback to configure module settings.
*/
function plus1_settings() {
$form['plus1_nodetypes_fieldset'] = array(
'#type' => 'fieldset',
'#title' => t('Content type settings'),
'#description' => t('Select all node types to which a +1 voting widget can be added.'),
);
$form['plus1_nodetypes_fieldset']['plus1_nodetypes'] = array(
'#type' => 'checkboxes',
'#options' => node_get_types('names'),
'#default_value' => variable_get('plus1_nodetypes', array(
'story',
)),
);
$form['plus1_display'] = array(
'#type' => 'fieldset',
'#title' => t('Display settings'),
'#description' => t('You may select none, one or both options.'),
);
$form['plus1_display']['plus1_in_teaser'] = array(
'#type' => 'checkbox',
'#title' => t('Add a +1 voting widget to the node in teaser view.'),
'#default_value' => variable_get('plus1_in_teaser', 0),
);
$form['plus1_display']['plus1_in_full_view'] = array(
'#type' => 'checkbox',
'#title' => t('Add a +1 voting widget to the node in full view.'),
'#default_value' => variable_get('plus1_in_full_view', 1),
);
$form['array_filter'] = array(
'#type' => 'hidden',
);
return system_settings_form($form);
}
/**
* Called by jQuery.
* This submits the vote request and returns JSON to be parsed by jQuery.
*/
function plus1_vote($nid) {
global $user;
// Authors may not vote on their own posts.
$is_author = db_result(db_query('SELECT uid FROM {node} WHERE nid = %d AND uid = %d', $nid, $user->uid));
// Before processing the vote we check that the user is logged in.
// We have a node ID, and the user is not the author of the node.
if ($user->uid && $nid > 0 && !$is_author) {
$vote = plus1_get_vote($nid, $user->uid);
if (!$vote) {
$values = array(
'uid' => $user->uid,
'nid' => $nid,
'vote' => 1,
);
plus1_vote_save($values);
$score = plus1_get_score($nid);
// This print statement will return results to jQuery's request.
// drupal_json has replaced drupal_to_js in Drupal 6 (it adds a header).
print drupal_json(array(
'score' => $score,
'voted' => t('<small>You voted</small>'),
));
}
}
// Out we go, we're not returning anything
exit;
}
/**
* Return the number of votes for a given node ID/user ID pair.
*
* @param $nid
* A node ID.
* @param $uid
* A user ID.
* @return Integer
* Number of votes the user has cast on this node.
*/
function plus1_get_vote($nid, $uid) {
return (int) db_result(db_query('SELECT vote FROM {plus1_vote} WHERE nid = %d AND uid = %d', $nid, $uid));
}
/**
* Return the total score of a node.
*
* @param $nid
* A node ID.
* @return Integer
* The score.
*/
function plus1_get_score($nid) {
return (int) db_result(db_query('SELECT SUM(vote) FROM {plus1_vote} WHERE nid = %d', $nid));
}
/**
* Save the vote.
*
* @param $values
* An array of the values to save to the database.
*/
function plus1_vote_save($values) {
db_query('DELETE FROM {plus1_vote} WHERE uid = %d AND nid = %d', $values['uid'], $values['nid']);
db_query('INSERT INTO {plus1_vote} (uid, nid, vote, created) VALUES (%d, %d, %d, %d)', $values['uid'], $values['nid'], $values['vote'], time());
}
/**
* Create voting widget to display on the webpage.
*/
function plus1_jquery_widget($nid, $teaser) {
// Load the JavaScript and CSS files.
drupal_add_js(drupal_get_path('module', 'plus1') . '/jquery.plus1.js');
drupal_add_css(drupal_get_path('module', 'plus1') . '/plus1.css');
$score = plus1_get_score($nid);
global $user;
// If user is not logged-in.
if ($user->uid == 0) {
$logged_in = FALSE;
}
else {
$logged_in = TRUE;
$is_author = db_result(db_query('SELECT uid FROM {node} WHERE nid = %d AND uid = %d', $nid, $user->uid));
$voted = plus1_get_vote($nid, $user->uid);
}
return theme('plus1_widget', $nid, $score, $logged_in, $is_author, $voted, $teaser);
}
/**
* Theme for the voting widget.
*/
function theme_plus1_widget($nid, $score, $logged_in, $is_author, $voted, $teaser) {
$output = '<div class="plus1-widget">';
if (!$logged_in || user_access('rate content')) {
$output .= '<div class="plus1-msg">';
if (!$logged_in) {
$output .= '<small>' . l(t('Log in<br />to vote'), 'user', array(
'html' => TRUE,
)) . '</small>';
}
else {
if ($is_author) {
// User is author so he's not allowed to vote.
$output .= '<small>' . t('Your<br />content') . '</small>';
}
else {
if ($voted) {
// User already voted.
$output .= '<small>' . t('You voted') . '</small>';
}
else {
// User is eligible to vote.
// The class plus1-link is what we will search for in our jQuery later.
// But we could have used the selector ".plus1-vote a".
// Beware : l() and url() have different signatures in Drupal 6.
$output .= '<div class="plus1-vote"' . l(t('Vote'), "plus1/vote/{$nid}", array(
'attributes' => array(
'class' => 'plus1-link',
),
)) . '</div>';
}
}
}
$output .= '</div>';
}
$output .= '<div class="plus1-score">';
$output .= $score;
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* Implementation of hook_theme().
*/
function plus1_theme() {
return array(
'plus1_widget' => array(
'arguments' => array(
'nid',
'score',
'is_author',
'voted',
),
),
);
}
/**
* Implementation of hook_nodeapi().
*/
function plus1_nodeapi(&$node, $op, $teaser, $page) {
switch ($op) {
case 'view':
// Only show the voting widget in allowed content types.
if (in_array($node->type, variable_get('plus1_nodetypes', array(
'story',
)))) {
// Show the widget.
if ($teaser && variable_get('plus1_in_teaser', 0) || !$teaser && variable_get('plus1_in_full_view', 1)) {
$node->content['plus1_widget'] = array(
'#value' => plus1_jquery_widget($node->nid, $teaser),
'#weight' => 100,
);
}
}
break;
case 'delete':
db_query('DELETE FROM {plus1_vote} WHERE nid = %d', $node->nid);
break;
}
}
Functions
Name![]() |
Description |
---|---|
plus1_get_score | Return the total score of a node. |
plus1_get_vote | Return the number of votes for a given node ID/user ID pair. |
plus1_jquery_widget | Create voting widget to display on the webpage. |
plus1_menu | Implementation of hook_menu(). |
plus1_nodeapi | Implementation of hook_nodeapi(). |
plus1_perm | Implementation of hook_perm(). |
plus1_settings | Menu callback to configure module settings. |
plus1_theme | Implementation of hook_theme(). |
plus1_vote | Called by jQuery. This submits the vote request and returns JSON to be parsed by jQuery. |
plus1_vote_save | Save the vote. |
theme_plus1_widget | Theme for the voting widget. |