Chris@76: $user_info['id'], Chris@76: 'current_topic' => $topic, Chris@76: 'not_guest' => 0, Chris@76: ) Chris@76: ); Chris@76: if ($smcFunc['db_num_rows']($request) == 0) Chris@76: fatal_lang_error('poll_error', false); Chris@76: $row = $smcFunc['db_fetch_assoc']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: // If this is a guest can they vote? Chris@76: if ($user_info['is_guest']) Chris@76: { Chris@76: // Guest voting disabled? Chris@76: if (!$row['guest_vote']) Chris@76: fatal_lang_error('guest_vote_disabled'); Chris@76: // Guest already voted? Chris@76: elseif (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $row['id_poll'] . ',') !== false) Chris@76: { Chris@76: // ;id,timestamp,[vote,vote...]; etc Chris@76: $guestinfo = explode(';', $_COOKIE['guest_poll_vote']); Chris@76: // Find the poll we're after. Chris@76: foreach ($guestinfo as $i => $guestvoted) Chris@76: { Chris@76: $guestvoted = explode(',', $guestvoted); Chris@76: if ($guestvoted[0] == $row['id_poll']) Chris@76: break; Chris@76: } Chris@76: // Has the poll been reset since guest voted? Chris@76: if ($row['reset_poll'] > $guestvoted[1]) Chris@76: { Chris@76: // Remove the poll info from the cookie to allow guest to vote again Chris@76: unset($guestinfo[$i]); Chris@76: if (!empty($guestinfo)) Chris@76: $_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo); Chris@76: else Chris@76: unset($_COOKIE['guest_poll_vote']); Chris@76: } Chris@76: else Chris@76: fatal_lang_error('poll_error', false); Chris@76: unset($guestinfo, $guestvoted, $i); Chris@76: } Chris@76: } Chris@76: Chris@76: // Is voting locked or has it expired? Chris@76: if (!empty($row['voting_locked']) || (!empty($row['expire_time']) && time() > $row['expire_time'])) Chris@76: fatal_lang_error('poll_error', false); Chris@76: Chris@76: // If they have already voted and aren't allowed to change their vote - hence they are outta here! Chris@76: if (!$user_info['is_guest'] && $row['selected'] != -1 && empty($row['change_vote'])) Chris@76: fatal_lang_error('poll_error', false); Chris@76: // Otherwise if they can change their vote yet they haven't sent any options... remove their vote and redirect. Chris@76: elseif (!empty($row['change_vote']) && !$user_info['is_guest']) Chris@76: { Chris@76: checkSession('request'); Chris@76: $pollOptions = array(); Chris@76: Chris@76: // Find out what they voted for before. Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT id_choice Chris@76: FROM {db_prefix}log_polls Chris@76: WHERE id_member = {int:current_member} Chris@76: AND id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'current_member' => $user_info['id'], Chris@76: 'id_poll' => $row['id_poll'], Chris@76: ) Chris@76: ); Chris@76: while ($choice = $smcFunc['db_fetch_row']($request)) Chris@76: $pollOptions[] = $choice[0]; Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: // Just skip it if they had voted for nothing before. Chris@76: if (!empty($pollOptions)) Chris@76: { Chris@76: // Update the poll totals. Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}poll_choices Chris@76: SET votes = votes - 1 Chris@76: WHERE id_poll = {int:id_poll} Chris@76: AND id_choice IN ({array_int:poll_options}) Chris@76: AND votes > {int:votes}', Chris@76: array( Chris@76: 'poll_options' => $pollOptions, Chris@76: 'id_poll' => $row['id_poll'], Chris@76: 'votes' => 0, Chris@76: ) Chris@76: ); Chris@76: Chris@76: // Delete off the log. Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}log_polls Chris@76: WHERE id_member = {int:current_member} Chris@76: AND id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'current_member' => $user_info['id'], Chris@76: 'id_poll' => $row['id_poll'], Chris@76: ) Chris@76: ); Chris@76: } Chris@76: Chris@76: // Redirect back to the topic so the user can vote again! Chris@76: if (empty($_POST['options'])) Chris@76: redirectexit('topic=' . $topic . '.' . $_REQUEST['start']); Chris@76: } Chris@76: Chris@76: checkSession('request'); Chris@76: Chris@76: // Make sure the option(s) are valid. Chris@76: if (empty($_POST['options'])) Chris@76: fatal_lang_error('didnt_select_vote', false); Chris@76: Chris@76: // Too many options checked! Chris@76: if (count($_REQUEST['options']) > $row['max_votes']) Chris@76: fatal_lang_error('poll_too_many_votes', false, array($row['max_votes'])); Chris@76: Chris@76: $pollOptions = array(); Chris@76: $inserts = array(); Chris@76: foreach ($_REQUEST['options'] as $id) Chris@76: { Chris@76: $id = (int) $id; Chris@76: Chris@76: $pollOptions[] = $id; Chris@76: $inserts[] = array($row['id_poll'], $user_info['id'], $id); Chris@76: } Chris@76: Chris@76: // Add their vote to the tally. Chris@76: $smcFunc['db_insert']('insert', Chris@76: '{db_prefix}log_polls', Chris@76: array('id_poll' => 'int', 'id_member' => 'int', 'id_choice' => 'int'), Chris@76: $inserts, Chris@76: array('id_poll', 'id_member', 'id_choice') Chris@76: ); Chris@76: Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}poll_choices Chris@76: SET votes = votes + 1 Chris@76: WHERE id_poll = {int:id_poll} Chris@76: AND id_choice IN ({array_int:poll_options})', Chris@76: array( Chris@76: 'poll_options' => $pollOptions, Chris@76: 'id_poll' => $row['id_poll'], Chris@76: ) Chris@76: ); Chris@76: Chris@76: // If it's a guest don't let them vote again. Chris@76: if ($user_info['is_guest'] && count($pollOptions) > 0) Chris@76: { Chris@76: // Time is stored in case the poll is reset later, plus what they voted for. Chris@76: $_COOKIE['guest_poll_vote'] = empty($_COOKIE['guest_poll_vote']) ? '' : $_COOKIE['guest_poll_vote']; Chris@76: // ;id,timestamp,[vote,vote...]; etc Chris@76: $_COOKIE['guest_poll_vote'] .= ';' . $row['id_poll'] . ',' . time() . ',' . (count($pollOptions) > 1 ? explode(',' . $pollOptions) : $pollOptions[0]); Chris@76: Chris@76: // Increase num guest voters count by 1 Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}polls Chris@76: SET num_guest_voters = num_guest_voters + 1 Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $row['id_poll'], Chris@76: ) Chris@76: ); Chris@76: Chris@76: require_once($sourcedir . '/Subs-Auth.php'); Chris@76: $cookie_url = url_parts(!empty($modSettings['localCookies']), !empty($modSettings['globalCookies'])); Chris@76: setcookie('guest_poll_vote', $_COOKIE['guest_poll_vote'], time() + 2500000, $cookie_url[1], $cookie_url[0], 0); Chris@76: } Chris@76: Chris@76: // Return to the post... Chris@76: redirectexit('topic=' . $topic . '.' . $_REQUEST['start']); Chris@76: } Chris@76: Chris@76: // Lock the voting for a poll. Chris@76: function LockVoting() Chris@76: { Chris@76: global $topic, $user_info, $smcFunc; Chris@76: Chris@76: checkSession('get'); Chris@76: Chris@76: // Get the poll starter, ID, and whether or not it is locked. Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT t.id_member_started, t.id_poll, p.voting_locked Chris@76: FROM {db_prefix}topics AS t Chris@76: INNER JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll) Chris@76: WHERE t.id_topic = {int:current_topic} Chris@76: LIMIT 1', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: ) Chris@76: ); Chris@76: list ($memberID, $pollID, $voting_locked) = $smcFunc['db_fetch_row']($request); Chris@76: Chris@76: // If the user _can_ modify the poll.... Chris@76: if (!allowedTo('poll_lock_any')) Chris@76: isAllowedTo('poll_lock_' . ($user_info['id'] == $memberID ? 'own' : 'any')); Chris@76: Chris@76: // It's been locked by a non-moderator. Chris@76: if ($voting_locked == '1') Chris@76: $voting_locked = '0'; Chris@76: // Locked by a moderator, and this is a moderator. Chris@76: elseif ($voting_locked == '2' && allowedTo('moderate_board')) Chris@76: $voting_locked = '0'; Chris@76: // Sorry, a moderator locked it. Chris@76: elseif ($voting_locked == '2' && !allowedTo('moderate_board')) Chris@76: fatal_lang_error('locked_by_admin', 'user'); Chris@76: // A moderator *is* locking it. Chris@76: elseif ($voting_locked == '0' && allowedTo('moderate_board')) Chris@76: $voting_locked = '2'; Chris@76: // Well, it's gonna be locked one way or another otherwise... Chris@76: else Chris@76: $voting_locked = '1'; Chris@76: Chris@76: // Lock! *Poof* - no one can vote. Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}polls Chris@76: SET voting_locked = {int:voting_locked} Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'voting_locked' => $voting_locked, Chris@76: 'id_poll' => $pollID, Chris@76: ) Chris@76: ); Chris@76: Chris@76: redirectexit('topic=' . $topic . '.' . $_REQUEST['start']); Chris@76: } Chris@76: Chris@76: // Ask what to change in a poll. Chris@76: function EditPoll() Chris@76: { Chris@76: global $txt, $user_info, $context, $topic, $board, $smcFunc, $sourcedir, $scripturl; Chris@76: Chris@76: if (empty($topic)) Chris@76: fatal_lang_error('no_access', false); Chris@76: Chris@76: loadLanguage('Post'); Chris@76: loadTemplate('Poll'); Chris@76: Chris@76: $context['can_moderate_poll'] = isset($_REQUEST['add']) ? 1 : allowedTo('moderate_board'); Chris@76: $context['start'] = (int) $_REQUEST['start']; Chris@76: $context['is_edit'] = isset($_REQUEST['add']) ? 0 : 1; Chris@76: Chris@76: // Check if a poll currently exists on this topic, and get the id, question and starter. Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT Chris@76: t.id_member_started, p.id_poll, p.question, p.hide_results, p.expire_time, p.max_votes, p.change_vote, Chris@76: m.subject, p.guest_vote, p.id_member AS poll_starter Chris@76: FROM {db_prefix}topics AS t Chris@76: INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg) Chris@76: LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll) Chris@76: WHERE t.id_topic = {int:current_topic} Chris@76: LIMIT 1', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: ) Chris@76: ); Chris@76: Chris@76: // Assume the the topic exists, right? Chris@76: if ($smcFunc['db_num_rows']($request) == 0) Chris@76: fatal_lang_error('no_board'); Chris@76: // Get the poll information. Chris@76: $pollinfo = $smcFunc['db_fetch_assoc']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: // If we are adding a new poll - make sure that there isn't already a poll there. Chris@76: if (!$context['is_edit'] && !empty($pollinfo['id_poll'])) Chris@76: fatal_lang_error('poll_already_exists'); Chris@76: // Otherwise, if we're editing it, it does exist I assume? Chris@76: elseif ($context['is_edit'] && empty($pollinfo['id_poll'])) Chris@76: fatal_lang_error('poll_not_found'); Chris@76: Chris@76: // Can you do this? Chris@76: if ($context['is_edit'] && !allowedTo('poll_edit_any')) Chris@76: isAllowedTo('poll_edit_' . ($user_info['id'] == $pollinfo['id_member_started'] || ($pollinfo['poll_starter'] != 0 && $user_info['id'] == $pollinfo['poll_starter']) ? 'own' : 'any')); Chris@76: elseif (!$context['is_edit'] && !allowedTo('poll_add_any')) Chris@76: isAllowedTo('poll_add_' . ($user_info['id'] == $pollinfo['id_member_started'] ? 'own' : 'any')); Chris@76: Chris@76: // Do we enable guest voting? Chris@76: require_once($sourcedir . '/Subs-Members.php'); Chris@76: $groupsAllowedVote = groupsAllowedTo('poll_vote', $board); Chris@76: Chris@76: // Want to make sure before you actually submit? Must be a lot of options, or something. Chris@76: if (isset($_POST['preview'])) Chris@76: { Chris@76: $question = $smcFunc['htmlspecialchars']($_POST['question']); Chris@76: Chris@76: // Basic theme info... Chris@76: $context['poll'] = array( Chris@76: 'id' => $pollinfo['id_poll'], Chris@76: 'question' => $question, Chris@76: 'hide_results' => empty($_POST['poll_hide']) ? 0 : $_POST['poll_hide'], Chris@76: 'change_vote' => isset($_POST['poll_change_vote']), Chris@76: 'guest_vote' => isset($_POST['poll_guest_vote']), Chris@76: 'guest_vote_allowed' => in_array(-1, $groupsAllowedVote['allowed']), Chris@76: 'max_votes' => empty($_POST['poll_max_votes']) ? '1' : max(1, $_POST['poll_max_votes']), Chris@76: ); Chris@76: Chris@76: // Start at number one with no last id to speak of. Chris@76: $number = 1; Chris@76: $last_id = 0; Chris@76: Chris@76: // Get all the choices - if this is an edit. Chris@76: if ($context['is_edit']) Chris@76: { Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT label, votes, id_choice Chris@76: FROM {db_prefix}poll_choices Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $pollinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: $context['choices'] = array(); Chris@76: while ($row = $smcFunc['db_fetch_assoc']($request)) Chris@76: { Chris@76: // Get the highest id so we can add more without reusing. Chris@76: if ($row['id_choice'] >= $last_id) Chris@76: $last_id = $row['id_choice'] + 1; Chris@76: Chris@76: // They cleared this by either omitting it or emptying it. Chris@76: if (!isset($_POST['options'][$row['id_choice']]) || $_POST['options'][$row['id_choice']] == '') Chris@76: continue; Chris@76: Chris@76: censorText($row['label']); Chris@76: Chris@76: // Add the choice! Chris@76: $context['choices'][$row['id_choice']] = array( Chris@76: 'id' => $row['id_choice'], Chris@76: 'number' => $number++, Chris@76: 'votes' => $row['votes'], Chris@76: 'label' => $row['label'], Chris@76: 'is_last' => false Chris@76: ); Chris@76: } Chris@76: $smcFunc['db_free_result']($request); Chris@76: } Chris@76: Chris@76: // Work out how many options we have, so we get the 'is_last' field right... Chris@76: $totalPostOptions = 0; Chris@76: foreach ($_POST['options'] as $id => $label) Chris@76: if ($label != '') Chris@76: $totalPostOptions++; Chris@76: Chris@76: $count = 1; Chris@76: // If an option exists, update it. If it is new, add it - but don't reuse ids! Chris@76: foreach ($_POST['options'] as $id => $label) Chris@76: { Chris@76: $label = $smcFunc['htmlspecialchars']($label); Chris@76: censorText($label); Chris@76: Chris@76: if (isset($context['choices'][$id])) Chris@76: $context['choices'][$id]['label'] = $label; Chris@76: elseif ($label != '') Chris@76: $context['choices'][] = array( Chris@76: 'id' => $last_id++, Chris@76: 'number' => $number++, Chris@76: 'label' => $label, Chris@76: 'votes' => -1, Chris@76: 'is_last' => $count++ == $totalPostOptions && $totalPostOptions > 1 ? true : false, Chris@76: ); Chris@76: } Chris@76: Chris@76: // Make sure we have two choices for sure! Chris@76: if ($totalPostOptions < 2) Chris@76: { Chris@76: // Need two? Chris@76: if ($totalPostOptions == 0) Chris@76: $context['choices'][] = array( Chris@76: 'id' => $last_id++, Chris@76: 'number' => $number++, Chris@76: 'label' => '', Chris@76: 'votes' => -1, Chris@76: 'is_last' => false Chris@76: ); Chris@76: $poll_errors[] = 'poll_few'; Chris@76: } Chris@76: Chris@76: // Always show one extra box... Chris@76: $context['choices'][] = array( Chris@76: 'id' => $last_id++, Chris@76: 'number' => $number++, Chris@76: 'label' => '', Chris@76: 'votes' => -1, Chris@76: 'is_last' => true Chris@76: ); Chris@76: Chris@76: if ($context['can_moderate_poll']) Chris@76: $context['poll']['expiration'] = $_POST['poll_expire']; Chris@76: Chris@76: // Check the question/option count for errors. Chris@76: if (trim($_POST['question']) == '' && empty($context['poll_error'])) Chris@76: $poll_errors[] = 'no_question'; Chris@76: Chris@76: // No check is needed, since nothing is really posted. Chris@76: checkSubmitOnce('free'); Chris@76: Chris@76: // Take a check for any errors... assuming we haven't already done so! Chris@76: if (!empty($poll_errors) && empty($context['poll_error'])) Chris@76: { Chris@76: loadLanguage('Errors'); Chris@76: Chris@76: $context['poll_error'] = array('messages' => array()); Chris@76: foreach ($poll_errors as $poll_error) Chris@76: { Chris@76: $context['poll_error'][$poll_error] = true; Chris@76: $context['poll_error']['messages'][] = $txt['error_' . $poll_error]; Chris@76: } Chris@76: } Chris@76: } Chris@76: else Chris@76: { Chris@76: // Basic theme info... Chris@76: $context['poll'] = array( Chris@76: 'id' => $pollinfo['id_poll'], Chris@76: 'question' => $pollinfo['question'], Chris@76: 'hide_results' => $pollinfo['hide_results'], Chris@76: 'max_votes' => $pollinfo['max_votes'], Chris@76: 'change_vote' => !empty($pollinfo['change_vote']), Chris@76: 'guest_vote' => !empty($pollinfo['guest_vote']), Chris@76: 'guest_vote_allowed' => in_array(-1, $groupsAllowedVote['allowed']), Chris@76: ); Chris@76: Chris@76: // Poll expiration time? Chris@76: $context['poll']['expiration'] = empty($pollinfo['expire_time']) || !allowedTo('moderate_board') ? '' : ceil($pollinfo['expire_time'] <= time() ? -1 : ($pollinfo['expire_time'] - time()) / (3600 * 24)); Chris@76: Chris@76: // Get all the choices - if this is an edit. Chris@76: if ($context['is_edit']) Chris@76: { Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT label, votes, id_choice Chris@76: FROM {db_prefix}poll_choices Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $pollinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: $context['choices'] = array(); Chris@76: $number = 1; Chris@76: while ($row = $smcFunc['db_fetch_assoc']($request)) Chris@76: { Chris@76: censorText($row['label']); Chris@76: Chris@76: $context['choices'][$row['id_choice']] = array( Chris@76: 'id' => $row['id_choice'], Chris@76: 'number' => $number++, Chris@76: 'votes' => $row['votes'], Chris@76: 'label' => $row['label'], Chris@76: 'is_last' => false Chris@76: ); Chris@76: } Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: $last_id = max(array_keys($context['choices'])) + 1; Chris@76: Chris@76: // Add an extra choice... Chris@76: $context['choices'][] = array( Chris@76: 'id' => $last_id, Chris@76: 'number' => $number, Chris@76: 'votes' => -1, Chris@76: 'label' => '', Chris@76: 'is_last' => true Chris@76: ); Chris@76: } Chris@76: // New poll? Chris@76: else Chris@76: { Chris@76: // Setup the default poll options. Chris@76: $context['poll'] = array( Chris@76: 'id' => 0, Chris@76: 'question' => '', Chris@76: 'hide_results' => 0, Chris@76: 'max_votes' => 1, Chris@76: 'change_vote' => 0, Chris@76: 'guest_vote' => 0, Chris@76: 'guest_vote_allowed' => in_array(-1, $groupsAllowedVote['allowed']), Chris@76: 'expiration' => '', Chris@76: ); Chris@76: Chris@76: // Make all five poll choices empty. Chris@76: $context['choices'] = array( Chris@76: array('id' => 0, 'number' => 1, 'votes' => -1, 'label' => '', 'is_last' => false), Chris@76: array('id' => 1, 'number' => 2, 'votes' => -1, 'label' => '', 'is_last' => false), Chris@76: array('id' => 2, 'number' => 3, 'votes' => -1, 'label' => '', 'is_last' => false), Chris@76: array('id' => 3, 'number' => 4, 'votes' => -1, 'label' => '', 'is_last' => false), Chris@76: array('id' => 4, 'number' => 5, 'votes' => -1, 'label' => '', 'is_last' => true) Chris@76: ); Chris@76: } Chris@76: } Chris@76: $context['page_title'] = $context['is_edit'] ? $txt['poll_edit'] : $txt['add_poll']; Chris@76: Chris@76: // Build the link tree. Chris@76: censorText($pollinfo['subject']); Chris@76: $context['linktree'][] = array( Chris@76: 'url' => $scripturl . '?topic=' . $topic . '.0', Chris@76: 'name' => $pollinfo['subject'], Chris@76: ); Chris@76: $context['linktree'][] = array( Chris@76: 'name' => $context['page_title'], Chris@76: ); Chris@76: Chris@76: // Register this form in the session variables. Chris@76: checkSubmitOnce('register'); Chris@76: } Chris@76: Chris@76: // Change a poll... Chris@76: function EditPoll2() Chris@76: { Chris@76: global $txt, $topic, $board, $context; Chris@76: global $modSettings, $user_info, $smcFunc, $sourcedir; Chris@76: Chris@76: // Sneaking off, are we? Chris@76: if (empty($_POST)) Chris@76: redirectexit('action=editpoll;topic=' . $topic . '.0'); Chris@76: Chris@76: if (checkSession('post', '', false) != '') Chris@76: $poll_errors[] = 'session_timeout'; Chris@76: Chris@76: if (isset($_POST['preview'])) Chris@76: return EditPoll(); Chris@76: Chris@76: // HACKERS (!!) can't edit :P. Chris@76: if (empty($topic)) Chris@76: fatal_lang_error('no_access', false); Chris@76: Chris@76: // Is this a new poll, or editing an existing? Chris@76: $isEdit = isset($_REQUEST['add']) ? 0 : 1; Chris@76: Chris@76: // Get the starter and the poll's ID - if it's an edit. Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT t.id_member_started, t.id_poll, p.id_member AS poll_starter, p.expire_time Chris@76: FROM {db_prefix}topics AS t Chris@76: LEFT JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll) Chris@76: WHERE t.id_topic = {int:current_topic} Chris@76: LIMIT 1', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: ) Chris@76: ); Chris@76: if ($smcFunc['db_num_rows']($request) == 0) Chris@76: fatal_lang_error('no_board'); Chris@76: $bcinfo = $smcFunc['db_fetch_assoc']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: // Check their adding/editing is valid. Chris@76: if (!$isEdit && !empty($bcinfo['id_poll'])) Chris@76: fatal_lang_error('poll_already_exists'); Chris@76: // Are we editing a poll which doesn't exist? Chris@76: elseif ($isEdit && empty($bcinfo['id_poll'])) Chris@76: fatal_lang_error('poll_not_found'); Chris@76: Chris@76: // Check if they have the power to add or edit the poll. Chris@76: if ($isEdit && !allowedTo('poll_edit_any')) Chris@76: isAllowedTo('poll_edit_' . ($user_info['id'] == $bcinfo['id_member_started'] || ($bcinfo['poll_starter'] != 0 && $user_info['id'] == $bcinfo['poll_starter']) ? 'own' : 'any')); Chris@76: elseif (!$isEdit && !allowedTo('poll_add_any')) Chris@76: isAllowedTo('poll_add_' . ($user_info['id'] == $bcinfo['id_member_started'] ? 'own' : 'any')); Chris@76: Chris@76: $optionCount = 0; Chris@76: // Ensure the user is leaving a valid amount of options - there must be at least two. Chris@76: foreach ($_POST['options'] as $k => $option) Chris@76: { Chris@76: if (trim($option) != '') Chris@76: $optionCount++; Chris@76: } Chris@76: if ($optionCount < 2) Chris@76: $poll_errors[] = 'poll_few'; Chris@76: Chris@76: // Also - ensure they are not removing the question. Chris@76: if (trim($_POST['question']) == '') Chris@76: $poll_errors[] = 'no_question'; Chris@76: Chris@76: // Got any errors to report? Chris@76: if (!empty($poll_errors)) Chris@76: { Chris@76: loadLanguage('Errors'); Chris@76: // Previewing. Chris@76: $_POST['preview'] = true; Chris@76: Chris@76: $context['poll_error'] = array('messages' => array()); Chris@76: foreach ($poll_errors as $poll_error) Chris@76: { Chris@76: $context['poll_error'][$poll_error] = true; Chris@76: $context['poll_error']['messages'][] = $txt['error_' . $poll_error]; Chris@76: } Chris@76: Chris@76: return EditPoll(); Chris@76: } Chris@76: Chris@76: // Prevent double submission of this form. Chris@76: checkSubmitOnce('check'); Chris@76: Chris@76: // Now we've done all our error checking, let's get the core poll information cleaned... question first. Chris@76: $_POST['question'] = $smcFunc['htmlspecialchars']($_POST['question']); Chris@76: $_POST['question'] = $smcFunc['truncate']($_POST['question'], 255); Chris@76: Chris@76: $_POST['poll_hide'] = (int) $_POST['poll_hide']; Chris@76: $_POST['poll_expire'] = isset($_POST['poll_expire']) ? (int) $_POST['poll_expire'] : 0; Chris@76: $_POST['poll_change_vote'] = isset($_POST['poll_change_vote']) ? 1 : 0; Chris@76: $_POST['poll_guest_vote'] = isset($_POST['poll_guest_vote']) ? 1 : 0; Chris@76: Chris@76: // Make sure guests are actually allowed to vote generally. Chris@76: if ($_POST['poll_guest_vote']) Chris@76: { Chris@76: require_once($sourcedir . '/Subs-Members.php'); Chris@76: $allowedGroups = groupsAllowedTo('poll_vote', $board); Chris@76: if (!in_array(-1, $allowedGroups['allowed'])) Chris@76: $_POST['poll_guest_vote'] = 0; Chris@76: } Chris@76: Chris@76: // Ensure that the number options allowed makes sense, and the expiration date is valid. Chris@76: if (!$isEdit || allowedTo('moderate_board')) Chris@76: { Chris@76: $_POST['poll_expire'] = $_POST['poll_expire'] > 9999 ? 9999 : ($_POST['poll_expire'] < 0 ? 0 : $_POST['poll_expire']); Chris@76: Chris@76: if (empty($_POST['poll_expire']) && $_POST['poll_hide'] == 2) Chris@76: $_POST['poll_hide'] = 1; Chris@76: elseif (!$isEdit || $_POST['poll_expire'] != ceil($bcinfo['expire_time'] <= time() ? -1 : ($bcinfo['expire_time'] - time()) / (3600 * 24))) Chris@76: $_POST['poll_expire'] = empty($_POST['poll_expire']) ? '0' : time() + $_POST['poll_expire'] * 3600 * 24; Chris@76: else Chris@76: $_POST['poll_expire'] = $bcinfo['expire_time']; Chris@76: Chris@76: if (empty($_POST['poll_max_votes']) || $_POST['poll_max_votes'] <= 0) Chris@76: $_POST['poll_max_votes'] = 1; Chris@76: else Chris@76: $_POST['poll_max_votes'] = (int) $_POST['poll_max_votes']; Chris@76: } Chris@76: Chris@76: // If we're editing, let's commit the changes. Chris@76: if ($isEdit) Chris@76: { Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}polls Chris@76: SET question = {string:question}, change_vote = {int:change_vote},' . (allowedTo('moderate_board') ? ' Chris@76: hide_results = {int:hide_results}, expire_time = {int:expire_time}, max_votes = {int:max_votes}, Chris@76: guest_vote = {int:guest_vote}' : ' Chris@76: hide_results = CASE WHEN expire_time = {int:expire_time_zero} AND {int:hide_results} = 2 THEN 1 ELSE {int:hide_results} END') . ' Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'change_vote' => $_POST['poll_change_vote'], Chris@76: 'hide_results' => $_POST['poll_hide'], Chris@76: 'expire_time' => !empty($_POST['poll_expire']) ? $_POST['poll_expire'] : 0, Chris@76: 'max_votes' => !empty($_POST['poll_max_votes']) ? $_POST['poll_max_votes'] : 0, Chris@76: 'guest_vote' => $_POST['poll_guest_vote'], Chris@76: 'expire_time_zero' => 0, Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: 'question' => $_POST['question'], Chris@76: ) Chris@76: ); Chris@76: } Chris@76: // Otherwise, let's get our poll going! Chris@76: else Chris@76: { Chris@76: // Create the poll. Chris@76: $smcFunc['db_insert']('', Chris@76: '{db_prefix}polls', Chris@76: array( Chris@76: 'question' => 'string-255', 'hide_results' => 'int', 'max_votes' => 'int', 'expire_time' => 'int', 'id_member' => 'int', Chris@76: 'poster_name' => 'string-255', 'change_vote' => 'int', 'guest_vote' => 'int' Chris@76: ), Chris@76: array( Chris@76: $_POST['question'], $_POST['poll_hide'], $_POST['poll_max_votes'], $_POST['poll_expire'], $user_info['id'], Chris@76: $user_info['username'], $_POST['poll_change_vote'], $_POST['poll_guest_vote'], Chris@76: ), Chris@76: array('id_poll') Chris@76: ); Chris@76: Chris@76: // Set the poll ID. Chris@76: $bcinfo['id_poll'] = $smcFunc['db_insert_id']('{db_prefix}polls', 'id_poll'); Chris@76: Chris@76: // Link the poll to the topic Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}topics Chris@76: SET id_poll = {int:id_poll} Chris@76: WHERE id_topic = {int:current_topic}', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: } Chris@76: Chris@76: // Get all the choices. (no better way to remove all emptied and add previously non-existent ones.) Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT id_choice Chris@76: FROM {db_prefix}poll_choices Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: $choices = array(); Chris@76: while ($row = $smcFunc['db_fetch_assoc']($request)) Chris@76: $choices[] = $row['id_choice']; Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: $delete_options = array(); Chris@76: foreach ($_POST['options'] as $k => $option) Chris@76: { Chris@76: // Make sure the key is numeric for sanity's sake. Chris@76: $k = (int) $k; Chris@76: Chris@76: // They've cleared the box. Either they want it deleted, or it never existed. Chris@76: if (trim($option) == '') Chris@76: { Chris@76: // They want it deleted. Bye. Chris@76: if (in_array($k, $choices)) Chris@76: $delete_options[] = $k; Chris@76: Chris@76: // Skip the rest... Chris@76: continue; Chris@76: } Chris@76: Chris@76: // Dress the option up for its big date with the database. Chris@76: $option = $smcFunc['htmlspecialchars']($option); Chris@76: Chris@76: // If it's already there, update it. If it's not... add it. Chris@76: if (in_array($k, $choices)) Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}poll_choices Chris@76: SET label = {string:option_name} Chris@76: WHERE id_poll = {int:id_poll} Chris@76: AND id_choice = {int:id_choice}', Chris@76: array( Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: 'id_choice' => $k, Chris@76: 'option_name' => $option, Chris@76: ) Chris@76: ); Chris@76: else Chris@76: $smcFunc['db_insert']('', Chris@76: '{db_prefix}poll_choices', Chris@76: array( Chris@76: 'id_poll' => 'int', 'id_choice' => 'int', 'label' => 'string-255', 'votes' => 'int', Chris@76: ), Chris@76: array( Chris@76: $bcinfo['id_poll'], $k, $option, 0, Chris@76: ), Chris@76: array() Chris@76: ); Chris@76: } Chris@76: Chris@76: // I'm sorry, but... well, no one was choosing you. Poor options, I'll put you out of your misery. Chris@76: if (!empty($delete_options)) Chris@76: { Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}log_polls Chris@76: WHERE id_poll = {int:id_poll} Chris@76: AND id_choice IN ({array_int:delete_options})', Chris@76: array( Chris@76: 'delete_options' => $delete_options, Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}poll_choices Chris@76: WHERE id_poll = {int:id_poll} Chris@76: AND id_choice IN ({array_int:delete_options})', Chris@76: array( Chris@76: 'delete_options' => $delete_options, Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: } Chris@76: Chris@76: // Shall I reset the vote count, sir? Chris@76: if (isset($_POST['resetVoteCount'])) Chris@76: { Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}polls Chris@76: SET num_guest_voters = {int:no_votes}, reset_poll = {int:time} Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'no_votes' => 0, Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: 'time' => time(), Chris@76: ) Chris@76: ); Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}poll_choices Chris@76: SET votes = {int:no_votes} Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'no_votes' => 0, Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}log_polls Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $bcinfo['id_poll'], Chris@76: ) Chris@76: ); Chris@76: } Chris@76: Chris@76: // Off we go. Chris@76: redirectexit('topic=' . $topic . '.' . $_REQUEST['start']); Chris@76: } Chris@76: Chris@76: // Remove a poll from a topic without removing the topic. Chris@76: function RemovePoll() Chris@76: { Chris@76: global $topic, $user_info, $smcFunc; Chris@76: Chris@76: // Make sure the topic is not empty. Chris@76: if (empty($topic)) Chris@76: fatal_lang_error('no_access', false); Chris@76: Chris@76: // Verify the session. Chris@76: checkSession('get'); Chris@76: Chris@76: // Check permissions. Chris@76: if (!allowedTo('poll_remove_any')) Chris@76: { Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT t.id_member_started, p.id_member AS poll_starter Chris@76: FROM {db_prefix}topics AS t Chris@76: INNER JOIN {db_prefix}polls AS p ON (p.id_poll = t.id_poll) Chris@76: WHERE t.id_topic = {int:current_topic} Chris@76: LIMIT 1', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: ) Chris@76: ); Chris@76: if ($smcFunc['db_num_rows']($request) == 0) Chris@76: fatal_lang_error('no_access', false); Chris@76: list ($topicStarter, $pollStarter) = $smcFunc['db_fetch_row']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: isAllowedTo('poll_remove_' . ($topicStarter == $user_info['id'] || ($pollStarter != 0 && $user_info['id'] == $pollStarter) ? 'own' : 'any')); Chris@76: } Chris@76: Chris@76: // Retrieve the poll ID. Chris@76: $request = $smcFunc['db_query']('', ' Chris@76: SELECT id_poll Chris@76: FROM {db_prefix}topics Chris@76: WHERE id_topic = {int:current_topic} Chris@76: LIMIT 1', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: ) Chris@76: ); Chris@76: list ($pollID) = $smcFunc['db_fetch_row']($request); Chris@76: $smcFunc['db_free_result']($request); Chris@76: Chris@76: // Remove all user logs for this poll. Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}log_polls Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $pollID, Chris@76: ) Chris@76: ); Chris@76: // Remove all poll choices. Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}poll_choices Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $pollID, Chris@76: ) Chris@76: ); Chris@76: // Remove the poll itself. Chris@76: $smcFunc['db_query']('', ' Chris@76: DELETE FROM {db_prefix}polls Chris@76: WHERE id_poll = {int:id_poll}', Chris@76: array( Chris@76: 'id_poll' => $pollID, Chris@76: ) Chris@76: ); Chris@76: // Finally set the topic poll ID back to 0! Chris@76: $smcFunc['db_query']('', ' Chris@76: UPDATE {db_prefix}topics Chris@76: SET id_poll = {int:no_poll} Chris@76: WHERE id_topic = {int:current_topic}', Chris@76: array( Chris@76: 'current_topic' => $topic, Chris@76: 'no_poll' => 0, Chris@76: ) Chris@76: ); Chris@76: Chris@76: // Take the moderator back to the topic. Chris@76: redirectexit('topic=' . $topic . '.' . $_REQUEST['start']); Chris@76: } Chris@76: Chris@76: ?>