poll.module 11.7 KB
Newer Older
1
<?php
2
// $Id$
3

Dries's avatar
 
Dries committed
4 5 6
// description:
//   A multiple choice Poll allows you to submit a question to other users to which anyone can answer. To be published on Tipic, the Poll has to be approved by the moderators.

Dries's avatar
 
Dries committed
7 8
/*

9 10 11 12 13 14
class Poll {
  function Poll($poll) {
    $this = new Node($poll);
    $this->runtime = $poll[runtime];
    $this->active = $poll[active];
    $this->voters = $poll[voters];
15 16
    $this->choice = $poll[choice];
    $this->chvotes = $poll[chvotes];
Dries's avatar
 
Dries committed
17
    $this->chid = $poll[chid];
18 19 20 21
  }
}

function poll_cron() {
22
  $result = _node_get(array("type" => "poll"));
23
  while ($poll = db_fetch_array($result)) {
24
    if (($poll[active]) && ($poll[runtime])) {
25 26
      if (($poll[timestamp] + $poll[runtime]) < time()) {
        $poll[active] = 0;
27
        node_save($poll, array(active));
28 29
      }
    }
30
  }
31 32
}

Steven Wittens's avatar
Steven Wittens committed
33 34 35 36
function poll_delete($node) {
  if ($node->nid)
  {
    db_query("DELETE FROM poll_choices WHERE nid='" . $node->nid . "'");
Dries's avatar
 
Dries committed
37
  }
Steven Wittens's avatar
Steven Wittens committed
38 39
}

40
function poll_get_choices_array($poll) {
41
  if (!is_array($poll[choice])) {
42 43 44 45 46 47 48 49 50 51
    $result = db_query("SELECT * FROM poll_choices WHERE nid='" . $poll[nid] . "'");
    if ($result) {
      while ($choices = db_fetch_array($result)) {
        $m = max($m, $choices[chvotes]);
        $t += $choices[chvotes];
        $poll[choice][$choices[chorder]] = $choices[chtext];
        $poll[chvotes][$choices[chorder]] = $choices[chvotes];
        $poll[chid][$choices[chorder]] = $choices[chid];
      }
      if ($poll[choice]) ksort($poll[choice]);
52 53
    }
  }
54 55
  $poll[maxvotes] = max(1, $m);
  $poll[totalvotes] = $t;
56 57 58 59
  return $poll;
}

function poll_get_choices_obj($poll) {
60
  if (!is_array($poll->choice)) {
61 62 63 64 65 66 67 68 69 70 71
    $result = db_query("SELECT * FROM poll_choices WHERE nid='" . $poll->nid . "'");
    if ($result) {
      while ($choices = db_fetch_array($result)) {
        $m = max($m,$choices[chvotes]);
        $t += $choices[chvotes];

        $poll->choice[$choices[chorder]] = $choices[chtext];
        $poll->chvotes[$choices[chorder]] = $choices[chvotes];
        $poll->chid[$choices[chorder]] = $choices[chid];
      }
      if ($poll->choice) ksort($poll->choice);
72 73
    }
  }
74 75
  $poll->maxvotes = max(1, $m);
  $poll->totalvotes = $t;
76 77 78 79 80 81 82 83
  return $poll;
}

function poll_status() {
  return array(dumped, queued, posted);
}

function poll_search($keys) {
Dries's avatar
 
Dries committed
84
  global $PHP_SELF, $status;
85 86
  $result = db_query("SELECT n.*, p.* FROM poll p LEFT JOIN node n ON n.nid = p.nid AND n.lid = p.lid WHERE n.status = '$status[posted]' AND (n.title LIKE '%$keys%') LIMIT 20");
  while ($poll = db_fetch_object($result)) {
Dries's avatar
 
Dries committed
87
    $find[$i++] = array("title" => check_output($poll->title), "link" => (strstr($PHP_SELF, "admin.php") ? "admin.php?mod=poll&op=edit&id=$poll->nid" : "node.php?id=$poll->nid"), "user" => $poll->name, "date" => $poll->timestamp);
88 89 90 91 92 93
  }
  return $find;
}

function poll_help() {
 ?>
Steven Wittens's avatar
Steven Wittens committed
94 95
   <p>Poll.module allows you to run simple multiple choice polls on your site. After creating the necessary categories, you can add a poll through this administration interface.</p>
   <p>The poll.module also has a block to show the latest poll. If you combine it with a poll category that doesn't promote to the mainpage, you'll get a side-block only poll system.</p>
Dries's avatar
 
Dries committed
96
   <p>If you want to set a limit on the duration of a poll, use the <i>Poll Duration</i> setting. After the specified interval, the poll will automatically be closed, preventing anymore voting.</p>
97 98 99
 <?php
}

100 101 102 103
function poll_graph($val) {
  global $theme;
  $clrfill = $theme->foreground ? $theme->foreground : "#000000";
  $clrempty = $theme->background ? $theme->background : "#ffffff";
104
  $p = round($val * 100);
105
  return "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tr>" . ($p ? "<td width=\"" . $p . "%\" style=\"background-color: $clrfill;\"><span style=\"font-size: 4pt;\">&nbsp;</span></td>" : "") . ($p < 100 ? "<td style=\"background-color: $clrempty;\" width=\"" . (100 - $p) . "%\"><span style=\"font-size: 4pt;\">&nbsp;</span></td>":"") . "</tr></table>";
106 107 108
}

function poll_view($node, $main = 0, $block = 0) {
Dries's avatar
 
Dries committed
109
  global $theme, $op, $user, $chid;
Dries's avatar
 
Dries committed
110

111
  $pollop = $op;
112

Dries's avatar
 
Dries committed
113
  if (($node->active) && (!field_get($node->voters, $user->name))) $voting = 1;
114
  if ((!$voting) && ($pollop != "View")) $pollop = "View";
Dries's avatar
 
Dries committed
115

116
  switch ($pollop) {
117
    case "Vote":
Dries's avatar
 
Dries committed
118
      if (($node->active) && (!field_get($node->voters, $user->name))) {
119 120
        $result = db_query("UPDATE poll_choices SET chvotes=chvotes+1 WHERE nid='" . $node->nid . "' && chid='" . check_input($chid) . "'");
        if (($result) && ($user)) {
121
          $new = node_get_array(array("nid" => $node->nid));
Dries's avatar
 
Dries committed
122
          $new[voters] = field_set($node->voters, $user->name, 1);
123
          node_save($new, array(voters));
124
          $node = node_get_object(array("nid" => $node->nid));
125 126
        }
      }
Dries's avatar
 
Dries committed
127

128 129
    case "View":
      $node = poll_get_choices_obj($node);
Dries's avatar
 
Dries committed
130

131
      $title = "<b>" . check_output($node->title) . "</b>";
132
      $footer = "<small>(" . format_plural($node->totalvotes ? $node->totalvotes : 0, "vote", "votes") . ")</small>";
Dries's avatar
 
Dries committed
133

134
      $node->totalvotes = max(1, $node->totalvotes);
Dries's avatar
 
Dries committed
135

136
      foreach ($node->choice as $key => $value) {
137
        if ($value) {
138
          if ($block) {
139
            $output .= (!$block ? "<br>" : "") . check_output($value) . "<br><table width=\"90%\" align=\"center\" cellspacing=\"1\" cellpadding=\"0\"><tr><td width=\"70%\" valign=\"middle\" align=\"left\">" . poll_graph($node->chvotes[$key] / $node->maxvotes, $theme->pollfill, $theme->pollempty) . "</td><td align=\"right\">" . round(($node->chvotes[$key] / $node->totalvotes) * 100) . "%</td></tr></table>";
140
          } else {
141
            $output .= "<table cellspacing=\"1\" cellpadding=\"0\" width=\"100%\"><tr><td width=\"20%\" valign=\"middle\" align=\"left\">" . check_output($value) . "</td><td width=\"70%\">" . poll_graph($node->chvotes[$key] / $node->maxvotes, $theme->pollfill, $theme->pollempty) . "</td><td width=\"10%\" align=\"right\">" . round(($node->chvotes[$key] / $node->totalvotes) * 100) . "%</td></tr></table>";
142
          }
143 144 145 146 147
        }
      }
      $output .= "<div align=\"center\">" . $footer . "</div>";
      break;

Dries's avatar
 
Dries committed
148
    default:
149 150 151
      $node = poll_get_choices_obj($node);

      $title = "<b>" . check_output($node->title) . "</b>";
152
      $footer = "<small>(" . format_plural($node->totalvotes ? $node->totalvotes : 0, "vote", "votes") . ")</small>";
Dries's avatar
 
Dries committed
153

154
      $node->totalvotes = max(1, $node->totalvotes);
155

Dries's avatar
 
Dries committed
156
      $output .= "<table align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td align=\"left\">";
157
      foreach ($node->choice as $key => $value) {
158
        if ($value) {
159
          $output .= "<input type=\"radio\" name=\"chid\" value=\"" . $node->chid[$key] . "\">&nbsp;" . check_output($value) . "<br>";
160
        }
161
      }
162 163 164
      if ($block) {
        $output .= "</td></tr></table><br><div align=\"center\">" . form_submit("Vote") . "<br>" . $footer  . "</div>";
      } else {
Dries's avatar
 
Dries committed
165
        $output .= "</td><td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td><td align=\"center\"><br><div align=\"center\">" . form_submit("Vote") . "<br>" . $footer  . "</div></td></tr></table>";
166
      }
Dries's avatar
 
Dries committed
167
      $output = form($output);
168 169
   }

Dries's avatar
 
Dries committed
170 171 172

   if (!$block) {
     $node->body = $output;
173
     $theme->node($node, $main);
Dries's avatar
 
Dries committed
174
   }
Dries's avatar
 
Dries committed
175
   return array("title" => $title, "content" => $output);
176 177 178
}

function poll_form($edit = array(), $nocheck = 0) {
Dries's avatar
 
Dries committed
179
  global $user;
180

181
  $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));
182
  $active = array(0 => "Closed", 1 => "Active");
Dries's avatar
 
Dries committed
183

Dries's avatar
 
Dries committed
184
  $admin = ($edit[nid] && user_access("administer nodes")) ? 1 : 0;
Dries's avatar
 
Dries committed
185

Steven Wittens's avatar
Steven Wittens committed
186
  if ($admin && !is_array($edit[choices])) $edit = poll_get_choices_array($edit);
Dries's avatar
 
Dries committed
187

Dries's avatar
 
Dries committed
188
  // Mini-form for number of choiceboxes
189
  $choices = $edit[choices] ? $edit[choices] : max(2, count($edit[choices]) ? count($edit[choices]) : 5);
190
  for ($c = 2; $c <= 20; $c++) $opts[$c]=$c;
Steven Wittens's avatar
Steven Wittens committed
191 192
  $form .= form_select(t("Number of choices"), "choices", $choices, $opts, t("This box only specifies the number of boxes in this form, it doesn't have to equal the actual amount of choices in the poll."));
  $form .= form_submit(t("Preview")) . "<br><br><br>";
193

Dries's avatar
 
Dries committed
194
  // Main form
Dries's avatar
 
Dries committed
195
  $form .= form_item(t("Your name"), ($edit[name] ? $edit[name] : ($user->name ? $user->name : variable_get(anonymous, "Anonymous"))));
Dries's avatar
 
Dries committed
196
  $form .= form_hidden("name", $edit[name]);
197
  $form .= form_textfield(t("Question"), "title", $edit[title], 50, 127);
Dries's avatar
 
Dries committed
198

199
  for ($a = 0; $a < $choices; $a++) {
200
    $form .= form_textfield(t("Choice"). " " . ($a + 1), "choice][$a", $edit[choice][$a], 50, 127);
Dries's avatar
 
Dries committed
201
    if ($admin) $form .= form_textfield(strtr(t("Votes for choice %n"), array("%n" => ($a + 1))), "chvotes][$a", $edit[chvotes][$a] ? $edit[chvotes][$a] : 0, 7, 7);
202
  }
Dries's avatar
 
Dries committed
203

204
  $form .= form_select(t("Poll duration"), "runtime", $edit[runtime] ? $edit[runtime] : t("1 week"), $duration, t("After this period, the poll will automatically be closed."));
Dries's avatar
 
Dries committed
205
  if ($admin) $form .= form_select(t("Poll status"), "active", $edit[active], $active);
Dries's avatar
 
Dries committed
206
  $form .= node_attributes_edit("poll", $edit);
207 208 209 210 211

  // hidden fields:
  if ($edit[nid] > 0) {
    $form .= form_hidden("nid", $edit[nid]);
  }
Dries's avatar
 
Dries committed
212

Dries's avatar
 
Dries committed
213
  if ($nocheck) {
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
    $form .= form_submit(t("Preview"));
  }
  else if (!$edit[title]) {
    $form .= "<FONT COLOR=\"red\">". t("Warning: you did not supply a question.") ."</FONT><P>\n";
    $form .= form_submit(t("Preview"));
  }
  else if ((!$edit[choice][0]) && (!$edit[choice][1])) {
    $form .= "<FONT COLOR=\"red\">". t("Warning: you must supply at least 2 choices.") ."</FONT><P>\n";
    $form .= form_submit(t("Preview"));
  }
  else {
    $form .= form_submit(t("Preview"));
    $form .= form_submit(t("Submit"));
  }

Dries's avatar
 
Dries committed
229
  return form($form);
230 231 232 233 234 235
}

function poll_save($edit) {
  global $status, $user;

  if (!$edit[nid]) {
Dries's avatar
 
Dries committed
236
    $nid = node_save($edit, array(active => 1, attributes => node_attributes_save("poll", $edit), author => $user->uid, comment => variable_get("poll_comment", 0), moderate => variable_get("poll_moderate", ""), promote => variable_get("poll_promote", 0), runtime, score => 0, status => variable_get("poll_status", $status[queued]), timestamp => time(), title, type => "poll", votes => 0, voters => ""));
237
  }
Dries's avatar
 
Dries committed
238
  else if (user_access("administer nodes")) {
Dries's avatar
 
Dries committed
239
    $nid = node_save($edit, array(active, attributes => node_attributes_save("poll", $edit), runtime, title, type => "poll"));
Dries's avatar
 
Dries committed
240
    db_query("DELETE FROM poll_choices WHERE nid='" . $nid . "'");
241 242 243 244
  }
  if ($nid) {
    foreach ($edit[choice] as $key => $value) {
      if ($value) {
245
        $v[] = "('" . $nid . "', '" . check_input($value) . "', '". check_input($edit[chvotes][$key]) ."', '". check_input($key) ."')";
Dries's avatar
 
Dries committed
246
      }
247
    }
248
    db_query("INSERT INTO poll_choices (nid, chtext, chvotes, chorder) VALUES " . implode(",", $v));
249 250 251
  }
}

Dries's avatar
 
Dries committed
252
function poll_block() {
253
  global $status;
254
  $result = _node_get(array("type" => "poll"));
255
  while ($poll = db_fetch_object($result)) {
256
    if (($poll->active) && ($poll->status == $status[posted])) {
Steven Wittens's avatar
Steven Wittens committed
257
      $content = poll_view($poll, 0, 1);
258
      $output = "<b>" . $content[title] . "</b><br>" . $content[content] . "<br><div align=\"center\">[ <a href=\"node.php?id=" . $poll->nid . "\">" . t("read more") . "</a> ]</div>";
259 260
      break;
    }
261 262 263
  }
  $blocks[0][subject] = "Latest poll";
  $blocks[0][content] = $output ? $output : "No active polls.";
Dries's avatar
 
Dries committed
264
  $blocks[0][info] = "Most recent poll";
265
  $blocks[0][link] = "index.php";
266
  return $blocks;
267 268 269 270 271 272 273 274
}


function poll_user() {
  global $edit, $op, $theme, $user;

  switch($op) {
    case t("Refresh"):
275
      $refresh = 1;
276
    case t("Preview"):
277
      $theme->box(t("Submit"), poll_form($edit, $refresh));
278 279 280 281 282 283 284 285 286
      break;
    case t("Submit"):
      poll_save($edit);
      $theme->box(t("Submit"), t("Thank you for your submission."));
      break;
    default:
      $theme->box(t("Submit"), poll_form());
  }
}
Dries's avatar
 
Dries committed
287
*/
288
?>