Dotclear

source: plugins/pollsFactory/_public.php @ 2338

Revision 2338, 18.4 KB checked in by JcDenis, 13 years ago (diff)

pollsFactory 1.3

  • Switched to DC 2.2
  • Fixed minor bugs
Line 
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
13if (!defined('DC_RC_PATH')){return;}
14
15require_once dirname(__FILE__).'/_widgets.php';
16
17$core->addBehavior('publicEntryBeforeContent',array('publicBehaviorPollsFactory','publicEntryBeforeContent'));
18$core->addBehavior('publicEntryAfterContent',array('publicBehaviorPollsFactory','publicEntryAfterContent'));
19
20$core->tpl->addValue('PollTitle',array('publicTplPollsFactory','PollTitle'));
21$core->tpl->addValue('PollContent',array('publicTplPollsFactory','PollContent'));
22$core->tpl->addValue('PollForm',array('publicTplPollsFactory','PollForm'));
23
24# URL handler
25class publicUrlPollsFactory extends dcUrlHandlers
26{
27     # Poll detail
28     public static function pollPage($args)
29     {
30          if ($args == '') {
31               self::p404();
32               return;
33          }
34
35          $_ctx =& $GLOBALS['_ctx'];
36          $core =& $GLOBALS['core'];
37
38          # Plugin not active
39          if (!$core->blog->settings->pollsFactory->pollsFactory_active) {
40               self::p404();
41               return;
42          }
43
44          # Submit vote for a poll
45          if ($args == 'vote' && !empty($_POST['poll']))
46          {
47               if (empty($_POST['pollquery']) || !is_array($_POST['pollquery']) || empty($_POST['poll'])) {
48                    self::p404();
49                    return;
50               }
51               $poll_id = (integer) $_POST['poll'];
52               $redir = !empty($_POST['redir']) ? $_POST['redir'] : $core->blog->url;
53
54               # Get poll
55               try {
56                    $poll_params = array();
57                    $poll_params['post_id'] = (integer) $poll_id;
58                    $poll_params['post_type'] = 'pollsfactory';
59                    $poll_params['sql'] = 'AND post_open_tb = 1 ';
60
61                    $poll = $core->blog->getPosts($poll_params);
62               }
63               catch (Exception $e) {
64                    self::p404();
65                    return;
66               }
67               if ($poll->isEmpty()) {
68                    self::p404();
69                    return;
70               }
71               try {
72                    $factory = new pollsFactory($core);
73               }
74               catch (Exception $e) {
75                    self::p404();
76                    return;
77               }
78               # Check if people already voted
79               if ($factory->checkVote($poll->post_id)) {
80                    http::redirect($redir);
81               }
82               # Get queries
83               try {
84                    $queries_params['option_type'] = 'pollsquery';
85                    $queries_params['post_id'] = $poll->post_id;
86                    $queries = $factory->getOptions($queries_params);
87               }
88               catch (Exception $e) {
89                    self::p404();
90                    return;
91               }
92               if ($queries->isEmpty()) {
93                    self::p404();
94                    return;
95               }
96               # Default values
97               $add = false;
98               $rsp = array();
99               # Loop through queries
100               while ($queries->fetch())
101               {
102                    if (isset($_POST['pollquery'][$queries->option_id]))
103                    {
104                         $id = (integer) $queries->option_id;
105                         switch($queries->option_meta) {
106
107                              case 'checkbox':
108                              if (is_array($_POST['pollquery'][$id])) {
109                                   foreach($_POST['pollquery'][$id] as $k => $v) {
110                                        $rsp[] = array($id,(integer) $v);
111                                        $add = true;
112                                   }
113                              }
114                              break;
115
116                              case 'radio':
117                              case 'combo':
118                              $rsp[] = array($id,(integer) $_POST['pollquery'][$id]);
119                              $add = true;
120                              break;
121
122                              case 'field':
123                              case 'textarea':
124                              $rsp[] = array($id,(string) $_POST['pollquery'][$id]);
125                              $add = true;
126                              break;
127
128                              default:
129                              break;
130                         }
131                    }
132               }
133               # Add reponse in database
134               if ($add && !empty($rsp)) {
135                    try {
136                         # --BEHAVIOR-- publicBeforePollsFactoryVote
137                         $core->callBehavior('publicBeforePollsFactoryVote',$poll);
138
139                         $people_id = $factory->setVote($poll->post_id);
140                         $cur = $factory->open();
141                         foreach($rsp as $k => $v) {
142                              $cur->clean();
143                              $cur->post_id = $poll->post_id;
144                              $cur->option_type = 'pollsresponse';
145                              $cur->option_lang = $poll->post_lang;
146                              $cur->option_meta = $v[0];
147                              $cur->option_title = $people_id;
148                              $cur->option_content = $core->con->escape($v[1]);
149                              $core->auth->sudo(array($factory,'addOption'),$cur);
150                         }
151
152                         # --BEHAVIOR-- publicAfterPollsFactoryVote
153                         $core->callBehavior('publicAfterPollsFactoryVote',$poll,$people_id);
154                    }
155                    catch (Exception $e) {}
156               }
157               # Redirect after vote
158               http::redirect($redir);
159          }
160
161          # params
162          $params = new ArrayObject();
163          $params['post_type'] = 'pollsfactory';
164          $params['post_url'] = $args;
165
166          if (!$_ctx->preview) {/* nothing to do now! see publicPollsFactoryForm */}
167
168          $_ctx->posts = $core->blog->getPosts($params);
169
170          if ($_ctx->posts->isEmpty()) {
171               self::p404();
172               return;
173          }
174
175          $core->tpl->setPath($core->tpl->getPath(),dirname(__FILE__).'/default-templates/');
176
177          self::serveDocument('pollsfactory.html','text/html');
178     }
179
180     public static function pollPagePreview($args)
181     {
182          global $core;
183          $_ctx = $GLOBALS['_ctx'];
184
185          if (!preg_match('#^(.+?)/([0-9a-z]{40})/(.+?)$#',$args,$m)) {
186               # The specified Preview URL is malformed.
187               self::p404();
188          }
189          else
190          {
191               $user_id = $m[1];
192               $user_key = $m[2];
193               $poll_url = $m[3];
194               if (!$core->auth->checkUser($user_id,null,$user_key)) {
195                    # The user has no access to the entry.
196                    self::p404();
197               }
198               else
199               {
200                    $_ctx->preview = true;
201                    self::pollPage($poll_url);
202               }
203          }
204     }
205
206     # Query image
207     public static function pollChart($args)
208     {
209          global $core;
210
211          # Plugin not active
212          if (!$core->blog->settings->pollsFactory->pollsFactory_active) {
213               self::p404();
214               return;
215          }
216          # Get poll and query id
217          $ids = explode('/',$args);
218          if (empty($ids[0]) || empty($ids[1])) {
219               self::p404();
220               return;
221          }
222     
223          $_ctx =& $GLOBALS['_ctx'];
224          $core =& $GLOBALS['core'];
225
226          if (!$_ctx->exists('pollsFactoryChart')) {
227               $_ctx->pollsFactoryChart = new pollsFactoryChart($core);
228          }
229          echo $_ctx->pollsFactoryChart->serveChart($ids[0],$ids[1]);
230          exit(1);
231     }
232}
233
234# Template
235class publicTplPollsFactory
236{
237     public static function PollTitle($a)
238     {
239          return '<?php echo '.sprintf($GLOBALS['core']->tpl->getFilters($a),'$_ctx->posts->post_title').'; ?>';
240     }
241
242     public static function PollContent($a)
243     {
244          $url = empty($attr['absolute_urls']) ? 0 : 1;
245          return '<?php echo '.sprintf($GLOBALS['core']->tpl->getFilters($a),'$_ctx->posts->getContent('.$url.')').'; ?>';
246     }
247
248     public static function PollForm($a)
249     {
250          return 
251          "<?php \n".
252          "echo publicPollsFactoryForm(\$core,\$_ctx->posts->post_id,false,false,\$core->blog->settings->pollsFactory->pollsFactory_public_graph); \n".
253          "?> \n";
254     }
255}
256
257# Post behavior
258class publicBehaviorPollsFactory
259{
260     public static function publicEntryBeforeContent($core,$_ctx)
261     {
262          if ($core->blog->settings->pollsFactory->pollsFactory_public_pos) return;
263          return self::publicEntryContent($core,$_ctx);
264     }
265
266     public static function publicEntryAfterContent($core,$_ctx)
267     {
268          if (!$core->blog->settings->pollsFactory->pollsFactory_public_pos) return;
269          return self::publicEntryContent($core,$_ctx);
270     }
271
272     public static function publicEntryContent($core,$_ctx)
273     {
274          # Plugin not active or not on post
275          if (!$core->blog->settings->pollsFactory->pollsFactory_active 
276           || !$_ctx->exists('posts'))
277          {
278               return;
279          }
280          # Not show poll on some pages
281          $types = @unserialize($core->blog->settings->pollsFactory->pollsFactory_public_tpltypes);
282          if (!is_array($types) || !in_array($core->url->type,$types))
283          {
284               return;
285          }
286
287          # pollsFactor object
288          $factory = new pollsFactory($core);
289
290          # Get polls linked to this post
291          $posts_params['option_type'] = 'pollspost';
292          $posts_params['post_id'] = $_ctx->posts->post_id;
293          $posts = $factory->getOptions($posts_params);
294          # No poll on this post
295          if ($posts->isEmpty())
296          {
297               return;
298          }
299
300          if ($core->blog->settings->pollsFactory->pollsFactory_public_full) {
301               while ($posts->fetch())
302               {
303                    # Use common form for tpl and widget
304                    echo publicPollsFactoryForm($core,$posts->option_meta,true,true,$core->blog->settings->pollsFactory->pollsFactory_public_graph);
305               }
306          }
307          else {
308               echo 
309               '<div class="pollsfactory pollslist-post"><h3>'.__('Polls').'</h3><ul>';
310               while ($posts->fetch())
311               {
312                    $poll_params['post_type'] = 'pollsfactory';
313                    $poll_params['post_id'] = $posts->option_meta;
314                    $poll_params['no_content'] = true;
315                    $poll_params['limit'] = 1;
316                    $poll = $core->blog->getPosts($poll_params);
317                    echo '<li><a href="'.$core->blog->url.$core->url->getBase('pollsFactoryPage').'/'.$poll->post_url.'">'.html::escapeHTML($poll->post_title).'</a></li>';
318               }
319               echo '</ul></div>';
320          }
321     }
322}
323
324# Common function to parse poll form/results
325function publicPollsFactoryForm($core,$poll_id,$show_title=false,$show_desc=false,$use_graph=false)
326{
327     # Start of all: a post id
328     $poll_id = (integer) $poll_id;
329     # Get poll
330     $poll_params['post_type'] = 'pollsfactory';
331     $poll_params['post_id'] = $poll_id;
332     $poll = $core->blog->getPosts($poll_params);
333     # No poll
334     if ($poll->isEmpty())
335     {
336          return;
337     }
338     # pollsFactor object
339     $factory = new pollsFactory($core);
340     # Poll title
341     $poll_title = '';
342     if ($show_title) {
343          $poll_title .= '<h3 class="poll-title">'.html::escapeHTML($poll->post_title).'</h3>';
344     }
345     if ($show_desc) {
346          $poll_title .= '<p class="poll-desc">'.context::global_filter($poll->post_content,0,0,0,0,0).'</p>';
347     }
348
349     # Check if poll is closed
350     $finished = !$poll->post_open_tb;
351     # If preview mode or people has not already voted and poll is not finished
352     if ($GLOBALS['_ctx']->preview || !$factory->checkVote($poll->post_id) && !$finished)
353     {
354          $res = 
355          '<div class="pollsfactory poll-form">'.$poll_title.
356          '<form id="poll'.$poll->post_id.'" method="post" action="'.$core->blog->url.$core->url->getBase('pollsFactoryPage').'/vote">';
357
358          # Poll queries
359          $queries_params['option_type'] = 'pollsquery';
360          $queries_params['post_id'] = $poll->post_id;
361          $queries_params['order'] = 'option_position ASC';
362          $queries = $factory->getOptions($queries_params);
363          # No query for this poll
364          if (!$queries->isEmpty())
365          {
366               # Loop throught queries of this poll
367               while ($queries->fetch())
368               {
369                    # Query selections
370                    $selections_params['option_type'] = 'pollsselection';
371                    $selections_params['post_id'] = $poll->post_id;
372                    $selections_params['option_meta'] = $queries->option_id;
373                    $selections_params['order'] = 'option_position ASC';
374                    $selections = $factory->getOptions($selections_params);
375                    # No option for this query
376                    if (!$selections->isEmpty())
377                    {
378                         # Default values
379                         $selections_res = $selections_combo = '';
380                         $selection_name = 'pollquery['.$queries->option_id.']';
381                         $selection_selected = 1;
382                         # Loop through options of this query
383                         while ($selections->fetch())
384                         {
385                              $selection_id = 'pollquery['.$queries->option_id.']['.$selections->option_id.']';
386                              # Parse option by type of query
387                              switch($queries->option_meta) {
388                             
389                                   case 'checkbox':
390                                   $selections_res .= 
391                                   '<p class="field"><label for="'.$selection_id.'">'.
392                                   form::checkbox($selection_id,$selections->option_id,0,'poll-checkbox').' '.
393                                   html::escapeHTML($selections->option_title).'</label></p>';
394                                   break;
395
396                                   case 'radio':
397                                   $selections_res .= 
398                                   '<p class="field"><label for="'.$selection_id.'">'.
399                                   form::radio(array($selection_name,$selection_id),$selections->option_id,$selection_selected,'poll-radio').' '.
400                                   html::escapeHTML($selections->option_title).'</label></p>';
401                                   $selection_selected = 0;
402                                   break;
403
404                                   case 'combo':
405                                   if ($selection_selected) {
406                                        $selection_combo_selected = $selections->option_id;
407                                        $selection_selected = 0;
408                                   }
409                                   $selections_combo_nid = array($selection_name,$selection_id);
410                                   $selections_combo[$selections->option_title] = $selections->option_id;
411                                   break;
412
413                                   case 'field':
414                                   $selections_res .= 
415                                   '<p class="field">'.form::field(array($selection_name,$selection_id),30,255,'','poll-field').'</p>';
416                                   break;
417
418                                   case 'textarea':
419                                   $selections_res .= 
420                                   '<p class="field">'.form::textArea(array($selection_name,$selection_id),35,7,'','poll-textarea').'</p>';
421                                   break;
422                             
423                                   default:
424                                   break;
425                              }
426                         }
427                         # Parse query options
428                         if (!empty($selections_res) && $queries->option_meta != 'combo' || !empty($selections_combo) && $queries->option_meta == 'combo')
429                         {
430                              $res .= '<div class="poll-query">';
431
432                              # Query title
433                              $res .= '<h4>'.html::escapeHTML($queries->option_title).'</h4>';
434                              # Query description
435                              if ('' != $queries->option_content)
436                              {
437                                   $res .= '<div class="poll-query-desc">'.context::global_filter($queries->option_content,0,0,0,0,0).'</div>';
438                              }
439                              # Options (and special content for combo)
440                              $res .= $queries->option_meta == 'combo' ?
441                                   '<p class="field">'.form::combo($selections_combo_nid,$selections_combo,$selection_combo_selected,'poll-combo').'</p>' :
442                                   $selections_res;
443
444                              $res .= '</div>';
445                         }
446                    }
447               }
448               # Form
449               return 
450               $res. 
451               '<div class="poll-submit"><p>'.
452               '<input type="hidden" name="poll" value="'.$poll->post_id.'" />'.
453               '<input type="hidden" name="redir" value="'.http::getSelfURI().'" />'.
454               '<input type="submit" name="submit" value="'.__('Validate').'" />'.
455               '</p></div>'.
456               '</form></div>';
457          }
458     }
459     # If people has voted and settings say to show reponses or poll is finished
460     elseif ($core->blog->settings->pollsFactory->pollsFactory_public_show || $finished)
461     {
462          $res = '';
463          # Count responses
464          $count = $factory->countVotes($poll->post_id);
465          if ($count > 0)
466          {
467               # Poll queries
468               $queries_params['option_type'] = 'pollsquery';
469               $queries_params['post_id'] = $poll->post_id;
470               $queries_params['order'] = 'option_position ASC';
471               $queries = $factory->getOptions($queries_params);
472               # No query for this poll
473               if (!$queries->isEmpty())
474               {
475                    # Loop through queries
476                    while ($queries->fetch())
477                    {
478                         # Query selections
479                         $selections_params['option_type'] = 'pollsselection';
480                         $selections_params['post_id'] = $poll->post_id;
481                         $selections_params['option_meta'] = $queries->option_id;
482                         $selections = $factory->getOptions($selections_params);
483
484                         # Query responses
485                         $responses_params['option_type'] = 'pollsresponse';
486                         $responses_params['post_id'] = $poll->post_id;
487                         $responses_params['option_meta'] = $queries->option_id;
488                         $responses = $factory->getOptions($responses_params);
489
490                         # If there's somthing to show
491                         if (!$selections->isEmpty() && !$responses->isEmpty())
492                         {
493                              # If display graphics is on, switch to image for integer responses
494                              if ($use_graph && in_array($queries->option_meta,array('checkbox','radio','combo'))) {
495                                   $res .= '<p class="poll-chart"><img src="'.
496                                   $core->blog->url.$core->url->getBase('pollsFactoryChart').'/'.
497                                   $poll->post_id.'/'.$queries->option_id.'.png" alt="'.html::escapeHTML($queries->option_title).'" /></p>';
498                              }
499                              # Else use html
500                              else {
501                                   $rs = array();
502
503                                   # Loop through responses for this query
504                                   while($responses->fetch())
505                                   {
506                                        switch($queries->option_meta) {
507                                       
508                                             case 'checkbox':
509                                             case 'radio':
510                                             case 'combo':
511                                             if (!isset($rs[$responses->option_content])) {
512                                                  $rs[$responses->option_content] = 0;
513                                             }
514                                             $rs[$responses->option_content] += 1;
515                                             break;
516
517                                             case 'field':
518                                             case 'textarea':
519                                             if ($responses->option_selected) {
520                                                  $rs[] = $responses->option_content;
521                                             }
522                                             default:
523                                             break;
524                                        }
525                                   }
526                                   # There's something to show
527                                   if (!empty($rs))
528                                   {
529                                        # For integer responses
530                                        if (in_array($queries->option_meta,array('checkbox','radio','combo'))) {
531                                             # Sort responses by number of votes
532                                             $rs_sort = array();
533                                             while($selections->fetch())
534                                             {
535                                                  $nb = isset($rs[$selections->option_id]) ? $rs[$selections->option_id] : 0;
536                                                  $percent = $nb ? ceil($nb / $count * 100).'% - ' : '';
537
538                                                  if ($nb == 0) {
539                                                       $nb_text = __('no vote');
540                                                  }
541                                                  elseif ($nb == 1) {
542                                                       $nb_text = __('one vote');
543                                                  }
544                                                  else {
545                                                       $nb_text = sprintf(__('%s votes'),$nb);
546                                                  }
547
548                                                  $rs_sort[] = array(
549                                                       'nb'=>$nb,
550                                                       'text'=>'<dt>'.$selections->option_title.'</dt><dd>'.$percent.$nb_text.'</dd>'
551                                                  );
552                                             }
553                                             $sorted = staticRecord::newFromArray($rs_sort);
554                                             $sorted->sort('nb','desc');
555
556                                             # Parse responses
557                                             $res .= '<h4>'.html::escapeHTML($queries->option_title).'</h4>';
558                                             if ('' != $queries->option_content) {
559               //                                 $res .= '<p class="poll-query-desc">'.html::escapeHTML($queries->query_desc).'<p>';
560                                             }
561                                             $res .= '<dl>';
562                                             while($sorted->fetch())
563                                             {
564                                                  $res .= $sorted->text;
565                                             }
566                                             $res .= '</dl>';
567                                        }
568                                        # For text responses
569                                        else {
570                                             $res .= '<h4>'.html::escapeHTML($queries->option_title).'</h4>';
571                                             if ('' != $queries->option_content) {
572               //                                 $res .= '<p class="poll-query-desc">'.html::escapeHTML($queries->query_desc).'<p>';
573                                             }
574                                             $res .= '<p><em>'.__('Some selected responses:').'</em><br />';
575                                             foreach($rs as $k => $v) {
576                                                  $res .= '<blockquote>'.html::escapeHTML($v).'</blockquote>'; //? some bugs on escape strings
577                                             }
578                                             $res .= '</p>';
579                                        }
580                                   }
581                              }
582                         }
583                    }
584               }
585          }
586          # If there are results or nobody has voted
587          if (!empty($res) || !$count)
588          {
589               if ($count == 0) {
590                    $participate = __('Nobody has participated.');
591               }
592               elseif ($count == 1) {
593                    $participate = __('One people has participated.');
594               }
595               else {
596                    $participate = sprintf(__('%s people participated.'),$count);
597               }
598
599               $closed = $finished ? __('This poll is closed.').'<br />' : '';
600
601               $res =   
602               '<div class="pollsfactory poll-result">'.$poll_title.
603               '<p class="poll-info">'.$closed.$participate.'</p>'.$res.
604               '</div>';
605          }
606          return $res;
607     }
608     # If people has voted and settings say not to show responses
609     else
610     {
611          return
612          '<div class="pollsfactory poll-wait">'.$poll_title.
613          '<p class="poll-info">'.
614          __('You have already participated to this poll.').'<br />'.
615          __('Please wait the end of this poll to see results.').'<br />'.
616          '</p>'.
617          '</div>';
618     }
619}
620?>
Note: See TracBrowser for help on using the repository browser.

Sites map