News:

SMF 2.1.4 has been released! Take it for a spin! Read more.

Main Menu

SSI Poll Bug?

Started by Zetan, November 23, 2007, 07:52:49 PM

Previous topic - Next topic

Zetan

I noticed when using a snippet of Thurnoks:
http://www.tinyportals.net/index.php?topic=10786.msg165049;topicseen

That regardless of if I set the poll to display the results after the poll has expired, the SSI function goes right ahead and displays the results to guests and other members.

http://labradio.co.uk/index.php?action=forum

That seems to be a bug to me, unless the snippet need extra elements?

SleePy

Its done on purpose. If they can't vote, it just shows the results.

You could have it return as an array and force a login instead.
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

Zetan

#2
Thanks for the reply.
It doesn't make sense to me, the poll in the topic does not display the results.
The polls are in a block above the board index, forcing a login won't let guests view the options?
Members can vote, yet it still displays the results to members logged in.

It's not just Guests that see the SSI Poll results, it's all member groups except Admin, it looks fine to me, and I can view the results in the topic as Admin, but not from the SSI.

metallica48423

so you're saying it ignores the settings of the poll as far as who can view the results and when?
Justin O'Leary
Ex-Project Manager
Ex-Lead Support Specialist

QuoteMicrosoft wants us to "Imagine life without walls"...
I say, "If there are no walls, who needs Windows?"


Useful Links:
Online Manual!
How to Help us Help you
Search
Settings Repair Tool

Zetan

Thats correct.. It totally ignores all the settings.

Here is the code used:


echo '<table><tr>
<td>
';
ssi_showPoll(1574);
echo '<br />
<a href="http://labradio.co.uk/index.php/topic,1574.0.html" >View Topic</a>
</td>
<td>';
ssi_showPoll(1575);
echo '<br />
<a href="http://labradio.co.uk/index.php/topic,1575.0.html" >View Topic</a>
</td>
<td>';
ssi_showPoll(1576);
echo '<br />
<a href="http://labradio.co.uk/index.php/topic,1576.0.html" >View Topic</a>
</td>
</tr></table>
';




Zetan

Anyone have any ideas on this?

It's spoiled the end of year Best Albums poll in a way as I  didn't want members influencing each others choices.

metallica48423

i'll pass it on to someone who might be able to take a better look, it may well be a bug.

Thanks
Justin O'Leary
Ex-Project Manager
Ex-Lead Support Specialist

QuoteMicrosoft wants us to "Imagine life without walls"...
I say, "If there are no walls, who needs Windows?"


Useful Links:
Online Manual!
How to Help us Help you
Search
Settings Repair Tool

SleePy

Its not a bug its done on purpose if you look at the code.

It finds out if your a guest or have already voted. If you are it shows results

Simple fix to just add a guest check around that code. I changed the style a little but you can see the not guest check that is performed first.

if(!$context['user']['is_guest'])
echo '
<table>
<tr>
<td>', ssi_showPoll(1574), '<br /><a href="http://labradio.co.uk/index.php/topic,1574.0.html" >View Topic</a>
</td><td>, ssi_showPoll(1575), '<br /><a href="http://labradio.co.uk/index.php/topic,1575.0.html" >View Topic</a>
</td><td>', ssi_showPoll(1576), '<br /><a href="http://labradio.co.uk/index.php/topic,1576.0.html" >View Topic</a>
</td>
</tr>
</table>';


You could make it even prompt to login by changing

if(!$context['user']['is_guest'])
to
if($context['user']['is_guest'])
ssi_login();
else
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

SleePy

#8
Hate to bump my own post. But actually after having another user explain to me what was going on (I wasn't getting it), I see the bug.

Quick fix. Remember while we don't suggest editing the SSI.php, I think we can ignore this to fix the bug. I can't say if the devs will use this to fix the bug though. Its my method :P
Open SSI.php and Find:

else
{
echo '
<table border="0" cellspacing="1" cellpadding="0" class="ssi_table">
<tr>
<td colspan="2"><b>', $return['question'], '</b></td>
</tr>';
foreach ($return['options'] as $option)
echo '
<tr>
<td align="right" valign="top">', $option['option'], '</td>
<td align="left">', $option['bar'], ' ', $option['votes'], ' (', $option['percent'], '%)</td>
</tr>';
echo '
<tr>
<td colspan="2"><b>', $txt['smf24'], ': ', $return['total_votes'], '</b></td>
</tr>
</table>';
}


Add before that:
elseif (!empty($row['expireTime']) && $row['expireTime'] > time())
{
if(!$context['user']['is_guest'])
echo $txt['smf27'];
else
echo $txt['cannot_poll_vote'];

}


Which basics sees if the poll is still running and if it is gives non guests an error that they already voted (as the first if would fail due to them voting) and falls back to saying they can't vote.

My other method above would still work though to give a login screen for guest ;)

