Submitted by Alaa on Sun, 09/01/2005 - 16:31.
( categories: )
<?php
/**
* @file
* Enables your site members to vote on decisions using a simple ranking voting system
*/
/**
* Implementation of hook_help().
*/
function rankvote_help($section) {
switch($section) {
case 'admin/help#rankvote':
return t("<p>some text to help admins</p>");
case 'admin/modules#description':
return t("Enables your site members to vote on decisions using a simple ranking vote system");
case 'node/add#rankvote':
return t("A Ranking Vote is a form where visitors can rank each option");
}
}
/**
* Implementation of hook_access().
*/
function rankvote_access($op, $node) {
if ($op == 'create') {
return user_access('create ranking votes');
}
}
/**
* Implementation of hook_block().
*
* Generates a block containing the latest rankvote.
*/
function rankvote_block($op = 'list', $delta = 0) {
if (user_access('access content')) {
if ($op == 'list') {
$blocks[0]['info'] = t('Most recent Ranking Vote');
return $blocks;
}
else {
// Retrieve the latest rankvote.
$timestamp = db_result(db_query('SELECT MAX(n.created) FROM {node} n '. node_access_join_sql() ." WHERE n.type = 'rankvote' AND n.status = 1 AND ". node_access_where_sql() .' AND n.moderate = 0'));
if ($timestamp) {
$rankvote = node_load(array('type' => 'rankvote', 'created' => $timestamp, 'moderate' => 0, 'status' => 1));
if ($rankvote->nid) {
// rankvote_view() dumps the output into $rankvote->body.
rankvote_view($rankvote, 1, 0, 1);
}
}
$block['subject'] = t('Ranking Vote');
$block['content'] = $rankvote->body;
return $block;
}
}
}
/**
* Implementation of hook_cron().
*
* Closes rankvotes that ave exceeded their allowed runtime.
*/
function rankvote_cron() {
$result = db_query("SELECT p.nid FROM {rankvote} p INNER JOIN {node} n ON p.nid=n.nid WHERE (n.created + p.runtime) < '". time() ."' AND p.active = '1' AND p.runtime != '0'");
while ($rankvote = db_fetch_object($result)) {
db_query("UPDATE {rankvote} SET active='0' WHERE nid = %d", $rankvote->nid);
}
}
/**
* Implementation of hook_delete().
*/
function rankvote_delete($node) {
db_query("DELETE FROM {rankvote} WHERE nid=%d", $node->nid);
db_query("DELETE FROM {rankvote_choices} WHERE nid = %d", $node->nid);
}
/**
* Implementation of hook_validate().
*/
function rankvote_validate(&$node) {
if (isset($node->title)) {
// Check for at least two options and validate amount of votes:
$realchoices = 0;
foreach($node->choice as $i => $choice) {
if ($choice['chtext'] != '') {
$realchoices++;
}
if ($choice['chvotes'] < 0) {
form_set_error("choice][$i][chvotes", t('Negative values are not allowed.'));
}
}
if ($realchoices < 2) {
form_set_error("choice][$realchoices][chtext", t('You must fill in at least two choices.'));
}
}
$node->teaser = rankvote_teaser($node);
}
/**
* Implementation of hook_form().
*/
function rankvote_form(&$node) {
$admin = user_access('administer nodes');
if (function_exists('taxonomy_node_form')) {
$output = implode('', taxonomy_node_form('rankvote', $node));
}
if (!isset($node->choices)) {
$node->choices = max(2, count($node->choice) ? count($node->choice) : 5);
}
// User ticked 'need more choices'.
if ($node->morechoices) {
$node->choices *= 2;
}
$output .= '<div class="rankvote-form">';
// RankVote choices
//$opts = drupal_map_assoc(range(2, $node->choices * 2 + 5));
for ($a = 0; $a < $node->choices; $a++) {
$group1 .= form_textfield(t('Choice %n', array('%n' => ($a + 1))), "choice][$a][chtext", $node->choice[$a]['chtext'], 50, 127);
if ($admin) {
$group1 .= form_textfield(t('Votes for choice %n', array('%n' => ($a + 1))), "choice][$a][chvotes", (int)$node->choice[$a]['chvotes'], 7, 7);
}
}
$group1 .= form_hidden('choices', $node->choices);
$group1 .= form_checkbox(t('Need more choices'), 'morechoices', 1, 0, t("If the amount of boxes above isn't enough, check this box and click the Preview button below to add some more."));
$output .= form_group(t('Choices'), $group1);
// RankVote attributes
$_duration = array(0 => t('Unlimited')) + drupal_map_assoc(array(86400, 172800, 345600, 604800, 1209600, 2419200, 4838400, 9767800, 31536000), "format_interval");
$_active = array(0 => t('Closed'), 1=> t('Active'));
if ($admin) {
$group2 .= form_radios(t('Ranking Vote status'), 'active', isset($node->active) ? $node->active : 1, $_active, t('When a Ranking Vote is closed, visitors can no longer vote for it.'));
}
$group2 .= form_select(t('Ranking Vote duration'), 'runtime', $node->runtime ? $node->runtime : 0, $_duration, t('After this period, the Ranking Vote will be closed automatically.'));
$output .= form_group(t('Settings'), $group2);
$output .= '</div>';
return $output;
}
/**
* Implementation of hook_insert().
*/
function rankvote_insert($node) {
if (!user_access('administer nodes')) {
// Make sure all votes are 0 initially
foreach ($node->choice as $i => $choice) {
$node->choice[$i]['chvotes'] = 0;
}
$node->active = 1;
}
db_query("INSERT INTO {rankvote} (nid, runtime, voters, active) VALUES (%d, %d, '', %d)", $node->nid, $node->runtime, $node->active);
$i=0;
foreach ($node->choice as $choice) {
if ($choice['chtext'] != '') {
db_query("INSERT INTO {rankvote_choices} (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $choice['chtext'], $choice['chvotes'], $i++);
}
}
}
/**
* Implementation of hook_link().
*/
function rankvote_link($type, $node = 0, $main) {
$links = array();
if ($type == 'page' && user_access('access content')) {
$links[] = l(t('votes'), 'rankvote', array('title' => t('View the list of Ranking Votes on this site.')));
}
return $links;
}
/**
* Implementation of hook_menu().
*/
function rankvote_menu($may_cache) {
$items = array();
if($may_cache) {
$items[] = array('path' => 'node/add/rankvote', 'title' => t('ranking vote'),
'access' => user_access('create ranking votes'));
$items[] = array('path' => 'rankvote', 'title' => t('ranking votes'),
'callback' => 'rankvote_page',
'access' => user_access('access content'),
'type' => MENU_SUGGESTED_ITEM);
$items[] = array('path' => 'rankvote/vote',
'title' => t('vote'),
'callback' => 'rankvote_vote',
'access' => user_access('vote on ranking votes'),
'type' => MENU_CALLBACK);
}
else {
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(array('nid' => arg(1)));
if ($node->type == 'rankvote' && $node->allowvotes) {
$items[] = array('path' => 'node/'. arg(1) .'/results',
'title' => t('results'),
'callback' => 'rankvote_results',
'access' => user_access('access content'),
'weight' => 3,
'type' => MENU_LOCAL_TASK);
}
}
}
return $items;
}
/**
* Determine an adjusted user id, to allow for basic tracking of anonymous
* users (IP-based).
*/
function rankvote_uid() {
global $user;
if ($user->uid) {
// Pad the UID with underscores to allow a simple strstr() search
$id = '_'. $user->uid .'_';
}
else {
$id = $_SERVER['REMOTE_ADDR'];
}
return $id;
}
/**
* Implementation of hook_load().
*/
function rankvote_load($node) {
// Load the appropriate choices into the $node object
$rankvote = db_fetch_object(db_query("SELECT runtime, voters, active FROM {rankvote} WHERE nid = %d", $node->nid));
$result = db_query("SELECT chtext, chvotes, chorder FROM {rankvote_choices} WHERE nid=%d ORDER BY RAND()", $node->nid);
while ($choice = db_fetch_array($result)) {
$rankvote->choice[$choice['chorder']] = $choice;
}
// Determine whether or not this user is allowed to vote
$rankvote->allowvotes = false;
if (user_access('vote on ranking votes')) {
if(!strstr($rankvote->voters, rankvote_uid())) {
$rankvote->allowvotes = $rankvote->active;
}
}
return $rankvote;
}
/**
* Implementation of hook_node_name().
*/
function rankvote_node_name($node) {
return t("Ranking Vote");
}
function rankvote_page() {
// List all Ranking Votes
$result = pager_query("SELECT DISTINCT(n.nid), n.title, p.active, n.created, SUM(c.chvotes) AS votes FROM {node} n ". node_access_join_sql() ." INNER JOIN {rankvote} p ON n.nid=p.nid INNER JOIN {rankvote_choices} c ON n.nid=c.nid WHERE type = 'rankvote' AND status = 1 AND ". node_access_where_sql() ." AND moderate = 0 GROUP BY n.nid, n.title, p.active, n.created ORDER BY n.created DESC", 15);
$output = '<ul>';
while ($node = db_fetch_object($result)) {
$output .= '<li>'. l($node->title, "node/$node->nid") .' - '. format_plural($node->votes, '1 vote', '%count votes') .' - '. ($node->active ? t('open') : t('closed')) . '</li>';
}
$output .= '</ul>';
$output .= theme("pager", NULL, 15);
print theme('page', $output);
}
/**
* Implementation of hook_perm().
*/
function rankvote_perm() {
return array('create ranking votes', 'vote on ranking votes');
}
/**
* Creates a simple teaser that lists all the choices.
*/
function rankvote_teaser($node) {
if (is_array($node->choice)) {
foreach ($node->choice as $k => $choice) {
$teaser .= '* '. $choice['chtext'] .'\n';
}
}
return $teaser;
}
/**
* Generates the voting form for a ranking vote.
*/
function rankvote_view_voting(&$node, $main, $page, $block) {
$output = '<div class="rankvote">';
$form = '<div class="vote-form">';
$form .= '<div class="choices">';
if ($node->choice) {
$options = drupal_map_assoc(range(1, count($node->choice)));
foreach ($node->choice as $i => $choice) {
$form .= form_select(drupal_specialchars($choice['chtext']), "choice][". $choice['chorder'], -1, $options, '', 0, false, true);
}
}
$form .= '</div>';
$form .= form_hidden('nid', $node->nid);
$form .= form_submit(t('Vote'), 'vote') .'</div>';
$output .= form($form, 'post', url('rankvote/vote/'. $node->nid));
$output .= '</div>';
return $output;
}
/**
* Generates a graphical representation of the results of a ranking vote.
*/
function rankvote_view_results(&$node, $main, $page, $block) {
// Display the results
// Count the votes and find the maximum
$temp = array();
foreach($node->choice as $i => $choice) {
$temp[$i] = $choice['chvotes'];
}
asort($temp);
// Output the divs for the text, bars and percentages
$output .= '<div class="rankvote">';
if ($block) {
$output .= '<div class="title">'. $node->title .'</div>';
}
$output .= '<ul>';
foreach($temp as $i => $score) {
$output .='<li>'. drupal_specialchars($node->choice[$i]['chtext']) .' <small>score = '. $node->choice[$i]['chvotes'] . '</small></li>';
}
$output .= '</ul></div>';
return $output;
}
/**
* Callback for the 'results' tab for ranking votes you can vote on
*/
function rankvote_results() {
if ($node = node_load(array('nid' => arg(1)))) {
print theme('page', node_show($node, 0), $node->title);
}
else {
drupal_not_found();
}
}
function _valid_rankvote($choice) {
$temp = array();
foreach($choice as $rank) {
$temp[] = $rank;
}
sort($temp);
for ($i=0; $i < count($temp); ++$i) {
if ($i != $temp[$i]-1) return false;
}
return true;
}
/**
* Callback for processing a vote
*/
function rankvote_vote(&$node) {
$nid = arg(2);
if ($node = node_load(array('nid' => $nid))) {
$edit = $_POST['edit'];
$choice = $edit['choice'];
$vote = $_POST['vote'];
if (isset($choice) && count($choice) == count($node->choice)) { //need to check valid vote data here
if (_valid_rankvote($choice)) {
if ($node->allowvotes) {
$id = rankvote_uid();
$node->voters = $node->voters ? ($node->voters .' '. $id) : $id;
db_query("UPDATE {rankvote} SET voters='%s' WHERE nid = %d", $node->voters, $node->nid);
foreach($choice as $i => $rank) {
db_query("UPDATE {rankvote_choices} SET chvotes = chvotes + %d WHERE nid = %d AND chorder = %d", $rank, $node->nid, $i);
$node->choice[$i]['chvotes'] += $rank;
}
$node->allowvotes = false;
drupal_set_message(t('Your vote was recorded.'));
}
else {
drupal_set_message(t("You're not allowed to vote on this ranking vote."), 'error');
}
} else {
drupal_set_message(t("Each choice should get a unique rank for the vote to be valid."), 'error');
}
} else {
drupal_set_message(t("All choices must be ranked for the vote to be valid."), 'error');
}
drupal_goto('node/'. $nid);
}
else {
drupal_not_found();
}
}
/**
* Implementation of hook_view().
*
* @param $block
* An extra parameter that adapts the hook to display a block-ready
* rendering of the ranking vote.
*/
function rankvote_view(&$node, $teaser = FALSE, $page = FALSE, $block = FALSE) {
global $user;
$output = '';
if ($node->allowvotes && ($block || arg(2) != 'results')) {
$output .= rankvote_view_voting($node, $main, $page, $block);
}
else {
$output .= rankvote_view_results($node, $main, $page, $block);
}
// Special display for side-block
if ($block) {
// No 'read more' link
$node->body = $node->teaser = '';
$links = link_node($node, $main);
$links[] = l(t('older ranking votes'), 'rankvote', array('title' => t('View the list of ranking votes on the site.')));
if ($node->allowvotes && $block) {
$link[] = l(t('results'), 'node/'. $node->nid .'/results', array('title' => t('View the current ranking vote results.')));
}
$output .= '<div class="links">'. theme("links", $links) .'</div>';
}
$node->body = $node->teaser = $output;
}
/**
* Implementation of hook_update().
*/
function rankvote_update($node) {
db_query('UPDATE {rankvote} SET runtime = %d, active = %d WHERE nid = %d', $node->runtime, $node->active, $node->nid);
db_query('DELETE FROM {rankvote_choices} WHERE nid = %d', $node->nid);
foreach ($node->choice as $choice) {
$chvotes = (int)$choice['chvotes'];
$chtext = $choice['chtext'];
$i=0;
if ($chtext != '') {
db_query("INSERT INTO {rankvote_choices} (nid, chtext, chvotes, chorder) VALUES (%d, '%s', %d, %d)", $node->nid, $chtext, $chvotes, $i++);
}
}
}

Get GNU / Linux
News Feed
Blogs
Event Photos
Screen Shots
Polls
Popular Content
Members
Search
Wall Papers