albertlast /
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)) |
|
|
0 ignored issues
–
show
|
|||
| 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')) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 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; |
||
| 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 . '">' |
||
| 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']) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 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'])) |
|
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. Loading history...
|
|||
| 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 | ?> |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.