Edit, moving back to bug reports board ;)
Sorry for not seeing it earlier.
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

Zetan

Brilliant! I'll do this when I get home from work, maybe I didn't explain it well enough.

I don't think I want to redirect guests to a login screen, I want members and guests to see the options, but not the results until the poll has expired.


Thanks SleePy  8)

Zetan

#10
That doesn't quite work, or I have done it wrong.. heres the code now:

Scrap that.. database error..

Zetan

ok.. I keep getting a database error when trying to post the full code here.

metallica48423

Justin O'Leary
Ex-Project Manager
Ex-Lead Support Specialist

QuoteMicrosoft wants us to "Imagine life without walls"...
I say, "If there are no walls, who needs Windows?"


Useful Links:
Online Manual!
How to Help us Help you
Search
Settings Repair Tool

Zetan

Okay.. after wanting to kill my laptop.. (scuse me.. Ale in pub and calm ZTN don't mix well) Grrr

lol

See attached..


[edit]

Gah.. wheres the attach option?

Additional Options...
   
Notify me of replies.    
Return to this topic.    
Don't use smileys.

thats it.. no attach

Zetan

Coda:




The following error or errors occurred while posting this message:
The message exceeds the maximum allowed length (65530 characters).



Gahhhhh.. give up!

I tried.. every which way  :-\

metallica48423

really?  Hrmmmm I can attach.

and it wont post with it in [code] tags?
Justin O'Leary
Ex-Project Manager
Ex-Lead Support Specialist

QuoteMicrosoft wants us to "Imagine life without walls"...
I say, "If there are no walls, who needs Windows?"


Useful Links:
Online Manual!
How to Help us Help you
Search
Settings Repair Tool

Zetan

it allows me to post some of the code..

I have to sleep.. will try again tomorrow, and pull just the code around the edit.

:)

Z

SleePy

Zetan we had some minor issues with the database server this morning. They are brand new servers and still need tweaking for proper setup.

What isn't working? Is it not showing anything? Can you detail more whats happening? Is there any errors in the SMF error log?
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

Zetan

#18
Apologies, had been to the pub last night = Stay away from computers!

All I see now are the links to the topics where the polls are. No poll or results are displayed.
Same for guests and members logged in.

Error log:
Quote
Only show the error messages of this URL

/index.php?action=forum


Only show the errors with the same message

8: Undefined index: smf27
File: /home/********/public_html/SSI.php
Line: 1069


Part of my SSI.php showing the Polls functions


// Show the most-voted-in poll.
function ssi_topPoll($output_method = 'echo')
{
// Just use recentPoll, no need to duplicate code...
return ssi_recentPoll($output_method, true);
}

