poll.module 12.3 KB
Newer Older
1 2 3 4 5 6 7 8
<?php

class Poll {
  function Poll($poll) {
    $this = new Node($poll);
    $this->runtime = $poll[runtime];
    $this->active = $poll[active];
    $this->voters = $poll[voters];
9 10 11
    $this->choice = $poll[choice];
    $this->chvotes = $poll[chvotes];
    $this->chid = $poll[chid];    
12 13 14 15
  }
}

function poll_cron() {
16
  $result = _node_get(array("type" => "poll"));
17 18 19 20
  while ($poll = db_fetch_array($result)) {
    if ($poll[active]) {
      if (($poll[timestamp] + $poll[runtime]) < time()) {
        $poll[active] = 0;
21
        node_save($poll, array(active));
22 23 24 25 26 27
      }
    }
  }
}

function poll_get_choices_array($poll) {
28 29 30 31 32 33 34 35 36 37 38
  if (!$poll[choice]) {
    $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]);
39 40
    }
  }
41 42
  $poll[maxvotes] = max(1, $m);
  $poll[totalvotes] = $t;
43 44 45 46
  return $poll;
}

function poll_get_choices_obj($poll) {
47 48 49 50 51 52 53 54 55 56 57 58
  if (!$poll->choice) {
    $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);
59 60
    }
  }
61 62
  $poll->maxvotes = max(1, $m);
  $poll->totalvotes = $t;
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
  return $poll;
}

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

function poll_search($keys) {
  global $status, $user;
  $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)) {
    $find[$i++] = array("title" => check_output($poll->title), "link" => (user_access($user, "poll") ? "admin.php?mod=poll&op=edit&id=$poll->nid" : "node.php?id=$poll->nid"), "user" => $poll->userid, "date" => $poll->timestamp);
  }
  return $find;
}

function poll_help() {
 ?>
   <i>No help available.</i>
 <?php
}

function poll_graph($val) {
  $p = round($val * 100);
87
  return "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tr>" . ($p ? "<td width=\"" . $p . "%\" style=\"background-color: #000000;\"><span style=\"font-size: 4pt;\">&nbsp;</span></td>" : "") . ($p < 100 ? "<td style=\"background-color: #ffffff;\" width=\"" . (100 - $p) . "%\"><span style=\"font-size: 4pt;\">&nbsp;</span></td>":"") . "</tr></table>";
88 89 90 91 92
}

function poll_view($node, $main = 0, $block = 0) {
  global $theme, $op, $user, $chid, $REQUEST_URI;

93
  if (($node->active) && (!field_get($node->voters, $user->userid))) $voting = 1;
94 95 96 97
  if ((!$voting) && ($op != "View")) $op = "View";
  
  switch ($op) {
    case "Vote":
98
      if (($node->active) && (!field_get($node->voters, $user->userid))) {
99 100
        $result = db_query("UPDATE poll_choices SET chvotes=chvotes+1 WHERE nid='" . $node->nid . "' && chid='" . check_input($chid) . "'");
        if (($result) && ($user)) {
101
          $new = node_get_array(array("nid" => $node->nid));
102 103
          $new[voters] = field_set($node->voters, $user->userid,1);
          node_save($new, array(voters));
104
          $node = node_get_object(array("nid" => $node->nid));
105 106 107 108 109 110 111
        }
      }
      
    case "View":
      $node = poll_get_choices_obj($node);
      
      $title = "<b>" . check_output($node->title) . "</b>";
112
      $footer = "<small>(" . format_plural($node->totalvotes ? $node->totalvotes : 0, "vote", "votes") . ")</small>";
113
      
114
      $node->totalvotes = max(1, $node->totalvotes);
115
      
116
      if (!$block) $output .= "<small>Posted by " . format_username($node->userid) . " on " . format_date($node->timestamp, "large") . "</small><br>\r\n";
117
      foreach ($node->choice as $key => $value) {
118 119 120 121 122 123 124
        if ($value) {
          if ($main) {
            $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) . "</td><td width=\"10%\" align=\"right\">" . round(($node->chvotes[$key] / $node->totalvotes) * 100) . "%</td></tr></table>";
          }
          else {
            $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) . "</td><td align=\"right\">" . round(($node->chvotes[$key] / $node->totalvotes) * 100) . "%</td></tr></table>\r\n";
          }
125 126 127 128 129 130 131 132 133
        }
      }
      $output .= "<div align=\"center\">" . $footer . "</div>";
      break;

    default:  
      $node = poll_get_choices_obj($node);

      $title = "<b>" . check_output($node->title) . "</b>";
