2 rcs_id('$Id: WikiPoll.php,v 1.1 2004-02-24 02:45:45 rurban Exp $');
4 Copyright 2004 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
8 PhpWiki is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 PhpWiki is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with PhpWiki; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * This plugin provides configurable polls.
27 * question[1]="Do you like PhpWiki?"
28 * answer[1][1]="Yes" answer[1][2]="Do not know" answer[1][3]="No"
29 * question[2]="Did you install other wiki engines before?"
30 * answer[2][1]="Yes" answer[2][2]="No"
31 * question[3]="What wiki engine do you like most?"
32 * answer[3][1]="c2Wiki" answer[3][2]="MoinMoin" answer[3][3]="PhpWiki"
33 * answer[3][4]="usemod" answer[3][5]="Twiki" answer[3][6]="Other"
37 * <?plugin WikiPoll page=PhpWikiPoll admin=1 ?>
38 * and protect this page properly (e.g. PhpWikiPoll/Admin)
41 * check all required buttons if require_all
42 * admin page (view and reset statistics)
47 class WikiPlugin_WikiPoll
56 function getDescription () {
57 return _("Enable configurable polls");
60 function getVersion() {
61 return preg_replace("/[Revision: $]/", '',
65 function getDefaultArguments() {
66 return array('page' => '[pagename]',
68 'require_all' => 1, // if all questions must be answered
72 function getArgs($argstr, $request=false, $defaults = false) {
73 if ($defaults === false)
74 $defaults = $this->getDefaultArguments();
75 //Fixme: on POST argstr is empty
77 list ($argstr_args, $argstr_defaults) = $this->parseArgStr($argstr);
78 if (isset($argstr_args["question_1"])) {
79 $args['question'] = $this->str2array("question",$argstr_args);
80 $args['answer'] = array();
81 for ($i = 0; $i <= count($args['question']); $i++) {
82 if ($array = $this->str2array(sprintf("%s_%d","answer",$i),$argstr_args))
83 $args['answer'][$i] = $array;
87 if (!empty($defaults))
88 foreach ($defaults as $arg => $default_val) {
89 if (isset($argstr_args[$arg]))
90 $args[$arg] = $argstr_args[$arg];
91 elseif ( $request and ($argval = $request->getArg($arg)) !== false )
92 $args[$arg] = $argval;
93 elseif (isset($argstr_defaults[$arg]))
94 $args[$arg] = (string) $argstr_defaults[$arg];
96 $args[$arg] = $default_val;
99 $args[$arg] = $this->expandArg($args[$arg], $request);
101 unset($argstr_args[$arg]);
102 unset($argstr_defaults[$arg]);
105 foreach (array_merge($argstr_args, $argstr_defaults) as $arg => $val) {
106 if (!preg_match("/^(answer_|question_)/",$arg))
107 trigger_error(sprintf(_("argument '%s' not declared by plugin"),
108 $arg), E_USER_NOTICE);
114 function handle_plugin_args_cruft($argstr, $args) {
115 $argstr = str_replace("\n"," ",$argstr);
116 $argstr = str_replace(array("[","]"),array("_",""),$argstr);
117 $this->_args = $this->getArgs($argstr, $GLOBALS['request']);
121 function str2array($var, $obarray=false) {
122 if (!$obarray) $obarray = $GLOBALS;
123 $i = 0; $array = array();
124 $name = sprintf("%s_%d",$var,$i);
125 if (isset($obarray[$name])) $array[$i] = $obarray[$name];
128 $name = sprintf("%s_%d",$var,$i);
129 if (isset($obarray[$name])) $array[$i] = $obarray[$name];
130 } while (isset($obarray[$name]));
134 function run($dbi, $argstr, &$request, $basepage) {
135 $args = $this->getArgs($argstr, $request);
137 return $this->error("No page specified");
138 if (!empty($args['admin']) and $request->_user->isAdmin()) {
140 return $this->doPollAdmin($dbi, $request, $page);
142 extract($this->_args);
143 $page = $dbi->getPage($args['page']);
144 // check ip and last visit
145 $poll = $page->get("poll");
146 $ip = $_SERVER['REMOTE_ADDR'];
147 if (isset($poll['ip'][$ip]) and ((time() - $poll['ip'][$ip]) < 20*60))
148 //todo: view at least the result or disable the Go button
149 return HTML::strong(_("Sorry! You must wait at least 20 minutes until you can vote again!"));
151 $poll['ip'][$ip] = time();
153 foreach ($poll['ip'] as $ip => $time) {
154 if ((time() - $time) > 21*60)
155 unset($poll['ip'][$ip]);
157 $page->set("poll",$poll);
159 if ($request->isPost() and $request->getArg('answer')) {
160 // update statistics and present them the user
161 return $this->doPoll(&$page, &$request, $request->getArg('answer'));
164 $html = HTML::form(array('action' => $request->getPostURL(),
165 'method' => 'POST'));
166 $init = isset($question[0]) ? 0 : 1;
167 for ($i = $init; $i <= count($question); $i++) {
168 if (!isset($question[$i])) break;
170 if (!isset($answer[$i]))
171 trigger_error(fmt("missing %s for %s","answer"."[$i]","question"."[$i]"),
174 if (! is_array($a)) {
176 $html->pushContent(HTML::p(HTML::strong($q)));
177 $html->pushContent(HTML::div(
178 HTML::input(array('type' => 'checkbox',
179 'name' => "answer[$i]",
181 HTML::raw(" "), $a));
184 for ($j=0; $j <= count($a); $j++) {
186 $row->pushContent(HTML::div(
187 HTML::input(array('type' => 'radio',
188 'name' => "answer[$i]",
190 HTML::raw(" "), $a[$j]));
192 $html->pushContent(HTML::p(HTML::strong($q)),$row);
195 $html->pushContent(HTML::p(
196 HTML::input(array('type' => 'submit',
197 'name' => "WikiPoll",
198 'value' => _("Ok"))),
199 HTML::input(array('type' => 'reset',
201 'value' => _("Reset")))));
205 function doPoll($page, $request, $answers) {
206 $question = $this->_args['question'];
207 $answer = $this->_args['answer'];
208 $html = HTML::table(array('cellspacing' => 2));
209 $init = isset($question[0]) ? 0 : 1;
210 for ($i = $init; $i <= count($question); $i++) {
211 if (!isset($question[$i])) break;
212 $poll = $page->get('poll');
213 @$poll['data']['all'][$i]++;
215 if (!isset($answer[$i]))
216 trigger_error(fmt("missing %s for %s","answer"."[$i]","question"."[$i]"),
218 $page->set('poll',$poll);
220 if (! is_array($a) ) {
221 $checkbox = HTML::input(array('type' => 'checkbox',
222 'name' => "answer[$i]",
225 $checkbox->setAttr('checked',1);
226 list($percent,$count,$all) = $this->storeResult(&$page, $i, $answers[$i] ? 1 : 0);
227 $result = sprintf(_(" %d%% selected this (%d/%d)"),$percent,$count,$all);
228 $html->pushContent(HTML::tr(HTML::th(array('colspan' => 3,'align'=>'left'),$q)));
229 $html->pushContent(HTML::tr(HTML::td($checkbox),
233 $html->pushContent(HTML::tr(HTML::th(array('colspan' => 3,'align'=>'left'),$q)));
235 $this->storeResult(&$page,$i,$answers[$i]);
236 for ($j=0; $j <= count($a); $j++) {
238 list($percent,$count,$all) = $this->getResult(&$page,$i,$j);
239 $result = sprintf(_(" %d%% selected this (%d/%d)"),$percent,$count,$all);
240 $radio = HTML::input(array('type' => 'radio',
241 'name' => "answer[$i]",
243 if ($answers[$i] == $j)
244 $radio->setAttr('checked',1);
245 $row->pushContent(HTML::tr(HTML::td($radio),
250 $html->pushContent($row);
253 return HTML($html,HTML::p(_("Thanks for participating!")));
256 function getResult($page,$i,$j) {
257 $poll = $page->get("poll");
258 @$count = $poll['data']['count'][$i][$j];
259 @$all = $poll['data']['all'][$i];
260 $percent = sprintf("%d", $count * 100.0 / $all);
261 return array($percent,$count,$all);
264 function storeResult($page, $i, $j) {
265 $poll = $page->get("poll");
267 $poll = array('data' => array('count' => array(),
270 @$poll['data']['count'][$i][$j]++;
271 //@$poll['data']['all'][$i];
272 $page->set("poll",$poll);
273 $percent = sprintf("%d", $poll['data']['count'][$i][$j] * 100.0 / $poll['data']['all'][$i]);
274 return array($percent,$poll['data']['count'][$i][$j],$poll['data']['all'][$i]);
279 // $Log: not supported by cvs2svn $
287 // c-hanging-comment-ender-p: nil
288 // indent-tabs-mode: nil