Table of Contents
MultiPoll Plugin
Compatible with DokuWiki
- 2024-02-06 "Kaos" unknown
- 2023-04-04 "Jack Jackrum" unknown
- 2022-07-31 "Igor" unknown
- 2020-07-29 "Hogfather" no
This plugin is the result of an attempt of mine to make the original poll plugin meet my requirements, I heavily hacked into its code, thus it looks very similar… I do not attempt to “steal” the original work, but the code I ended with was too much different to just propose a patch… If the authors of the poll plugin are interested in a merge, they are welcome!
Animated version, adopted from cssdeck.com can be downloaded here (MD5 sum 392d7a5075aaf36c6f49feecdb67bd15)
Animated version with conf[width of poll bars] can be downloaded here (MD5 sum 4cbf093a456e6414cb9960e626f06f70)
Universal bug (at least in Binky) - nonregistered users can press F5 for reload page and automatically adding votes for first answers in all questions. That crush all.
Syntax
Use this plugin to add a poll to a wiki page. The syntax looks like this:
<multipoll [hideresults] [hideifvoted] [showresultsto]=user,@grp,... | [id]> [question 1] * [option] * [option] * ... [question 2] * [option] * [option] [multivaluated question] + [option] + [option] + [option] + ... </multipoll>
[hideresults] | hides the results of the poll to users who don't have write access on the page, displays a “You already voted” message instead | optional |
---|---|---|
[hideifvoted] | completly hides the poll once the user voted, only users with write access on the page can see the results | optional |
[showresultsto] | comma separated list of users or @groups which can see the results without the need to vote or to have editing rights | optional |
[id] | the ID of the poll; must be unique1); appears as title | required |
[question] | the question you'd like to ask | optional |
[option] | a possible answer to the immediately above question | required |
The poll title is converted to a md5sum. This is used as the filename in data/meta: md5sum.multipoll - so all polls in the whole wiki must be unique. As a result you can move your poll around and the poll data is accessible. If you remove the poll you must remove the poll data with “rm”.
Installation Notes
When the blog plugin is also installed, you need to turn $conf['plugin']['blog']['useifmodifiedsince']
off. I will try to eliminate this incompatibility.
Discussion
Following patch provides:
- Fix - poll results percentage indicators are accurate even in case when user votes for some questions while not choosing any radio-button for other questions
- Feature - IP can vote again after one hour time limit expires
- Feature - After vote, return user to $ID.'#anketa', that means his browser is pointed to poll results
- Feature - More space is added between two questions so they can be easily distinguished
- syntax.diff
--- syntax.orig.php 2010-04-12 18:08:48.000000000 +0200 +++ syntax.php 2010-06-06 21:48:50.000000000 +0200 @@ -151,6 +151,8 @@ if($save) { $poll['votes']++; $poll['ips'][] = $ip; + // CHANGE + $poll['time'] = time(); if($_SERVER['REMOTE_USER']) $poll['users'][] = $_SERVER['REMOTE_USER']; if($fh = fopen($pfile, 'w')) { fwrite($fh, serialize($poll)); @@ -158,7 +160,7 @@ } $voted = true; } - }elseif(in_array($ip, $poll['ips']) || ($_SERVER['REMOTE_USER'] && in_array($_SERVER['REMOTE_USER'], $poll['users']))) { + }elseif( (in_array($ip, $poll['ips']) /*CHANGE - one hour limit*/ && time()-$poll['time'] <= 60*60) || ($_SERVER['REMOTE_USER'] && in_array($_SERVER['REMOTE_USER'], $poll['users']))) { $voted = true; } @@ -188,11 +190,20 @@ foreach($questions as $question) { $ret .= ' <div class="multipoll_question" id="poll_question_'.$q.'">'.$renderer->_xmlEntities($question['q']).'</div>'."\n"; $ret .= ' <table class="blind">'."\n"; + // CHANGE - Find total number of votes for this question; note this might be different from $poll['votes'], + // since user might vote only for some questions and not for others + $total = 0; + foreach($question['a'] as $a) { + $s = isset($poll['results'][$q]) ? (isset($poll['results'][$q][$a]) ? $poll['results'][$q][$a] : 0) : 0; + $total += $s; + } foreach($question['a'] as $a) { $ret .= ' <tr>'."\n"; $a = $renderer->_xmlEntities($a); $s = isset($poll['results'][$q]) ? (isset($poll['results'][$q][$a]) ? $poll['results'][$q][$a] : 0) : 0; - $pct = sprintf('%3.1f', 100 * $s / $poll['votes']); + // CHANGE + // $pct = sprintf('%3.1f', 100 * $s / $poll['votes']); + $pct = sprintf('%3.1f', 100 * $s / $total); $ret .= ' <td>'.$a.'</td>'."\n"; $ret .= ' <td><div class="multipoll_bar">'.($s ? '<div class="multipoll_full" style="width:'.($pct * 2).'px"> </div>' : '').'</div></td>'."\n"; $ret .= ' <td class="rightalign">'.$pct.'% ('.$s.')</td>'."\n"; @@ -209,7 +220,9 @@ global $lang; global $ID; - $ret = '<form id="multipoll__form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">'."\n"; + // CHANGE + // $ret = '<form id="multipoll__form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">'."\n"; + $ret = '<form id="multipoll__form" method="post" action="'.$ID.'#anketa" accept-charset="'.$lang['encoding'].'">'."\n"; $ret .= ' <div class="no">'."\n"; $ret .= ' <input type="hidden" name="do" value="show" />'."\n"; $ret .= ' <input type="hidden" name="id" value="'.$ID.'" />'."\n"; @@ -225,7 +238,8 @@ $ret .= ' <input type="checkbox" name="multipoll_question_'.$q.'[]" value="'.$a.'" /> <span>'.$a.'</span><br />'."\n"; }else $ret .= ' <input type="radio" name="multipoll_question_'.$q.'" value="'.$a.'" /> <span>'.$a.'</span><br />'."\n"; } - $ret .= ' <hr />'."\n"; + // CHANGE + $ret .= ' <br><hr><br>'."\n"; $q++; } $ret .= ' <input class="button" type="submit" name="multipoll_vote" value="'.$this->getLang('btn_vote').'" />'."\n";