// Show the most recently posted poll.
function ssi_recentPoll($output_method = 'echo', $topPollInstead = false)
{
global $db_prefix, $txt, $ID_MEMBER, $settings, $boardurl, $sc, $user_info;
global $context;

$boardsAllowed = array_intersect(boardsAllowedTo('poll_view'), boardsAllowedTo('poll_vote'));

if (empty($boardsAllowed))
return array();

$request = db_query("
SELECT p.ID_POLL, p.question, t.ID_TOPIC, p.maxVotes
FROM ({$db_prefix}polls AS p, {$db_prefix}boards AS b, {$db_prefix}topics AS t" . ($topPollInstead ? ", {$db_prefix}poll_choices AS pc" : '') . ")
LEFT JOIN {$db_prefix}log_polls AS lp ON (lp.ID_POLL = p.ID_POLL AND lp.ID_MEMBER = $ID_MEMBER)
WHERE p.votingLocked = 0" . ($topPollInstead ? "
AND pc.ID_POLL = p.ID_POLL" : '') . "
AND lp.ID_CHOICE IS NULL
AND t.ID_POLL = p.ID_POLL
AND b.ID_BOARD = t.ID_BOARD
AND $user_info[query_see_board]" . (!in_array(0, $boardsAllowed) ? "
AND b.ID_BOARD IN (" . implode(', ', $boardsAllowed) . ")" : '') . "
ORDER BY " . ($topPollInstead ? 'pc.votes' : 'p.ID_POLL') . " DESC
LIMIT 1", __FILE__, __LINE__);
$row = mysql_fetch_assoc($request);
mysql_free_result($request);

// This user has voted on all the polls.
if ($row === false)
return array();

$request = db_query("
SELECT COUNT(DISTINCT ID_MEMBER)
FROM {$db_prefix}log_polls
WHERE ID_POLL = $row[ID_POLL]", __FILE__, __LINE__);
list ($total) = mysql_fetch_row($request);
mysql_free_result($request);

$request = db_query("
SELECT ID_CHOICE, label, votes
FROM {$db_prefix}poll_choices
WHERE ID_POLL = $row[ID_POLL]", __FILE__, __LINE__);
$options = array();
while ($rowChoice = mysql_fetch_assoc($request))
{
censorText($rowChoice['label']);

$options[$rowChoice['ID_CHOICE']] = array($rowChoice['label'], $rowChoice['votes']);
}
mysql_free_result($request);

$return = array(
'id' => $row['ID_POLL'],
'image' => 'poll',
'question' => $row['question'],
'total_votes' => $total,
'is_locked' => false,
'topic' => $row['ID_TOPIC'],
'options' => array()
);

// Calculate the percentages and bar lengths...
$divisor = $return['total_votes'] == 0 ? 1 : $return['total_votes'];
foreach ($options as $i => $option)
{
$bar = floor(($option[1] * 100) / $divisor);
$barWide = $bar == 0 ? 1 : floor(($bar * 5) / 3);
$return['options'][$i] = array(
'id' => 'options-' . $i,
'percent' => $bar,
'votes' => $option[1],
'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_left.gif" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.gif" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_right.gif" alt="" /></span>',
'option' => parse_bbc($option[0]),
'vote_button' => '<input type="' . ($row['maxVotes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="check" />'
);
}

$return['allowed_warning'] = $row['maxVotes'] > 1 ? sprintf($txt['poll_options6'], $row['maxVotes']) : '';

if ($output_method != 'echo')
return $return;

echo '
<form action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '">
<input type="hidden" name="poll" value="', $return['id'], '" />
<table border="0" cellspacing="1" cellpadding="0" class="ssi_table">
<tr>
<td><b>', $return['question'], '</b></td>
</tr>
<tr>
<td>', $return['allowed_warning'], '</td>
</tr>';
foreach ($return['options'] as $option)
echo '
<tr>
<td><label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label></td>
</tr>';
echo '
<tr>
<td><input type="submit" value="', $txt['smf23'], '" /></td>
</tr>
</table>
<input type="hidden" name="sc" value="', $sc, '" />
</form>';
}

function ssi_showPoll($topic = null, $output_method = 'echo')
{
global $db_prefix, $txt, $ID_MEMBER, $settings, $boardurl, $sc, $user_info;
global $context;

$boardsAllowed = boardsAllowedTo('poll_view');

if (empty($boardsAllowed))
return array();

if ($topic === null && isset($_REQUEST['ssi_topic']))
$topic = (int) $_REQUEST['ssi_topic'];
else
$topic = (int) $topic;

$request = db_query("
SELECT
p.ID_POLL, p.question, p.votingLocked, p.hideResults, p.expireTime, p.maxVotes
FROM ({$db_prefix}topics AS t, {$db_prefix}polls AS p, {$db_prefix}boards AS b)
WHERE p.ID_POLL = t.ID_POLL
AND t.ID_TOPIC = $topic
AND b.ID_BOARD = t.ID_BOARD
AND $user_info[query_see_board]" . (!in_array(0, $boardsAllowed) ? "
AND b.ID_BOARD IN (" . implode(', ', $boardsAllowed) . ")" : '') . "
LIMIT 1", __FILE__, __LINE__);

// Either this topic has no poll, or the user cannot view it.
if (mysql_num_rows($request) == 0)
return array();

$row = mysql_fetch_assoc($request);
mysql_free_result($request);

// Check if they can vote.
if (!empty($row['expireTime']) && $row['expireTime'] < time())
$allow_vote = false;
elseif ($user_info['is_guest'] || !empty($row['votingLocked']) || !allowedTo('poll_vote'))
$allow_vote = false;
else
{
$request = db_query("
SELECT ID_MEMBER
FROM {$db_prefix}log_polls
WHERE ID_POLL = $row[ID_POLL]
AND ID_MEMBER = $ID_MEMBER
LIMIT 1", __FILE__, __LINE__);
$allow_vote = mysql_num_rows($request) == 0;
mysql_free_result($request);
}

$request = db_query("
SELECT COUNT(DISTINCT ID_MEMBER)
FROM {$db_prefix}log_polls
WHERE ID_POLL = $row[ID_POLL]", __FILE__, __LINE__);
list ($total) = mysql_fetch_row($request);
mysql_free_result($request);

$request = db_query("
SELECT ID_CHOICE, label, votes
FROM {$db_prefix}poll_choices
WHERE ID_POLL = $row[ID_POLL]", __FILE__, __LINE__);
$options = array();
$total_votes = 0;
while ($rowChoice = mysql_fetch_assoc($request))
{
censorText($rowChoice['label']);

$options[$rowChoice['ID_CHOICE']] = array($rowChoice['label'], $rowChoice['votes']);
$total_votes += $rowChoice['votes'];
}
mysql_free_result($request);

$return = array(
'id' => $row['ID_POLL'],
'image' => empty($pollinfo['votingLocked']) ? 'poll' : 'locked_poll',
'question' => $row['question'],
'total_votes' => $total,
'is_locked' => !empty($pollinfo['votingLocked']),
'allow_vote' => $allow_vote,
'topic' => $topic
);

// Calculate the percentages and bar lengths...
$divisor = $total_votes == 0 ? 1 : $total_votes;
foreach ($options as $i => $option)
{
$bar = floor(($option[1] * 100) / $divisor);
$barWide = $bar == 0 ? 1 : floor(($bar * 5) / 3);
$return['options'][$i] = array(
'id' => 'options-' . $i,
'percent' => $bar,
'votes' => $option[1],
'bar' => '<span style="white-space: nowrap;"><img src="' . $settings['images_url'] . '/poll_left.gif" alt="" /><img src="' . $settings['images_url'] . '/poll_middle.gif" width="' . $barWide . '" height="12" alt="-" /><img src="' . $settings['images_url'] . '/poll_right.gif" alt="" /></span>',
'option' => parse_bbc($option[0]),
'vote_button' => '<input type="' . ($row['maxVotes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="check" />'
);
}

$return['allowed_warning'] = $row['maxVotes'] > 1 ? sprintf($txt['poll_options6'], $row['maxVotes']) : '';

if ($output_method != 'echo')
return $return;

if ($return['allow_vote'])
{
echo '
<form action="', $boardurl, '/SSI.php?ssi_function=pollVote" method="post" accept-charset="', $context['character_set'], '">
<input type="hidden" name="poll" value="', $return['id'], '" />
<table border="0" cellspacing="1" cellpadding="0" class="ssi_table">
<tr>
<td><b>', $return['question'], '</b></td>
</tr>
<tr>
<td>', $return['allowed_warning'], '</td>
</tr>';
foreach ($return['options'] as $option)
echo '
<tr>
<td><label for="', $option['id'], '">', $option['vote_button'], ' ', $option['option'], '</label></td>
</tr>';
echo '
<tr>
<td><input type="submit" value="', $txt['smf23'], '" /></td>
</tr>
</table>
<input type="hidden" name="sc" value="', $sc, '" />
</form>';
}
elseif (!empty($row['expireTime']) && $row['expireTime'] > time())
{
if(!$context['user']['is_guest'])
echo $txt['smf27'];
else
echo $txt['cannot_poll_vote'];

}
else
{
echo '
<table border="0" cellspacing="1" cellpadding="0" class="ssi_table">
<tr>
<td colspan="2"><b>', $return['question'], '</b></td>
</tr>';
foreach ($return['options'] as $option)
echo '
<tr>
<td align="right" valign="top">', $option['option'], '</td>
<td align="left">', $option['bar'], ' ', $option['votes'], ' (', $option['percent'], '%)</td>
</tr>';
echo '
<tr>
<td colspan="2"><b>', $txt['smf24'], ': ', $return['total_votes'], '</b></td>
</tr>
</table>';
}
}

// Takes care of voting - don't worry, this is done automatically.
function ssi_pollVote()
{
global $db_prefix, $ID_MEMBER, $user_info, $sc;

if (!isset($_POST['sc']) || $_POST['sc'] != $sc || empty($_POST['options']) || !isset($_POST['poll']))
{
echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script language="JavaScript" type="text/javascript"><!-- // --><![CDATA[
history.go(-1);
// ]]></script>
</head>
<body>&laquo;</body>
</html>';
return;
}


I can't make edits at work as Uploads are blocked by the firewall, I've removed that edit to the code for now.

SleePy

Hmmm. Seems that the errors language File isn't loaded.

In the code I had you add Find:
if(!$context['user']['is_guest'])

Add before:
loadLanguage('Errors');

That error code means you have already voted in that poll
Jeremy D ~ Site Team / SMF Developer ~ GitHub Profile ~ Join us on IRC @ Libera.chat/#smf ~ Support the SMF Support team!

Advertisement: