*/ 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_multipoll extends DokuWiki_Syntax_Plugin { /** * return some info */ function getInfo() { return confToHash(dirname(__FILE__).'/INFO'); } function getType() { return 'substition';} function getPType() { return 'block';} function getSort() { return 167; } /** * Connect pattern to lexer */ function connectTo($mode) { $this->Lexer->addSpecialPattern('.+?', $mode, 'plugin_multipoll'); } /** * Handle the match */ function handle($match, $state, $pos, &$handler) { $match = substr($match, 11, -12); // strip markup if(preg_match('`^\s*((hideresults|hideifvoted|showresultsto\=(\@?[a-z0-9_-]+,)*(\@?[a-z0-9_-]+))\s+)+\|`i', $match)) { $o = array_map('trim', explode(' ', substr($match, 0, strpos($match, '|')))); $opts = array(); foreach($o as $v) { if(substr($v, 0, 14) == 'showresultsto=') { $k = 'showresultsto'; $v = array_map('trim', explode(',', substr($v, 14))); }else{ $k = $v; $v = true; } $opts[$k] = $v; } $match = substr($match, strpos($match, '|') + 1); } $title = substr($match, 0, strpos($match, '>')); $r = substr($match, strpos($match, '>') + 1); $questions = array(); $q = array('q' => array(), 'a' => array(), 'm' => false); $lwq = true; foreach(explode("\n", $r) as $l) { if($lwq) { if(preg_match('`^\s\s([\+\*])\s(.+)$`', $l, $m)) { $lwq = false; $q['a'][] = $m[2]; if($m[1] == '+') $q['m'] = true; }else $q['q'][] = $l; }else{ if(preg_match('`^\s\s([\+\*])\s(.+)$`', $l, $m)) { $q['a'][] = $m[2]; if($m[1] == '+') $q['m'] = true; }else{ $lwq = true; $q['q'] = implode(' ', array_map('trim', $q['q'])); $q['a'] = array_filter(array_map('trim', $q['a']), create_function('$e', 'return ($e["q"] != "");')); $questions[] = $q; $q = array('q' => array(), 'a' => array()); $q['q'][] = $l; } } } if(count($questions) > 1) { // if more than 1 question => only keep questions with text $questions = array_filter($questions, create_function('$e', 'return ($e["q"] != "");')); } return array(trim($title), $questions, $opts); } /** * Create output */ function render($mode, &$renderer, $data) { if ($mode == 'xhtml') { global $ID; global $INFO; $opts = $data[2]; $questions = $data[1]; $title = $renderer->_xmlEntities($data[0]); $authedit = (auth_quickaclcheck($ID) >= AUTH_EDIT); $showresults = ((!isset($opts['hideifvoted']) && !isset($opts['hideresults'])) || $authedit); $showresultsextra = false; if(isset($opts['showresultsto']) && $_SERVER['REMOTE_USER']) { if(in_array($_SERVER['REMOTE_USER'], $opts['showresultsto'])) $showresultsextra = true; foreach($INFO['userinfo']['grps'] as $g) { if(in_array('@'.$g, $opts['showresultsto'])) $showresultsextra = true; } } $showalreadyvoted = (isset($opts['hideresults']) && !$authedit); // prevent caching to ensure the poll results are fresh $renderer->info['cache'] = false; // get poll file contents $pfile = metaFN(md5($title), '.multipoll'); $poll = unserialize(@file_get_contents($pfile)); if(!isset($poll['results'])) $poll['results'] = array(); if(!isset($poll['votes'])) $poll['votes'] = 0; if(!isset($poll['ips'])) $poll['ips'] = array(); if(!isset($poll['users'])) $poll['users'] = array(); $ip = clientIP(true); $voted = false; // just voted if(isset($_POST['multipoll_vote'])) { $save = false; foreach($_POST as $k => $v) { if(preg_match('`^multipoll_question_([0-9]+)$`', $k, $m)) { $q = (int)$m[1]; if(!isset($questions[$q])) continue; if(!isset($poll['results'][$q])) $poll['results'][$q] = array(); if($questions[$q]['m']) { if(!is_array($v)) $v = array($v); foreach($v as $ans) { if(!isset($poll['results'][$q][$ans])) $poll['results'][$q][$ans] = 0; $poll['results'][$q][$ans]++; } }else{ if(is_array($v)) $v = array_shift($v); if(!isset($poll['results'][$q][$v])) $poll['results'][$q][$v] = 0; $poll['results'][$q][$v]++; } $save = true; } } if($save) { $poll['votes']++; $poll['ips'][] = $ip; if($_SERVER['REMOTE_USER']) $poll['users'][] = $_SERVER['REMOTE_USER']; if($fh = fopen($pfile, 'w')) { fwrite($fh, serialize($poll)); fclose($fh); } $voted = true; } }elseif(in_array($ip, $poll['ips']) || ($_SERVER['REMOTE_USER'] && in_array($_SERVER['REMOTE_USER'], $poll['users']))) { $voted = true; } if(!$voted || $showresults || $showresultsextra || $showalreadyvoted) { $renderer->doc .= '
'."\n".''.$title.''; if(!$voted) $renderer->doc .= $this->_pollForm($questions, $renderer); if($voted && $showalreadyvoted) { $renderer->doc .= $this->getLang('already_voted'); } if(($voted && $showresults) || $showresultsextra) { $renderer->doc .= $this->_pollResults($questions, $poll, $renderer); } $renderer->doc .= '
'; } return true; } return false; } function _pollResults($questions, $poll, &$renderer) { if($poll['votes'] == 0) return ''; $q = 0; foreach($questions as $question) { $ret .= '
'.$renderer->_xmlEntities($question['q']).'
'."\n"; $ret .= ' '."\n"; foreach($question['a'] as $a) { $ret .= ' '."\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']); $ret .= ' '."\n"; $ret .= ' '."\n"; $ret .= ' '."\n"; $ret .= ' '."\n"; } $ret .= '
'.$a.'
'.($s ? '
 
' : '').'
'.$pct.'% ('.$s.')
'."\n"; $ret .= '
'."\n"; $q++; } return $ret; } function _pollForm($questions, &$renderer) { global $lang; global $ID; $ret = '
'."\n"; $ret .= '
'."\n"; $ret .= ' '."\n"; $ret .= ' '."\n"; $ret .= '
'."\n"; $qret = array(); $q = 0; foreach($questions as $question) { $ret .= '
'.$renderer->_xmlEntities($question['q']).'
'."\n"; foreach($question['a'] as $a) { $a = $renderer->_xmlEntities($a); if($question['m']) { $ret .= ' '.$a.'
'."\n"; }else $ret .= ' '.$a.'
'."\n"; } $ret .= '
'."\n"; $q++; } $ret .= ' '."\n"; $ret .= '
'."\n"; return $ret; } }