134
      $footer = "<small>(" . format_plural($node->totalvotes ? $node->totalvotes : 0, "vote", "votes") . ")</small>";
135
      
136
      $node->totalvotes = max(1, $node->totalvotes);
137

138
      if (!$block) $output .= "<small>Posted by " . format_username($node->userid) . " on " . format_date($node->timestamp, "large") . "</small><br><br>\r\n";
139 140
      $output .= "<table align=\"center\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td align=\"left\">"; 
      foreach ($node->choice as $key => $value) {
141 142 143
        if ($value) {
          $output .= "<input type=\"radio\" name=\"chid\" value=\"" . $node->chid[$key] . "\">&nbsp;" . check_output($value) . "<br>\r\n";
        }
144 145
      }
      $output .= "</td></tr></table>";
146
      $output .= "<br><div align=\"center\">" . form_submit("Vote") . "<br>" . $footer  . "</div>";
147 148 149
      $output = form($REQUEST_URI, $output);
   }

150
   if (!$block) $theme->box($title, $output);
151 152 153 154
   return array("title" => $title, "content" => $output);   
}

function poll_form($edit = array(), $nocheck = 0) {
Dries's avatar
CHANGES  
Dries committed
155
  global $REQUEST_URI, $user;
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176

  $duration = array(0 => t("Unlimited"), 86400 => t("1 day"), 172800 => t("2 days"), 345600 => t("4 days"),
                    604800 => t("1 week"), 1209600 => t("2 weeks"), 2678400 => t("1 month"), 5356800 => t("2 months"),
                    10713600 => t("4 months"), 31536000 => t("1 year"));
  
  $active = array(0 => "Closed", 1 => "Active");
                    
  $admin = ($edit[nid] && user_access($user,"poll")) ? 1 : 0; 

  /* Mini-form for number of choiceboxes */  
  $choices = $edit[choices]?$edit[choices]:5;
  for ($c = 2; $c <= 20; $c++) $opts[$c]=$c;
  $form .= form_select(t("Number of choices"), "choices", $choices, $opts, t("This box specifies the number of choiceboxes in this form, it doesn't affect the actual amount of choices in the poll."));
  $form .= form_submit(t("Refresh")) . "<br><br><br>";

  /* Main form */
  $form .= form_item(t("Your name"), format_username(($edit[userid] ? $edit[userid] : $user->userid)));
  $form .= form_hidden("userid", $edit[userid]);
  $form .= form_textfield(t("Question"), "title", $edit[title], 50, 127);
  
  for ($a = 0; $a < $choices; $a++) {
177 178
    $form .= form_textfield(t("Choice"). " " . ($a + 1), "choice][$a", $edit[choice][$a], 50, 127);
    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);    
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
  }
  
  $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."));
  if ($admin) $form .= form_select(t("Poll status"), "active", $edit[active], $active);    
  $form .= structure_form("poll", $edit);
  

  // hidden fields:
  if ($edit[nid] > 0) {
    $form .= form_hidden("nid", $edit[nid]);
  }
  
  if ((!$edit) || ($nocheck)) {
    $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"));
  }

  return form($REQUEST_URI, $form);
}

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

  if (!$edit[nid]) {
    $nid = node_save($edit, array(active => 1, author => $user->id, cid, comment => category_comment($edit[cid]), moderate => topic_moderate($edit[tid]), promote => category_promote($edit[cid]), runtime, score => 0, status => (category_submission($edit[cid]) ? $status[queued] : $status[posted]), tid, timestamp => time(), title, type => "poll", votes => 0, voters => ""));
  }
  else if (user_access($user)) {
    $nid = node_save($edit, array(active, cid, tid, runtime, title, type => "poll"));    
    db_query("DELETE FROM poll_choices WHERE nid='" . $nid . "'"); 
  }
  if ($nid) {
    foreach ($edit[choice] as $key => $value) {
      if ($value) {
        $v[] = "('" . $nid . "', '" . check_input($value) . "', '". check_input($edit[votes][$key]) ."', '". check_input($key) ."')";
      } 
    }
226
    db_query("INSERT INTO poll_choices (nid, chtext, chvotes, chorder) VALUES " . implode(",", $v));
227 228 229 230
  }
}

