userpoll plugin by Stephane Chazelas
Lets you add polls to a wiki page.
Last updated on 2007-02-09. Provides Syntax.
Compatible with DokuWiki 2007-06-11.
Similar to poll.
| Download | http://stchaz.free.fr/userpoll.zip (4.4 KB) |
|---|
Use this plugin to add a poll to a wiki page. The syntax looks like this:
<userpoll [id]> [question] * [option] * [option] * ... </userpoll>
That means, you can simply put <userpoll> tags around regular bulleted lists to get a radio button poll.
| [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 above question | required |
The main difference with Esther's plugin is that this plugin is user based. That is while Esther's poll allows one vote per client IP address. This one allows one vote per logged in user. It also remembers what every voter voted, to let them change their mind if they wish.
It is compatible with the poll plugin except that if there are one poll and one userpoll on a same page, voting for userpoll will make you vote for the poll one. The contrary is not true as userpoll checks for what you're voting for, which allows you do have several userpolls in a same page.
You can download and install the http://stchaz.free.fr/userpoll.zip (4.4 KB) with the plugin manager.
<?php /** * Usepoll Plugin: allows to create simple polls * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Stephane Chazelas <stephane@artesyncp.com> * * heavily inspired (copy-pasted) from * Esther Brunner <wikidesign@gmail.com>'s poll plugin */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_userpoll extends DokuWiki_Syntax_Plugin { /** * return some info */ function getInfo(){ return array( 'author' => 'Stephane Chazelas', 'email' => 'stephane@artesyncp.com', 'date' => '2007-02-09', 'name' => 'Userpoll Plugin', 'desc' => 'allows to create simple polls', 'url' => 'http://www.dokuwiki.org/plugin:userpoll', ); } function getType(){ return 'substition';} function getPType(){ return 'block';} function getSort(){ return 167; } /** * Connect pattern to lexer */ function connectTo($mode){ $this->Lexer->addSpecialPattern('<userpoll.*?>.+?</userpoll>', $mode, 'plugin_userpoll'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler){ $match = substr($match, 10, -11); // strip markup list($title, $options) = preg_split('/>/u', $match, 2); if (!$options){ $options = $title; $title = NULL; } $options = explode('*', $options); $c = count($options); for ($i = 0; $i < $c; $i++){ $options[$i] = trim($options[$i]); } return array(trim($title), $options); } /** * Create output */ function render($mode, &$renderer, $data) { if ($mode == 'xhtml'){ global $ID; $options = $data[1]; $title = $renderer->_xmlEntities($data[0]); // prevent caching to ensure the poll results are fresh $renderer->info['cache'] = false; // get poll file contents $pollid = md5('@userpoll@'.$title); $pfile = metaFN($pollid, '.userpoll'); $poll = unserialize(@file_get_contents($pfile)); // output the poll $renderer->doc .= '<fieldset class="userpoll">'. '<legend>'.$title.'</legend>'; $more = trim(array_shift($options)); if ($more){ $renderer->doc .= '<div>'.$renderer->_xmlEntities($more).'</div>'; } if (isset($_SERVER['REMOTE_USER'])) { $user = $_SERVER['REMOTE_USER']; if (isset($poll['users']) && isset($poll['users'][$user])) { if (($vote = $_REQUEST['vote']) == '@FORGET@' && $pollid == $_REQUEST['pollid']) { // user changed his/her mind, wipe him from the records $opt = $poll['users'][$user]; unset($poll['users'][$user]); $poll['results'][$opt] -= 1; $poll['votes'] -= 1; $fh = fopen($pfile, 'w'); fwrite($fh, serialize($poll)); fclose($fh); $renderer->doc .= $this->_pollForm($options, $renderer, $pollid); } else { // display results $renderer->doc .= $this->_pollResults($poll, $pollid); } } elseif (($vote = $_REQUEST['vote']) && $pollid == $_REQUEST['pollid']){ // user has just voted -> update results $c = count($options); for ($i = 0; $i < $c; $i++){ $opt = $renderer->_xmlEntities($options[$i]); if ($vote == $opt){ $poll['results'][$opt] += 1; $poll['votes'] += 1; $poll['users'][$user] = $opt; } elseif (!isset($poll['results'][$opt])){ $poll['results'][$opt] = 0; } } $fh = fopen($pfile, 'w'); fwrite($fh, serialize($poll)); fclose($fh); // display results $renderer->doc .= $this->_pollResults($poll, $pollid); } elseif (count($options) > 0){ // display poll form $renderer->doc .= $this->_pollForm($options, $renderer, $pollid); } else { // display results $renderer->doc .= $this->_pollResults($poll); } } else { $renderer->doc .= '<div class="userpoll_error">' .$this->getLang('login_required') . '</div>' . $this->_pollResults($poll); } $renderer->doc .= '</fieldset>'; return true; } return false; } function _pollResults($poll, $pollid = false){ global $ID; global $lang; $total = $poll['votes']; if ($total == 0) return ''; $ret = '<table class="blind">'; $c = count($poll['results']); $options = array_keys($poll['results']); $votes = array_values($poll['results']); for ($i = 0; $i < $c; $i++){ $absolute = $votes[$i]; $percent = round(($absolute*100)/$total); $ret .= '<tr><td>'.$options[$i].'</td><td><div class="userpoll_bar">'; if ($percent) $ret .= '<div class="userpoll_full" style="width:'.($percent*2).'px"> </div>'; $ret .= '</div></td><td class="rightalign">'.$percent.'%</td>'. '<td class="rightalign">('.$absolute.')</td></tr>'; } if ($pollid) { // user had already voted, allow him/her to changer his/her mind $ret .= '<tr><td colspan="4">' . '<form id="userpoll__form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">' . '<div class="no"><input type="hidden" name="do" value="show" />' . '<input type="hidden" name="pollid" value="' . $pollid . '" />' . '<input type="hidden" name="id" value="'.$ID.'" />' . '<input type="hidden" name="vote" value="@FORGET@">' . '<input class="button" type="submit" value="' . $this->getLang('btn_changemind') . '"></form></div></td></tr>'; } $ret .= '</table>'; return $ret; } function _pollForm($options, &$renderer, $pollid){ global $lang; global $ID; $i = 0; $ret = '<form id="userpoll__form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'"><div class="no">'. '<input type="hidden" name="do" value="show" />'. '<input type="hidden" name="pollid" value="' . $pollid . '" />'. '<input type="hidden" name="id" value="'.$ID.'" />'; foreach ($options as $option){ $i++; $option = $renderer->_xmlEntities($option); $ret.= '<label class="simple" for="userpoll__option'.$i.'">'. '<input type="radio" name="vote" id="userpoll__option'.$i.'" '. 'value="'.$option.'" /> <span>'.$option.'</span></label>'; } $ret .= '<input class="button" type="submit" '. 'value="'.$this->getLang('btn_vote').'" />'. '</div></form>'; return $ret; } } //Setup VIM: ex: et ts=4 enc=utf-8 :
Only English, French and Spanish supported so far.
Maybe you should have the title and the id different.
And maybe change the “*” that indicates a question to something else so you can do ordinary styles inside the poll.
Example:
<userpoll [ ID | Title ]> **We want this ?** <question> ====== [yes] ======</question> <question>[no]</question> <question>[Maybe]</question> </userpoll>
Solved this idea with the following lines of code in lib/plugins/userpoll/syntax.php
If you use the syntax <userpoll [PAGEID|Title]> the ID of the current document is used as the userpoll ID or use e.g. <userpoll [123|Title]>function render($mode, &$renderer, $data) { if ($mode == 'xhtml'){ global $ID; $options = $data[1]; $title = $renderer->_xmlEntities($data[0]); // prevent caching to ensure the poll results are fresh $renderer->info['cache'] = false; // get poll file contents //starting modifications for syntax <userpoll [ID|Title]> $title=preg_replace( "/^\[/","",$title ); $title=preg_replace( "/\]$/","",$title ); if( preg_match( "/\|/", $title ) ) { $tmp_array = explode("|", $title); if( $tmp_array[0] == "PAGEID" ) { $pollid = $ID; } else { $pollid = $tmp_array[0]; } $title = $tmp_array[1]; if( strlen($title) > 0 ) { $title = '[' . $tmp_array[1] . ']'; } } else { $pollid = $title; } //$title = $title . "id=" . $pollid; //debug //$pollid = md5('@userpoll@'.$title); $pollid = md5('@userpoll@'.$pollid); //end of modifications for syntax <userpoll [ID|Title]> $pfile = metaFN($pollid, '.userpoll'); $poll = unserialize(@file_get_contents($pfile));
Oli
I've excluded the chance for the users to modify their vote.. It's a very easy hack… You have simply to edit syntax.php and comment the code from line 174 to line 183.
/*if ($pollid) {
// user had already voted, allow him/her to changer his/her mind
$ret .= '<tr><td colspan="4">'
. '<form id="userpoll__form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">'
. '<div class="no"><input type="hidden" name="do" value="show" />'
. '<input type="hidden" name="pollid" value="' . $pollid . '" />'
. '<input type="hidden" name="id" value="'.$ID.'" />'
. '<input type="hidden" name="vote" value="@FORGET@">'
. '<input class="button" type="submit" value="' . $this->getLang('btn_changemind') . '"></form></div></td></tr>';
}
*/
Not sure where to report bugs in this plugin. We just downloaded it and tried it in our installation (on 1/24/08). Some people were able to vote, while others were not. That is, they cast their vote, but in the results screen, they didn't see their vote reflected. I can obtain more information on this end if there's someone on that end who's interested. Thanks!
Quick update on this: I figured out what the problem was. One of the choices in the poll did not work, either because of an ampersand (&) or an apostrophe ('). I created a new poll and took those symbols out, and everything worked. Just FYI for anyone who uses this plugin.