Revision | cd4a724b8cf2dec6a0fac422847d6e13a75f39d6 (tree) |
---|---|
Time | 2022-01-24 02:06:34 |
Author | hai-fun <haifun129@gmai...> |
Commiter | hai-fun |
v1.5, author: sonots
@@ -0,0 +1,816 @@ | ||
1 | +<?php | |
2 | +/** | |
3 | + * Yet Another Vote Plugin eXtension | |
4 | + * | |
5 | + * @author sonots | |
6 | + * @license http://www.gnu.org/licenses/gpl.html GPL v2 | |
7 | + * @link http://lsx.sourceforge.jp/?Plugin%2Fvotex.inc.php | |
8 | + * @version $Id: votex.inc.php,v 1.5 2007-06-05 13:23:20Z sonots $ | |
9 | + * @package plugin | |
10 | + */ | |
11 | + | |
12 | +/** | |
13 | + * votex plugin class | |
14 | + * | |
15 | + * @author sonots | |
16 | + * @license http://www.gnu.org/licenses/gpl.html GPL2 | |
17 | + * @link http://lsx.sourceforge.jp/?Plugin%2Fvotex | |
18 | + */ | |
19 | +class PluginVotex | |
20 | +{ | |
21 | + function PluginVotex() | |
22 | + { | |
23 | + // static | |
24 | + static $CONF = array(); | |
25 | + $this->CONF = &$CONF; | |
26 | + if (empty($this->CONF)) { | |
27 | + $this->CONF['RECENT_PAGE'] = 'RecentVotes'; | |
28 | + $this->CONF['RECENT_LOG'] = CACHE_DIR . 'recentvotes.dat'; | |
29 | + $this->CONF['RECENT_LIMIT'] = 100; | |
30 | + $this->CONF['COOKIE_EXPIRED'] = 60*60*24*3; | |
31 | + $this->CONF['BARCHART_LIB_FILE'] = LIB_DIR . 'barchart.cls.php'; | |
32 | + $this->CONF['BARCHART_COLOR_BAR'] = ' #0000cc'; | |
33 | + $this->CONF['BARCHART_COLOR_BG'] = 'transparent'; | |
34 | + $this->CONF['BARCHART_COLOR_BORDER'] = 'transparent'; | |
35 | + } | |
36 | + static $default_options = array(); | |
37 | + $this->default_options = &$default_options; | |
38 | + if (empty($this->default_options)) { | |
39 | + $this->default_options['readonly'] = FALSE; | |
40 | + $this->default_options['addchoice'] = FALSE; | |
41 | + $this->default_options['barchart'] = FALSE; | |
42 | + } | |
43 | + | |
44 | + // init | |
45 | + $this->options = $this->default_options; | |
46 | + if (function_exists('textdomain')) { | |
47 | + textdomain('vote'); // use i18n msgs of vote.inc.php | |
48 | + } | |
49 | + } | |
50 | + | |
51 | + // static | |
52 | + var $CONF; | |
53 | + var $default_options; | |
54 | + // var | |
55 | + var $options; | |
56 | + | |
57 | + /** | |
58 | + * Action Plugin Main Function | |
59 | + * @static | |
60 | + */ | |
61 | + function action() | |
62 | + { | |
63 | + global $vars; | |
64 | + if ($vars['pcmd'] === 'inline') { | |
65 | + return $this->action_inline(); | |
66 | + } else { | |
67 | + return $this->action_convert(); | |
68 | + } | |
69 | + } | |
70 | + | |
71 | + /** | |
72 | + * POST action via inline plugin | |
73 | + */ | |
74 | + function action_inline() | |
75 | + { | |
76 | + global $vars, $defaultpage; | |
77 | + $_title_collided = _('On updating $1, a collision has occurred.'); | |
78 | + $_title_updated = _('$1 was updated'); | |
79 | + $_msg_collided = _('It seems that someone has already updated this page while you were editing it.<br /> | |
80 | + + is placed at the beginning of a line that was newly added.<br /> | |
81 | + ! is placed at the beginning of a line that has possibly been updated.<br /> | |
82 | + Edit those lines, and submit again.'); | |
83 | + | |
84 | + if (method_exists('auth', 'check_role')) { // Plus! | |
85 | + if (auth::check_role('readonly')) die_message('PKWK_READONLY prohibits editing'); | |
86 | + } else { | |
87 | + if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing'); | |
88 | + } | |
89 | + | |
90 | + $page = isset($vars['refer']) ? $vars['refer'] : $defaultpage; | |
91 | + $pcmd = $vars['pcmd']; | |
92 | + $vote_id = $vars['vote_id']; | |
93 | + $vars['page'] = $page; | |
94 | + $choice_id = $vars['choice_id']; | |
95 | + | |
96 | + if ($this->is_continuous_vote($page, $pcmd, $vote_id)) { | |
97 | + return array( | |
98 | + 'msg' => _('Error in vote'), | |
99 | + 'body' => _('Continuation vote cannot be performed.'), | |
100 | + ); | |
101 | + } | |
102 | + | |
103 | + // parse contents of wiki page and get update | |
104 | + $lines = get_source($page); | |
105 | + list($linenum, $newline, $newtext, $newvotes) = $this->get_update_inline($lines, $vote_id, $choice_id); | |
106 | + if ($linenum === false) { | |
107 | + die_message(_('There was no matching vote. ')); | |
108 | + } | |
109 | + $newlines = $lines; | |
110 | + $newlines[$linenum] = $newline; | |
111 | + $newcontents = implode('', $newlines); | |
112 | + | |
113 | + // collision check | |
114 | + $contents = implode('', $lines); | |
115 | + if (md5($contents) !== $vars['digest']) { | |
116 | + $msg = $_title_collided; | |
117 | + $body = $this->show_preview_form($_msg_collided, $newline); | |
118 | + return array('msg'=>$msg, 'body'=>$body); | |
119 | + } | |
120 | + | |
121 | + page_write($page, $newcontents, TRUE); // notimestamp | |
122 | + $this->update_recent_voted($page, $pcmd, $vote_id, $choice_id, $newvotes); | |
123 | + //static in convert() was somehow wierd if return(msg=>'',body=>''); | |
124 | + //$msg = $_title_updated; | |
125 | + //$body = ''; | |
126 | + //return array('msg'=>$msg, 'body'=>$body); | |
127 | + $anchor = $this->get_anchor($pcmd, $vote_id); | |
128 | + header('Location: ' . get_script_uri() . '?' . rawurlencode($page) . '#' . $anchor); | |
129 | + exit; | |
130 | + } | |
131 | + | |
132 | + /** | |
133 | + * POST action via convert plugin | |
134 | + */ | |
135 | + function action_convert() | |
136 | + { | |
137 | + global $vars, $defaultpage; | |
138 | + $_title_collided = _('On updating $1, a collision has occurred.'); | |
139 | + $_title_updated = _('$1 was updated'); | |
140 | + $_msg_collided = _('It seems that someone has already updated this page while you were editing it.<br /> | |
141 | + + is placed at the beginning of a line that was newly added.<br /> | |
142 | + ! is placed at the beginning of a line that has possibly been updated.<br /> | |
143 | + Edit those lines, and submit again.'); | |
144 | + | |
145 | + if (method_exists('auth', 'check_role')) { // Plus! | |
146 | + if (auth::check_role('readonly')) die_message('PKWK_READONLY prohibits editing'); | |
147 | + } else { | |
148 | + if (PKWK_READONLY) die_message('PKWK_READONLY prohibits editing'); | |
149 | + } | |
150 | + | |
151 | + $page = isset($vars['refer']) ? $vars['refer'] : $defaultpage; | |
152 | + $pcmd = $vars['pcmd']; | |
153 | + $vote_id = $vars['vote_id']; | |
154 | + $vars['page'] = $page; | |
155 | + $choice_id = $this->get_selected_choice_convert(); | |
156 | + $addchoice = isset($vars['addchoice']) && $vars['addchoice'] !== '' | |
157 | + ? $vars['addchoice'] : null; | |
158 | + | |
159 | + if ($this->is_continuous_vote($page, $pcmd, $vote_id)) { | |
160 | + return array( | |
161 | + 'msg' => _('Error in vote'), | |
162 | + 'body' => _('Continuation vote cannot be performed.'), | |
163 | + ); | |
164 | + } | |
165 | + | |
166 | + // parse contents of wiki page and get update | |
167 | + $lines = get_source($page); | |
168 | + list($linenum, $newline, $newtext, $newvotes) = $this->get_update_convert($lines, $vote_id, $choice_id, $addchoice); | |
169 | + if ($linenum === false) { | |
170 | + die_message(_('There was no matching vote. ')); | |
171 | + } | |
172 | + $newlines = $lines; | |
173 | + $newlines[$linenum] = $newline; | |
174 | + $newcontents = implode('', $newlines); | |
175 | + | |
176 | + // collision check | |
177 | + $contents = implode('', $lines); | |
178 | + if (md5($contents) !== $vars['digest']) { | |
179 | + $msg = $_title_collided; | |
180 | + $body = $this->show_preview_form($_msg_collided, $newline); | |
181 | + return array('msg'=>$msg, 'body'=>$body); | |
182 | + } | |
183 | + | |
184 | + page_write($page, $newcontents, TRUE); // notimestamp | |
185 | + if (isset($addchoice)) $choice_id = count($newvotes) - 1; // to make sure | |
186 | + $this->update_recent_voted($page, $pcmd, $vote_id, $choice_id, $newvotes); | |
187 | + //static in convert() was somehow wierd if return(msg=>'',body=>''); | |
188 | + //$msg = $_title_updated; | |
189 | + //$body = ''; | |
190 | + //return array('msg'=>$msg, 'body'=>$body); | |
191 | + $anchor = $this->get_anchor($pcmd, $vote_id); | |
192 | + header('Location: ' . get_script_uri() . '?' . rawurlencode($page) . '#' . $anchor); | |
193 | + exit; | |
194 | + } | |
195 | + | |
196 | + /** | |
197 | + * Update Vote for inline plugin | |
198 | + * | |
199 | + * @param array &$lines | |
200 | + * @param integer $vote_id | |
201 | + * @parram string $choice_id | |
202 | + * @return array array($linenum, $updated_line, $updated_text, $updated_votes) | |
203 | + */ | |
204 | + function get_update_inline(&$lines, $vote_id, $choice_id) | |
205 | + { | |
206 | + $contents = implode('', $lines); | |
207 | + | |
208 | + global $vars, $defaultpage; | |
209 | + $page = isset($vars['refer']) ? $vars['refer'] : $defaultpage; | |
210 | + | |
211 | + $ic = new InlineConverter(array('plugin')); | |
212 | + $vote_count = 0; | |
213 | + foreach ($lines as $linenum => $line) { | |
214 | + if (strpos($line, ' ') === 0) continue; // skip pre | |
215 | + $inlines = $ic->get_objects($line, $page); | |
216 | + $pos = 0; | |
217 | + foreach ($inlines as $inline) { | |
218 | + if ($inline->name !== 'votex') continue; | |
219 | + $pos = strpos($line, '&votex', $pos); | |
220 | + if ($vote_id > $vote_count++) { | |
221 | + $pos++; | |
222 | + } else { | |
223 | + $l_remain = substr($line, 0, $pos); | |
224 | + $r_remain = substr($line, $pos + strlen($inline->text)); | |
225 | + $arg = $inline->param; | |
226 | + $body = $inline->body; | |
227 | + $args = csv_explode(',', $arg); | |
228 | + list($votes, $options) = $this->parse_args_inline($args, $this->default_options); | |
229 | + if ($options['readonly']) return array(false, false, false, false); | |
230 | + | |
231 | + foreach ($votes as $i => $vote) { | |
232 | + list($choice, $count) = $vote; | |
233 | + if ($i == $choice_id) { | |
234 | + ++$count; | |
235 | + $votes[$i] = array($choice, $count); | |
236 | + } | |
237 | + } | |
238 | + $new_args = $this->restore_args_inline($votes, $options, $this->default_options); | |
239 | + $new_arg = csv_implode(',', $new_args); | |
240 | + $body = ($body != '') ? '{' . $body . '};' : ';'; | |
241 | + $newtext = '&votex(' . $new_arg . ')' . $body; | |
242 | + $newline = $l_remain . $newtext . $r_remain; | |
243 | + return array($linenum, $newline, $newtext, $votes); | |
244 | + } | |
245 | + } | |
246 | + } | |
247 | + return array(false, false, false, false); | |
248 | + } | |
249 | + | |
250 | + /** | |
251 | + * Update Vote for convert plugin | |
252 | + * | |
253 | + * @param array &$lines | |
254 | + * @param integer $vote_id | |
255 | + * @parram string $choice_id | |
256 | + * @param string $addchoice | |
257 | + * @return array array($linenum, $updated_line, $updated_text, $updated_votes) | |
258 | + */ | |
259 | + function get_update_convert(&$lines, $vote_id, $choice_id, $addchoice = null) | |
260 | + { | |
261 | + $vote_count = 0; | |
262 | + foreach($lines as $linenum => $line) { | |
263 | + $matches = array(); | |
264 | + if (preg_match('/^#votex(?:\((.*)\)(.*))?$/i', $line, $matches) | |
265 | + && $vote_id == $vote_count++) { | |
266 | + | |
267 | + $args = csv_explode(',', $matches[1]); | |
268 | + $remain = isset($matches[2]) ? $matches[2] : ''; | |
269 | + list($votes, $options) = $this->parse_args_convert($args, $this->default_options); | |
270 | + if ($options['readonly']) return array(false, false, false, false); | |
271 | + | |
272 | + if (isset($addchoice)) { | |
273 | + $votes[] = array($addchoice, 1); | |
274 | + } elseif (isset($votes[$choice_id])) { | |
275 | + list($choice, $count) = $votes[$choice_id]; | |
276 | + $votes[$choice_id] = array($choice, $count + 1); | |
277 | + } | |
278 | + $new_args = $this->restore_args_convert($votes, $options, $this->default_options); | |
279 | + $new_arg = csv_implode(',', $new_args); | |
280 | + $newtext = '#votex(' . $new_arg . ')'; | |
281 | + $newline = $newtext . $remain . "\n"; | |
282 | + return array($linenum, $newline, $newtext, $votes); | |
283 | + } | |
284 | + } | |
285 | + return array(false, false, false, false); | |
286 | + } | |
287 | + | |
288 | + /** | |
289 | + * Get the selected choice id | |
290 | + * | |
291 | + * @global $vars; | |
292 | + * @return string $choice_id | |
293 | + * @uses decode_choice() | |
294 | + */ | |
295 | + function get_selected_choice_convert() | |
296 | + { | |
297 | + global $vars; | |
298 | + $choice_id = false; | |
299 | + foreach ($vars as $key => $val) { | |
300 | + if (strpos($key, 'choice_') === 0) { | |
301 | + $choice_id = $this->decode_choice($key); | |
302 | + break; | |
303 | + } | |
304 | + } | |
305 | + return $choice_id; | |
306 | + } | |
307 | + | |
308 | + /** | |
309 | + * Recent Voted | |
310 | + * | |
311 | + * @param string $page voted page | |
312 | + * @param string $pcmd convert or inline | |
313 | + * @param integer $vote_id | |
314 | + * @param integer $choice_id | |
315 | + * @param array $votes | |
316 | + * @return void | |
317 | + */ | |
318 | + function update_recent_voted($page, $pcmd, $vote_id, $choice_id, $votes) | |
319 | + { | |
320 | + $limit = max(0, $this->CONF['RECENT_LIMIT']); | |
321 | + $time = UTIME; | |
322 | + | |
323 | + // RecentVoted | |
324 | + $lines = get_source($this->CONF['RECENT_PAGE']); | |
325 | + $anchor = $this->get_anchor($pcmd, $vote_id); | |
326 | + $args = array(); | |
327 | + foreach ($votes as $vote) { | |
328 | + list($choice, $count) = $vote; | |
329 | + $args[] = $choice . '[' . $count . ']'; | |
330 | + } | |
331 | + $arg = csv_implode(',', $args); | |
332 | + list($choice, $count) = $votes[$choice_id]; | |
333 | + $addline = | |
334 | + '-' . format_date($time) . | |
335 | + ' - [[' . $page . '#' . $vote_id . '>' . $page . '#' . $anchor . ']] ' . | |
336 | + $choice . | |
337 | + ' (' . $arg . ')' . | |
338 | + "\n"; | |
339 | + array_unshift($lines, $addline); | |
340 | + $lines = array_splice($lines, 0, $limit); | |
341 | + page_write($this->CONF['RECENT_PAGE'], implode('', $lines)); | |
342 | + | |
343 | + // recentvoted.dat (serialization) | |
344 | + if (is_readable($this->CONF['RECENT_LOG'])) { | |
345 | + $log_contents = file_get_contents($this->CONF['RECENT_LOG']); | |
346 | + $logs = unserialize($log_contents); | |
347 | + } else { | |
348 | + $logs = array(); | |
349 | + } | |
350 | + $addlog = array($time, $page, $pcmd, $vote_id, $choice_id, $votes); | |
351 | + array_unshift($logs, $addlog); | |
352 | + $logs = array_splice($logs, 0, $limit); | |
353 | + file_put_contents($this->CONF['RECENT_LOG'], serialize($logs)); | |
354 | + } | |
355 | + | |
356 | + /** | |
357 | + * Check if a continuous vote | |
358 | + * | |
359 | + * @param string $page | |
360 | + * @param string $pcmd convert or inline | |
361 | + * @param integer $vote_id vote form id | |
362 | + * @return boolean true if if is a continuous vote | |
363 | + * @global $_COOKIE | |
364 | + * @global $_SERVER | |
365 | + * @vars $CONF 'COOKIE_EXPIRED' | |
366 | + */ | |
367 | + function is_continuous_vote($page, $pcmd, $vote_id) | |
368 | + { | |
369 | + $cmd = 'votex'; | |
370 | + $votedkey = $cmd . '_' . $pcmd . '_' . $page . '_' . $vote_id; | |
371 | + if (isset($_COOKIE[$votedkey])) { | |
372 | + return true; | |
373 | + } | |
374 | + $_COOKIE[$votedkey] = 1; | |
375 | + $matches = array(); | |
376 | + preg_match('!(.*/)!', $_SERVER['REQUEST_URI'], $matches); | |
377 | + setcookie($votedkey, 1, time()+$this->CONF['COOKIE_EXPIRED'], $matches[0]); | |
378 | + return false; | |
379 | + } | |
380 | + | |
381 | + /** | |
382 | + * Get Preview Form HTML (for when collision occured) | |
383 | + * | |
384 | + * @param string $msg message | |
385 | + * @param string $body | |
386 | + * @return string | |
387 | + */ | |
388 | + function show_preview_form($msg = '', $body = '') | |
389 | + { | |
390 | + global $vars, $rows, $cols; | |
391 | + $s_refer = htmlspecialchars($vars['refer']); | |
392 | + $s_digest = htmlspecialchars($vars['digest']); | |
393 | + $s_body = htmlspecialchars($body); | |
394 | + $form = ''; | |
395 | + $form .= $msg . "\n"; | |
396 | + $form .= '<form action="' . get_script_uri() . '?cmd=preview" method="post">' . "\n"; | |
397 | + $form .= '<div>' . "\n"; | |
398 | + $form .= ' <input type="hidden" name="refer" value="' . $s_refer . '" />' . "\n"; | |
399 | + $form .= ' <input type="hidden" name="digest" value="' . $s_digest . '" />' . "\n"; | |
400 | + $form .= ' <textarea name="msg" rows="' . $rows . '" cols="' . $cols . '" id="textarea">' . $s_body . '</textarea><br />' . "\n"; | |
401 | + $form .= '</div>' . "\n"; | |
402 | + $form .= '</form>' . "\n"; | |
403 | + return $form; | |
404 | + } | |
405 | + | |
406 | + /** | |
407 | + * Get anchor | |
408 | + * | |
409 | + * @param $pcmd | |
410 | + * @param $vote_id | |
411 | + */ | |
412 | + function get_anchor($pcmd = 'convert', $vote_id = 0) | |
413 | + { | |
414 | + return rawurlencode('vote_' . $pcmd . '_' . $vote_id); | |
415 | + } | |
416 | + | |
417 | + /** | |
418 | + * Inline Plugin Main Function | |
419 | + * @static | |
420 | + */ | |
421 | + function inline() | |
422 | + { | |
423 | + global $vars, $defaultpage; | |
424 | + static $number = array(); | |
425 | + | |
426 | + $page = isset($vars['page']) ? $vars['page'] : $defaultpage; | |
427 | + if (! isset($number[$page])) $number[$page] = 0; // Init | |
428 | + $vote_id = $number[$page]++; | |
429 | + | |
430 | + $args = func_get_args(); | |
431 | + array_pop($args); // drop {} | |
432 | + list($votes, $this->options) = $this->parse_args_inline($args, $this->default_options); | |
433 | + | |
434 | + $form = $this->get_vote_form_inline($votes, $vote_id); | |
435 | + return $form; | |
436 | + } | |
437 | + | |
438 | + /** | |
439 | + * Get Vote Form HTML for inline plugin | |
440 | + * | |
441 | + * @static | |
442 | + * @param array $vote | |
443 | + * @param integer $vote_id vote form id | |
444 | + * @global $vars | |
445 | + * @global $vars['page'] | |
446 | + * @global $defaultpage | |
447 | + * @global $digest | |
448 | + * @var $options 'readonly' | |
449 | + * @uses get_script_uri() | |
450 | + * @return string | |
451 | + */ | |
452 | + function get_vote_form_inline($votes, $vote_id) | |
453 | + { | |
454 | + global $vars, $defaultpage; | |
455 | + global $digest; | |
456 | + $page = isset($vars['page']) ? $vars['page'] : $defaultpage; | |
457 | + $r_page = rawurlencode($page); | |
458 | + $r_digest = rawurlencode($digest); | |
459 | + $r_vote_id = rawurlencode($vote_id); | |
460 | + $anchor = $this->get_anchor('inline', $vote_id); | |
461 | + | |
462 | + $form = ''; | |
463 | + $form .= '<span class="votex">'; | |
464 | + $form .= '<a name="' . $anchor . '" id="' . $anchor . '"></a>'; | |
465 | + foreach ($votes as $choice_id => $vote) { | |
466 | + list($choice, $count) = $vote; | |
467 | + $r_choice_id = rawurlencode($choice_id); | |
468 | + $r_choice = rawurlencode($choice); | |
469 | + $r_count = rawurlencode($count); | |
470 | + $s_choice = htmlspecialchars($choice); | |
471 | + $s_count = htmlspecialchars($count); | |
472 | + if ($this->options['readonly']) { | |
473 | + $form .= $s_choice . '<span> ' . $s_count . ' </span>'; | |
474 | + } else { | |
475 | + $form .= | |
476 | + '<a href="' . get_script_uri() . '?cmd=votex' . | |
477 | + '&pcmd=inline' . | |
478 | + '&refer=' . $r_page . | |
479 | + '&digest=' . $r_digest . | |
480 | + '&vote_id=' . $r_vote_id . | |
481 | + '&choice_id=' . $r_choice_id . | |
482 | + '">' . $s_choice . '</a>' . | |
483 | + '<span> ' . $s_count . ' </span>'; | |
484 | + } | |
485 | + } | |
486 | + $form .= '</span>' . "\n"; | |
487 | + return $form; | |
488 | + } | |
489 | + | |
490 | + /** | |
491 | + * Block Plugin Main Function | |
492 | + * @static | |
493 | + */ | |
494 | + function convert() | |
495 | + { | |
496 | + global $vars, $defaultpage; | |
497 | + static $number = array(); | |
498 | + | |
499 | + $page = isset($vars['page']) ? $vars['page'] : $defaultpage; | |
500 | + if (! isset($number[$page])) $number[$page] = 0; // Init | |
501 | + $vote_id = $number[$page]++; | |
502 | + | |
503 | + $args = func_get_args(); | |
504 | + list($votes, $this->options) = $this->parse_args_convert($args, $this->default_options); | |
505 | + | |
506 | + $form = $this->get_vote_form_convert($votes, $vote_id); | |
507 | + return $form; | |
508 | + } | |
509 | + | |
510 | + /** | |
511 | + * Restore Arguments of inline plugin | |
512 | + * | |
513 | + * @param array &$votes | |
514 | + * @param array &$options | |
515 | + * @return array &$args | |
516 | + */ | |
517 | + function &restore_args_inline(&$votes, &$options, &$default_options) | |
518 | + { | |
519 | + // currently same | |
520 | + return $this->restore_args_convert($votes, $options, &$default_options); | |
521 | + } | |
522 | + | |
523 | + /** | |
524 | + * Parse Arguemnts of inline plugin | |
525 | + * | |
526 | + * @param array &$args arguments | |
527 | + * @param array &$default_options default_options | |
528 | + * @return array $votes id => array($choice[id], $count[id]) | |
529 | + * @return array $options | |
530 | + */ | |
531 | + function parse_args_inline(&$args, &$default_options) | |
532 | + { | |
533 | + // currently same | |
534 | + return $this->parse_args_convert($args, $default_options); | |
535 | + } | |
536 | + | |
537 | + /** | |
538 | + * Restore Arguments of convert plugin | |
539 | + * | |
540 | + * @param array &$votes | |
541 | + * @param array &$options | |
542 | + * @param array &$default_options | |
543 | + * @return array &$args | |
544 | + */ | |
545 | + function &restore_args_convert(&$votes, &$options, &$default_options) | |
546 | + { | |
547 | + $vote_args = array(); | |
548 | + foreach ($votes as $vote) { | |
549 | + list($choice, $count) = $vote; | |
550 | + $vote_args[] = $choice . '[' . $count . ']'; | |
551 | + } | |
552 | + $opt_args = array(); | |
553 | + foreach ($options as $key => $val) { | |
554 | + if ($default_options[$key] !== $val) { | |
555 | + if (is_bool($val)) { | |
556 | + $opt_args[] = $key; // currently supports only on | |
557 | + } else { | |
558 | + $opt_args[] = $key . '=' . $val; | |
559 | + } | |
560 | + } | |
561 | + } | |
562 | + $args = array_merge($vote_args, $opt_args); | |
563 | + return $args; | |
564 | + } | |
565 | + | |
566 | + /** | |
567 | + * Parse Arguemnts of convert plugin | |
568 | + * | |
569 | + * @param array &$args arguments | |
570 | + * @param array &$default_options default_options | |
571 | + * @return array $votes id => array($choice[id], $count[id]) | |
572 | + * @return array $options | |
573 | + */ | |
574 | + function parse_args_convert(&$args, &$default_options) | |
575 | + { | |
576 | + $votes = array(); | |
577 | + $options = $default_options; | |
578 | + foreach ($args as $arg) { | |
579 | + $arg = trim($arg); | |
580 | + list($key, $val) = array_pad(explode('=', $arg, 2), 2, TRUE); | |
581 | + if (array_key_exists($key, $options)) { | |
582 | + $options[$key] = $val; | |
583 | + continue; | |
584 | + } | |
585 | + $matches = array(); | |
586 | + $choice = $arg; | |
587 | + $count = 0; | |
588 | + if (preg_match('/^(.+)\[(\d+)\]$/', $arg, $matches)) { | |
589 | + $choice = $matches[1]; | |
590 | + $count = $matches[2]; | |
591 | + } | |
592 | + $votes[] = array($choice, $count); | |
593 | + } | |
594 | + if ($options['barchart']) { | |
595 | + require_once($this->CONF['BARCHART_LIB_FILE']); | |
596 | + } | |
597 | + return array($votes, $options); | |
598 | + } | |
599 | + | |
600 | + /** | |
601 | + * Decode choice key | |
602 | + * | |
603 | + * @param string $choice_key | |
604 | + * @return integer $id | |
605 | + */ | |
606 | + function decode_choice($choice_key) | |
607 | + { | |
608 | + list($prefix, $id) = explode('_', $choice_key, 2); | |
609 | + if ($prefix !== 'choice') return false; | |
610 | + return $id; | |
611 | + } | |
612 | + | |
613 | + /** | |
614 | + * Encode choice to key | |
615 | + * | |
616 | + * @param integer $id | |
617 | + * @return string | |
618 | + */ | |
619 | + function encode_choice($id) | |
620 | + { | |
621 | + return 'choice_' . $id; | |
622 | + } | |
623 | + | |
624 | + /** | |
625 | + * Get Vote Form HTML for convert plugin | |
626 | + * | |
627 | + * @static | |
628 | + * @param array $votes | |
629 | + * @param integer $vote_id vote form id | |
630 | + * @global $vars | |
631 | + * @global $vars['page'] | |
632 | + * @global $defaultpage | |
633 | + * @global $digest | |
634 | + * @var $options 'readonly' | |
635 | + * @var $options 'addchoice' | |
636 | + * @var $options 'barchart' | |
637 | + * @uses get_script_uri() | |
638 | + * @return string | |
639 | + */ | |
640 | + function get_vote_form_convert($votes, $vote_id) | |
641 | + { | |
642 | + $choice_label = _('Selection'); | |
643 | + $vote_label = _('Vote'); | |
644 | + $vote_button = _('Vote'); | |
645 | + $add_button = _('Vote'); // _('Add'); | |
646 | + | |
647 | + // Initilization | |
648 | + global $vars, $defaultpage; | |
649 | + global $digest; | |
650 | + $page = isset($vars['page']) ? $vars['page'] : $defaultpage; | |
651 | + $s_page = htmlspecialchars($page); | |
652 | + $s_digest = htmlspecialchars($digest); | |
653 | + $script = ($this->options['readonly']) ? '' : get_script_uri(); | |
654 | + $submit = ($this->options['readonly']) ? 'hidden' : 'submit'; | |
655 | + $choicestyle = 'padding-left:1em;padding-right:1em;'; | |
656 | + $countstyle = (($this->options['barchart']) ? 'width:120px;' : '') . 'padding-right:1em;'; | |
657 | + $buttonstyle = ($this->options['readonly']) ? 'display:none;' : ''; | |
658 | + $anchor = $this->get_anchor('convert', $vote_id); | |
659 | + | |
660 | + // Init barchart | |
661 | + if ($this->options['barchart']) { | |
662 | + $barchart = new BARCHART(0, 0, 100); | |
663 | + $barchart->setColorCompound($this->CONF['BARCHART_COLOR_BAR']); | |
664 | + $barchart->setColorBg($this->CONF['BARCHART_COLOR_BG']); | |
665 | + $barchart->setColorBorder($this->CONF['BARCHART_COLOR_BORDER']); | |
666 | + | |
667 | + $sum = 0; $max = 0; $argmax = 0; | |
668 | + foreach ($votes as $choice_id => $vote) { | |
669 | + list($choice, $count) = $vote; | |
670 | + $sum += $count; | |
671 | + if ($max < $count) { | |
672 | + $max = $count; | |
673 | + $argmax = $choice_id; | |
674 | + } | |
675 | + } | |
676 | + } | |
677 | + | |
678 | + // Header | |
679 | + $form = ''; | |
680 | + $form .= '<form class="votex" action="' . $script . '" method="post">' . "\n"; | |
681 | + $form .= '<table cellspacing="0" cellpadding="2" class="style_table" summary="vote">' . "\n"; | |
682 | + $form .= ' <tr>' . "\n"; | |
683 | + $form .= ' <td align="left" class="vote_label" style="' . $choicestyle . '"><strong>' . $choice_label . '</strong>' . "\n"; | |
684 | + $form .= ' <a name="' . $anchor . '" id="' . $anchor . '"></a>' . "\n"; | |
685 | + $form .= ' <input type="hidden" name="cmd" value="votex" />' . "\n"; | |
686 | + $form .= ' <input type="hidden" name="pcmd" value="convert" />' . "\n"; | |
687 | + $form .= ' <input type="hidden" name="refer" value="' . $s_page . '" />' . "\n"; | |
688 | + $form .= ' <input type="hidden" name="vote_id" value="' . $vote_id . '" />' . "\n"; | |
689 | + $form .= ' <input type="hidden" name="digest" value="' . $s_digest . '" />' . "\n"; | |
690 | + $form .= ' </td>' . "\n"; | |
691 | + $form .= ' <td align="right" class="vote_label" style="' . $countstyle . '"><strong>' . $vote_label . '</strong></td>' . "\n"; | |
692 | + $form .= ' <td align="right" class="vote_label" style="' . $buttonstyle . '"></td>' . "\n"; | |
693 | + $form .= ' </tr>' . "\n"; | |
694 | + | |
695 | + // Body | |
696 | + foreach ($votes as $choice_id => $vote) { | |
697 | + list($choice, $count) = $vote; | |
698 | + $class = ($choice_id % 2) ? 'vote_td1' : 'vote_td2'; | |
699 | + $s_choice = make_link($choice); | |
700 | + $s_count = htmlspecialchars($count); | |
701 | + $choice_key = $this->encode_choice($choice_id); | |
702 | + if ($this->options['barchart']) { | |
703 | + $percent = (int)(($count / $max) * 100); // / $sum | |
704 | + $barchart->setCurrPoint($percent); | |
705 | + $barchart->setStrAfterBar(' ' . $s_count); | |
706 | + $s_count = $barchart->getBar(); | |
707 | + } | |
708 | + $form .= ' <tr>' . "\n"; | |
709 | + $form .= ' <td align="left" class="' . $class . '" style="' . $choicestyle . '">' . $s_choice . '</td>' . "\n"; | |
710 | + $form .= ' <td align="right" class="' . $class . '" style="' . $countstyle . '">' . $s_count . '</td>' . "\n"; | |
711 | + $form .= ' <td align="right" class="' . $class . '" style="' . $buttonstyle . '">' . "\n"; | |
712 | + $form .= ' <input type="' . $submit . '" name="' . $choice_key . '" value="' . $vote_button . '" class="submit" />' . "\n"; | |
713 | + $form .= ' </td>' . "\n"; | |
714 | + $form .= ' </tr>' . "\n"; | |
715 | + } | |
716 | + | |
717 | + // add choice | |
718 | + if ($this->options['addchoice']) { | |
719 | + $choice_id++; | |
720 | + $class = ($choice_id % 2) ? 'vote_td1' : 'vote_td2'; | |
721 | + $choice_key = $this->encode_choice($choice_id); | |
722 | + $form .= ' <tr>' . "\n"; | |
723 | + $form .= ' <td colspan="2" align="left" class="' . $class . '" style="' . $choicestyle . '">' . "\n"; | |
724 | + $form .= ' <input type="text" size="40" name="addchoice" value="" />' . "\n"; | |
725 | + $form .= ' </td>' . "\n"; | |
726 | + $form .= ' <td align="right" class="' . $class . '" style="' . $buttonstyle . '">' . "\n"; | |
727 | + $form .= ' <input type="' . $submit . '" name="' . $choice_key . '" value="' . $add_button . '" class="submit" />' . "\n"; | |
728 | + $form .= ' </td>' . "\n"; | |
729 | + $form .= ' </tr>' . "\n"; | |
730 | + } | |
731 | + | |
732 | + // Footer | |
733 | + $form .= '</table>' . "\n"; | |
734 | + $form .= '</form>' . "\n"; | |
735 | + | |
736 | + return $form; | |
737 | + } | |
738 | +} | |
739 | + | |
740 | +///////////////////// PHP Adapter | |
741 | +if (! function_exists('_')) { | |
742 | + function &_($str) | |
743 | + { | |
744 | + return $str; | |
745 | + } | |
746 | +} | |
747 | +if (! function_exists('file_put_contents')) { | |
748 | + if (! defined('FILE_APPEND')) | |
749 | + define('FILE_APPEND', 8); | |
750 | + if (! defined('FILE_USE_INCLUDE_PATH')) | |
751 | + define('FILE_USE_INCLUDE_PATH', 1); | |
752 | + function file_put_contents($filename, $data, $flags = 0) | |
753 | + { | |
754 | + $mode = ($flags & FILE_APPEND) ? 'a' : 'w'; | |
755 | + $fp = fopen($filename, $mode); | |
756 | + if ($fp === false) { | |
757 | + return false; | |
758 | + } | |
759 | + if (is_array($data)) $data = implode('', $data); | |
760 | + if ($flags & LOCK_EX) flock($fp, LOCK_EX); | |
761 | + $bytes = fwrite($fp, $data); | |
762 | + if ($flags & LOCK_EX) flock($fp, LOCK_UN); | |
763 | + fclose($fp); | |
764 | + return $bytes; | |
765 | + } | |
766 | +} | |
767 | + | |
768 | +/////////////////////////////////////////// | |
769 | +function plugin_votex_init() | |
770 | +{ | |
771 | + global $plugin_votex_name; | |
772 | + if (class_exists('PluginVotexUnitTest')) { | |
773 | + $plugin_votex_name = 'PluginVotexUnitTest'; | |
774 | + } elseif (class_exists('PluginVotexUser')) { | |
775 | + $plugin_votex_name = 'PluginVotexUser'; | |
776 | + } else { | |
777 | + $plugin_votex_name = 'PluginVotex'; | |
778 | + } | |
779 | +} | |
780 | + | |
781 | +function plugin_votex_action() | |
782 | +{ | |
783 | + global $plugin_votex, $plugin_votex_name; | |
784 | + $plugin_votex = new $plugin_votex_name(); | |
785 | + return $plugin_votex->action(); | |
786 | +} | |
787 | + | |
788 | +function plugin_votex_convert() | |
789 | +{ | |
790 | + global $plugin_votex, $plugin_votex_name; | |
791 | + $plugin_votex = new $plugin_votex_name(); | |
792 | + $args = func_get_args(); | |
793 | + return call_user_func_array(array(&$plugin_votex, 'convert'), $args); | |
794 | +} | |
795 | + | |
796 | +function plugin_votex_inline() | |
797 | +{ | |
798 | + global $plugin_votex, $plugin_votex_name; | |
799 | + $plugin_votex = new $plugin_votex_name(); | |
800 | + $args = func_get_args(); | |
801 | + return call_user_func_array(array(&$plugin_votex, 'inline'), $args); | |
802 | +} | |
803 | + | |
804 | +function plugin_votex_write_after() | |
805 | +{ | |
806 | + global $plugin_votex, $plugin_votex_name; | |
807 | + $plugin_votex = new $plugin_votex_name(); | |
808 | + $args = func_get_args(); | |
809 | + return call_user_func_array(array(&$plugin_votex, 'write_after'), $args); | |
810 | +} | |
811 | + | |
812 | +if (! defined('INIT_DIR')) // if not Plus! | |
813 | + if (file_exists(DATA_HOME . 'init/votex.ini.php')) | |
814 | + include_once(DATA_HOME . 'init/votex.ini.php'); | |
815 | + | |
816 | +?> |