drupal/modules/poll.module

295 lines
10 KiB
Plaintext
Raw Normal View History

<?php
// $Id$
function poll_access($op, $node) {
if ($op == "view") {
return $node->status;
}
if ($op == "create") {
return 1;
This a rather large commit that needs a lot of fine-tuning. If you update, you'll break your site as you need switching from structure to index.module: so this can be considered an intermediate commit. If you upgrade, and you are welcome to, just create a collection called "section" (for now) and assign your nodes some attributes in the described format. Feedback and bugreports are welcomed. Questions will be answered. CHANGES: - comment system: + when replying to a node (rather then to a comment), that node is displayed above the reply form. + when replying to a comment (rather then to a node), that comment is displayd above the reply form. - removed structure.inc, removed structure.module. - node.inc: + added 2 new node functions called 'node_attribute_edit()' and 'node_attribute_save()' used to 'hook in' any indexing system including your home-brewed stuff if you'd want to. Currently, index.module is the facto default index system. See story.module for usage. - book.module, story.module, poll.module, page.module, forum.module: + added preview functionality to administration section (via node module). + removed all references to structure.inc (category, topic). - moderate.module: + removed all references to structure.inc (category, topic). - book.module, story.module, page.module, forum.module: + increased the sizes of some textareas. - submit.php: + removed all references to structure.inc (category, topic). - marvin.theme: + removed dead code: function story() was depricated. - unconed.theme: + removed hardcoded references to drop.org. - marvin.theme, unconed.theme, jeroen.theme, yaroon.theme, example.theme: + removed all references to structure.inc (category, topic). TODO: - file.module, trip_link.module: + update preview functionality: see story.module for example. + remove references to 'cid' and 'tid', use 'attribute' instead: see story.module for example. - extend and build upon index.module as well as making it configurable
2001-06-10 15:01:20 +00:00
}
}
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] = 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(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[] = lm(t("create poll"), array("mod" => "node", "op" => "add", "type" => "poll"), t("Add a new poll."));
}
return $links ? $links : array();
}
This a rather large commit that needs a lot of fine-tuning. If you update, you'll break your site as you need switching from structure to index.module: so this can be considered an intermediate commit. If you upgrade, and you are welcome to, just create a collection called "section" (for now) and assign your nodes some attributes in the described format. Feedback and bugreports are welcomed. Questions will be answered. CHANGES: - comment system: + when replying to a node (rather then to a comment), that node is displayed above the reply form. + when replying to a comment (rather then to a node), that comment is displayd above the reply form. - removed structure.inc, removed structure.module. - node.inc: + added 2 new node functions called 'node_attribute_edit()' and 'node_attribute_save()' used to 'hook in' any indexing system including your home-brewed stuff if you'd want to. Currently, index.module is the facto default index system. See story.module for usage. - book.module, story.module, poll.module, page.module, forum.module: + added preview functionality to administration section (via node module). + removed all references to structure.inc (category, topic). - moderate.module: + removed all references to structure.inc (category, topic). - book.module, story.module, page.module, forum.module: + increased the sizes of some textareas. - submit.php: + removed all references to structure.inc (category, topic). - marvin.theme: + removed dead code: function story() was depricated. - unconed.theme: + removed hardcoded references to drop.org. - marvin.theme, unconed.theme, jeroen.theme, yaroon.theme, example.theme: + removed all references to structure.inc (category, topic). TODO: - file.module, trip_link.module: + update preview functionality: see story.module for example. + remove references to 'cid' and 'tid', use 'attribute' instead: see story.module for example. - extend and build upon index.module as well as making it configurable
2001-06-10 15:01:20 +00:00
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;
}
This a rather large commit that needs a lot of fine-tuning. If you update, you'll break your site as you need switching from structure to index.module: so this can be considered an intermediate commit. If you upgrade, and you are welcome to, just create a collection called "section" (for now) and assign your nodes some attributes in the described format. Feedback and bugreports are welcomed. Questions will be answered. CHANGES: - comment system: + when replying to a node (rather then to a comment), that node is displayed above the reply form. + when replying to a comment (rather then to a node), that comment is displayd above the reply form. - removed structure.inc, removed structure.module. - node.inc: + added 2 new node functions called 'node_attribute_edit()' and 'node_attribute_save()' used to 'hook in' any indexing system including your home-brewed stuff if you'd want to. Currently, index.module is the facto default index system. See story.module for usage. - book.module, story.module, poll.module, page.module, forum.module: + added preview functionality to administration section (via node module). + removed all references to structure.inc (category, topic). - moderate.module: + removed all references to structure.inc (category, topic). - book.module, story.module, page.module, forum.module: + increased the sizes of some textareas. - submit.php: + removed all references to structure.inc (category, topic). - marvin.theme: + removed dead code: function story() was depricated. - unconed.theme: + removed hardcoded references to drop.org. - marvin.theme, unconed.theme, jeroen.theme, yaroon.theme, example.theme: + removed all references to structure.inc (category, topic). TODO: - file.module, trip_link.module: + update preview functionality: see story.module for example. + remove references to 'cid' and 'tid', use 'attribute' instead: see story.module for example. - extend and build upon index.module as well as making it configurable
2001-06-10 15:01:20 +00:00
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;
$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\">&nbsp;&nbsp;&nbsp;" . 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%\">&nbsp;</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%\">&nbsp;</td></tr></table>";
}
else {
$output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"95%\" align=\"center\"><tr><td class=\"pollfg\" width=\"" . $width . "%\">&nbsp;</td><td class=\"pollbg\" width=\"" . (100 - $width) . "%\">&nbsp;</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')");
}
}
}
?>