Skip to content
Snippets Groups Projects
poll.module 12.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • function poll_access($op, $node) {
      if ($op == "view") {
        return $node->status;
    
      if ($op == "create") {
        return 1;
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      }
    
    function poll_block() {
    
      $timestamp = db_result(db_query("SELECT MAX(created) FROM node WHERE type='poll' AND status='1' AND moderate='0'"));
    
      if ($timestamp) {
    
        $poll = node_load(array("type" => "poll", "created" => $timestamp, "moderate" => "0", "status" => "1"));
    
        if ($poll->nid) {
          // Poll_view dumps the output into $poll->body
    
    Steven Wittens's avatar
    Steven Wittens committed
          poll_view($poll, 1, 1);
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      $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
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
      $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'");
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      while ($poll = db_fetch_object($result)) {
    
    Steven Wittens's avatar
    Steven Wittens committed
        db_query("UPDATE poll SET active='0' WHERE nid='$poll->nid'");
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      }
    
    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));
    
    Steven Wittens's avatar
    Steven Wittens committed
      $_active = array(0 => t("Closed"), 1 => t("Active"));
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
    Steven Wittens's avatar
    Steven Wittens committed
      $node->choices = $node->choices ? $node->choices : max(2, count($node->choice) ? count($node->choice) : 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++;
          }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
          if ($node->chvotes[$i] < 0) {
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
            $error["chvotes][$i"] = "<span style=\"color: red;\">". t("Negative values are not allowed.") ."</span>";
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
        if ($actualchoices < 2) {
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
          $error["choice][0"] = "<span style=\"color: red;\">". t("You must fill in at least two choices.") ."</span>";
    
        }
      }
      else {
        $help = variable_get("poll_help", "");
      }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      if (function_exists("taxonomy_node_form")) {
        $output = implode("", taxonomy_node_form("poll", $node));
      }
    
    
      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."));
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
      $output .= form_submit(t("Preview")) ."<br /><br /><br />";
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      for ($a = 0; $a < $node->choices; $a++) {
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
        $output .= form_textfield(t("Choice") ." ". ($a + 1), "choice][$a", $node->choice[$a], 50, 127, $error["choice][$a"]);
    
        if ($admin) {
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
          $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"]);
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      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;
    }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
    function poll_help() {
    
    Steven Wittens's avatar
    Steven Wittens committed
     ?><p>Drupal's poll module allows users to submit multiple-choice questions that others can vote on.</p>
    
    function poll_insert($node) {
      if (!user_access("administer nodes")) {
        // Make sure all votes are 0 initially
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
        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')");
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      for ($i = 0; $i < $node->choices; $i++) {
        $choice->chtext = filter($node->choice[$i]);
        $choice->chvotes = (int)$node->chvotes[$i];
        $choice->chorder = $i;
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
        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")) {
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
        $links[] = lm(t("create poll"), array("mod" => "node", "op" => "add", "type" => "poll"), "", array("title" => t("Add a new poll.")));
    
    Steven Wittens's avatar
    Steven Wittens committed
      else if ($type == "page" && user_access("access content")) {
        $links[] = lm(t("polls"), array("mod" => "poll"), "", array("title" => t("View the list of polls on this site.")));
      }
    
      return $links ? $links : array();
    }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
    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'"));
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      $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;
    }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
    function poll_node($field) {
      $info["name"] = t("poll");
      $info["description"] = t("A poll is a multiple-choice question which visitors can vote on.");
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      return $info[$field];
    }
    
    Steven Wittens's avatar
    Steven Wittens committed
    function poll_page() {
      global $theme;
      
      $theme->header();
    
    Steven Wittens's avatar
    Steven Wittens committed
      $result = db_query("SELECT n.nid, n.title, p.active, SUM(c.chvotes) AS votes FROM node n LEFT JOIN poll p ON n.nid=p.nid LEFT JOIN poll_choices c ON n.nid=c.nid WHERE type='poll' AND status='1' AND moderate='0' GROUP BY n.nid ORDER BY n.created DESC");
    
    Steven Wittens's avatar
    Steven Wittens committed
      while ($node = db_fetch_object($result)) {
        $output .= "<li>". l($node->title, array("id" => $node->nid)) ." - ". format_plural($node->votes, "vote", "votes") ." - ". ($node->active ? t("open") : t("closed")) ."</li>";
      }
      $theme->box(t("Polls"), $output);
      $theme->footer();
    }
    
    
    function poll_perm() {
      return array("vote on polls");
    }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
    function poll_save($op, $node) {
      if ($op == "approve") {
        return array("status" => 1, "promote" => 1);
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      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));
        }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      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;
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      /* When a poll is displayed twice on the same page (e.g. on the front page and in the side bar)
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
         we only want to vote on one of them. We keep count using $pollid */
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      global $pollidcount, $pollvote, $pollid, $REMOTE_ADDR;
    
      $pollidcount++;
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      // 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
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
          $id = "_". $user->uid ."_";
    
        }
        else {
          $id = $REMOTE_ADDR;
        }
        if (!strstr($node->voters, $id)) {
          $allowvotes = $node->active;
        }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      }
    
    
      if (($pollid == $pollidcount) && isset($pollvote) && ($allowvotes)) {
        // The user has submitted a valid vote
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
        if (!empty($node->choice[$pollvote])) {
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
          $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]++;
        }
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
      if ($allowvotes) {
        // Display the vote form
    
        $url = request_uri() . (strstr(request_uri(), "?") ? "&amp;" : "?") ."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) {
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
          $output .= "</td></tr><tr><td><div align=\"center\">". form_submit(t("Vote")) ."</div></td></tr></table>";
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
          $output .= "</td><td valign=\"middle\"><div align=\"right\">&nbsp;&nbsp;&nbsp;". form_submit(t("Vote")) ."</div></td></tr></table>";
    
    Steven Wittens's avatar
    Steven Wittens committed
        $links = link_node($node, $main);
        $links[] = lm(t("older polls"), array("mod" => "poll"), "", array("title" => t("View the list of polls on this site.")));
        $output .= $block ? "<div align=\"center\">". $theme->links($links) ."</div>" : "";
    
        $output .= "</form>";
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
      else {
    
        // Display the results
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
        // 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);
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
        // 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>";
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
    
    
        foreach ($node->choice as $key => $value) {
          if ($value != "") {
            $width = round($node->chvotes[$key] * 100 / $votesmax);
            $percentage = round($node->chvotes[$key] * 100 / max($votestotal, 1));
    
    
    Steven Wittens's avatar
    Steven Wittens committed
            $output .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"95%\" align=\"center\"><tr><td>$value</td><td><div align=\"right\"> $percentage%". (!$block ? " (". format_plural($node->chvotes[$key], "vote", "votes") .")" : "") ."</div></td></tr></table>";
    
            if ($width == 0) {
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
              $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 {
    
    Kjartan Mannes's avatar
    Kjartan Mannes committed
              $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>";
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
          }
    
    Steven Wittens's avatar
    Steven Wittens committed
        if ($block) {
          // Prevent a 'read more' link in the side-block.
          $node->body = $node->teaser = "";
        }
    
    Steven Wittens's avatar
    Steven Wittens committed
        $links = link_node($node, $main);
        $links[] = lm(t("older polls"), array("mod" => "poll"), "", array("title" => t("View the list of polls on this site.")));
        $output .= "<br /><div align=\"center\">Total votes: ". $votestotal . ($block ? "<br />". $theme->links($links) : "") ."</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];
    
    Dries Buytaert's avatar
     
    Dries Buytaert committed
        $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')");
        }