function poll_block() {  
231
  $poll = node_get_object(array("type" => "poll", "active" => 1));
232 233 234 235 236 237 238 239
  if ($poll) {
    $poll = poll_view($poll, 0, 1);
    $output = "<b>" . $poll[title] . "</b><br>" . $poll[content];
  }
  $blocks[0][subject] = "Latest poll";
  $blocks[0][content] = $output ? $output : "No active polls.";
  $blocks[0][info] = "Display the latest active poll.";
  $blocks[0][link] = "index.php";
240
  return $blocks;
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
}

function poll_query($type = "") {
  global $status;
  $queries = array(array("recent polls", "WHERE n.type = 'poll' ORDER BY n.timestamp DESC"), array("active polls", "WHERE n.type = 'poll' AND n.status = '$status[posted]' ORDER BY n.timestamp DESC"), array("queued polls", "WHERE n.type = 'poll' AND n.status = '$status[queued]' ORDER BY n.timestamp DESC"), array("dumped polls", "WHERE n.type = 'poll' AND n.status = '$status[dumped]' ORDER BY n.timestamp DESC"), array("polls without category (integrity)", "WHERE n.type = 'poll' AND n.cid = '0' ORDER BY n.timestamp DESC"), array("polls without topic (integrity)", "WHERE n.type = 'poll' AND n.tid = '0' ORDER BY n.timestamp DESC"));
  return ($queries[$type] ? $queries[$type] : $queries);
}

function poll_overview($query = array()) {
  return node_overview($query);
}

function poll_admin() {
  global $id, $edit, $mod, $keys, $op, $theme, $type, $user;

  print "<SMALL><A HREF=\"admin.php?mod=poll&op=add\">add new poll</A> | <A HREF=\"admin.php?mod=poll&op=listing\">poll listing</A> | <A HREF=\"admin.php?mod=poll&op=search\">search poll</A> | <A HREF=\"admin.php?mod=poll\">overview</A> | <A HREF=\"admin.php?mod=poll&op=help\">help</A></SMALL><HR>\n";

  $type = ($type ? $type : 0);

  switch ($op) {
    case "delete":
      print poll_delete($id);
      print poll_overview(poll_query($type));
      break;
    case "edit":
266
      print poll_form(poll_get_choices_array(node_get_array(array("nid" => check_input($id)))));
267 268 269 270 271 272 273 274 275 276 277
      break;
    case "help":
      poll_help();
      break;
    case "listing":
      print node_listing(poll_query());
      break;
    case "search":
      print search_form($keys);
      print search_data($keys, $mod);
      break;
278 279
    case t("Refresh"):
      $refresh = 1;
280
    case t("Preview"):
Dries's avatar
CHANGES  
Dries committed
281
      poll_view(new Poll(node_preview($edit)));
282
    case "add":
283
      print poll_form($edit, $refresh);
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
      break;
    case t("Submit"):
      poll_save($edit);
      // fall through:
    default:
      print poll_overview(poll_query($type));
  }
}


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

  switch($op) {
    case t("Refresh"):
299
      $refresh = 1;
300
    case t("Preview"):
Dries's avatar
CHANGES  
Dries committed
301
      poll_view(new Poll(node_preview($edit)));
302
      $theme->box(t("Submit"), poll_form($edit, $refresh));
303 304 305 306 307 308 309 310 311 312 313
      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());
  }
}

?>