Fixed display of the Polls block when it only contained blocks not visible for anonymous visitors (bug #0000996)
3 /* Reminder: always indent with 4 spaces (no tabs). */
4 // +---------------------------------------------------------------------------+
5 // | Polls Plugin 2.1 |
6 // +---------------------------------------------------------------------------+
9 // | This file does two things: 1) it implements the necessary Geeklog Plugin |
10 // | API method and 2) implements all the common code needed by the Polls |
11 // | plugin' PHP files. |
12 // +---------------------------------------------------------------------------+
13 // | Copyright (C) 2000-2009 by the following authors: |
15 // | Authors: Tony Bibbs - tony AT tonybibbs DOT com |
16 // | Tom Willett - twillett AT users DOT sourceforge DOT net |
17 // | Blaine Lang - langmail AT sympatico DOT ca |
18 // | Dirk Haun - dirk AT haun-online DOT de |
19 // +---------------------------------------------------------------------------+
21 // | This program is free software; you can redistribute it and/or |
22 // | modify it under the terms of the GNU General Public License |
23 // | as published by the Free Software Foundation; either version 2 |
24 // | of the License, or (at your option) any later version. |
26 // | This program is distributed in the hope that it will be useful, |
27 // | but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 // | GNU General Public License for more details. |
31 // | You should have received a copy of the GNU General Public License |
32 // | along with this program; if not, write to the Free Software Foundation, |
33 // | Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
35 // +---------------------------------------------------------------------------+
38 * Implementation of the Plugin API for the Polls plugin
43 if (strpos(strtolower($_SERVER['PHP_SELF']), 'functions.inc') !== false) {
44 die('This file can not be used on its own.');
47 $plugin_path = $_CONF['path'] . 'plugins/polls/';
50 * Language file include
52 $langfile = $plugin_path . 'language/' . $_CONF['language'] . '.php';
53 if (file_exists($langfile)) {
54 require_once $langfile;
56 require_once $plugin_path . 'language/english.php';
60 * Check and see if we need to load the plugin configuration
62 if (!isset($_PO_CONF['pollsloginrequired'])) {
63 require_once $_CONF['path_system'] . 'classes/config.class.php';
65 $po_config = config::get_instance();
66 $_PO_CONF = $po_config->get_config('polls');
70 // +---------------------------------------------------------------------------+
71 // | Geeklog Plugin API Implementations |
72 // +---------------------------------------------------------------------------+
75 * Returns the items for this plugin that should appear on the main menu
77 * NOTE: this MUST return the url/value pairs in the following format
78 * $<arrayname>[<label>] = <url>
80 * @return mixed menu entry, or boolean false if disabled / hidden
82 function plugin_getmenuitems_polls ()
84 global $_CONF, $_PO_CONF, $LANG_POLLS;
86 if (($_PO_CONF['hidepollsmenu'] == 1) || (COM_isAnonUser() &&
87 ($_CONF['loginrequired'] || $_PO_CONF['pollsloginrequired']))) {
91 $menuitems[$LANG_POLLS['polls']] = $_CONF['site_url'] . '/polls/index.php';
97 * Poll saves a comment
99 * @param string $title comment title
100 * @param string $comment comment text
101 * @param string $id Item id to which $cid belongs
102 * @param int $pid comment parent
103 * @param string $postmode 'html' or 'text'
104 * @return mixed false for failure, HTML string (redirect?) for success
106 function plugin_savecomment_polls($title, $comment, $id, $pid, $postmode)
108 global $_CONF, $_TABLES, $LANG03, $_USER;
112 $commentcode = DB_getItem($_TABLES['polltopics'], 'commentcode',
114 if ($commentcode != 0) {
115 return COM_refresh($_CONF['site_url'] . '/index.php');
118 $ret = CMT_saveComment($title, $comment, $id, $pid, 'polls', $postmode);
119 if ($ret > 0) { // failure //FIXME: some failures should not return to comment form
120 $retval .= COM_siteHeader('menu', $LANG03[1])
121 . CMT_commentForm($title, $comment, $id, $pid, 'polls',
122 $LANG03[14], $postmode)
126 if (($_CONF['commentsubmission'] == 1) &&
127 !SEC_hasRights('comment.submit')) {
130 $retval = COM_refresh($_CONF['site_url']
131 . "/polls/index.php?pid=$id&aid=-1$msg");
138 * polls: delete a comment
140 * @param int $cid Comment to be deleted
141 * @param string $id Item id to which $cid belongs
142 * @return mixed false for failure, HTML string (redirect?) for success
144 function plugin_deletecomment_polls($cid, $id)
146 global $_CONF, $_TABLES, $_USER;
150 $has_editPermissions = SEC_hasRights ('polls.edit');
151 $result = DB_query ("SELECT owner_id,group_id,perm_owner,perm_group,perm_members,perm_anon FROM {$_TABLES['polltopics']} WHERE pid = '{$id}'");
152 $A = DB_fetchArray ($result);
154 if ($has_editPermissions && SEC_hasAccess ($A['owner_id'],
155 $A['group_id'], $A['perm_owner'], $A['perm_group'],
156 $A['perm_members'], $A['perm_anon']) == 3) {
157 CMT_deleteComment($cid, $id, 'polls');
158 $retval .= COM_refresh ($_CONF['site_url']
159 . "/polls/index.php?pid=$id&aid=-1");
161 COM_errorLog ("User {$_USER['username']} (IP: {$_SERVER['REMOTE_ADDR']}) "
162 . "tried to illegally delete comment $cid from poll $id");
163 $retval .= COM_refresh ($_CONF['site_url'] . '/index.php');
171 * Helper function: count number of polls and total number of votes
173 * @return array(number of polls, number of votes);
176 function POLLS_countPollsAndVotes ()
183 $result = DB_query ("SELECT COUNT(*) AS count FROM {$_TABLES['polltopics']}" . COM_getPermSQL ());
184 $A = DB_fetchArray($result);
185 $total_polls = $A['count'];
187 $result = DB_query ("SELECT pid FROM {$_TABLES['polltopics']}" . COM_getPermSQL ());
188 $nrows = DB_numRows ($result);
191 for ($i = 1; $i <= $nrows; $i++) {
192 $A = DB_fetchArray($result);
196 $topics .= "'" . $A['pid'] . "'";
198 $result = DB_query ("SELECT SUM(votes) FROM {$_TABLES['pollanswers']} WHERE pid IN ({$topics})");
199 $A = DB_fetchArray($result, true);
200 $total_answers = $A[0];
203 return array ($total_polls, $total_answers);
207 * Shows the statistics for the Polls plugin on stats.php.
208 * If $showsitestats is 1 then we are to only print the overall stats in the
209 * 'site statistics box' otherwise we show the detailed stats
211 * @param int showsitestate Flag to let us know which stats to get
213 function plugin_showstats_polls ($showsitestats)
215 global $_CONF, $_TABLES, $LANG_POLLS;
217 require_once ($_CONF['path_system'] . 'lib-admin.php');
221 $result = DB_query ("SELECT pid,topic,voters FROM {$_TABLES['polltopics']} WHERE (voters > 0)" . COM_getPermSQL ('AND') . " ORDER BY voters DESC LIMIT 10");
222 $nrows = DB_numRows ($result);
226 array('text' => $LANG_POLLS['stats_topics'],
228 'header_class' => 'stats-header-title'
230 array('text' => $LANG_POLLS['stats_votes'],
232 'header_class' => 'stats-header-count',
233 'field_class' => 'stats-list-count'
237 $text_arr = array('has_menu' => false,
238 'title' => $LANG_POLLS['stats_top10'],
240 for ($i = 0; $i < $nrows; $i++) {
241 $A = DB_fetchArray ($result);
242 $url = $_CONF['site_url'] . '/polls/index.php?pid=' . $A['pid']
244 $pid = COM_createLink($A['topic'], $url);
245 $voters = COM_NumberFormat ($A['voters']);
246 $data_arr[] = array ('pid' => $pid, 'voters' => $voters);
248 $retval .= ADMIN_simpleList ('', $header_arr, $text_arr, $data_arr);
250 $retval .= COM_startBlock ($LANG_POLLS['stats_top10']);
251 $retval .= $LANG_POLLS['stats_none'];
252 $retval .= COM_endBlock ();
259 * New stats plugin API function for proper integration with the site stats
261 * @return array(item text, item count);
264 function plugin_statssummary_polls ()
268 list($total_polls, $total_answers) = POLLS_countPollsAndVotes ();
270 $item_count = COM_numberFormat ($total_polls)
271 . ' (' . COM_numberFormat ($total_answers) . ')';
273 return array ($LANG_POLLS['stats_summary'], $item_count);
278 * This will put an option for polls in the command and control block on
282 function plugin_cclabel_polls()
284 global $_CONF, $LANG_POLLS;
286 if (SEC_hasRights ('polls.edit')) {
287 return array ($LANG_POLLS['polls'],
288 $_CONF['site_admin_url'] . '/plugins/polls/index.php',
289 plugin_geticon_polls ());
297 * returns the administrative option for this plugin
300 function plugin_getadminoption_polls()
302 global $_CONF, $_TABLES, $LANG_POLLS;
304 if (SEC_hasRights ('polls.edit')) {
305 $result = DB_query ("SELECT COUNT(*) AS cnt FROM {$_TABLES['polltopics']}" . COM_getPermSQL ());
306 $A = DB_fetchArray ($result);
307 $total_pages = $A['cnt'];
309 return array ($LANG_POLLS['polls'],
310 $_CONF['site_admin_url'] . '/plugins/polls/index.php',
317 * A user is about to be deleted. Update ownership of any polls owned
318 * by that user or delete them.
320 * @param uid int User id of deleted user
323 function plugin_user_delete_polls ($uid)
325 global $_TABLES, $_PO_CONF;
327 if (DB_count ($_TABLES['polltopics'], 'owner_id', $uid) == 0) {
328 // there are no polls owned by this user
332 if ($_PO_CONF['delete_polls'] == 1) {
334 $result = DB_query ("SELECT pid FROM {$_TABLES['polltopics']} WHERE owner_id = $uid");
335 $numPolls = DB_numRows ($result);
336 for ($i = 0; $i < $numPolls; $i++) {
337 list($pid) = DB_fetchArray($result);
338 DB_delete($_TABLES['pollanswers'], 'pid', $pid);
339 DB_delete($_TABLES['pollvoters'], 'pid', $pid);
340 DB_delete($_TABLES['comments'], array('sid', 'type'),
341 array($pid, 'polls'));
343 DB_delete($_TABLES['polltopics'], 'owner_id', $uid);
345 // assign ownership to a user from the Root group
346 $rootgroup = DB_getItem ($_TABLES['groups'], 'grp_id',
347 "grp_name = 'Root'");
348 $result = DB_query ("SELECT DISTINCT ug_uid FROM {$_TABLES['group_assignments']} WHERE ug_main_grp_id = $rootgroup ORDER BY ug_uid LIMIT 1");
349 list($rootuser) = DB_fetchArray ($result);
351 DB_query ("UPDATE {$_TABLES['polltopics']} SET owner_id = $rootuser WHERE owner_id = $uid");
356 * Return the current version of code.
357 * Used in the Plugin Editor to show the registered version and code version
359 function plugin_chkVersion_polls()
363 require_once $_CONF['path'] . 'plugins/polls/autoinstall.php';
365 $inst_parms = plugin_autoinstall_polls('polls');
367 return $inst_parms['info']['pi_version'];
371 * Geeklog informs us that we're about to be enabled or disabled
373 * @param boolean $enable true = we're being enabled, false = disabled
377 function plugin_enablestatechange_polls ($enable)
381 $is_enabled = $enable ? 1 : 0;
384 DB_query ("UPDATE {$_TABLES['blocks']} SET is_enabled = $is_enabled WHERE (type = 'phpblock') AND (phpblockfn = 'phpblock_polls')");
388 * Automatic uninstall function for plugins
392 * This code is automatically uninstalling the plugin.
393 * It passes an array to the core code function that removes
394 * tables, groups, features and php blocks from the tables.
395 * Additionally, this code can perform special actions that cannot be
396 * foreseen by the core code (interactions with other plugins for example)
399 function plugin_autouninstall_polls ()
402 /* give the name of the tables, without $_TABLES[] */
403 'tables' => array('pollanswers','polltopics','pollvoters','pollquestions'),
404 /* give the full name of the group, as in the db */
405 'groups' => array('Polls Admin'),
406 /* give the full name of the feature, as in the db */
407 'features' => array('polls.edit'),
408 /* give the full name of the block, including 'phpblock_', etc */
409 'php_blocks' => array('phpblock_polls'),
410 /* give all vars with their name */
417 * Get path for the template files.
419 * @param string $path subdirectory within the base template path
420 * @return string full path to template directory
423 function polls_templatePath ($path = '')
428 $layout_path = $_CONF['path_layout'] . polls;
430 $layout_path = $_CONF['path_layout'] . polls . '/' . $path;
433 if (is_dir ($layout_path)) {
434 $retval = $layout_path;
436 $retval = $_CONF['path'] . 'plugins/polls/templates';
437 if (!empty ($path)) {
438 $retval .= '/' . $path;
449 * Shows an HTML formatted poll for the given topic ID
451 * @param string $pid ID for poll topic
452 * @param boolean $showall Show only the first question in the poll or all?
453 * @param int $displaytype Possible values 0 = Normal, 1 = In Block, 2 = autotag
454 * @see function COM_pollResults
455 * @see function COM_showPoll
456 * @return string HTML Formatted Poll
460 function POLLS_pollVote($pid, $showall = true, $displaytype = 0)
462 global $_CONF, $_TABLES, $LANG_POLLS, $LANG01, $_USER, $LANG25, $_IMAGE_TYPE;
465 $topic = DB_query("SELECT topic,voters,commentcode,is_open,hideresults,owner_id "
466 . ",group_id,perm_owner,perm_group,perm_anon,perm_members "
467 . "FROM {$_TABLES['polltopics']} WHERE pid='$pid'" . COM_getPermSql('AND'));
468 $ntopics = DB_numRows($topic);
474 $P = DB_fetchArray($topic);
476 if ((!isset($_COOKIE[$pid]) && !POLLS_ipAlreadyVoted($pid)) or ($P['is_open'] == 1)) {
478 $questions_sql = "SELECT question,qid "
479 . "FROM {$_TABLES['pollquestions']} "
480 . "WHERE pid='$pid' ORDER BY qid";
482 $questions = DB_query($questions_sql);
483 $nquestions = DB_numRows($questions );
485 if ($nquestions > 0) {
486 $poll = new Template($_CONF['path']
487 . 'plugins/polls/templates/');
488 $poll->set_file(array('panswer' => 'pollanswer.thtml',
489 'block' => 'pollblock.thtml',
490 'pquestions' => 'pollquestions.thtml',
491 'comments' => 'pollcomments.thtml'));
492 $poll->set_var('xhtml', XHTML);
493 $poll->set_var('site_url', $_CONF['site_url']);
494 $poll->set_var('layout_url', $_CONF['layout_url']);
495 $poll->set_var('site_admin_url', $_CONF['site_admin_url']);
496 $poll->set_var('poll_id', $pid );
497 $poll->set_var('poll_topic', $P['topic'] );
498 $poll->set_var('num_votes', COM_numberFormat($P['voters']));
499 $poll->set_var('poll_vote_url', $_CONF['site_url']
500 . '/polls/index.php');
501 if (($nquestions == 1) || $showall) {
502 $poll->set_var('lang_vote', $LANG_POLLS['vote']);
504 $poll->set_var('lang_vote', $LANG_POLLS['start_poll']);
506 $poll->set_var('lang_votes', $LANG_POLLS['votes']);
509 if (($P['is_open'] == 0) || ($P['hideresults'] == 0) ||
510 (($P['hideresults'] == 1) &&
512 SEC_inGroup('Root') ||
513 (isset($_USER['uid'])
514 && ($_USER['uid'] == $P['owner_id']))
516 $results = COM_createLink($LANG_POLLS['results'],
517 $_CONF['site_url'] . '/polls/index.php?pid=' . $pid
520 $poll->set_var('poll_results', $results);
522 $access = SEC_hasAccess($topic['owner_id'], $topic['group_id'],
523 $topic['perm_owner'], $topic['perm_group'],
524 $topic['perm_members'], $topic['perm_anon']);
526 $editlink = COM_createLink($LANG25[27], $_CONF['site_admin_url']
527 . '/plugins/polls/index.php?mode=edit&pid=' . $pid);
528 $poll->set_var('edit_link', $editlink);
529 $editicon = $_CONF['layout_url'] . '/images/edit.' . $_IMAGE_TYPE;
530 $icon_attr = array('title' => $LANG25[27]);
531 $editiconhtml = COM_createImage($editicon, $LANG25[27], $icon_attr);
532 $editlink = COM_createLink($editiconhtml, $_CONF['site_admin_url']
533 . '/plugins/polls/index.php?mode=edit&pid=' . $pid);
534 $poll->set_var('edit_icon', $editlink);
537 if (array_key_exists('aid', $_POST)) {
538 $aid = $_POST['aid'];
543 for ($j = 0; $j < $nquestions; $j++) {
544 $Q = DB_fetchArray($questions);
545 $poll->set_var('poll_question', $Q['question']);
546 $poll->set_var('question_id', $j);
552 $notification = $LANG25[35] . " $nquestions " . $LANG25[36];
553 $filter = "AND qid='0'";
556 $filter = "AND qid = '{$Q['qid']}'";
557 $poll->set_var('lang_question_number', " ". ($j+1).":");
559 $answer_sql = "SELECT answer,aid "
560 . "FROM {$_TABLES['pollanswers']} "
561 . "WHERE pid='$pid'$filter ORDER BY qid, aid";
562 $answers = DB_query($answer_sql);
563 $nanswers = DB_numRows($answers );
564 for($i=0; $i<$nanswers; $i++) {
565 $A = DB_fetchArray($answers );
566 if (($j < count($aid)) && ($aid[$j] == $A['aid'])) {
567 $poll->set_var('selected', ' checked');
569 $poll->set_var('answer_id', $A['aid']);
570 $poll->set_var('answer_text', $A['answer']);
571 $poll->parse('poll_answers', 'panswer', true);
572 $poll->clear_var('selected');
574 $poll->parse('poll_questions', 'pquestions', true);
575 $poll->clear_var('poll_answers');
577 if ($nquestions > 1) {
578 $poll->set_var('poll_topic', $LANG25['34'] . " " . $P['topic']);
579 $poll->set_var('lang_question', $LANG25[31]);
581 $poll->set_var('lang_polltopics', $LANG_POLLS['polltopics']);
582 $poll->set_var('poll_notification', $notification);
583 if($P['commentcode'] >= 0 ) {
584 $num_comments = DB_count($_TABLES['comments'],
585 array('sid', 'type'), array($pid, 'polls'));
586 $poll->set_var('num_comments',
587 COM_numberFormat($num_comments));
588 $poll->set_var('lang_comments', $LANG01[3]);
589 $poll->set_var('poll_comments_url', $_CONF['site_url'] .
590 '/polls/index.php?pid=' . $pid . '#comments');
591 $poll->parse('poll_comments', 'comments', true);
593 $poll->set_var('poll_comments', '');
594 $poll->set_var('poll_comments_url', '');
596 $retval = $poll->finish($poll->parse('output', 'block')) . LB;
598 if ($showall && ($P['commentcode'] >= 0 AND $displaytype != 2)) {
599 $delete_option = (SEC_hasRights('polls.edit') &&
600 SEC_hasAccess($P['owner_id'], $P['group_id'],
601 $P['perm_owner'], $P['perm_group'], $P['perm_members'],
602 $P['perm_anon']) == 3 ? true : false);
604 require_once $_CONF['path_system'] . 'lib-comment.php';
608 $retval .= CMT_userComments($pid, $P['topic'], 'polls',
609 $order, $mode, 0, 1, false,
610 $delete_option, $P['commentcode']);
615 $retval .= POLLS_pollResults($pid, 0, '', '', $displaytype);
624 * This will determine if a user needs to see the poll form OR the poll result.
626 * @param int $size Size in pixels of poll results
627 * @param string $pid Poll topic ID to show (optional)
628 * @param bool $showall Show only the first question or all
629 * @param int $displaytype Possible values 0 = Normal, 1 = In Block, 2 = autotag
630 * @return string HTML formatted string of poll
631 * @see function COM_pollVote
632 * @see function COM_pollResults
635 function POLLS_showPoll($size, $pid = '', $showall = false, $displaytype = 0)
637 global $_CONF, $_TABLES, $_PO_CONF, $LANG_POLLS;
641 DB_query("DELETE FROM {$_TABLES['pollvoters']} WHERE date < UNIX_TIMESTAMP() - {$_PO_CONF['polladdresstime']}");
644 $Q['is_open'] = DB_getItem($_TABLES['polltopics'], 'is_open', "pid = '".$pid."'");
646 if (($displaytype == 2) && ($Q['is_open'] == 0)) {
647 $retval = '<div class="poll-autotag-message">'
648 . $LANG_POLLS['pollclosed'] . '</div>';
650 if (!isset($_COOKIE['poll-' . $pid]) && !POLLS_ipAlreadyVoted($pid) &&
651 ($Q['is_open'] == 1)) {
652 $retval .= POLLS_pollVote($pid, $showall, $displaytype);
654 $retval .= POLLS_pollResults($pid, $size, '', '', $displaytype);
657 $result = DB_query("SELECT pid,topic,is_open FROM {$_TABLES['polltopics']} WHERE display = 1" . COM_getPermSql('AND') . " ORDER BY date DESC");
658 $nrows = DB_numRows($result);
660 $title = DB_getItem($_TABLES['blocks'], 'title', "name='poll_block'");
663 for ($i = 1; $i <= $nrows; $i++) {
664 $Q = DB_fetchArray($result);
666 if ($displaytype == 1) { // in the poll block
668 } else { // assume we're in polls/index.php
669 $retval .= COM_startBlock($title);
673 if (!isset($_COOKIE['poll-' . $pid]) &&
674 !POLLS_ipAlreadyVoted($pid) && ($Q['is_open'] == 1)) {
675 $retval .= POLLS_pollVote($pid, $showall, $displaytype);
677 $retval .= POLLS_pollResults($pid, $size, '', '',
681 if ($displaytype == 1) { // in the poll block
682 if (($i < $nrows) && !empty($retval)) {
683 $retval .= '<div class="poll-divider"></div>';
686 $retval .= COM_endBlock();
696 * Saves a user's vote
698 * Saves the users vote, if allowed for the poll $pid.
699 * NOTE: all data comes from form post
701 * @param string $pid poll id
702 * @param array $aid selected answers
703 * @return string HTML for poll results
706 function POLLS_pollsave($pid, $aid)
708 global $_TABLES, $LANG_POLLS;
712 if (POLLS_ipAlreadyVoted ($pid)) {
716 DB_change($_TABLES['polltopics'],'voters',"voters + 1",'pid',$pid,'',true);
717 // This call to DB-change will properly supress the insertion of quotes around $value in the sql
718 $answers = count($aid);
719 for ($i = 0; $i < $answers; $i++) {
721 $_TABLES['pollanswers'],
724 array('pid', 'qid', 'aid'),
725 array($pid, $i, COM_applyFilter($aid[$i], true)),
731 // This always does an insert so no need to provide key_field and key_value args
732 DB_save($_TABLES['pollvoters'],'ipaddress,date,pid',"'{$_SERVER['REMOTE_ADDR']}'," . time() . ",'$pid'");
733 $retval .= COM_startBlock ($LANG_POLLS['savedvotetitle'], '',
734 COM_getBlockTemplate ('_msg_block', 'header'))
735 . $LANG_POLLS['savedvotemsg'] . ' "'
736 . DB_getItem ($_TABLES['polltopics'], 'topic', "pid = '{$pid}'")
738 . COM_endBlock (COM_getBlockTemplate ('_msg_block', 'footer'))
739 . POLLS_pollResults($pid);
745 * Shows the results of a poll
747 * Shows the poll results for a given poll topic
749 * @param string $pid ID for poll topic to show
750 * @param int $scale Size in pixels to scale formatted results to
751 * @param string $order 'ASC' or 'DESC' for Comment ordering (SQL statment ordering)
752 * @param string $mode Comment Mode possible values 'nocomment', 'flat', 'nested', 'threaded'
753 * @param int $displaytype Possible values 0 = Normal, 1 = In Block, 2 = autotag
754 * @see POLLS_pollVote
755 * @see POLLS_showPoll
756 * @return string HTML Formated Poll Results
759 function POLLS_pollResults($pid, $scale=400, $order='', $mode='', $displaytype = 0)
761 global $_CONF, $_TABLES, $_USER, $_IMAGE_TYPE,
762 $_PO_CONF, $LANG01, $LANG_POLLS, $_COM_VERBOSE, $LANG25;
765 $topic_sql = "SELECT topic,voters,is_open,hideresults,commentcode,owner_id,group_id,"
766 . "perm_owner,perm_group,perm_members,perm_anon "
767 . "FROM {$_TABLES['polltopics']} WHERE pid='$pid'";
768 $topic = DB_query($topic_sql);
769 $P = DB_fetchArray($topic);
771 if(SEC_hasAccess($P['owner_id'], $P['group_id'], $P['perm_owner'],
772 $P['perm_group'], $P['perm_members'], $P['perm_anon']) == 0 ) {
777 $P['hideresults'] == 0
779 ($P['hideresults'] == 1) && (isset($_USER['uid']) &&
780 ($_USER['uid'] == $P['owner_id']))
782 ($P['hideresults'] == 1) && (SEC_inGroup('Root'))
787 if ($displaytype == 2) {
788 $retval = '<div class="poll-autotag-message">' . $LANG_POLLS['pollhidden']. "</div>";
794 $ntopic = DB_numRows($topic );
796 $questions_sql = "SELECT qid,pid,question "
797 . "FROM {$_TABLES['pollquestions']} "
798 . "WHERE pid='$pid' "
800 $questions = DB_query ($questions_sql);
801 $nquestions = DB_numRows($questions);
804 COM_errorLog("got $questions questions in COM_pollResults", 1 );
807 if ($nquestions > 0){
808 $poll = new Template($_CONF['path'] . 'plugins/polls/templates/' );
809 $poll->set_file(array('result' => 'pollresult.thtml',
810 'question' => 'pollquestion.thtml',
811 'comments' => 'pollcomments.thtml',
812 'votes_bar' => 'pollvotes_bar.thtml',
813 'votes_num' => 'pollvotes_num.thtml' ));
814 $poll->set_var('xhtml', XHTML);
815 $poll->set_var('site_url', $_CONF['site_url']);
816 $poll->set_var('site_admin_url', $_CONF['site_admin_url']);
817 $poll->set_var('layout_url', $_CONF['layout_url']);
818 $poll->set_var('poll_topic', $P['topic']);
819 $poll->set_var('poll_id', $pid);
820 $poll->set_var('num_votes', COM_numberFormat($P['voters']));
821 $poll->set_var('lang_votes', $LANG_POLLS['votes']);
822 $access = SEC_hasAccess($P['owner_id'],$P['group_id'],$P['perm_owner'],
823 $P['perm_group'],$P['perm_members'],$P['perm_anon']);
825 $editlink = COM_createLink($LANG25[27], $_CONF['site_admin_url']
826 . '/plugins/polls/index.php?mode=edit&pid=' . $pid );
827 $poll->set_var('edit_link', $editlink);
828 $editicon = $_CONF['layout_url'] . '/images/edit.' . $_IMAGE_TYPE;
829 $icon_attr = array('title' => $LANG25[27]);
830 $editiconhtml = COM_createImage($editicon, $LANG25[27], $icon_attr);
831 $editlink = COM_createLink($editiconhtml, $_CONF['site_admin_url']
832 . '/plugins/polls/index.php?mode=edit&pid=' . $pid );
833 $poll->set_var('edit_icon', $editlink);
835 if ($_PO_CONF['answerorder'] == 'voteorder'){
836 $order = "votes DESC";
841 for ($j = 0; $j < $nquestions; $j++) {
842 $Q = DB_fetchArray($questions);
844 if ($nquestions >= 1) {
845 $counter = ($j + 1) . "/$nquestions: " ;
847 $poll->set_var('poll_question', $counter . $Q['question']);
849 $answer_sql = "SELECT votes,answer,remark "
850 . "FROM {$_TABLES['pollanswers']} "
851 . "WHERE pid='$pid' and qid='{$Q['qid']}' "
853 $answers = DB_query ($answer_sql);
854 $nanswers = DB_numRows($answers);
856 $a_summ_sql = "SELECT SUM(votes) as votesumm FROM {$_TABLES['pollanswers']} "
857 . "WHERE pid='$pid' and qid='{$Q['qid']}' "
859 $a_summ = DB_query ($a_summ_sql);
860 $S = DB_fetchArray($a_summ);
863 COM_errorLog("got $answers answers in COM_pollResults", 1 );
865 for ($i=1; $i<=$nanswers; $i++) {
866 $A = DB_fetchArray($answers);
867 if ($S['votesumm'] == 0) {
870 $percent = $A['votes'] / $S['votesumm'];
872 $poll->set_var('cssida', 1);
873 $poll->set_var('cssidb', 2);
874 $poll->set_var('answer_text', $A['answer']);
875 $poll->set_var('remark_text', $A['remark']);
876 $poll->set_var('answer_counter', $i);
877 $poll->set_var('answer_odd', (($i - 1) % 2));
878 $poll->set_var('answer_num', COM_numberFormat($A['votes']));
879 $poll->set_var('answer_percent',
880 sprintf('%.2f', $percent * 100));
882 $poll->parse('poll_votes', 'votes_num', true );
884 $width = (int)($percent * $scale);
885 $poll->set_var('bar_width', $width);
886 $poll->parse('poll_votes', 'votes_bar', true);
889 $poll->parse('poll_questions', 'question', true);
890 $poll->clear_var('poll_votes');
891 if (($scale < 100) && ($j < 1)) {
892 $url = $_CONF['site_url'] . "/polls/index.php?pid=$pid";
893 $poll->set_var('notification', COM_createLink($LANG25[40], $url). "<br" . XHTML . ">");
898 if($P['commentcode'] >= 0 ) {
899 $num_comments = DB_count($_TABLES['comments'],
900 array('sid', 'type' ), array($pid, 'polls' ));
901 $poll->set_var('num_comments',
902 COM_numberFormat($num_comments));
903 $poll->set_var('lang_comments', $LANG01[3]);
904 $poll->set_var('poll_comments_url', $_CONF['site_url'] .
905 '/polls/index.php?pid=' . $pid . '#comments');
906 $poll->parse('poll_comments', 'comments', true);
908 $poll->set_var('poll_comments_url', '');
909 $poll->set_var('poll_comments', '');
912 $poll->set_var('lang_polltopics', $LANG_POLLS['polltopics'] );
914 $retval .= $poll->finish($poll->parse('output', 'result' ));
916 if($scale > 399 && $P['commentcode'] >= 0 && $displaytype != 2) {
917 $delete_option = (SEC_hasRights('polls.edit') &&
918 SEC_hasAccess($P['owner_id'], $P['group_id'],
919 $P['perm_owner'], $P['perm_group'], $P['perm_members'],
920 $P['perm_anon']) == 3 ? true : false);
921 require_once $_CONF['path_system'] . 'lib-comment.php';
922 $retval .= CMT_userComments($pid, $P['topic'], 'polls',
923 $order, $mode, 0, 1, false,
924 $delete_option, $P['commentcode']);
933 * Check if we already have a vote from this IP address
935 * @param string $pid Poll ID
936 * @param string $ip (optional) IP address
937 * @return boolean true: IP already voted; false: didn't
940 function POLLS_ipAlreadyVoted($pid, $ip = '' )
947 $ip = $_SERVER['REMOTE_ADDR'];
950 if(DB_count($_TABLES['pollvoters'],
951 array('ipaddress', 'pid'),
952 array($ip, $pid)) > 0) {
960 * Display the current poll(s) in a side block
962 * @return string HTML for the poll(s) to be displayed (or an empty string)
965 function phpblock_polls()
967 return POLLS_showPoll(60, '', false, 1);
972 * Returns the URL of the plugin's icon
974 * @return string URL of the icon
977 function plugin_geticon_polls ()
980 return $_CONF['site_url'] . '/polls/images/polls.png';
984 * Plugin should display [a] comment[s]
986 * @param string $id Unique idenifier for item comment belongs to
987 * @param int $cid Comment id to display (possibly including sub-comments)
988 * @param string $title Page/comment title
989 * @param string $order 'ASC' or 'DESC' or blank
990 * @param string $format 'threaded', 'nested', or 'flat'
991 * @param int $page Page number of comments to display
992 * @param boolean $view True to view comment (by cid), false to display (by $pid)
993 * @return mixed results of calling the plugin_displaycomment_ function
995 function plugin_displaycomment_polls ($id, $cid, $title, $order, $format, $page, $view)
997 global $_TABLES, $LANG_ACCESS;
1001 $sql = "SELECT COUNT(*) AS count, commentcode, owner_id, group_id, perm_owner, "
1002 . "perm_group, perm_members, perm_anon "
1003 . "FROM {$_TABLES['polltopics']} "
1004 . "WHERE (pid = '$id')" . COM_getPermSQL('AND')
1006 $result = DB_query ($sql);
1007 $A = DB_fetchArray ($result);
1008 $allowed = $A['count'];
1010 if ($allowed == 1) {
1011 $delete_option = (SEC_hasRights ('polls.edit') &&
1012 (SEC_hasAccess ($A['owner_id'], $A['group_id'],
1013 $A['perm_owner'], $A['perm_group'], $A['perm_members'],
1014 $A['perm_anon']) == 3));
1015 $retval .= CMT_userComments ($id, $title, 'polls', $order, $format,
1016 $cid, $page, $view, $delete_option,
1019 $retval .= COM_startBlock ($LANG_ACCESS['accessdenied'], '',
1020 COM_getBlockTemplate ('_msg_block', 'header'))
1021 . $LANG_ACCESS['storydenialmsg']
1022 . COM_endBlock (COM_getBlockTemplate ('_msg_block', 'footer'));
1028 function plugin_getListField_polls($fieldname, $fieldvalue, $A, $icon_arr)
1030 global $_CONF, $LANG25, $LANG_ACCESS, $_USER;
1034 $access = SEC_hasAccess ($A['owner_id'], $A['group_id'],
1035 $A['perm_owner'], $A['perm_group'],
1036 $A['perm_members'], $A['perm_anon']);
1038 switch($fieldname) {
1041 $retval = COM_createLink($icon_arr['edit'],
1042 "{$_CONF['site_admin_url']}/plugins/polls/index.php?mode=edit&pid={$A['pid']}");
1046 $retval = strftime ($_CONF['daytime'], $A['unixdate']);
1049 if (($A['hideresults'] == 0) ||
1050 (isset($_USER['uid']) && ($_USER['uid'] == $A['owner_id'])) || SEC_inGroup('Root')) {
1051 $retval = COM_createLink($fieldvalue,
1052 "{$_CONF['site_url']}/polls/index.php?pid={$A['pid']}");
1054 $retval = $fieldvalue;
1059 $access = $LANG_ACCESS['edit'];
1061 $access = $LANG_ACCESS['readonly'];
1066 if ($A['is_open'] == 1) {
1067 $retval = $LANG25[25];
1069 $retval = $LANG25[26];
1073 if ($A['display'] == 1) {
1074 $retval = $LANG25[25];
1076 $retval = $LANG25[26];
1080 $retval = COM_numberFormat ($A['voters']);
1083 $retval = $fieldvalue;
1094 * Set template variables
1096 * @param string $templatename name of template, e.g. 'header'
1097 * @param ref $template reference of actual template
1100 * Note: A plugin should use its name as a prefix for the names of its
1101 * template variables, e.g. 'polls_xxx' and 'lang_polls_xxx'.
1102 * 'button_polls' is an exception, as such a variable existed for header.thtml
1103 * in Geeklog 1.3.11 and earlier, where the Polls were an integral part
1104 * of Geeklog. It is added here for backward-compatibility.
1107 function plugin_templatesetvars_polls ($templatename, &$template)
1111 if ($templatename == 'header') {
1112 $template->set_var ('button_polls', $LANG_POLLS['polls']);
1116 function plugin_getheadercode_polls()
1121 $str = LB . '<link rel="stylesheet" type="text/css" href="'
1122 . $_CONF['site_url'] . '/polls/style.css"' . XHTML . '>';
1128 * Update the Polls plugin
1130 * @return int Number of message to display (true = generic success msg)
1133 function plugin_upgrade_polls()
1135 global $_CONF, $_TABLES, $_DB_dbms;
1137 $installed_version = DB_getItem($_TABLES['plugins'], 'pi_version',
1138 "pi_name = 'polls'");
1139 $code_version = plugin_chkVersion_polls();
1140 if ($installed_version == $code_version) {
1145 require_once $_CONF['path'] . 'plugins/polls/autoinstall.php';
1147 if (! plugin_compatible_with_this_version_polls('polls')) {
1151 $inst_parms = plugin_autoinstall_polls('polls');
1152 $pi_gl_version = $inst_parms['info']['pi_gl_version'];
1154 require_once $_CONF['path'] . 'plugins/polls/sql/'
1155 . $_DB_dbms . '_updates.php';
1157 $current_version = $installed_version;
1160 switch ($current_version) {
1162 $current_version = '2.0.2';
1166 $current_version = '2.1.0';
1170 if (isset($_UPDATES[$current_version])) {
1171 $_SQL = $_UPDATES[$current_version];
1172 foreach ($_SQL as $sql) {
1177 update_ConfValues_2_1_0();
1179 $current_version = '2.1.1';
1187 DB_query("UPDATE {$_TABLES['plugins']} SET pi_version = '$code_version', pi_gl_version = '$pi_gl_version' WHERE pi_name = 'polls'");
1193 * Called during site migration - handle changed URLs or paths
1195 * @param array $old_conf contents of the $_CONF array on the old site
1196 * @param boolean true on success, otherwise false
1199 function plugin_migrate_polls($old_conf)
1204 'pollanswers' => 'aid, answer',
1205 'pollquestions' => 'qid, question',
1206 'polltopics' => 'pid, topic'
1209 if ($old_conf['site_url'] != $_CONF['site_url']) {
1210 INST_updateSiteUrl($old_conf['site_url'], $_CONF['site_url'], $tables);
1217 * Return information for a poll
1219 * @param string $pid poll ID or '*'
1220 * @param string $what comma-separated list of properties
1221 * @param int $uid user ID or 0 = current user
1222 * @param array $options (reserved for future extensions)
1223 * @return mixed string or array of strings with the information
1226 function plugin_getiteminfo_polls($pid, $what, $uid = 0, $options = array())
1228 global $_CONF, $_TABLES;
1230 // parse $what to see what we need to pull from the database
1231 $properties = explode(',', $what);
1233 foreach ($properties as $p) {
1235 case 'date-modified':
1236 $fields[] = 'UNIX_TIMESTAMP(date) AS unixdate';
1242 $fields[] = 'topic';
1245 // needed for $pid == '*', but also in case we're only requesting
1246 // the URL (so that $fields isn't emtpy)
1255 $fields = array_unique($fields);
1257 if (count($fields) == 0) {
1263 // prepare SQL request
1268 $where = " WHERE pid = '" . addslashes($pid) . "'";
1272 $permSql = COM_getPermSql($permOp, $uid);
1274 $permSql = COM_getPermSql($permOp);
1276 $sql = "SELECT " . implode(',', $fields)
1277 . " FROM {$_TABLES['polltopics']}" . $where . $permSql;
1282 $result = DB_query($sql);
1283 $numRows = DB_numRows($result);
1286 for ($i = 0; $i < $numRows; $i++) {
1287 $A = DB_fetchArray($result);
1290 foreach ($properties as $p) {
1292 case 'date-modified':
1293 $props['date-modified'] = $A['unixdate'];
1296 $props['id'] = $A['pid'];
1299 $props['title'] = $A['topic'];
1302 if (empty($A['pid'])) {
1303 $props['url'] = $_CONF['site_url']
1304 . '/polls/index.php?pid=' . $pid
1307 $props['url'] = $_CONF['site_url']
1308 . '/polls/index.php?pid=' . $A['pid']
1313 // return empty string for unknown properties
1320 foreach ($props as $key => $value) {
1323 $mapped[$key] = $value;
1331 $retval[] = $mapped;
1338 if (($pid != '*') && (count($retval) == 1)) {
1339 $retval = $retval[0];
1346 * Provide URL of a documentation file
1348 * @param string $file documentation file being requested, e.g. 'config'
1349 * @return mixed URL or false when not available
1352 function plugin_getdocumentationurl_polls($file)
1361 if (isset($docurl)) {
1364 $doclang = COM_getLanguageName();
1365 $docs = 'docs/' . $doclang . '/polls.html';
1366 if (file_exists($_CONF['path_html'] . $docs)) {
1367 $retval = $_CONF['site_url'] . '/' . $docs;
1369 $retval = $_CONF['site_url'] . '/docs/english/polls.html';
1384 * Provide URL and ID for the link to a comment's parent
1386 * @return array array consisting of the base URL and the ID name
1389 function plugin_getcommenturlid_polls()
1394 $_CONF['site_url'] . '/polls/index.php',
1403 * [poll: pid] - Displays a link to a poll using the Poll Topic as the title. A alternate title may be specified.
1404 * [poll_vote: pid pid class:poll-autotag showall:1] - Class and showall not required. Class specifies the css class and Showall if set to 1, shows all questions
1405 * [poll_result: pid class:poll-autotag] - Class not required. Class specifies the css class
1408 function plugin_autotags_polls($op, $content = '', $autotag = '')
1410 global $_CONF, $_TABLES;
1412 if ($op == 'tagname' ) {
1413 return array('poll_vote', 'poll_result', 'poll');
1414 } elseif ($op == 'parse') {
1415 $pid = COM_applyFilter($autotag['parm1']);
1418 switch ($autotag['tag']) {
1420 if (!empty($autotag['parm2'])) {
1421 $title = COM_applyFilter($autotag['parm2']);
1423 $title = DB_getItem($_TABLES['polltopics'], 'topic',
1427 $retval = COM_createLink($title, $_CONF['site_url']
1428 . '/polls/index.php?pid=' . $pid . '&aid=-1');
1433 $px = explode(' ', trim($autotag['parm2']));
1434 $css_class = "poll-autotag";
1436 if (is_array($px)) {
1437 foreach ($px as $part) {
1438 if (substr($part, 0, 6) == 'class:') {
1439 $a = explode(':', $part);
1441 } elseif (substr($part, 0, 8) == 'showall:') {
1442 $a = explode(':', $part);
1453 if ($autotag['tag'] == 'poll_vote') {
1454 $retval = POLLS_showPoll(0, $pid, $showall, 2);
1456 $retval = POLLS_pollResults($pid, 0,'', '', 2);
1458 $retval = '<div class="' . $css_class . '">' . $retval . '</div>';
1462 $content = str_replace($autotag['tagstr'], $retval, $content);