295 lines
11 KiB
Plaintext
295 lines
11 KiB
Plaintext
<?php
|
|
// $Id$
|
|
|
|
function poll_access($op, $node) {
|
|
if ($op == "view") {
|
|
return $node->status;
|
|
}
|
|
|
|
if ($op == "create") {
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
function poll_block() {
|
|
$timestamp = db_result(db_query("SELECT MAX(created) FROM node WHERE type='poll' AND status='1'"));
|
|
if ($timestamp) {
|
|
$poll = node_load(array("type" => "poll", "created" => $timestamp, "status" => "1"));
|
|
if ($poll->nid) {
|
|
// Poll_view dumps the output into $poll->body
|
|
poll_view($poll, 0, 1);
|
|
}
|
|
}
|
|
$blocks[0][subject] = strtr(t("Latest poll: %t"), array("%t" => $poll->title));
|
|
$blocks[0][content] = $poll->body;
|
|
$blocks[0][info] = t("Most recent poll");
|
|
return $blocks;
|
|
}
|
|
|
|
function poll_cron() {
|
|
// Close polls that have exceeded their allowed runtime
|
|
$result = db_query("SELECT p.nid FROM poll p LEFT JOIN node n ON p.nid=n.nid WHERE (n.created + p.runtime) < '" . time() . "' AND p.active = '1' AND p.runtime != '0'");
|
|
while ($poll = db_fetch_object($result)) {
|
|
db_query("UPDATE poll SET active='0' WHERE nid='$poll->nid'");
|
|
}
|
|
}
|
|
|
|
function poll_delete($node) {
|
|
db_query("DELETE FROM poll WHERE nid='$node->nid'");
|
|
db_query("DELETE FROM poll_choices WHERE nid='$node->nid'");
|
|
}
|
|
|
|
function poll_form(&$node, &$help, &$error) {
|
|
$admin = user_access("administer nodes");
|
|
|
|
$_duration = array(0 => t("Unlimited"), 86400 => format_interval(86400), 172800 => format_interval(172800), 345600 => format_interval(345600), 604800 => format_interval(604800), 1209600 => format_interval(1209600), 2419200 => format_interval(2419200), 4838400 => format_interval(4838400), 9676800 => format_interval(9676800), 31536000 => format_interval(31536000));
|
|
$_active = array(0 => t("Closed"), 1 => t("Active"));
|
|
|
|
$node->choices = $node->choices ? $node->choices : max(2, count($node->choices) ? count($node->choices) : 5);
|
|
|
|
if (isset($node->title)) {
|
|
// Check for at least two options and validate amount of votes:
|
|
for ($i = 0; $i < $node->choices; $i++) {
|
|
if ($node->choice[$i] != "") {
|
|
$actualchoices++;
|
|
}
|
|
|
|
if ($node->chvotes[$i] < 0) {
|
|
$error["chvotes][$i"] = "<span style=\"color: red;\">" . t("Negative values are not allowed.") . "</span>";
|
|
}
|
|
}
|
|
|
|
if ($actualchoices < 2) {
|
|
$error["choice][0"] = "<span style=\"color: red;\">" . t("You must fill in at least two choices.") . "</span>";
|
|
}
|
|
}
|
|
else {
|
|
$help = variable_get("poll_help", "");
|
|
}
|
|
|
|
for ($c = 2; $c <= 20; $c++) {
|
|
$opts[$c] = $c;
|
|
}
|
|
$output .= form_select(t("Number of choices"), "choices", $node->choices, $opts, t("This item only specifies the number of boxes in this form, but it doesn't have to equal the actual amount of options: you can leave the extra boxes empty."));
|
|
$output .= form_submit(t("Preview")) . "<br><br><br>";
|
|
|
|
for ($a = 0; $a < $node->choices; $a++) {
|
|
$output .= form_textfield(t("Choice"). " " . ($a + 1), "choice][$a", $node->choice[$a], 50, 127, $error["choice][$a"]);
|
|
if ($admin) {
|
|
$output .= form_textfield(strtr(t("Votes for choice %n"), array("%n" => ($a + 1))), "chvotes][$a", $node->chvotes[$a] ? $node->chvotes[$a] : 0, 7, 7, $error["chvotes][$a"]);
|
|
}
|
|
}
|
|
|
|
if ($admin) {
|
|
$output .= form_select(t("Poll status"), "active", isset($node->active) ? $node->active : 1, $_active);
|
|
}
|
|
|
|
$output .= form_select(t("Poll duration"), "runtime", $node->runtime ? $node->runtime : 0, $_duration, t("After this period, the poll will automatically be closed."));
|
|
|
|
return $output;
|
|
}
|
|
|
|
function poll_help() {
|
|
?><p>Drupal's poll module allows users to submit multiple-choice questions that others can vote on.</p>
|
|
<?php
|
|
}
|
|
|
|
function poll_insert($node) {
|
|
if (!user_access("administer nodes")) {
|
|
// Make sure all votes are 0 initially
|
|
for ($i = 0; $i < count($node->chvotes); $i++)
|
|
$node->chvotes[$i] = 0;
|
|
$node->active = 1;
|
|
}
|
|
|
|
db_query("INSERT INTO poll (nid, runtime, voters, active) VALUES ('$node->nid', '$node->runtime', '', '$node->active')");
|
|
|
|
for ($i = 0; $i < $node->choices; $i++) {
|
|
$choice->chtext = filter($node->choice[$i]);
|
|
$choice->chvotes = (int)$node->chvotes[$i];
|
|
$choice->chorder = $i;
|
|
|
|
if ($choice->chtext != "") {
|
|
db_query("INSERT INTO poll_choices (nid, chtext, chvotes, chorder) VALUES ('$node->nid', '$choice->chtext', '$choice->chvotes', '$choice->chorder')");
|
|
}
|
|
}
|
|
}
|
|
|
|
function poll_link($type) {
|
|
if ($type == "menu.create" && user_access("post content")) {
|
|
$links[] = "<a href=\"module.php?mod=node&op=add&type=poll\" title=\"". t("Add a new poll.") ."\">". t("create poll") ."</a>";
|
|
}
|
|
|
|
return $links ? $links : array();
|
|
}
|
|
|
|
function poll_load($node) {
|
|
// Load the appropriate choices into the $node object
|
|
$poll = db_fetch_object(db_query("SELECT runtime, voters, active FROM poll WHERE nid = '$node->nid'"));
|
|
|
|
$result = db_query("SELECT chtext, chvotes, chorder FROM poll_choices WHERE nid='$node->nid' ORDER BY chorder");
|
|
while ($choice = db_fetch_object($result)) {
|
|
$poll->choice[$choice->chorder] = $choice->chtext;
|
|
$poll->chvotes[$choice->chorder] = $choice->chvotes;
|
|
}
|
|
return $poll;
|
|
}
|
|
|
|
function poll_node($field) {
|
|
$info["name"] = t("poll");
|
|
$info["description"] = t("A poll is a multiple-choice question which visitors can vote on.");
|
|
|
|
return $info[$field];
|
|
}
|
|
|
|
function poll_perm() {
|
|
return array("vote on polls");
|
|
}
|
|
|
|
function poll_save($op, $node) {
|
|
if ($op == "approve") {
|
|
return array("status" => 1, "promote" => 1);
|
|
}
|
|
|
|
if ($op == "create") {
|
|
if (user_access("administer nodes")) {
|
|
return array("runtime", "active", "choice", "choices", "chvotes", "body" => "", "teaser" => poll_teaser($node));
|
|
}
|
|
else {
|
|
return array("runtime", "active", "choice", "choices", "chvotes", "body" => "", "moderate" => 1, "teaser" => poll_teaser($node));
|
|
}
|
|
}
|
|
|
|
if ($op == "decline") {
|
|
return array("status" => 0, "promote" => 0);
|
|
}
|
|
|
|
if ($op == "update") {
|
|
return array("runtime", "active", "choice", "choices", "chvotes");
|
|
}
|
|
}
|
|
|
|
function poll_teaser($node) {
|
|
// Create a simple teaser that lists all the choices
|
|
foreach ($node->choice as $k => $v) {
|
|
if ($v != "") {
|
|
$teaser .= "* $v\n";
|
|
}
|
|
}
|
|
return $teaser;
|
|
}
|
|
|
|
function poll_view(&$node, $main = 0, $block = 0) {
|
|
global $theme, $user;
|
|
|
|
/* When a poll is displayed twice on the same page (e.g. on the front page and in the side bar)
|
|
we only want to vote on one of them. We keep count using $pollid */
|
|
global $pollidcount, $pollvote, $pollid, $REMOTE_ADDR, $REQUEST_URI;
|
|
$pollidcount++;
|
|
|
|
// Only accept votes on specific cases to prevent double voting
|
|
$allowvotes = false;
|
|
if (user_access("vote on polls")) {
|
|
if ($user->uid) {
|
|
// Pad the UID with underscores to allow a simple strstr() search
|
|
$id = "_" . $user->uid . "_";
|
|
}
|
|
else {
|
|
$id = $REMOTE_ADDR;
|
|
}
|
|
if (!strstr($node->voters, $id)) {
|
|
$allowvotes = $node->active;
|
|
}
|
|
}
|
|
|
|
if (($pollid == $pollidcount) && isset($pollvote) && ($allowvotes)) {
|
|
// The user has submitted a valid vote
|
|
if (!empty($node->choice[$pollvote])) {
|
|
$node->voters = $node->voters ? ($node->voters . " " . $id) : $id;
|
|
db_query("UPDATE poll SET voters='$node->voters' WHERE nid='$node->nid'");
|
|
db_query("UPDATE poll_choices SET chvotes = chvotes + 1 WHERE nid='$node->nid' AND chorder='$pollvote'");
|
|
$allowvotes = false;
|
|
$node->chvotes[$pollvote]++;
|
|
}
|
|
}
|
|
|
|
if ($allowvotes) {
|
|
// Display the vote form
|
|
$url = $REQUEST_URI . (strstr($REQUEST_URI, "?") ? "&" : "?") . "pollid=" . $pollidcount;
|
|
$output .= "<form action=\"$url\" method=\"post\">";
|
|
$output .= "<table border=\"0\" align=\"center\"><tr><td>";
|
|
|
|
foreach ($node->choice as $key => $value) {
|
|
if ($value != "") {
|
|
$output .= "<input type=\"radio\" name=\"pollvote\" value=\"$key\" /> $value<br />";
|
|
}
|
|
}
|
|
if ($block) {
|
|
$output .= "</td></tr><tr><td><div align=\"center\">" . form_submit(t("Vote")) . "</div></td></tr></table>";
|
|
} else {
|
|
$output .= "</td><td valign=\"middle\"><div align=\"right\"> " . form_submit(t("Vote")) . "</div></td></tr></table>";
|
|
}
|
|
$output .= "</form>";
|
|
}
|
|
else {
|
|
// Display the results
|
|
|
|
// Count the votes and find the maximum
|
|
foreach ($node->choice as $key => $value) {
|
|
$votestotal += $node->chvotes[$key];
|
|
$votesmax = max($votesmax, $node->chvotes[$key]);
|
|
}
|
|
$votesmax = max($votesmax, 1);
|
|
|
|
// Define CSS classes for the bars
|
|
$output .= "<style type=\"text/css\">";
|
|
$output .= "td.pollfg { background-color: " . $theme->foreground . "; font-size: 5pt; }";
|
|
$output .= "td.pollbg { background-color: " . $theme->background . "; font-size: 5pt; }";
|
|
$output .= "</style>";
|
|
|
|
foreach ($node->choice as $key => $value) {
|
|
if ($value != "") {
|
|
$width = round($node->chvotes[$key] * 100 / $votesmax);
|
|
$percentage = round($node->chvotes[$key] * 100 / max($votestotal, 1));
|
|
|
|
$output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"95%\" align=\"center\"><tr><td>$value</td><td><div align=\"right\"> $percentage%" . (!$block ? " (" . $node->chvotes[$key] . " votes)" : "") . "</div></td></tr></table>";
|
|
if ($width == 0) {
|
|
$output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"95%\" align=\"center\"><tr><td class=\"pollbg\" width=\"100%\"> </td></tr></table>";
|
|
}
|
|
else if ($width == 100) {
|
|
$output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"95%\" align=\"center\"><tr><td class=\"pollfg\" width=\"100%\"> </td></tr></table>";
|
|
}
|
|
else {
|
|
$output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"95%\" align=\"center\"><tr><td class=\"pollfg\" width=\"" . $width . "%\"> </td><td class=\"pollbg\" width=\"" . (100 - $width) . "%\"> </td></tr></table>";
|
|
}
|
|
}
|
|
}
|
|
$output .= "<br><div align=\"center\">Total votes: " . $votestotal . "</div>";
|
|
}
|
|
// Force the output on both the mainpage and elsewhere
|
|
$node->body = $output;
|
|
$node->teaser = $output;
|
|
|
|
// We also use poll_view() for the side-block
|
|
if ($block == 0) {
|
|
$theme->node($node, $main);
|
|
}
|
|
}
|
|
|
|
function poll_update($node) {
|
|
db_query("UPDATE poll SET runtime='$node->runtime', active='$node->active' WHERE nid='$node->nid'");
|
|
|
|
db_query("DELETE FROM poll_choices WHERE nid='$node->nid'");
|
|
for ($i = 0; $i < $node->choices; $i++) {
|
|
$choice->chtext = filter($node->choice[$i]);
|
|
$choice->chvotes = (int)$node->chvotes[$i];
|
|
$choice->chorder = $i;
|
|
|
|
if ($choice->chtext != "") {
|
|
db_query("INSERT INTO poll_choices (nid, chtext, chvotes, chorder) VALUES ('$node->nid', '$choice->chtext', '$choice->chvotes', '$choice->chorder')");
|
|
}
|
|
}
|
|
}
|
|
|
|
?>
|