1 | <?php |
---|
2 | # -- BEGIN LICENSE BLOCK ---------------------------------- |
---|
3 | # This file is part of pollsFactory, a plugin for Dotclear 2. |
---|
4 | # |
---|
5 | # Copyright (c) 2009-2010 JC Denis and contributors |
---|
6 | # jcdenis@gdwd.com |
---|
7 | # |
---|
8 | # Licensed under the GPL version 2.0 license. |
---|
9 | # A copy of this license is available in LICENSE file or at |
---|
10 | # http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
---|
11 | # -- END LICENSE BLOCK ------------------------------------ |
---|
12 | |
---|
13 | if (!defined('DC_RC_PATH')){return;} |
---|
14 | |
---|
15 | require_once dirname(__FILE__).'/_widgets.php'; |
---|
16 | |
---|
17 | $core->addBehavior('publicEntryAfterContent',array('publicBehaviorPollsFactory','publicEntryAfterContent')); |
---|
18 | |
---|
19 | class publicUrlPollsFactory extends dcUrlHandlers |
---|
20 | { |
---|
21 | public static function page($args) |
---|
22 | { |
---|
23 | global $core; |
---|
24 | # Plugin not active |
---|
25 | if (!$core->blog->settings->pollsFactory_active) { |
---|
26 | self::p404(); |
---|
27 | return; |
---|
28 | } |
---|
29 | # Submit vote for a poll |
---|
30 | if ($args == '/vote' && !empty($_POST)) |
---|
31 | { |
---|
32 | if (empty($_POST['pollquery']) || !is_array($_POST['pollquery']) || empty($_POST['poll'])) { |
---|
33 | self::p404(); |
---|
34 | return; |
---|
35 | } |
---|
36 | $poll_id = (integer) $_POST['poll']; |
---|
37 | $redir = !empty($_POST['redir']) ? $_POST['redir'] : $core->blog->url; |
---|
38 | |
---|
39 | try { |
---|
40 | $fact = new pollsFactory($core); |
---|
41 | } |
---|
42 | catch (Exception $e) { |
---|
43 | self::p404(); |
---|
44 | return; |
---|
45 | } |
---|
46 | # Get poll |
---|
47 | try { |
---|
48 | $poll = $fact->getPolls(array('poll_id'=>$poll_id)); |
---|
49 | } |
---|
50 | catch (Exception $e) { |
---|
51 | self::p404(); |
---|
52 | return; |
---|
53 | } |
---|
54 | if ($poll->isEmpty()) { |
---|
55 | self::p404(); |
---|
56 | return; |
---|
57 | } |
---|
58 | # Check if user already voted |
---|
59 | if ($fact->hasUser($poll_id)) { |
---|
60 | http::redirect($redir); |
---|
61 | } |
---|
62 | # Get queries |
---|
63 | try { |
---|
64 | $queries = $fact->getQueries(array('poll_id'=>$poll_id)); |
---|
65 | } |
---|
66 | catch (Exception $e) { |
---|
67 | self::p404(); |
---|
68 | return; |
---|
69 | } |
---|
70 | if ($queries->isEmpty()) { |
---|
71 | self::p404(); |
---|
72 | return; |
---|
73 | } |
---|
74 | # Default values |
---|
75 | $add = false; |
---|
76 | $rsp = array(); |
---|
77 | # Loop through queries |
---|
78 | while ($queries->fetch()) |
---|
79 | { |
---|
80 | if (isset($_POST['pollquery'][$queries->query_id])) |
---|
81 | { |
---|
82 | $id = (integer) $queries->query_id; |
---|
83 | switch($queries->query_type) { |
---|
84 | |
---|
85 | case 'checkbox': |
---|
86 | if (is_array($_POST['pollquery'][$id])) { |
---|
87 | foreach($_POST['pollquery'][$id] as $k => $v) { |
---|
88 | $rsp[] = array($id,(integer) $v); |
---|
89 | $add = true; |
---|
90 | } |
---|
91 | } |
---|
92 | break; |
---|
93 | |
---|
94 | case 'radio': |
---|
95 | case 'combo': |
---|
96 | $rsp[] = array($id,(integer) $_POST['pollquery'][$id]); |
---|
97 | $add = true; |
---|
98 | break; |
---|
99 | |
---|
100 | case 'field': |
---|
101 | case 'textarea': |
---|
102 | $rsp[] = array($id,(string) $_POST['pollquery'][$id]); |
---|
103 | $add = true; |
---|
104 | break; |
---|
105 | |
---|
106 | default: |
---|
107 | break; |
---|
108 | } |
---|
109 | } |
---|
110 | } |
---|
111 | # Add reponse in database |
---|
112 | if ($add && !empty($rsp)) { |
---|
113 | try { |
---|
114 | $user_id = $fact->setUser($poll_id); |
---|
115 | $cur = $fact->openCursor('response'); |
---|
116 | foreach($rsp as $k => $v) { |
---|
117 | $cur->clean(); |
---|
118 | $cur->query_id = $v[0]; |
---|
119 | $cur->user_id = $user_id; |
---|
120 | $cur->response_text = $core->con->escape($v[1]); |
---|
121 | $fact->addResponse($cur); |
---|
122 | } |
---|
123 | |
---|
124 | # --BEHAVIOR-- publicAfterAddResponse |
---|
125 | $core->callBehavior('publicAfterAddResponse',$poll,$user_id); |
---|
126 | } |
---|
127 | catch (Exception $e) {} |
---|
128 | } |
---|
129 | # Redirect after vote |
---|
130 | http::redirect($redir); |
---|
131 | } |
---|
132 | } |
---|
133 | public static function chart($args) |
---|
134 | { |
---|
135 | $ids = explode('/',$args); |
---|
136 | if (empty($ids[0]) || empty($ids[1])) { |
---|
137 | self::p404(); |
---|
138 | return; |
---|
139 | } |
---|
140 | |
---|
141 | $_ctx =& $GLOBALS['_ctx']; |
---|
142 | $core =& $GLOBALS['core']; |
---|
143 | |
---|
144 | if (!$_ctx->exists('pollsFactoryChart')) { |
---|
145 | $_ctx->pollsFactoryChart = new pollsFactoryChart($core); |
---|
146 | } |
---|
147 | echo $_ctx->pollsFactoryChart->serveChart($ids[0],$ids[1]); |
---|
148 | } |
---|
149 | } |
---|
150 | |
---|
151 | class publicBehaviorPollsFactory |
---|
152 | { |
---|
153 | public static function publicEntryAfterContent($core,$_ctx) |
---|
154 | { |
---|
155 | # Plugin not active or not on post |
---|
156 | if (!$core->blog->settings->pollsFactory_active |
---|
157 | || !$_ctx->exists('posts') |
---|
158 | || !$_ctx->posts->post_type == 'post') |
---|
159 | { |
---|
160 | return; |
---|
161 | } |
---|
162 | # Not show poll on some pages |
---|
163 | $types = @unserialize($core->blog->settings->pollsFactory_public_tpltypes); |
---|
164 | if (!is_array($types) || !in_array($core->url->type,$types)) |
---|
165 | { |
---|
166 | return; |
---|
167 | } |
---|
168 | # Use common form for tpl and widget |
---|
169 | echo publicPollsFactoryForm($core,$_ctx->posts->post_id,__('Poll'),false,$core->blog->settings->pollsFactory_public_graph); |
---|
170 | } |
---|
171 | } |
---|
172 | |
---|
173 | function publicPollsFactoryForm($core,$post_id,$title='',$show_post_title=false,$use_graph=false) |
---|
174 | { |
---|
175 | # Start of all: a post id |
---|
176 | $post_id = (integer) $post_id; |
---|
177 | # pollsFactor object |
---|
178 | $fact = new pollsFactory($core); |
---|
179 | # Poll |
---|
180 | $p_params = array( |
---|
181 | 'post_id' => $post_id, |
---|
182 | 'sql' => "AND poll_strdt < TIMESTAMP '".date('Y-m-d H:i:s')."' " |
---|
183 | ); |
---|
184 | $poll = $fact->getPolls($p_params); |
---|
185 | # No poll on this post |
---|
186 | if ($poll->isEmpty()) |
---|
187 | { |
---|
188 | return; |
---|
189 | } |
---|
190 | # Check if poll is finished |
---|
191 | $finished = strtotime($poll->poll_enddt) < time(); |
---|
192 | # If user has not already voted and poll is not finished |
---|
193 | if (!$fact->hasUser($poll->poll_id) && !$finished) |
---|
194 | { |
---|
195 | $res = |
---|
196 | '<div class="pollsfactory poll-form">'. |
---|
197 | (empty($title) ? '' : '<h2>'.$title.'</h2>'). |
---|
198 | ($show_post_title ? '<p>'.html::escapeHTML($poll->post_title).'</>' : ''). |
---|
199 | '<form id="poll'.$poll->poll_id.'" method="post" action="'.$core->blog->url.$core->url->getBase('pollsFactoryPage').'/vote">'; |
---|
200 | |
---|
201 | # Poll queries |
---|
202 | $queries = $fact->getQueries(array('poll_id'=>$poll->poll_id)); |
---|
203 | # No query for this poll |
---|
204 | if ($queries->isEmpty()) |
---|
205 | { |
---|
206 | return; |
---|
207 | } |
---|
208 | # Loop throught queries of this poll |
---|
209 | while ($queries->fetch()) |
---|
210 | { |
---|
211 | # Query options |
---|
212 | $options = $fact->getOptions(array('query_id'=>$queries->query_id)); |
---|
213 | # No option for this query |
---|
214 | if ($options->isEmpty()) |
---|
215 | { |
---|
216 | return; |
---|
217 | } |
---|
218 | # Default values |
---|
219 | $options_res = $options_combo = ''; |
---|
220 | $option_name = 'pollquery['.$queries->query_id.']'; |
---|
221 | $option_selected = 1; |
---|
222 | # Loop through options of this query |
---|
223 | while ($options->fetch()) |
---|
224 | { |
---|
225 | $option_id = 'pollquery['.$queries->query_id.']['.$options->option_id.']'; |
---|
226 | # Parse option by type of query |
---|
227 | switch($queries->query_type) { |
---|
228 | |
---|
229 | case 'checkbox': |
---|
230 | $options_res .= |
---|
231 | '<p><label for="'.$option_id.'">'. |
---|
232 | form::checkbox($option_id,$options->option_id,0,'poll-checkbox').' '. |
---|
233 | html::escapeHTML($options->option_text).'</label></p>'; |
---|
234 | break; |
---|
235 | |
---|
236 | case 'radio': |
---|
237 | $options_res .= |
---|
238 | '<p><label for="'.$option_id.'">'. |
---|
239 | form::radio(array($option_name,$option_id),$options->option_id,$option_selected,'poll-combo').' '. |
---|
240 | html::escapeHTML($options->option_text).'</label></p>'; |
---|
241 | $option_selected = 0; |
---|
242 | break; |
---|
243 | |
---|
244 | case 'combo': |
---|
245 | if ($option_selected) { |
---|
246 | $option_combo_selected = $options->option_id; |
---|
247 | $option_selected = 0; |
---|
248 | } |
---|
249 | $options_combo_nid = array($option_name,$option_id); |
---|
250 | $options_combo[$options->option_text] = $options->option_id; |
---|
251 | break; |
---|
252 | |
---|
253 | case 'field': |
---|
254 | $options_res .= |
---|
255 | '<p>'.form::field(array($option_name,$option_id),65,255,'','poll-field').'</p>'; |
---|
256 | break; |
---|
257 | |
---|
258 | case 'textarea': |
---|
259 | $options_res .= |
---|
260 | '<p>'.form::textArea(array($option_name,$option_id),65,5,'','poll-textarea').'</p>'; |
---|
261 | break; |
---|
262 | |
---|
263 | default: |
---|
264 | break; |
---|
265 | } |
---|
266 | } |
---|
267 | # Parse query options |
---|
268 | if (!empty($options_res) && $queries->query_type != 'combo' || !empty($options_combo) && $queries->query_type == 'combo') |
---|
269 | { |
---|
270 | $res .= '<div class="poll-query">'; |
---|
271 | |
---|
272 | # Query title |
---|
273 | $res .= '<h3>'.html::escapeHTML($queries->query_title).'</h3>'; |
---|
274 | # Query description |
---|
275 | if (!empty($queries->query_desc)) |
---|
276 | { |
---|
277 | $res .= '<div class="poll-query-desc">'.$queries->query_desc.'</div>'; |
---|
278 | } |
---|
279 | # Options (and special content for combo) |
---|
280 | $res .= $queries->query_type == 'combo' ? |
---|
281 | '<p>'.form::combo($options_combo_nid,$options_combo,$option_combo_selected,'poll-combo').'</p>' : |
---|
282 | $options_res; |
---|
283 | |
---|
284 | $res .= '</div>'; |
---|
285 | } |
---|
286 | } |
---|
287 | # Form |
---|
288 | return |
---|
289 | $res. |
---|
290 | '<div class="poll-submit"><p>'. |
---|
291 | '<input type="hidden" name="poll" value="'.$poll->poll_id.'" />'. |
---|
292 | '<input type="hidden" name="redir" value="'.http::getSelfURI().'" />'. |
---|
293 | '<input type="submit" name="submit" value="'.__('Validate').'" />'. |
---|
294 | '</p></div>'. |
---|
295 | '</form></div>'; |
---|
296 | } |
---|
297 | # If user has voted and settings say to show reponses or poll is finished |
---|
298 | elseif ($core->blog->settings->pollsFactory_public_show || $finished) |
---|
299 | { |
---|
300 | # Count responses |
---|
301 | $count = $fact->countUsers($poll->poll_id); |
---|
302 | # Poll queries |
---|
303 | $queries = $fact->getQueries(array('poll_id'=>$poll->poll_id)); |
---|
304 | # No query for this poll |
---|
305 | if ($queries->isEmpty()) |
---|
306 | { |
---|
307 | return; |
---|
308 | } |
---|
309 | $res = ''; |
---|
310 | # Loop through queries |
---|
311 | while ($queries->fetch()) |
---|
312 | { |
---|
313 | # If display graphics is on, switch to image for integer responses |
---|
314 | if ($use_graph && in_array($queries->query_type,array('checkbox','radio','combo'))) { |
---|
315 | $res .= '<p class="poll-chart"><img src="'. |
---|
316 | $core->blog->url.$core->url->getBase('pollsFactoryChart').'/'. |
---|
317 | $poll->poll_id.'/'.$queries->query_id.'" alt="'.html::escapeHTML($queries->query_title).'" /></p>'; |
---|
318 | } |
---|
319 | # Else use html |
---|
320 | else { |
---|
321 | $rs = array(); |
---|
322 | $id = $queries->query_id; |
---|
323 | $options = $fact->getOptions(array('query_id'=>$id)); |
---|
324 | $responses = $fact->getResponses(array('query_id'=>$id)); |
---|
325 | |
---|
326 | # Loop through responses for this query |
---|
327 | while($responses->fetch()) |
---|
328 | { |
---|
329 | switch($queries->query_type) { |
---|
330 | |
---|
331 | case 'checkbox': |
---|
332 | case 'radio': |
---|
333 | case 'combo': |
---|
334 | $rs[$responses->response_text] += 1; |
---|
335 | break; |
---|
336 | |
---|
337 | case 'field': |
---|
338 | case 'textarea': |
---|
339 | if ($responses->response_selected) { |
---|
340 | $rs[] = $responses->response_text; |
---|
341 | } |
---|
342 | default: |
---|
343 | break; |
---|
344 | } |
---|
345 | } |
---|
346 | # There's something to show |
---|
347 | if (!empty($rs)) |
---|
348 | { |
---|
349 | # For integer responses |
---|
350 | if (in_array($queries->query_type,array('checkbox','radio','combo'))) { |
---|
351 | # Sort responses by number of votes |
---|
352 | $rs_sort = array(); |
---|
353 | while($options->fetch()) |
---|
354 | { |
---|
355 | $nb = isset($rs[$options->option_id]) ? $rs[$options->option_id] : 0; |
---|
356 | $percent = ceil($nb / $count * 100).'%'; |
---|
357 | |
---|
358 | if ($nb == 0) { |
---|
359 | $nb_text = __('no vote'); |
---|
360 | } |
---|
361 | elseif ($nb == 1) { |
---|
362 | $nb_text = __('one vote'); |
---|
363 | } |
---|
364 | else { |
---|
365 | $nb_text = sprintf(__('%s votes'),$nb); |
---|
366 | } |
---|
367 | |
---|
368 | $rs_sort[] = array( |
---|
369 | 'nb'=>$nb, |
---|
370 | 'text'=>'<li><strong>'.$options->option_text.'</strong> '.$percent.' <em>('.$nb_text.')</em></li>' |
---|
371 | ); |
---|
372 | } |
---|
373 | $sorted = staticRecord::newFromArray($rs_sort); |
---|
374 | $sorted->sort('nb','desc'); |
---|
375 | |
---|
376 | # Parse responses |
---|
377 | $res .= '<h3>'.html::escapeHTML($queries->query_title).'</h3>'; |
---|
378 | if ('' != $queries->query_desc) { |
---|
379 | // $res .= '<p class="poll-query-desc">'.html::escapeHTML($queries->query_desc).'<p>'; |
---|
380 | } |
---|
381 | $res .= '<ul>'; |
---|
382 | while($sorted->fetch()) |
---|
383 | { |
---|
384 | $res .= $sorted->text; |
---|
385 | } |
---|
386 | $res .= '</ul>'; |
---|
387 | } |
---|
388 | # For text responses |
---|
389 | else { |
---|
390 | $res .= '<h3>'.html::escapeHTML($queries->query_title).'</h3>'; |
---|
391 | if ('' != $queries->query_desc) { |
---|
392 | // $res .= '<p class="poll-query-desc">'.html::escapeHTML($queries->query_desc).'<p>'; |
---|
393 | } |
---|
394 | $res .= '<p><em>'.__('Some selected responses:').'</em><br />'; |
---|
395 | foreach($rs as $k => $v) { |
---|
396 | $res .= '<blockquote>'.html::escapeHTML($v).'</blockquote>'; |
---|
397 | } |
---|
398 | $res .= '</p>'; |
---|
399 | } |
---|
400 | } |
---|
401 | } |
---|
402 | } |
---|
403 | if (!empty($res)) |
---|
404 | { |
---|
405 | $res = |
---|
406 | '<div class="pollsfactory poll-result"><h2>'.$title.'</h2>'. |
---|
407 | ($show_post_title ? '<p>'.html::escapeHTML($poll->post_title).'</p>' : ''). |
---|
408 | '<p>'. |
---|
409 | (!$finished ? |
---|
410 | sprintf(__('This poll ends on %s.'),dt::dt2str($core->blog->settings->date_format.', '.$core->blog->settings->time_format,$poll->poll_enddt,$core->blog->timezone)).'<br />' : |
---|
411 | __('This poll is closed').'<br />' |
---|
412 | ). |
---|
413 | sprintf(__('%s people participated.'),$count). |
---|
414 | '</p>'. |
---|
415 | $res. |
---|
416 | '</div>'; |
---|
417 | } |
---|
418 | return $res; |
---|
419 | } |
---|
420 | # If user has voted and settings say not to show responses |
---|
421 | else |
---|
422 | { |
---|
423 | return |
---|
424 | '<div class="pollsfactory poll-wait"><h2>'.$title.'</h2>'. |
---|
425 | ($show_post_title ? '<p>'.html::escapeHTML($poll->post_title).'</>' : ''). |
---|
426 | '<p>'. |
---|
427 | __('You have already participated to this poll.').'<br />'. |
---|
428 | __('Please wait the end of this poll to see results.').'<br />'. |
---|
429 | sprintf(__('This poll ends on %s.'),dt::dt2str($core->blog->settings->date_format.', '.$core->blog->settings->time_format,$poll->poll_enddt,$core->blog->timezone)). |
---|
430 | '</p>'. |
---|
431 | '</div>'; |
---|
432 | } |
---|
433 | } |
---|
434 | ?> |
---|