1<?php
2/**
3 * Vote Plugin: allows to create simple votes
4 *
5 * @license	GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author	Esther Brunner <wikidesign@gmail.com>
7 * @author	Gina Häußge, Michael Klier
8 * @author	Norihiro Tobo
9 */
10
11if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
13require_once(DOKU_PLUGIN.'syntax.php');
14
15
16class syntax_plugin_vote extends DokuWiki_Syntax_Plugin {
17
18
19function getInfo(){
20	return confToHash(dirname(__FILE__).'/INFO');
21}
22function getType(){ return 'substition'; }
23function getPType(){ return 'block'; }
24function getSort(){ return 168; }
25function connectTo( $mode ) {
26	$this->Lexer->addSpecialPattern( '<vote.*?>.+?</vote>',  $mode, 'plugin_vote' );
27}
28
29
30
31function handle( $match, $state, $pos, &$handler ){
32
33	$data = $match;
34	//$this->_debug_out( 'vote_debug', $data );
35
36	// Extract Title and Param
37	preg_match( '/<vote\s+(.*?)[\s>]/s', $data, $regx_result );
38	$title = htmlspecialchars( $regx_result[1] );
39	if( ! isset( $title ) ) { return NULL; }
40
41	preg_match( '/<vote\s+.*?\s+(.*?)>/s', $data, $regx_result );
42	$param = htmlspecialchars( $regx_result[1] );
43
44	preg_match( '/<vote.*?>\n(.*?)\n\*/s', $data, $regx_result );
45	$question = htmlspecialchars( $regx_result[1] );
46
47	//$this->_debug_out( 'vote_debug1', "\n:$title:$param:$question:\n" );
48
49
50	// Extract options
51	$data = strip_tags( $data );
52	preg_match_all( '/^\*\s*(.*?)\n/m', $data, $regex_result );
53	foreach( $regex_result[1] as $option ) {
54		$options[] = htmlspecialchars( trim( $option ) );
55	}
56
57	$this->_create_vote_log_file( $title, $options );
58
59	return array( $title, $param, $question, $options );
60}
61
62
63
64function render( $mode, &$renderer, $data ) {
65
66
67	$ouotput = "";
68	if ( $mode != 'xhtml' ){ return FALSE; }
69
70	// Parse data
71	list( $title, $param, $question, $options ) = $data;
72	$renderer->info['cache'] = false;
73	$vote_log =  $this->_read_vote_log( $title );
74
75	//Print header parts
76	$output .= '<fieldset class="vote">'.'<legend>'.$title.'</legend>';
77	$output .= "\n";
78	if ( $question ) {
79		$output .= '<div>'.$question.'</div>';
80	}
81 	$output .= "\n";
82
83	//Update vote log
84	if ( $_REQUEST['vote'] &&
85		$this->_user_check( $vote_log, $param ) ){
86
87		$vote = $_REQUEST['vote'];
88
89   		foreach( $options as $option ) {
90
91			if ( $vote == $option ) {
92				$vote_log[ 'results' ][ $option ] += 1;
93				$vote_log[ 'votes' ] += 1;
94				$vote_log[ 'ips' ][] = clientIP( true );
95				global $USERINFO;
96				$vote_log[ 'users' ][] = $USERINFO['name'];
97			}
98		}
99
100		$this->_write_vote_log( $title, $vote_log );
101	}
102
103	// display vote form
104	$output .= $this->_print_vote_form( $vote_log );
105	$output .= '</fieldset>';
106	$output .= "\n";
107
108	$renderer->doc .= $output;
109	return true;
110
111}
112
113
114
115function _user_check( $vote_log, $param ) {
116
117	if( preg_match( '/check=(\w+)/s', $param, $regex_result )  > 0 ) {
118		$check = $regex_result[1];
119	} else {
120		return TRUE;
121	}
122
123	switch( $check ) {
124
125		case "ip":
126			$ip = clientIP( true );
127			if ( isset( $vote_log['ips'] ) && in_array( $ip, $vote_log['ips'] ) ) {
128				return FALSE;
129			}
130		break;
131
132		case "user":
133			global $USERINFO;
134			$user = $USERINFO['name'];
135			if ( isset( $vote_log['users'] ) && in_array( $user, $vote_log['users'] ) ) {
136				return FALSE;
137			}
138		break;
139	}
140
141	return TRUE;
142
143}
144
145
146
147function _create_vote_log_file( $title, $options ) {
148
149	$vote_log_file = metaFN( md5( $title ), '.vote' );
150
151	if( file_exists( $vote_log_file ) ){ return TRUE; }
152
153	foreach( $options as $option ) {
154		$vote_skelton[ 'results' ][ $option ] = 0;
155	}
156	$vote_skelton[ 'votes' ] = 0;
157
158	$fh = fopen( $vote_log_file, 'w' );
159	fwrite( $fh, serialize( $vote_skelton ) );
160	fclose( $fh );
161
162	return TRUE;
163
164}
165
166
167function _debug_out( $title, $data ) {
168
169	$file = metaFN( $title, '.dbg' );
170	$fh = fopen( $file, 'a' );
171	fwrite( $fh, $data );
172	fclose( $fh );
173
174	return TRUE;
175
176}
177
178
179function _read_vote_log( $title ) {
180
181	$vote_log = NULL;
182
183	$vote_log_file = metaFN( md5( $title ), '.vote' );
184	$vote_log  = unserialize( @file_get_contents( $vote_log_file ) );
185
186	return $vote_log;
187}
188
189
190
191function _write_vote_log( $title, $vote_log ) {
192
193	$vote_log_file = metaFN( md5( $title ), '.vote' );
194
195	$fh = fopen( $vote_log_file, 'w' );
196	fwrite( $fh, serialize( $vote_log ) );
197	fclose( $fh);
198
199	return TRUE;
200}
201
202
203
204function _print_vote_form( $vote_log ){
205
206	global $lang;
207	global $ID;
208
209	$total = $vote_log['votes'];
210	if ( $total < 0 ) { return ''; }
211
212	$option_count = count( $vote_log['results'] );
213	$options = array_keys( (array)( $vote_log[ 'results' ] ) );
214	$votes   = array_values( (array)( $vote_log[ 'results' ] ) );
215
216	$ret = '<form id="vote__form" method="post" action="'.script().
217		'" accept-charset="'.$lang[ 'encoding' ].'"><div align="center" class="no">'.
218		'<input type="hidden" name="do" value="show" />'.
219		'<input type="hidden" name="id" value="'.$ID.'" />';
220	$ret .= "\n";
221
222	$ret .= '<table class="blind" align="center">';
223	$ret .= "\n";
224
225
226	for ( $i = 0; $i < $option_count; $i++ ) {
227
228		$absolute = $votes[ $i ];
229		if( $total == 0 ) {
230			$percent = 0;
231		} else {
232			$percent  = round( ( $absolute * 100 ) / $total );
233		}
234
235		$ret .= "\t";
236		$ret .= '<tr><td align="left" colspan="3">'.$options[$i].'</td></tr>';
237		$ret .= '<tr><td><div class="vote_bar">';
238
239		if ( $percent ) {
240			$ret .= '<div class="vote_full" style="width:'.( $percent * 2 ).'px">&nbsp;</div>';
241		}
242		//Result
243		$ret .= '</div></td>'.
244			'<td class="rightalign">'.$percent.'%</td>'.
245			'<td class="rightalign">('.$absolute.')</td>';
246		//Form
247		$ret .= '<td class="rightalign"><label class="simple" for="vote__option'.$i.'">'.
248			'<input type="radio" name="vote" id="vote__option'.$i.'" '.
249			'value="'.$options[$i].'" /></label></td>';
250		$ret .= '</tr>';
251		$ret .= "\n";
252
253	}
254
255	$ret .= "</table>\n";
256	$ret .= '<input class="button" type="submit" '.
257		'value="'.$this->getLang( 'btn_vote' ).'" />';
258
259	$ret .= "</div>\n</form>\n";
260
261
262	return $ret;
263}
264
265} // Class Definition
266
267//Setup VIM: ex: et ts=4 enc=utf-8 :