Yoshi2889 /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | /** |
||
| 4 | * This file contains just one function that formats a topic to be printer |
||
| 5 | * friendly. |
||
| 6 | * |
||
| 7 | * Simple Machines Forum (SMF) |
||
| 8 | * |
||
| 9 | * @package SMF |
||
| 10 | * @author Simple Machines http://www.simplemachines.org |
||
| 11 | * @copyright 2017 Simple Machines and individual contributors |
||
| 12 | * @license http://www.simplemachines.org/about/smf/license.php BSD |
||
| 13 | * |
||
| 14 | * @version 2.1 Beta 4 |
||
| 15 | */ |
||
| 16 | |||
| 17 | if (!defined('SMF')) |
||
| 18 | die('No direct access...'); |
||
| 19 | |||
| 20 | /** |
||
| 21 | * Format a topic to be printer friendly. |
||
| 22 | * Must be called with a topic specified. |
||
| 23 | * Accessed via ?action=printpage. |
||
| 24 | * |
||
| 25 | * @uses Printpage template, main sub-template. |
||
| 26 | * @uses print_above/print_below later without the main layer. |
||
| 27 | */ |
||
| 28 | |||
| 29 | function PrintTopic() |
||
| 30 | { |
||
| 31 | global $topic, $txt, $scripturl, $context, $user_info; |
||
| 32 | global $board_info, $smcFunc, $modSettings; |
||
| 33 | |||
| 34 | // Redirect to the boardindex if no valid topic id is provided. |
||
| 35 | if (empty($topic)) |
||
| 36 | redirectexit(); |
||
| 37 | |||
| 38 | if (!empty($modSettings['disable_print_topic'])) |
||
| 39 | { |
||
| 40 | unset($_REQUEST['action']); |
||
| 41 | $context['theme_loaded'] = false; |
||
| 42 | fatal_lang_error('feature_disabled', false); |
||
| 43 | } |
||
| 44 | |||
| 45 | // Whatever happens don't index this. |
||
| 46 | $context['robot_no_index'] = true; |
||
| 47 | |||
| 48 | // Get the topic starter information. |
||
| 49 | $request = $smcFunc['db_query']('', ' |
||
| 50 | SELECT mem.id_member, m.poster_time, COALESCE(mem.real_name, m.poster_name) AS poster_name, t.id_poll |
||
| 51 | FROM {db_prefix}messages AS m |
||
| 52 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) |
||
| 53 | LEFT JOIN {db_prefix}topics as t ON (t.id_first_msg = m.id_msg) |
||
| 54 | WHERE m.id_topic = {int:current_topic} |
||
| 55 | ORDER BY m.id_msg |
||
| 56 | LIMIT 1', |
||
| 57 | array( |
||
| 58 | 'current_topic' => $topic, |
||
| 59 | ) |
||
| 60 | ); |
||
| 61 | // Redirect to the boardindex if no valid topic id is provided. |
||
| 62 | if ($smcFunc['db_num_rows']($request) == 0) |
||
| 63 | redirectexit(); |
||
| 64 | $row = $smcFunc['db_fetch_assoc']($request); |
||
| 65 | $smcFunc['db_free_result']($request); |
||
| 66 | |||
| 67 | if (!empty($row['id_poll'])) |
||
| 68 | { |
||
| 69 | loadLanguage('Post'); |
||
| 70 | // Get the question and if it's locked. |
||
| 71 | $request = $smcFunc['db_query']('', ' |
||
| 72 | SELECT |
||
| 73 | p.question, p.voting_locked, p.hide_results, p.expire_time, p.max_votes, p.change_vote, |
||
| 74 | p.guest_vote, p.id_member, COALESCE(mem.real_name, p.poster_name) AS poster_name, p.num_guest_voters, p.reset_poll |
||
| 75 | FROM {db_prefix}polls AS p |
||
| 76 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = p.id_member) |
||
| 77 | WHERE p.id_poll = {int:id_poll} |
||
| 78 | LIMIT 1', |
||
| 79 | array( |
||
| 80 | 'id_poll' => $row['id_poll'], |
||
| 81 | ) |
||
| 82 | ); |
||
| 83 | $pollinfo = $smcFunc['db_fetch_assoc']($request); |
||
| 84 | $smcFunc['db_free_result']($request); |
||
| 85 | |||
| 86 | $request = $smcFunc['db_query']('', ' |
||
| 87 | SELECT COUNT(DISTINCT id_member) AS total |
||
| 88 | FROM {db_prefix}log_polls |
||
| 89 | WHERE id_poll = {int:id_poll} |
||
| 90 | AND id_member != {int:not_guest}', |
||
| 91 | array( |
||
| 92 | 'id_poll' => $row['id_poll'], |
||
| 93 | 'not_guest' => 0, |
||
| 94 | ) |
||
| 95 | ); |
||
| 96 | list ($pollinfo['total']) = $smcFunc['db_fetch_row']($request); |
||
| 97 | $smcFunc['db_free_result']($request); |
||
| 98 | |||
| 99 | // Total voters needs to include guest voters |
||
| 100 | $pollinfo['total'] += $pollinfo['num_guest_voters']; |
||
| 101 | |||
| 102 | // Get all the options, and calculate the total votes. |
||
| 103 | $request = $smcFunc['db_query']('', ' |
||
| 104 | SELECT pc.id_choice, pc.label, pc.votes, COALESCE(lp.id_choice, -1) AS voted_this |
||
| 105 | FROM {db_prefix}poll_choices AS pc |
||
| 106 | LEFT JOIN {db_prefix}log_polls AS lp ON (lp.id_choice = pc.id_choice AND lp.id_poll = {int:id_poll} AND lp.id_member = {int:current_member} AND lp.id_member != {int:not_guest}) |
||
| 107 | WHERE pc.id_poll = {int:id_poll}', |
||
| 108 | array( |
||
| 109 | 'current_member' => $user_info['id'], |
||
| 110 | 'id_poll' => $row['id_poll'], |
||
| 111 | 'not_guest' => 0, |
||
| 112 | ) |
||
| 113 | ); |
||
| 114 | $pollOptions = array(); |
||
| 115 | $realtotal = 0; |
||
| 116 | $pollinfo['has_voted'] = false; |
||
| 117 | View Code Duplication | while ($row = $smcFunc['db_fetch_assoc']($request)) |
|
| 118 | { |
||
| 119 | censorText($row['label']); |
||
| 120 | $pollOptions[$row['id_choice']] = $row; |
||
| 121 | $realtotal += $row['votes']; |
||
| 122 | $pollinfo['has_voted'] |= $row['voted_this'] != -1; |
||
| 123 | } |
||
| 124 | $smcFunc['db_free_result']($request); |
||
| 125 | |||
| 126 | // If this is a guest we need to do our best to work out if they have voted, and what they voted for. |
||
| 127 | View Code Duplication | if ($user_info['is_guest'] && $pollinfo['guest_vote'] && allowedTo('poll_vote')) |
|
| 128 | { |
||
| 129 | if (!empty($_COOKIE['guest_poll_vote']) && preg_match('~^[0-9,;]+$~', $_COOKIE['guest_poll_vote']) && strpos($_COOKIE['guest_poll_vote'], ';' . $row['id_poll'] . ',') !== false) |
||
| 130 | { |
||
| 131 | // ;id,timestamp,[vote,vote...]; etc |
||
| 132 | $guestinfo = explode(';', $_COOKIE['guest_poll_vote']); |
||
| 133 | // Find the poll we're after. |
||
| 134 | foreach ($guestinfo as $i => $guestvoted) |
||
| 135 | { |
||
| 136 | $guestvoted = explode(',', $guestvoted); |
||
| 137 | if ($guestvoted[0] == $row['id_poll']) |
||
| 138 | break; |
||
| 139 | } |
||
| 140 | // Has the poll been reset since guest voted? |
||
| 141 | if ($pollinfo['reset_poll'] > $guestvoted[1]) |
||
| 142 | { |
||
| 143 | // Remove the poll info from the cookie to allow guest to vote again |
||
| 144 | unset($guestinfo[$i]); |
||
| 145 | if (!empty($guestinfo)) |
||
| 146 | $_COOKIE['guest_poll_vote'] = ';' . implode(';', $guestinfo); |
||
| 147 | else |
||
| 148 | unset($_COOKIE['guest_poll_vote']); |
||
| 149 | } |
||
| 150 | else |
||
| 151 | { |
||
| 152 | // What did they vote for? |
||
| 153 | unset($guestvoted[0], $guestvoted[1]); |
||
| 154 | foreach ($pollOptions as $choice => $details) |
||
| 155 | { |
||
| 156 | $pollOptions[$choice]['voted_this'] = in_array($choice, $guestvoted) ? 1 : -1; |
||
|
0 ignored issues
–
show
|
|||
| 157 | $pollinfo['has_voted'] |= $pollOptions[$choice]['voted_this'] != -1; |
||
| 158 | } |
||
| 159 | unset($choice, $details, $guestvoted); |
||
| 160 | } |
||
| 161 | unset($guestinfo, $guestvoted, $i); |
||
| 162 | } |
||
| 163 | } |
||
| 164 | |||
| 165 | $context['user']['started'] = $user_info['id'] == $row['id_member'] && !$user_info['is_guest']; |
||
| 166 | // Set up the basic poll information. |
||
| 167 | $context['poll'] = array( |
||
| 168 | 'id' => $row['id_poll'], |
||
| 169 | 'image' => 'normal_' . (empty($pollinfo['voting_locked']) ? 'poll' : 'locked_poll'), |
||
| 170 | 'question' => parse_bbc($pollinfo['question']), |
||
| 171 | 'total_votes' => $pollinfo['total'], |
||
| 172 | 'change_vote' => !empty($pollinfo['change_vote']), |
||
| 173 | 'is_locked' => !empty($pollinfo['voting_locked']), |
||
| 174 | 'options' => array(), |
||
| 175 | 'lock' => allowedTo('poll_lock_any') || ($context['user']['started'] && allowedTo('poll_lock_own')), |
||
| 176 | 'edit' => allowedTo('poll_edit_any') || ($context['user']['started'] && allowedTo('poll_edit_own')), |
||
| 177 | 'allowed_warning' => $pollinfo['max_votes'] > 1 ? sprintf($txt['poll_options6'], min(count($pollOptions), $pollinfo['max_votes'])) : '', |
||
| 178 | 'is_expired' => !empty($pollinfo['expire_time']) && $pollinfo['expire_time'] < time(), |
||
| 179 | 'expire_time' => !empty($pollinfo['expire_time']) ? timeformat($pollinfo['expire_time']) : 0, |
||
| 180 | 'has_voted' => !empty($pollinfo['has_voted']), |
||
| 181 | 'starter' => array( |
||
| 182 | 'id' => $pollinfo['id_member'], |
||
| 183 | 'name' => $row['poster_name'], |
||
| 184 | 'href' => $pollinfo['id_member'] == 0 ? '' : $scripturl . '?action=profile;u=' . $pollinfo['id_member'], |
||
| 185 | 'link' => $pollinfo['id_member'] == 0 ? $row['poster_name'] : '<a href="' . $scripturl . '?action=profile;u=' . $pollinfo['id_member'] . '">' . $row['poster_name'] . '</a>' |
||
| 186 | ) |
||
| 187 | ); |
||
| 188 | |||
| 189 | // Make the lock and edit permissions defined above more directly accessible. |
||
| 190 | $context['allow_lock_poll'] = $context['poll']['lock']; |
||
| 191 | $context['allow_edit_poll'] = $context['poll']['edit']; |
||
| 192 | |||
| 193 | // You're allowed to view the results if: |
||
| 194 | // 1. you're just a super-nice-guy, or |
||
| 195 | // 2. anyone can see them (hide_results == 0), or |
||
| 196 | // 3. you can see them after you voted (hide_results == 1), or |
||
| 197 | // 4. you've waited long enough for the poll to expire. (whether hide_results is 1 or 2.) |
||
| 198 | $context['allow_poll_view'] = allowedTo('moderate_board') || $pollinfo['hide_results'] == 0 || ($pollinfo['hide_results'] == 1 && $context['poll']['has_voted']) || $context['poll']['is_expired']; |
||
| 199 | |||
| 200 | // Calculate the percentages and bar lengths... |
||
| 201 | $divisor = $realtotal == 0 ? 1 : $realtotal; |
||
| 202 | |||
| 203 | // Determine if a decimal point is needed in order for the options to add to 100%. |
||
| 204 | $precision = $realtotal == 100 ? 0 : 1; |
||
| 205 | |||
| 206 | // Now look through each option, and... |
||
| 207 | foreach ($pollOptions as $i => $option) |
||
| 208 | { |
||
| 209 | // First calculate the percentage, and then the width of the bar... |
||
| 210 | $bar = round(($option['votes'] * 100) / $divisor, $precision); |
||
| 211 | $barWide = $bar == 0 ? 1 : floor(($bar * 8) / 3); |
||
| 212 | |||
| 213 | // Now add it to the poll's contextual theme data. |
||
| 214 | $context['poll']['options'][$i] = array( |
||
| 215 | 'id' => 'options-' . $i, |
||
| 216 | 'percent' => $bar, |
||
| 217 | 'votes' => $option['votes'], |
||
| 218 | 'voted_this' => $option['voted_this'] != -1, |
||
| 219 | // Note: IE < 8 requires us to set a width on the container, too. |
||
| 220 | 'bar_ndt' => $bar > 0 ? '<div class="bar" style="width: ' . ($bar * 3.5 + 4) . 'px;"><div style="width: ' . $bar * 3.5 . 'px;"></div></div>' : '', |
||
| 221 | 'bar_width' => $barWide, |
||
| 222 | 'option' => parse_bbc($option['label']), |
||
| 223 | 'vote_button' => '<input type="' . ($pollinfo['max_votes'] > 1 ? 'checkbox' : 'radio') . '" name="options[]" id="options-' . $i . '" value="' . $i . '" class="input_' . ($pollinfo['max_votes'] > 1 ? 'check' : 'radio') . '">' |
||
| 224 | ); |
||
| 225 | } |
||
| 226 | } |
||
| 227 | |||
| 228 | // Lets "output" all that info. |
||
| 229 | loadTemplate('Printpage'); |
||
| 230 | $context['template_layers'] = array('print'); |
||
| 231 | $context['board_name'] = $board_info['name']; |
||
| 232 | $context['category_name'] = $board_info['cat']['name']; |
||
| 233 | $context['poster_name'] = $row['poster_name']; |
||
| 234 | $context['post_time'] = timeformat($row['poster_time'], false); |
||
| 235 | $context['parent_boards'] = array(); |
||
| 236 | foreach ($board_info['parent_boards'] as $parent) |
||
| 237 | $context['parent_boards'][] = $parent['name']; |
||
| 238 | |||
| 239 | // Split the topics up so we can print them. |
||
| 240 | $request = $smcFunc['db_query']('', ' |
||
| 241 | SELECT subject, poster_time, body, COALESCE(mem.real_name, poster_name) AS poster_name, id_msg |
||
| 242 | FROM {db_prefix}messages AS m |
||
| 243 | LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member) |
||
| 244 | WHERE m.id_topic = {int:current_topic}' . ($modSettings['postmod_active'] && !allowedTo('approve_posts') ? ' |
||
| 245 | AND (m.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR m.id_member = {int:current_member}') . ')' : '') . ' |
||
| 246 | ORDER BY m.id_msg', |
||
| 247 | array( |
||
| 248 | 'current_topic' => $topic, |
||
| 249 | 'is_approved' => 1, |
||
| 250 | 'current_member' => $user_info['id'], |
||
| 251 | ) |
||
| 252 | ); |
||
| 253 | $context['posts'] = array(); |
||
| 254 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 255 | { |
||
| 256 | // Censor the subject and message. |
||
| 257 | censorText($row['subject']); |
||
| 258 | censorText($row['body']); |
||
| 259 | |||
| 260 | $context['posts'][] = array( |
||
| 261 | 'subject' => $row['subject'], |
||
| 262 | 'member' => $row['poster_name'], |
||
| 263 | 'time' => timeformat($row['poster_time'], false), |
||
| 264 | 'timestamp' => forum_time(true, $row['poster_time']), |
||
| 265 | 'body' => parse_bbc($row['body'], 'print'), |
||
| 266 | 'id_msg' => $row['id_msg'], |
||
| 267 | ); |
||
| 268 | |||
| 269 | if (!isset($context['topic_subject'])) |
||
| 270 | $context['topic_subject'] = $row['subject']; |
||
| 271 | } |
||
| 272 | $smcFunc['db_free_result']($request); |
||
| 273 | |||
| 274 | // Fetch attachments so we can print them if asked, enabled and allowed |
||
| 275 | if (isset($_REQUEST['images']) && !empty($modSettings['attachmentEnable']) && allowedTo('view_attachments')) |
||
| 276 | { |
||
| 277 | $messages = array(); |
||
| 278 | foreach ($context['posts'] as $temp) |
||
| 279 | $messages[] = $temp['id_msg']; |
||
| 280 | |||
| 281 | // build the request |
||
| 282 | $request = $smcFunc['db_query']('', ' |
||
| 283 | SELECT |
||
| 284 | a.id_attach, a.id_msg, a.approved, a.width, a.height, a.file_hash, a.filename, a.id_folder, a.mime_type |
||
| 285 | FROM {db_prefix}attachments AS a |
||
| 286 | WHERE a.id_msg IN ({array_int:message_list}) |
||
| 287 | AND a.attachment_type = {int:attachment_type}', |
||
| 288 | array( |
||
| 289 | 'message_list' => $messages, |
||
| 290 | 'attachment_type' => 0, |
||
| 291 | 'is_approved' => 1, |
||
| 292 | ) |
||
| 293 | ); |
||
| 294 | $temp = array(); |
||
| 295 | while ($row = $smcFunc['db_fetch_assoc']($request)) |
||
| 296 | { |
||
| 297 | $temp[$row['id_attach']] = $row; |
||
| 298 | if (!isset($context['printattach'][$row['id_msg']])) |
||
| 299 | $context['printattach'][$row['id_msg']] = array(); |
||
| 300 | } |
||
| 301 | $smcFunc['db_free_result']($request); |
||
| 302 | ksort($temp); |
||
| 303 | |||
| 304 | // load them into $context so the template can use them |
||
| 305 | foreach ($temp as $row) |
||
| 306 | { |
||
| 307 | if (!empty($row['width']) && !empty($row['height'])) |
||
| 308 | { |
||
| 309 | if (!empty($modSettings['max_image_width']) && (empty($modSettings['max_image_height']) || $row['height'] * ($modSettings['max_image_width'] / $row['width']) <= $modSettings['max_image_height'])) |
||
| 310 | { |
||
| 311 | View Code Duplication | if ($row['width'] > $modSettings['max_image_width']) |
|
| 312 | { |
||
| 313 | $row['height'] = floor($row['height'] * ($modSettings['max_image_width'] / $row['width'])); |
||
| 314 | $row['width'] = $modSettings['max_image_width']; |
||
| 315 | } |
||
| 316 | } |
||
| 317 | View Code Duplication | elseif (!empty($modSettings['max_image_width'])) |
|
| 318 | { |
||
| 319 | if ($row['height'] > $modSettings['max_image_height']) |
||
| 320 | { |
||
| 321 | $row['width'] = floor($row['width'] * $modSettings['max_image_height'] / $row['height']); |
||
| 322 | $row['height'] = $modSettings['max_image_height']; |
||
| 323 | } |
||
| 324 | } |
||
| 325 | |||
| 326 | $row['filename'] = getAttachmentFilename($row['filename'], $row['id_attach'], $row['id_folder'], false, $row['file_hash']); |
||
| 327 | |||
| 328 | // save for the template |
||
| 329 | $context['printattach'][$row['id_msg']][] = $row; |
||
| 330 | } |
||
| 331 | } |
||
| 332 | } |
||
| 333 | |||
| 334 | // Set a canonical URL for this page. |
||
| 335 | $context['canonical_url'] = $scripturl . '?topic=' . $topic . '.0'; |
||
| 336 | } |
||
| 337 | |||
| 338 | ?> |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: