Guest

vigge_sWe

By: a guest on Mar 18th, 2010  |  syntax: PHP  |  size: 76.21 KB  |  hits: 59  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. <?php
  2. /**
  3. *
  4. * @package phpBB3
  5. * @version $Id$
  6. * @copyright (c) 2005 phpBB Group
  7. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  8. *
  9. */
  10.  
  11. /**
  12. * @ignore
  13. */
  14. define('IN_PHPBB', true);
  15. $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
  16. $phpEx = substr(strrchr(__FILE__, '.'), 1);
  17. include($phpbb_root_path . 'common.' . $phpEx);
  18. include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
  19. include($phpbb_root_path . 'includes/bbcode.' . $phpEx);
  20. // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  21. if (empty($_REQUEST['f'])) {
  22.         $phpbb_seo->get_forum_id($session_forum_id);
  23.         if ($session_forum_id > 0) {
  24.                 $_REQUEST['f'] = (int) $session_forum_id;
  25.         }
  26. }
  27. if (!empty($_REQUEST['hilit'])) {
  28.         $_REQUEST['hilit'] = rawurldecode($_REQUEST['hilit']);
  29.         if (!$phpbb_seo->is_utf8($_REQUEST['hilit'])) {
  30.                 $_REQUEST['hilit'] = utf8_normalize_nfc(utf8_recode($_REQUEST['hilit'], 'iso-8859-1'));
  31.         }
  32. }
  33. // www.phpBB-SEO.com SEO TOOLKIT END
  34.  
  35. // Start session management
  36. $user->session_begin();
  37. $auth->acl($user->data);
  38. // Start Ultimate Points
  39. $user->setup('mods/points');
  40. // End Ultimate Points
  41.  
  42.  
  43. // Initial var setup
  44. $forum_id       = request_var('f', 0);
  45. $topic_id       = request_var('t', 0);
  46. $post_id        = request_var('p', 0);
  47. $voted_id       = request_var('vote_id', array('' => 0));
  48.  
  49. $voted_id = (sizeof($voted_id) > 1) ? array_unique($voted_id) : $voted_id;
  50.  
  51.  
  52. $start          = request_var('start', 0);
  53. $view           = request_var('view', '');
  54.  
  55. $default_sort_days      = (!empty($user->data['user_post_show_days'])) ? $user->data['user_post_show_days'] : 0;
  56. $default_sort_key       = (!empty($user->data['user_post_sortby_type'])) ? $user->data['user_post_sortby_type'] : 't';
  57. $default_sort_dir       = (!empty($user->data['user_post_sortby_dir'])) ? $user->data['user_post_sortby_dir'] : 'a';
  58.  
  59. $sort_days      = request_var('st', $default_sort_days);
  60. $sort_key       = request_var('sk', $default_sort_key);
  61. $sort_dir       = request_var('sd', $default_sort_dir);
  62.  
  63. $update         = request_var('update', false);
  64.  
  65. $s_can_vote = false;
  66. /**
  67. * @todo normalize?
  68. */
  69. $hilit_words    = request_var('hilit', '', true);
  70.  
  71. // Do we have a topic or post id?
  72. if (!$topic_id && !$post_id)
  73. {
  74.         trigger_error('NO_TOPIC');
  75. }
  76.  
  77. // Find topic id if user requested a newer or older topic
  78. if ($view && !$post_id)
  79. {
  80.         if (!$forum_id)
  81.         {
  82.                 $sql = 'SELECT forum_id
  83.                         FROM ' . TOPICS_TABLE . "
  84.                         WHERE topic_id = $topic_id";
  85.                 $result = $db->sql_query($sql);
  86.                 $forum_id = (int) $db->sql_fetchfield('forum_id');
  87.                 $db->sql_freeresult($result);
  88.  
  89.                 if (!$forum_id)
  90.                 {
  91.                         trigger_error('NO_TOPIC');
  92.                 }
  93.         }
  94.  
  95.         if ($view == 'unread')
  96.         {
  97.                 // Get topic tracking info
  98.                 $topic_tracking_info = get_complete_topic_tracking($forum_id, $topic_id);
  99.  
  100.                 $topic_last_read = (isset($topic_tracking_info[$topic_id])) ? $topic_tracking_info[$topic_id] : 0;
  101.  
  102.                 $sql = 'SELECT post_id, topic_id, forum_id
  103.                         FROM ' . POSTS_TABLE . "
  104.                         WHERE topic_id = $topic_id
  105.                                 " . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND post_approved = 1') . "
  106.                                 AND post_time > $topic_last_read
  107.                                 AND forum_id = $forum_id
  108.                         ORDER BY post_time ASC";
  109.                 $result = $db->sql_query_limit($sql, 1);
  110.                 $row = $db->sql_fetchrow($result);
  111.                 $db->sql_freeresult($result);
  112.  
  113.                 if (!$row)
  114.                 {
  115.                         $sql = 'SELECT topic_last_post_id as post_id, topic_id, forum_id
  116.                                 FROM ' . TOPICS_TABLE . '
  117.                                 WHERE topic_id = ' . $topic_id;
  118.                         $result = $db->sql_query($sql);
  119.                         $row = $db->sql_fetchrow($result);
  120.                         $db->sql_freeresult($result);
  121.                 }
  122.  
  123.                 if (!$row)
  124.                 {
  125.                         // Setup user environment so we can process lang string
  126.                         $user->setup('viewtopic');
  127.  
  128.                         trigger_error('NO_TOPIC');
  129.                 }
  130.  
  131.                 $post_id = $row['post_id'];
  132.                 $topic_id = $row['topic_id'];
  133.         }
  134.         else if ($view == 'next' || $view == 'previous')
  135.         {
  136.                 $sql_condition = ($view == 'next') ? '>' : '<';
  137.                 $sql_ordering = ($view == 'next') ? 'ASC' : 'DESC';
  138.  
  139.                 $sql = 'SELECT forum_id, topic_last_post_time
  140.                         FROM ' . TOPICS_TABLE . '
  141.                         WHERE topic_id = ' . $topic_id;
  142.                 $result = $db->sql_query($sql);
  143.                 $row = $db->sql_fetchrow($result);
  144.                 $db->sql_freeresult($result);
  145.  
  146.                 if (!$row)
  147.                 {
  148.                         $user->setup('viewtopic');
  149.                         // OK, the topic doesn't exist. This error message is not helpful, but technically correct.
  150.                         trigger_error(($view == 'next') ? 'NO_NEWER_TOPICS' : 'NO_OLDER_TOPICS');
  151.                 }
  152.                 else
  153.                 {
  154.                         $sql = 'SELECT topic_id, forum_id
  155.                                 FROM ' . TOPICS_TABLE . '
  156.                                 WHERE forum_id = ' . $row['forum_id'] . "
  157.                                         AND topic_moved_id = 0
  158.                                         AND topic_last_post_time $sql_condition {$row['topic_last_post_time']}
  159.                                         " . (($auth->acl_get('m_approve', $row['forum_id'])) ? '' : 'AND topic_approved = 1') . "
  160.                                 ORDER BY topic_last_post_time $sql_ordering";
  161.                         $result = $db->sql_query_limit($sql, 1);
  162.                         $row = $db->sql_fetchrow($result);
  163.                         $db->sql_freeresult($result);
  164.  
  165.                         if (!$row)
  166.                         {
  167.                                 $user->setup('viewtopic');
  168.                                 trigger_error(($view == 'next') ? 'NO_NEWER_TOPICS' : 'NO_OLDER_TOPICS');
  169.                         }
  170.                         else
  171.                         {
  172.                                 $topic_id = $row['topic_id'];
  173.  
  174.                                 // Check for global announcement correctness?
  175.                                 if (!$row['forum_id'] && !$forum_id)
  176.                                 {
  177.                                         trigger_error('NO_TOPIC');
  178.                                 }
  179.                                 else if ($row['forum_id'])
  180.                                 {
  181.                                         $forum_id = $row['forum_id'];
  182.                                 }
  183.                         }
  184.                 }
  185.         }
  186.  
  187.         // Check for global announcement correctness?
  188.         if ((!isset($row) || !$row['forum_id']) && !$forum_id)
  189.         {
  190.                 trigger_error('NO_TOPIC');
  191.         }
  192.         else if (isset($row) && $row['forum_id'])
  193.         {
  194.                 $forum_id = $row['forum_id'];
  195.         }
  196. }
  197.  
  198. // This rather complex gaggle of code handles querying for topics but
  199. // also allows for direct linking to a post (and the calculation of which
  200. // page the post is on and the correct display of viewtopic)
  201. $sql_array = array(
  202.         'SELECT'        => 't.*, f.*',
  203.  
  204.         'FROM'          => array(FORUMS_TABLE => 'f'),
  205. );
  206.  
  207. // Firebird handles two columns of the same name a little differently, this
  208. // addresses that by forcing the forum_id to come from the forums table.
  209. if ($db->sql_layer === 'firebird')
  210. {
  211.         $sql_array['SELECT'] = 'f.forum_id AS forum_id, ' . $sql_array['SELECT'];
  212. }
  213.  
  214. // The FROM-Order is quite important here, else t.* columns can not be correctly bound.
  215. if ($post_id)
  216. {
  217.         $sql_array['SELECT'] .= ', p.post_approved';
  218.         $sql_array['FROM'][POSTS_TABLE] = 'p';
  219. }
  220.  
  221. // Topics table need to be the last in the chain
  222. $sql_array['FROM'][TOPICS_TABLE] = 't';
  223.  
  224. if ($user->data['is_registered'])
  225. {
  226.         $sql_array['SELECT'] .= ', tw.notify_status';
  227.         $sql_array['LEFT_JOIN'] = array();
  228.  
  229.         $sql_array['LEFT_JOIN'][] = array(
  230.                 'FROM'  => array(TOPICS_WATCH_TABLE => 'tw'),
  231.                 'ON'    => 'tw.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tw.topic_id'
  232.         );
  233.  
  234.         if ($config['allow_bookmarks'])
  235.         {
  236.                 $sql_array['SELECT'] .= ', bm.topic_id as bookmarked';
  237.                 $sql_array['LEFT_JOIN'][] = array(
  238.                         'FROM'  => array(BOOKMARKS_TABLE => 'bm'),
  239.                         'ON'    => 'bm.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = bm.topic_id'
  240.                 );
  241.         }
  242.  
  243.         if ($config['load_db_lastread'])
  244.         {
  245.                 $sql_array['SELECT'] .= ', tt.mark_time, ft.mark_time as forum_mark_time';
  246.  
  247.                 $sql_array['LEFT_JOIN'][] = array(
  248.                         'FROM'  => array(TOPICS_TRACK_TABLE => 'tt'),
  249.                         'ON'    => 'tt.user_id = ' . $user->data['user_id'] . ' AND t.topic_id = tt.topic_id'
  250.                 );
  251.  
  252.                 $sql_array['LEFT_JOIN'][] = array(
  253.                         'FROM'  => array(FORUMS_TRACK_TABLE => 'ft'),
  254.                         'ON'    => 'ft.user_id = ' . $user->data['user_id'] . ' AND t.forum_id = ft.forum_id'
  255.                 );
  256.         }
  257. }
  258.  
  259. if (!$post_id)
  260. {
  261.         $sql_array['WHERE'] = "t.topic_id = $topic_id";
  262. }
  263. else
  264. {
  265.         $sql_array['WHERE'] = "p.post_id = $post_id AND t.topic_id = p.topic_id";
  266. }
  267.  
  268. $sql_array['WHERE'] .= ' AND (f.forum_id = t.forum_id';
  269.  
  270. if (!$forum_id)
  271. {
  272.         // If it is a global announcement make sure to set the forum id to a postable forum
  273.         $sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . '
  274.                 AND f.forum_type = ' . FORUM_POST . ')';
  275. }
  276. else
  277. {
  278.         $sql_array['WHERE'] .= ' OR (t.topic_type = ' . POST_GLOBAL . "
  279.                 AND f.forum_id = $forum_id)";
  280. }
  281.  
  282. $sql_array['WHERE'] .= ')';
  283.  
  284. // Join to forum table on topic forum_id unless topic forum_id is zero
  285. // whereupon we join on the forum_id passed as a parameter ... this
  286. // is done so navigation, forum name, etc. remain consistent with where
  287. // user clicked to view a global topic
  288. $sql = $db->sql_build_query('SELECT', $sql_array);
  289. $result = $db->sql_query($sql);
  290. $topic_data = $db->sql_fetchrow($result);
  291. $db->sql_freeresult($result);
  292.  
  293. // link to unapproved post or incorrect link
  294. if (!$topic_data)
  295. {
  296.         // If post_id was submitted, we try at least to display the topic as a last resort...
  297.         if ($post_id && $topic_id)
  298.         {
  299.                 redirect(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id" . (($forum_id) ? "&amp;f=$forum_id" : '')));
  300.         }
  301.  
  302.         trigger_error('NO_TOPIC');
  303. }
  304.  
  305. $forum_id = (int) $topic_data['forum_id'];
  306. // This is for determining where we are (page)
  307. if ($post_id)
  308. {
  309.         // are we where we are supposed to be?
  310.         if (!$topic_data['post_approved'] && !$auth->acl_get('m_approve', $topic_data['forum_id']))
  311.         {
  312.                 // If post_id was submitted, we try at least to display the topic as a last resort...
  313.                 if ($topic_id)
  314.                 {
  315.                         redirect(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "t=$topic_id" . (($forum_id) ? "&amp;f=$forum_id" : '')));
  316.                 }
  317.  
  318.                 trigger_error('NO_TOPIC');
  319.         }
  320.         if ($post_id == $topic_data['topic_first_post_id'] || $post_id == $topic_data['topic_last_post_id'])
  321.         {
  322.                 $check_sort = ($post_id == $topic_data['topic_first_post_id']) ? 'd' : 'a';
  323.  
  324.                 if ($sort_dir == $check_sort)
  325.                 {
  326.                         $topic_data['prev_posts'] = ($auth->acl_get('m_approve', $forum_id)) ? $topic_data['topic_replies_real'] : $topic_data['topic_replies'];
  327.                 }
  328.                 else
  329.                 {
  330.                         $topic_data['prev_posts'] = 0;
  331.                 }
  332.         }
  333.         else
  334.         {
  335.                 $sql = 'SELECT COUNT(p1.post_id) AS prev_posts
  336.                         FROM ' . POSTS_TABLE . ' p1, ' . POSTS_TABLE . " p2
  337.                         WHERE p1.topic_id = {$topic_data['topic_id']}
  338.                                 AND p2.post_id = {$post_id}
  339.                                 " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p1.post_approved = 1' : '') . '
  340.                                 AND ' . (($sort_dir == 'd') ? 'p1.post_time >= p2.post_time' : 'p1.post_time <= p2.post_time');
  341.  
  342.                 $result = $db->sql_query($sql);
  343.                 $row = $db->sql_fetchrow($result);
  344.                 $db->sql_freeresult($result);
  345.  
  346.                 $topic_data['prev_posts'] = $row['prev_posts'] - 1;
  347.         }
  348. }
  349.  
  350. $topic_id = (int) $topic_data['topic_id'];
  351. // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  352. $phpbb_seo->set_url($topic_data['forum_name'], $forum_id, $phpbb_seo->seo_static['forum']);
  353. if ($topic_data['topic_type'] == POST_GLOBAL) {
  354.         // Let's make sure user will see global annoucements
  355.         $auth->cache[$forum_id]['f_read'] = 1;
  356.         $_parent = $phpbb_seo->seo_static['global_announce'];
  357. } else {
  358.         $_parent = $phpbb_seo->seo_url['forum'][$forum_id];
  359. }
  360. if (!empty($phpbb_seo->seo_opt['sql_rewrite'])) {
  361.         if ( !$phpbb_seo->check_url('topic', $topic_data['topic_url'], $_parent)) {
  362.                 if (!empty($topic_data['topic_url'])) {
  363.                         // Here we get rid of the seo delim (-t) and put it back even in simple mod
  364.                         // to be able to handle all cases at once
  365.                         $_url = preg_replace('`' . $phpbb_seo->seo_delim['topic'] . '$`i', '', $topic_data['topic_url']);
  366.                         $_title = $phpbb_seo->get_url_info('topic', $_url . $phpbb_seo->seo_delim['topic'] . $topic_id, 'title');
  367.                 } else {
  368.                         $_title = $phpbb_seo->modrtype > 2 ? censor_text($topic_data['topic_title']) : '';
  369.                 }
  370.                 unset($phpbb_seo->seo_url['topic'][$topic_id]);
  371.                 $topic_data['topic_url'] = $phpbb_seo->get_url_info('topic', $phpbb_seo->prepare_url( 'topic', $_title, $topic_id, $_parent, (( empty($_title) || ($_title == $phpbb_seo->seo_static['topic']) ) ? true : false) ), 'url');
  372.                 unset($phpbb_seo->seo_url['topic'][$topic_id]);
  373.                 if ($topic_data['topic_url']) {
  374.                         // Update the topic_url field for later re-use
  375.                         $sql = "UPDATE " . TOPICS_TABLE . " SET topic_url = '" . $db->sql_escape($topic_data['topic_url']) . "'
  376.                                 WHERE topic_id = $topic_id";
  377.                         $db->sql_query($sql);
  378.                 }
  379.         }
  380. } else {
  381.         $topic_data['topic_url'] = '';
  382. }
  383. $phpbb_seo->prepare_iurl($topic_data, 'topic', $_parent);
  384. // www.phpBB-SEO.com SEO TOOLKIT END
  385. //
  386. $topic_replies = ($auth->acl_get('m_approve', $forum_id)) ? $topic_data['topic_replies_real'] : $topic_data['topic_replies'];
  387.  
  388. // Check sticky/announcement time limit
  389. if (($topic_data['topic_type'] == POST_STICKY || $topic_data['topic_type'] == POST_ANNOUNCE) && $topic_data['topic_time_limit'] && ($topic_data['topic_time'] + $topic_data['topic_time_limit']) < time())
  390. {
  391.         $sql = 'UPDATE ' . TOPICS_TABLE . '
  392.                 SET topic_type = ' . POST_NORMAL . ', topic_time_limit = 0
  393.                 WHERE topic_id = ' . $topic_id;
  394.         $db->sql_query($sql);
  395.  
  396.         $topic_data['topic_type'] = POST_NORMAL;
  397.         $topic_data['topic_time_limit'] = 0;
  398. }
  399.  
  400. // Setup look and feel
  401. $user->setup('viewtopic', $topic_data['forum_style']);
  402.  
  403. if (!$topic_data['topic_approved'] && !$auth->acl_get('m_approve', $forum_id))
  404. {
  405.         trigger_error('NO_TOPIC');
  406. }
  407.  
  408. // Start auth check
  409. if (!$auth->acl_get('f_read', $forum_id))
  410. {
  411.         if ($user->data['user_id'] != ANONYMOUS)
  412.         {
  413.                 trigger_error('SORRY_AUTH_READ');
  414.         }
  415.  
  416.         login_box('', $user->lang['LOGIN_VIEWFORUM']);
  417. }
  418.  
  419. // Forum is passworded ... check whether access has been granted to this
  420. // user this session, if not show login box
  421. if ($topic_data['forum_password'])
  422. {
  423.         login_forum_box($topic_data);
  424. }
  425.  
  426. // Redirect to login or to the correct post upon emailed notification links
  427. if (isset($_GET['e']))
  428. {
  429.         $jump_to = request_var('e', 0);
  430.  
  431.         // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  432.         //$redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id");
  433.         // www.phpBB-SEO.com SEO TOOLKIT END
  434.  
  435.         if ($user->data['user_id'] == ANONYMOUS)
  436.         {
  437.                 // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  438.                 login_box(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p=$post_id&amp;e=$jump_to"), $user->lang['LOGIN_NOTIFY_TOPIC']);
  439.                 // www.phpBB-SEO.com SEO TOOLKIT END
  440.         }
  441.  
  442.         if ($jump_to > 0)
  443.         {
  444.                 // We direct the already logged in user to the correct post...
  445.                 // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  446.                 redirect(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id" . ((!$post_id) ? "&amp;p=$jump_to" : "&amp;p=$post_id")) . "#p$jump_to");
  447.                 // www.phpBB-SEO.com SEO TOOLKIT END
  448.         }
  449. }
  450.  
  451. // What is start equal to?
  452. if ($post_id)
  453. {
  454.         $start = floor(($topic_data['prev_posts']) / $config['posts_per_page']) * $config['posts_per_page'];
  455. }
  456.  
  457. // Get topic tracking info
  458. if (!isset($topic_tracking_info))
  459. {
  460.         $topic_tracking_info = array();
  461.  
  462.         // Get topic tracking info
  463.         if ($config['load_db_lastread'] && $user->data['is_registered'])
  464.         {
  465.                 $tmp_topic_data = array($topic_id => $topic_data);
  466.                 $topic_tracking_info = get_topic_tracking($forum_id, $topic_id, $tmp_topic_data, array($forum_id => $topic_data['forum_mark_time']));
  467.                 unset($tmp_topic_data);
  468.         }
  469.         else if ($config['load_anon_lastread'] || $user->data['is_registered'])
  470.         {
  471.                 $topic_tracking_info = get_complete_topic_tracking($forum_id, $topic_id);
  472.         }
  473. }
  474.  
  475. // Post ordering options
  476. $limit_days = array(0 => $user->lang['ALL_POSTS'], 1 => $user->lang['1_DAY'], 7 => $user->lang['7_DAYS'], 14 => $user->lang['2_WEEKS'], 30 => $user->lang['1_MONTH'], 90 => $user->lang['3_MONTHS'], 180 => $user->lang['6_MONTHS'], 365 => $user->lang['1_YEAR']);
  477.  
  478. $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 's' => $user->lang['SUBJECT']);
  479. $sort_by_sql = array('a' => array('u.username_clean', 'p.post_id'), 't' => 'p.post_time', 's' => array('p.post_subject', 'p.post_id'));
  480. $join_user_sql = array('a' => true, 't' => false, 's' => false);
  481.  
  482. $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
  483.  
  484. gen_sort_selects($limit_days, $sort_by_text, $sort_days, $sort_key, $sort_dir, $s_limit_days, $s_sort_key, $s_sort_dir, $u_sort_param, $default_sort_days, $default_sort_key, $default_sort_dir);
  485.  
  486. // Obtain correct post count and ordering SQL if user has
  487. // requested anything different
  488. if ($sort_days)
  489. {
  490.         $min_post_time = time() - ($sort_days * 86400);
  491.  
  492.         $sql = 'SELECT COUNT(post_id) AS num_posts
  493.                 FROM ' . POSTS_TABLE . "
  494.                 WHERE topic_id = $topic_id
  495.                         AND post_time >= $min_post_time
  496.                 " . (($auth->acl_get('m_approve', $forum_id)) ? '' : 'AND post_approved = 1');
  497.         $result = $db->sql_query($sql);
  498.         $total_posts = (int) $db->sql_fetchfield('num_posts');
  499.         $db->sql_freeresult($result);
  500.  
  501.         $limit_posts_time = "AND p.post_time >= $min_post_time ";
  502.  
  503.         if (isset($_POST['sort']))
  504.         {
  505.                 $start = 0;
  506.         }
  507. }
  508. else
  509. {
  510.         $total_posts = $topic_replies + 1;
  511.         $limit_posts_time = '';
  512. }
  513.  
  514. // Was a highlight request part of the URI?
  515. $highlight_match = $highlight = '';
  516. if ($hilit_words)
  517. {
  518.         foreach (explode(' ', trim($hilit_words)) as $word)
  519.         {
  520.                 if (trim($word))
  521.                 {
  522.                         $word = str_replace('\*', '\w+?', preg_quote($word, '#'));
  523.                         $word = preg_replace('#(^|\s)\\\\w\*\?(\s|$)#', '$1\w+?$2', $word);
  524.                         $highlight_match .= (($highlight_match != '') ? '|' : '') . $word;
  525.                 }
  526.         }
  527.  
  528.         $highlight = urlencode($hilit_words);
  529. }
  530.  
  531. // Make sure $start is set to the last page if it exceeds the amount
  532. if ($start < 0 || $start >= $total_posts)
  533. {
  534.         $start = ($start < 0) ? 0 : floor(($total_posts - 1) / $config['posts_per_page']) * $config['posts_per_page'];
  535. }
  536.  
  537. // General Viewtopic URL for return links
  538. $viewtopic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;start=$start" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : '') . (($highlight_match) ? "&amp;hilit=$highlight" : ''));
  539.  
  540. // Are we watching this topic?
  541. $s_watching_topic = array(
  542.         'link'                  => '',
  543.         'title'                 => '',
  544.         'is_watching'   => false,
  545. );
  546.  
  547. if (($config['email_enable'] || $config['jab_enable']) && $config['allow_topic_notify'] && $user->data['is_registered'])
  548. {
  549.         watch_topic_forum('topic', $s_watching_topic, $user->data['user_id'], $forum_id, $topic_id, $topic_data['notify_status'], $start);
  550.  
  551.         // Reset forum notification if forum notify is set
  552.         if ($config['allow_forum_notify'] && $auth->acl_get('f_subscribe', $forum_id))
  553.         {
  554.                 $s_watching_forum = $s_watching_topic;
  555.                 watch_topic_forum('forum', $s_watching_forum, $user->data['user_id'], $forum_id, 0);
  556.         }
  557. }
  558.  
  559. // Bookmarks
  560. if ($config['allow_bookmarks'] && $user->data['is_registered'] && request_var('bookmark', 0))
  561. {
  562.         if (check_link_hash(request_var('hash', ''), "topic_$topic_id"))
  563.         {
  564.                 if (!$topic_data['bookmarked'])
  565.                 {
  566.                         $sql = 'INSERT INTO ' . BOOKMARKS_TABLE . ' ' . $db->sql_build_array('INSERT', array(
  567.                                 'user_id'       => $user->data['user_id'],
  568.                                 'topic_id'      => $topic_id,
  569.                         ));
  570.                         $db->sql_query($sql);
  571.                 }
  572.                 else
  573.                 {
  574.                         $sql = 'DELETE FROM ' . BOOKMARKS_TABLE . "
  575.                                 WHERE user_id = {$user->data['user_id']}
  576.                                         AND topic_id = $topic_id";
  577.                         $db->sql_query($sql);
  578.                 }
  579.                 $message = (($topic_data['bookmarked']) ? $user->lang['BOOKMARK_REMOVED'] : $user->lang['BOOKMARK_ADDED']) . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $viewtopic_url . '">', '</a>');
  580.         }
  581.         else
  582.         {
  583.                 $message = $user->lang['BOOKMARK_ERR'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $viewtopic_url . '">', '</a>');
  584.         }
  585.         meta_refresh(3, $viewtopic_url);
  586.  
  587.         trigger_error($message);
  588. }
  589.  
  590.  
  591. // Grab country flags
  592. $flags = $cache->obtain_flags();
  593. // Grab ranks
  594. $ranks = $cache->obtain_ranks();
  595.  
  596. // Grab icons
  597. $icons = $cache->obtain_icons();
  598.  
  599. // Grab extensions
  600. $extensions = array();
  601. if ($topic_data['topic_attachment'])
  602. {
  603.         $extensions = $cache->obtain_attach_extensions($forum_id);
  604. }
  605.  
  606. // Forum rules listing
  607. $s_forum_rules = '';
  608. gen_forum_auth_level('topic', $forum_id, $topic_data['forum_status']);
  609.  
  610. // Quick mod tools
  611. $allow_change_type = ($auth->acl_get('m_', $forum_id) || ($user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster'])) ? true : false;
  612.  
  613. $topic_mod = '';
  614. $topic_mod .= ($auth->acl_get('m_lock', $forum_id) || ($auth->acl_get('f_user_lock', $forum_id) && $user->data['is_registered'] && $user->data['user_id'] == $topic_data['topic_poster'] && $topic_data['topic_status'] == ITEM_UNLOCKED)) ? (($topic_data['topic_status'] == ITEM_UNLOCKED) ? '<option value="lock">' . $user->lang['LOCK_TOPIC'] . '</option>' : '<option value="unlock">' . $user->lang['UNLOCK_TOPIC'] . '</option>') : '';
  615. $topic_mod .= ($auth->acl_get('m_delete', $forum_id)) ? '<option value="delete_topic">' . $user->lang['DELETE_TOPIC'] . '</option>' : '';
  616. $topic_mod .= ($auth->acl_get('m_move', $forum_id) && $topic_data['topic_status'] != ITEM_MOVED) ? '<option value="move">' . $user->lang['MOVE_TOPIC'] . '</option>' : '';
  617. $topic_mod .= ($auth->acl_get('m_split', $forum_id)) ? '<option value="split">' . $user->lang['SPLIT_TOPIC'] . '</option>' : '';
  618. $topic_mod .= ($auth->acl_get('m_merge', $forum_id)) ? '<option value="merge">' . $user->lang['MERGE_POSTS'] . '</option>' : '';
  619. $topic_mod .= ($auth->acl_get('m_merge', $forum_id)) ? '<option value="merge_topic">' . $user->lang['MERGE_TOPIC'] . '</option>' : '';
  620. $topic_mod .= ($auth->acl_get('m_move', $forum_id)) ? '<option value="fork">' . $user->lang['FORK_TOPIC'] . '</option>' : '';
  621. $topic_mod .= ($allow_change_type && $auth->acl_gets('f_sticky', 'f_announce', $forum_id) && $topic_data['topic_type'] != POST_NORMAL) ? '<option value="make_normal">' . $user->lang['MAKE_NORMAL'] . '</option>' : '';
  622. $topic_mod .= ($allow_change_type && $auth->acl_get('f_sticky', $forum_id) && $topic_data['topic_type'] != POST_STICKY) ? '<option value="make_sticky">' . $user->lang['MAKE_STICKY'] . '</option>' : '';
  623. $topic_mod .= ($allow_change_type && $auth->acl_get('f_announce', $forum_id) && $topic_data['topic_type'] != POST_ANNOUNCE) ? '<option value="make_announce">' . $user->lang['MAKE_ANNOUNCE'] . '</option>' : '';
  624. $topic_mod .= ($allow_change_type && $auth->acl_get('f_announce', $forum_id) && $topic_data['topic_type'] != POST_GLOBAL) ? '<option value="make_global">' . $user->lang['MAKE_GLOBAL'] . '</option>' : '';
  625. $topic_mod .= ($auth->acl_get('m_', $forum_id)) ? '<option value="topic_logs">' . $user->lang['VIEW_TOPIC_LOGS'] . '</option>' : '';
  626.  
  627. // If we've got a hightlight set pass it on to pagination.
  628. $pagination = generate_pagination(append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : '') . (($highlight_match) ? "&amp;hilit=$highlight" : '')), $total_posts, $config['posts_per_page'], $start);
  629.  
  630. // Navigation links
  631. generate_forum_nav($topic_data);
  632.  
  633. // Forum Rules
  634. generate_forum_rules($topic_data);
  635.  
  636. // Moderators
  637. $forum_moderators = array();
  638. if ($config['load_moderators'])
  639. {
  640.         get_moderators($forum_moderators, $forum_id);
  641. }
  642.  
  643. // This is only used for print view so ...
  644. $server_path = (!$view) ? $phpbb_root_path : generate_board_url() . '/';
  645.  
  646. // Replace naughty words in title
  647. $topic_data['topic_title'] = censor_text($topic_data['topic_title']);
  648.  
  649. // Send vars to template
  650. $template->assign_vars(array(
  651.         'FORUM_ID'              => $forum_id,
  652.         'FORUM_NAME'    => $topic_data['forum_name'],
  653.         'FORUM_DESC'    => generate_text_for_display($topic_data['forum_desc'], $topic_data['forum_desc_uid'], $topic_data['forum_desc_bitfield'], $topic_data['forum_desc_options']),
  654.         'TOPIC_ID'              => $topic_id,
  655.         'TOPIC_TITLE'   => $topic_data['topic_title'],
  656.         'TOPIC_POSTER'  => $topic_data['topic_poster'],
  657.  
  658.  
  659.         // Start Ultimate Points
  660.         'P_NAME'                        => $config['points_name'],
  661.         'USE_POINTS'            => $config['points_enable'],
  662.         'USE_IMAGES_POINTS'     => $points_config['images_topic_enable'],
  663.         'USE_BANK'                      => $points_config['bank_enable'],
  664.         // End Ultimate Points
  665.         'TOPIC_AUTHOR_FULL'             => get_username_string('full', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']),
  666.         'TOPIC_AUTHOR_COLOUR'   => get_username_string('colour', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']),
  667.         'TOPIC_AUTHOR'                  => get_username_string('username', $topic_data['topic_poster'], $topic_data['topic_first_poster_name'], $topic_data['topic_first_poster_colour']),
  668.  
  669.         'PAGINATION'    => $pagination,
  670.         'PAGE_NUMBER'   => on_page($total_posts, $config['posts_per_page'], $start),
  671.         'TOTAL_POSTS'   => ($total_posts == 1) ? $user->lang['VIEW_TOPIC_POST'] : sprintf($user->lang['VIEW_TOPIC_POSTS'], $total_posts),
  672.         'U_MCP'                 => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&amp;mode=topic_view&amp;f=$forum_id&amp;t=$topic_id&amp;start=$start" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : ''), true, $user->session_id) : '',
  673.         'MODERATORS'    => (isset($forum_moderators[$forum_id]) && sizeof($forum_moderators[$forum_id])) ? implode(', ', $forum_moderators[$forum_id]) : '',
  674.  
  675.         'POST_IMG'                      => ($topic_data['forum_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', 'FORUM_LOCKED') : $user->img('button_topic_new', 'POST_NEW_TOPIC'),
  676.         'QUOTE_IMG'             => $user->img('icon_post_quote', 'REPLY_WITH_QUOTE'),
  677.         'REPLY_IMG'                     => ($topic_data['forum_status'] == ITEM_LOCKED || $topic_data['topic_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', 'TOPIC_LOCKED') : $user->img('button_topic_reply', 'REPLY_TO_TOPIC'),
  678.         'EDIT_IMG'                      => $user->img('icon_post_edit', 'EDIT_POST'),
  679.         'DELETE_IMG'            => $user->img('icon_post_delete', 'DELETE_POST'),
  680.         'INFO_IMG'                      => $user->img('icon_post_info', 'VIEW_INFO'),
  681.         'PROFILE_IMG'           => $user->img('icon_user_profile', 'READ_PROFILE'),
  682.         'SEARCH_IMG'            => $user->img('icon_user_search', 'SEARCH_USER_POSTS'),
  683.         'PM_IMG'                        => $user->img('icon_contact_pm', 'SEND_PRIVATE_MESSAGE'),
  684.         'EMAIL_IMG'             => $user->img('icon_contact_email', 'SEND_EMAIL'),
  685.         'WWW_IMG'                       => $user->img('icon_contact_www', 'VISIT_WEBSITE'),
  686.         'ICQ_IMG'                       => $user->img('icon_contact_icq', 'ICQ'),
  687.         'AIM_IMG'                       => $user->img('icon_contact_aim', 'AIM'),
  688.         'MSN_IMG'                       => $user->img('icon_contact_msnm', 'MSNM'),
  689.         'YIM_IMG'                       => $user->img('icon_contact_yahoo', 'YIM'),
  690.         'JABBER_IMG'            => $user->img('icon_contact_jabber', 'JABBER') ,
  691.         'REPORT_IMG'            => $user->img('icon_post_report', 'REPORT_POST'),
  692.         'REPORTED_IMG'          => $user->img('icon_topic_reported', 'POST_REPORTED'),
  693.         'UNAPPROVED_IMG'        => $user->img('icon_topic_unapproved', 'POST_UNAPPROVED'),
  694.         'WARN_IMG'                      => $user->img('icon_user_warn', 'WARN_USER'),
  695.  
  696.         'S_IS_LOCKED'                   => ($topic_data['topic_status'] == ITEM_UNLOCKED && $topic_data['forum_status'] == ITEM_UNLOCKED) ? false : true,
  697.         'S_SELECT_SORT_DIR'     => $s_sort_dir,
  698.         'S_SELECT_SORT_KEY'     => $s_sort_key,
  699.         'S_SELECT_SORT_DAYS'    => $s_limit_days,
  700.         'S_SINGLE_MODERATOR'    => (!empty($forum_moderators[$forum_id]) && sizeof($forum_moderators[$forum_id]) > 1) ? false : true,
  701.         'S_TOPIC_ACTION'                => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;start=$start"),
  702.         'S_TOPIC_MOD'                   => ($topic_mod != '') ? '<select name="action" id="quick-mod-select">' . $topic_mod . '</select>' : '',
  703.         'S_MOD_ACTION'                  => append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;start=$start&amp;quickmod=1&amp;redirect=" . urlencode(str_replace('&amp;', '&', $viewtopic_url)), true, $user->session_id),
  704.  
  705.         'S_VIEWTOPIC'                   => true,
  706.         'S_DISPLAY_SEARCHBOX'   => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false,
  707.         'S_SEARCHBOX_ACTION'    => append_sid("{$phpbb_root_path}search.$phpEx", 't=' . $topic_id),
  708.  
  709.         'S_DISPLAY_POST_INFO'   => ($topic_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false,
  710.         'S_DISPLAY_REPLY_INFO'  => ($topic_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_reply', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false,
  711.         'S_ENABLE_FEEDS_TOPIC'  => ($config['feed_topic'] && !phpbb_optionget(FORUM_OPTION_FEED_EXCLUDE, $topic_data['forum_options'])) ? true : false,
  712.  
  713.         // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  714.         'U_TOPIC'                               => !empty($phpbb_seo->seo_opt['url_rewrite']) ? $phpbb_seo->drop_sid($viewtopic_url) : "{$server_path}viewtopic.$phpEx?f=$forum_id&amp;t=$topic_id",
  715.         // www.phpBB-SEO.com SEO TOOLKIT END
  716.         'U_FORUM'                               => $server_path,
  717.         'U_VIEW_TOPIC'                  => $viewtopic_url,
  718.         'U_VIEW_FORUM'                  => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id),
  719.         'U_VIEW_OLDER_TOPIC'    => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;view=previous"),
  720.         'U_VIEW_NEWER_TOPIC'    => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;view=next"),
  721.         // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  722.         'U_PRINT_TOPIC'                 => ($auth->acl_get('f_print', $forum_id)) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;start=$start&amp;" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : '') . (($highlight_match) ? "&amp;hilit=$highlight" : '') . "&amp;view=print") : '',
  723.         // www.phpBB-SEO.com SEO TOOLKIT END
  724.         'U_EMAIL_TOPIC'                 => ($auth->acl_get('f_email', $forum_id) && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&amp;t=$topic_id") : '',
  725.  
  726.         'U_WATCH_TOPIC'                 => $s_watching_topic['link'],
  727.         'L_WATCH_TOPIC'                 => $s_watching_topic['title'],
  728.         'S_WATCHING_TOPIC'              => $s_watching_topic['is_watching'],
  729.  
  730.         // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  731.         'U_BOOKMARK_TOPIC'              => ($user->data['is_registered'] && $config['allow_bookmarks']) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;bookmark=1&amp;hash=" . generate_link_hash("topic_$topic_id")) : '',
  732.         // www.phpBB-SEO.com SEO TOOLKIT END
  733.         'L_BOOKMARK_TOPIC'              => ($user->data['is_registered'] && $config['allow_bookmarks'] && $topic_data['bookmarked']) ? $user->lang['BOOKMARK_TOPIC_REMOVE'] : $user->lang['BOOKMARK_TOPIC'],
  734.  
  735.         'U_POST_NEW_TOPIC'              => ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=post&amp;f=$forum_id") : '',
  736.         'U_POST_REPLY_TOPIC'    => ($auth->acl_get('f_reply', $forum_id) || $user->data['user_id'] == ANONYMOUS) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=reply&amp;f=$forum_id&amp;t=$topic_id") : '',
  737.         'U_BUMP_TOPIC'                  => (bump_topic_allowed($forum_id, $topic_data['topic_bumped'], $topic_data['topic_last_post_time'], $topic_data['topic_poster'], $topic_data['topic_last_poster_id'])) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=bump&amp;f=$forum_id&amp;t=$topic_id&amp;hash=" . generate_link_hash("topic_$topic_id")) : '')
  738. );
  739.  
  740. // Does this topic contain a poll?
  741. if (!empty($topic_data['poll_start']))
  742. {
  743.         $sql = 'SELECT o.*, p.bbcode_bitfield, p.bbcode_uid
  744.                 FROM ' . POLL_OPTIONS_TABLE . ' o, ' . POSTS_TABLE . " p
  745.                 WHERE o.topic_id = $topic_id
  746.                         AND p.post_id = {$topic_data['topic_first_post_id']}
  747.                         AND p.topic_id = o.topic_id
  748.                 ORDER BY o.poll_option_id";
  749.         $result = $db->sql_query($sql);
  750.  
  751.         $poll_info = array();
  752.         while ($row = $db->sql_fetchrow($result))
  753.         {
  754.                 $poll_info[] = $row;
  755.         }
  756.         $db->sql_freeresult($result);
  757.  
  758.         $cur_voted_id = array();
  759.         if ($user->data['is_registered'])
  760.         {
  761.                 $sql = 'SELECT poll_option_id
  762.                         FROM ' . POLL_VOTES_TABLE . '
  763.                         WHERE topic_id = ' . $topic_id . '
  764.                                 AND vote_user_id = ' . $user->data['user_id'];
  765.                 $result = $db->sql_query($sql);
  766.  
  767.                 while ($row = $db->sql_fetchrow($result))
  768.                 {
  769.                         $cur_voted_id[] = $row['poll_option_id'];
  770.                 }
  771.                 $db->sql_freeresult($result);
  772.         }
  773.         else
  774.         {
  775.                 // Cookie based guest tracking ... I don't like this but hum ho
  776.                 // it's oft requested. This relies on "nice" users who don't feel
  777.                 // the need to delete cookies to mess with results.
  778.                 if (isset($_COOKIE[$config['cookie_name'] . '_poll_' . $topic_id]))
  779.                 {
  780.                         $cur_voted_id = explode(',', $_COOKIE[$config['cookie_name'] . '_poll_' . $topic_id]);
  781.                         $cur_voted_id = array_map('intval', $cur_voted_id);
  782.                 }
  783.         }
  784.  
  785.         // Can not vote at all if no vote permission
  786.         $s_can_vote = ($auth->acl_get('f_vote', $forum_id) &&
  787.                 (($topic_data['poll_length'] != 0 && $topic_data['poll_start'] + $topic_data['poll_length'] > time()) || $topic_data['poll_length'] == 0) &&
  788.                 $topic_data['topic_status'] != ITEM_LOCKED &&
  789.                 $topic_data['forum_status'] != ITEM_LOCKED &&
  790.                 (!sizeof($cur_voted_id) ||
  791.                 ($auth->acl_get('f_votechg', $forum_id) && $topic_data['poll_vote_change']))) ? true : false;
  792.         $s_display_results = (!$s_can_vote || ($s_can_vote && sizeof($cur_voted_id)) || $view == 'viewpoll') ? true : false;
  793.  
  794.         if ($update && $s_can_vote)
  795.         {
  796.  
  797.                 if (!sizeof($voted_id) || sizeof($voted_id) > $topic_data['poll_max_options'] || in_array(VOTE_CONVERTED, $cur_voted_id) || !check_form_key('posting'))
  798.                 {
  799.                         $redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;start=$start");
  800.  
  801.                         meta_refresh(5, $redirect_url);
  802.                         if (!sizeof($voted_id))
  803.                         {
  804.                                 $message = 'NO_VOTE_OPTION';
  805.                         }
  806.                         else if (sizeof($voted_id) > $topic_data['poll_max_options'])
  807.                         {
  808.                                 $message = 'TOO_MANY_VOTE_OPTIONS';
  809.                         }
  810.                         else if (in_array(VOTE_CONVERTED, $cur_voted_id))
  811.                         {
  812.                                 $message = 'VOTE_CONVERTED';
  813.                         }
  814.                         else
  815.                         {
  816.                                 $message = 'FORM_INVALID';
  817.                         }
  818.  
  819.                         $message = $user->lang[$message] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $redirect_url . '">', '</a>');
  820.                         trigger_error($message);
  821.                 }
  822.  
  823.                 foreach ($voted_id as $option)
  824.                 {
  825.                         if (in_array($option, $cur_voted_id))
  826.                         {
  827.                                 continue;
  828.                         }
  829.  
  830.                         $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . '
  831.                                 SET poll_option_total = poll_option_total + 1
  832.                                 WHERE poll_option_id = ' . (int) $option . '
  833.                                         AND topic_id = ' . (int) $topic_id;
  834.                         $db->sql_query($sql);
  835.  
  836.                         if ($user->data['is_registered'])
  837.                         {
  838.                                 $sql_ary = array(
  839.                                         'topic_id'                      => (int) $topic_id,
  840.                                         'poll_option_id'        => (int) $option,
  841.                                         'vote_user_id'          => (int) $user->data['user_id'],
  842.                                         'vote_user_ip'          => (string) $user->ip,
  843.                                 );
  844.  
  845.                                 $sql = 'INSERT INTO ' . POLL_VOTES_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary);
  846.                                 $db->sql_query($sql);
  847.                         }
  848.                 }
  849.  
  850.                 foreach ($cur_voted_id as $option)
  851.                 {
  852.                         if (!in_array($option, $voted_id))
  853.                         {
  854.                                 $sql = 'UPDATE ' . POLL_OPTIONS_TABLE . '
  855.                                         SET poll_option_total = poll_option_total - 1
  856.                                         WHERE poll_option_id = ' . (int) $option . '
  857.                                                 AND topic_id = ' . (int) $topic_id;
  858.                                 $db->sql_query($sql);
  859.  
  860.                                 if ($user->data['is_registered'])
  861.                                 {
  862.                                         $sql = 'DELETE FROM ' . POLL_VOTES_TABLE . '
  863.                                                 WHERE topic_id = ' . (int) $topic_id . '
  864.                                                         AND poll_option_id = ' . (int) $option . '
  865.                                                         AND vote_user_id = ' . (int) $user->data['user_id'];
  866.                                         $db->sql_query($sql);
  867.                                 }
  868.                         }
  869.                 }
  870.  
  871.                 if ($user->data['user_id'] == ANONYMOUS && !$user->data['is_bot'])
  872.                 {
  873.                         $user->set_cookie('poll_' . $topic_id, implode(',', $voted_id), time() + 31536000);
  874.                 }
  875.  
  876.                 $sql = 'UPDATE ' . TOPICS_TABLE . '
  877.                         SET poll_last_vote = ' . time() . "
  878.                         WHERE topic_id = $topic_id";
  879.                 //, topic_last_post_time = ' . time() . " -- for bumping topics with new votes, ignore for now
  880.                 $db->sql_query($sql);
  881.  
  882.                 $redirect_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;start=$start");
  883.  
  884.                 meta_refresh(5, $redirect_url);
  885.                 trigger_error($user->lang['VOTE_SUBMITTED'] . '<br /><br />' . sprintf($user->lang['RETURN_TOPIC'], '<a href="' . $redirect_url . '">', '</a>'));
  886.         }
  887.  
  888.         $poll_total = 0;
  889.         foreach ($poll_info as $poll_option)
  890.         {
  891.                 $poll_total += $poll_option['poll_option_total'];
  892.         }
  893.  
  894.         if ($poll_info[0]['bbcode_bitfield'])
  895.         {
  896.                 $poll_bbcode = new bbcode();
  897.         }
  898.         else
  899.         {
  900.                 $poll_bbcode = false;
  901.         }
  902.  
  903.         for ($i = 0, $size = sizeof($poll_info); $i < $size; $i++)
  904.         {
  905.                 $poll_info[$i]['poll_option_text'] = censor_text($poll_info[$i]['poll_option_text']);
  906.  
  907.                 if ($poll_bbcode !== false)
  908.                 {
  909.                         $poll_bbcode->bbcode_second_pass($poll_info[$i]['poll_option_text'], $poll_info[$i]['bbcode_uid'], $poll_option['bbcode_bitfield']);
  910.                 }
  911.  
  912.                 $poll_info[$i]['poll_option_text'] = bbcode_nl2br($poll_info[$i]['poll_option_text']);
  913.                 $poll_info[$i]['poll_option_text'] = smiley_text($poll_info[$i]['poll_option_text']);
  914.         }
  915.  
  916.         $topic_data['poll_title'] = censor_text($topic_data['poll_title']);
  917.  
  918.         if ($poll_bbcode !== false)
  919.         {
  920.                 $poll_bbcode->bbcode_second_pass($topic_data['poll_title'], $poll_info[0]['bbcode_uid'], $poll_info[0]['bbcode_bitfield']);
  921.         }
  922.  
  923.         $topic_data['poll_title'] = bbcode_nl2br($topic_data['poll_title']);
  924.         $topic_data['poll_title'] = smiley_text($topic_data['poll_title']);
  925.  
  926.         unset($poll_bbcode);
  927.  
  928.         foreach ($poll_info as $poll_option)
  929.         {
  930.                 $option_pct = ($poll_total > 0) ? $poll_option['poll_option_total'] / $poll_total : 0;
  931.                 $option_pct_txt = sprintf("%.1d%%", round($option_pct * 100));
  932.  
  933.                 $template->assign_block_vars('poll_option', array(
  934.                         'POLL_OPTION_ID'                => $poll_option['poll_option_id'],
  935.                         'POLL_OPTION_CAPTION'   => $poll_option['poll_option_text'],
  936.                         'POLL_OPTION_RESULT'    => $poll_option['poll_option_total'],
  937.                         'POLL_OPTION_PERCENT'   => $option_pct_txt,
  938.                         'POLL_OPTION_PCT'               => round($option_pct * 100),
  939.                         'POLL_OPTION_IMG'               => $user->img('poll_center', $option_pct_txt, round($option_pct * 250)),
  940.                         'POLL_OPTION_VOTED'             => (in_array($poll_option['poll_option_id'], $cur_voted_id)) ? true : false)
  941.                 );
  942.         }
  943.  
  944.         $poll_end = $topic_data['poll_length'] + $topic_data['poll_start'];
  945.  
  946.         $template->assign_vars(array(
  947.                 'POLL_QUESTION'         => $topic_data['poll_title'],
  948.                 'TOTAL_VOTES'           => $poll_total,
  949.                 'POLL_LEFT_CAP_IMG'     => $user->img('poll_left'),
  950.                 'POLL_RIGHT_CAP_IMG'=> $user->img('poll_right'),
  951.  
  952.                 'L_MAX_VOTES'           => ($topic_data['poll_max_options'] == 1) ? $user->lang['MAX_OPTION_SELECT'] : sprintf($user->lang['MAX_OPTIONS_SELECT'], $topic_data['poll_max_options']),
  953.                 'L_POLL_LENGTH'         => ($topic_data['poll_length']) ? sprintf($user->lang[($poll_end > time()) ? 'POLL_RUN_TILL' : 'POLL_ENDED_AT'], $user->format_date($poll_end)) : '',
  954.  
  955.                 'S_HAS_POLL'            => true,
  956.                 'S_CAN_VOTE'            => $s_can_vote,
  957.                 'S_DISPLAY_RESULTS'     => $s_display_results,
  958.                 'S_IS_MULTI_CHOICE'     => ($topic_data['poll_max_options'] > 1) ? true : false,
  959.                 'S_POLL_ACTION'         => $viewtopic_url,
  960.  
  961.                 // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  962.                 'U_VIEW_RESULTS'        => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;view=viewpoll") )
  963.                 // www.phpBB-SEO.com SEO TOOLKIT END
  964.         );
  965.  
  966.         unset($poll_end, $poll_info, $voted_id);
  967. }
  968.  
  969. // If the user is trying to reach the second half of the topic, fetch it starting from the end
  970. $store_reverse = false;
  971. $sql_limit = $config['posts_per_page'];
  972. $sql_sort_order = $direction = '';
  973.  
  974. if ($start > $total_posts / 2)
  975. {
  976.         $store_reverse = true;
  977.  
  978.         if ($start + $config['posts_per_page'] > $total_posts)
  979.         {
  980.                 $sql_limit = min($config['posts_per_page'], max(1, $total_posts - $start));
  981.         }
  982.  
  983.         // Select the sort order
  984.         $direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
  985.         $sql_start = max(0, $total_posts - $sql_limit - $start);
  986. }
  987. else
  988. {
  989.         // Select the sort order
  990.         $direction = (($sort_dir == 'd') ? 'DESC' : 'ASC');
  991.         $sql_start = $start;
  992. }
  993.  
  994. if (is_array($sort_by_sql[$sort_key]))
  995. {
  996.         $sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
  997. }
  998. else
  999. {
  1000.         $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
  1001. }
  1002.  
  1003. // Container for user details, only process once
  1004. $post_list = $user_cache = $id_cache = $attachments = $attach_list = $rowset = $update_count = $post_edit_list = array();
  1005. $has_attachments = $display_notice = false;
  1006. $bbcode_bitfield = '';
  1007. $i = $i_total = 0;
  1008.  
  1009. // Go ahead and pull all data for this topic
  1010. $sql = 'SELECT p.post_id
  1011.         FROM ' . POSTS_TABLE . ' p' . (($join_user_sql[$sort_key]) ? ', ' . USERS_TABLE . ' u': '') . "
  1012.         WHERE p.topic_id = $topic_id
  1013.                 " . ((!$auth->acl_get('m_approve', $forum_id)) ? 'AND p.post_approved = 1' : '') . "
  1014.                 " . (($join_user_sql[$sort_key]) ? 'AND u.user_id = p.poster_id': '') . "
  1015.                 $limit_posts_time
  1016.         ORDER BY $sql_sort_order";
  1017. $result = $db->sql_query_limit($sql, $sql_limit, $sql_start);
  1018.  
  1019. $i = ($store_reverse) ? $sql_limit - 1 : 0;
  1020. while ($row = $db->sql_fetchrow($result))
  1021. {
  1022.         $post_list[$i] = (int) $row['post_id'];
  1023.         ($store_reverse) ? $i-- : $i++;
  1024. }
  1025. $db->sql_freeresult($result);
  1026.  
  1027. if (!sizeof($post_list))
  1028. {
  1029.         if ($sort_days)
  1030.         {
  1031.                 trigger_error('NO_POSTS_TIME_FRAME');
  1032.         }
  1033.         else
  1034.         {
  1035.                 trigger_error('NO_TOPIC');
  1036.         }
  1037. }
  1038.  
  1039. // Holding maximum post time for marking topic read
  1040. // We need to grab it because we do reverse ordering sometimes
  1041. $max_post_time = 0;
  1042.  
  1043. $sql = $db->sql_build_query('SELECT', array(
  1044.         'SELECT'        => 'u.*, z.friend, z.foe, p.*, pb.id AS pb_id, pb.holding AS pb_holding, pb.id AS pb_id, pb.holding AS pb_holding',
  1045.  
  1046.         'FROM'          => array(
  1047.                 USERS_TABLE             => 'u',
  1048.                 POSTS_TABLE             => 'p',
  1049.         ),
  1050.  
  1051.         'LEFT_JOIN'     => array(
  1052.                 array(
  1053.                         'FROM'  => array(ZEBRA_TABLE => 'z'),
  1054.                         'ON'    => 'z.user_id = ' . $user->data['user_id'] . ' AND z.zebra_id = p.poster_id'
  1055.                 )
  1056.                 , array(
  1057.                         'FROM'  => array(POINTS_BANK_TABLE => 'pb'),
  1058.                         'ON'    => 'pb.user_id = p.poster_id'
  1059.                 )
  1060.                 , array(
  1061.                         'FROM'  => array(POINTS_BANK_TABLE => 'pb'),
  1062.                         'ON'    => 'pb.user_id = p.poster_id'
  1063.                 )
  1064.         ),
  1065.  
  1066.         'WHERE'         => $db->sql_in_set('p.post_id', $post_list) . '
  1067.                 AND u.user_id = p.poster_id'
  1068. ));
  1069.  
  1070. $result = $db->sql_query($sql);
  1071.  
  1072. $now = getdate(time() + $user->timezone + $user->dst - date('Z'));
  1073.  
  1074. // Posts are stored in the $rowset array while $attach_list, $user_cache
  1075. // and the global bbcode_bitfield are built
  1076. while ($row = $db->sql_fetchrow($result))
  1077. {
  1078.         // Set max_post_time
  1079.         if ($row['post_time'] > $max_post_time)
  1080.         {
  1081.                 $max_post_time = $row['post_time'];
  1082.         }
  1083.  
  1084. $poster_id = (int) $row['poster_id'];
  1085.         // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  1086.         $phpbb_seo->set_user_url( $row['username'], $poster_id );
  1087.         // www.phpBB-SEO.com SEO TOOLKIT END
  1088.  
  1089.         // Does post have an attachment? If so, add it to the list
  1090.         if ($row['post_attachment'] && $config['allow_attachments'])
  1091.         {
  1092.                 $attach_list[] = (int) $row['post_id'];
  1093.  
  1094.                 if ($row['post_approved'])
  1095.                 {
  1096.                         $has_attachments = true;
  1097.                 }
  1098.         }
  1099.        
  1100.         // Start Ultimate Points
  1101.         $has_account = true;
  1102.         $holding = ( empty($holding) ) ? array() : $holding;
  1103.         $pointslock = $banklock = '';
  1104.  
  1105.         if ( $config['points_enable'] )
  1106.         {
  1107.                 // Get the points status
  1108.                 $check_auth = new auth();
  1109.                 $check_auth->acl($row);
  1110.                 $pointslock = !$check_auth->acl_get('u_use_points');
  1111.  
  1112.                 // Get the bank status
  1113.                 if ($points_config['bank_enable'])
  1114.                 {
  1115.                         $check_auth = new auth();
  1116.                         $check_auth->acl($row);
  1117.                         $banklock = !$check_auth->acl_get('u_use_bank');
  1118.                 }
  1119.  
  1120.                 if ( !isset($row['pb_holding']) && $poster_id > 0 )
  1121.                 {
  1122.                         $has_account = false;
  1123.                 }
  1124.                 $holding[$poster_id] = ( $row['pb_holding'] ) ? $row['pb_holding'] : '0';
  1125.         }
  1126.         else
  1127.         {
  1128.                 $holding[$poster_id] = '0';
  1129.         }
  1130.         // End Ultimate Points
  1131.  
  1132.         $rowset[$row['post_id']] = array(
  1133.                 'hide_post'                     => ($row['foe'] && ($view != 'show' || $post_id != $row['post_id'])) ? true : false,
  1134.  
  1135.                 'post_id'                       => $row['post_id'],
  1136.                 'post_time'                     => $row['post_time'],
  1137.                 'user_id'                       => $row['user_id'],
  1138.                 'username'                      => $row['username'],
  1139.                 'user_colour'           => $row['user_colour'],
  1140.                 'topic_id'                      => $row['topic_id'],
  1141.                 'forum_id'                      => $row['forum_id'],
  1142.                 'post_subject'          => $row['post_subject'],
  1143.                 'post_edit_count'       => $row['post_edit_count'],
  1144.                 'post_edit_time'        => $row['post_edit_time'],
  1145.                 'post_edit_reason'      => $row['post_edit_reason'],
  1146.                 'post_edit_user'        => $row['post_edit_user'],
  1147.                 'post_edit_locked'      => $row['post_edit_locked'],
  1148.  
  1149.  
  1150.  
  1151.                 // Start Ultimate Points
  1152.                 'points'                        => $row['user_points'],
  1153.                 'points_lock'           => $pointslock,
  1154.                 'bank_lock'                     => $banklock,
  1155.                 'bank_account'          => $has_account,
  1156.                 // End Ultimate Points
  1157.                 // Make sure the icon actually exists
  1158.                 'icon_id'                       => (isset($icons[$row['icon_id']]['img'], $icons[$row['icon_id']]['height'], $icons[$row['icon_id']]['width'])) ? $row['icon_id'] : 0,
  1159.                 'post_attachment'       => $row['post_attachment'],
  1160.                 'post_approved'         => $row['post_approved'],
  1161.                 'post_reported'         => $row['post_reported'],
  1162.                 'post_username'         => $row['post_username'],
  1163.                 'post_text'                     => $row['post_text'],
  1164.                 'bbcode_uid'            => $row['bbcode_uid'],
  1165.                 'bbcode_bitfield'       => $row['bbcode_bitfield'],
  1166.                 'enable_smilies'        => $row['enable_smilies'],
  1167.                 'enable_sig'            => $row['enable_sig'],
  1168.                 'friend'                        => $row['friend'],
  1169.                 'foe'                           => $row['foe'],
  1170.         );
  1171.  
  1172.         // Define the global bbcode bitfield, will be used to load bbcodes
  1173.         $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['bbcode_bitfield']);
  1174.  
  1175.         // Is a signature attached? Are we going to display it?
  1176.         if ($row['enable_sig'] && $config['allow_sig'] && $user->optionget('viewsigs'))
  1177.         {
  1178.                 $bbcode_bitfield = $bbcode_bitfield | base64_decode($row['user_sig_bbcode_bitfield']);
  1179.         }
  1180.  
  1181.         // Cache various user specific data ... so we don't have to recompute
  1182.         // this each time the same user appears on this page
  1183.         if (!isset($user_cache[$poster_id]))
  1184.         {
  1185.                 if ($poster_id == ANONYMOUS)
  1186.                 {
  1187.                         $user_cache[$poster_id] = array(
  1188.                                 'joined'                => '',
  1189.                                 'posts'                 => '',
  1190.                                 'from'                  => '',
  1191.  
  1192.                                 'sig'                                   => '',
  1193.                                 'sig_bbcode_uid'                => '',
  1194.                                 'sig_bbcode_bitfield'   => '',
  1195.  
  1196.                                 'online'                        => false,
  1197.                                 'avatar'                        => ($user->optionget('viewavatars')) ? get_user_avatar($row['user_avatar'], $row['user_avatar_type'], $row['user_avatar_width'], $row['user_avatar_height']) : '',
  1198.                                 'flag_country'          => '',
  1199.                                 'flag_code'                     => '',
  1200.                                 'flag_img'                      => '',
  1201.                                 'flag_img_src'          => '',
  1202.                                 'rank_title'            => '',
  1203.                                 'rank_image'            => '',
  1204.                                 'rank_image_src'        => '',
  1205.                                 'sig'                           => '',
  1206.                                 'profile'                       => '',
  1207.                                 'pm'                            => '',
  1208.                                 'email'                         => '',
  1209.                                 'www'                           => '',
  1210.                                 'icq_status_img'        => '',
  1211.                                 'icq'                           => '',
  1212.                                 'aim'                           => '',
  1213.                                 'msn'                           => '',
  1214.                                 'yim'                           => '',
  1215.                                 'jabber'                        => '',
  1216.                                 'search'                        => '',
  1217.                                 'age'                           => '',
  1218.                                
  1219.                                 // Start Ultimate Points
  1220.                                 'points'                        => 0.00,
  1221.                                 'points_lock'           => true,
  1222.                                 'bank_lock'                     => true,
  1223.                                 'bank_account'          => true,
  1224.                                 // End Ultimate Points
  1225.  
  1226.                                 'username'                      => $row['username'],
  1227.                                 'user_colour'           => $row['user_colour'],
  1228.  
  1229.                                 'warnings'                      => 0,
  1230.                                 'allow_pm'                      => 0,
  1231.                         );
  1232.  
  1233.                         get_user_rank($row['user_rank'], false, $user_cache[$poster_id]['rank_title'], $user_cache[$poster_id]['rank_image'], $user_cache[$poster_id]['rank_image_src']);
  1234.                 }
  1235.                 else
  1236.                 {
  1237.                         $user_sig = '';
  1238.  
  1239.                         // We add the signature to every posters entry because enable_sig is post dependant
  1240.                         if ($row['user_sig'] && $config['allow_sig'] && $user->optionget('viewsigs'))
  1241.                         {
  1242.                                 $user_sig = $row['user_sig'];
  1243.                         }
  1244.  
  1245.                         $id_cache[] = $poster_id;
  1246.  
  1247.                         $user_cache[$poster_id] = array(
  1248.                                 'joined'                => $user->format_date($row['user_regdate']),
  1249.                                 'posts'                 => $row['user_posts'],
  1250.                                 'warnings'              => (isset($row['user_warnings'])) ? $row['user_warnings'] : 0,
  1251.                                 'from'                  => (!empty($row['user_from'])) ? $row['user_from'] : '',
  1252.  
  1253.                                 // Start Ultimate Points
  1254.                                 'points'                => $row['user_points'],
  1255.                                 'points_lock'   => $pointslock,
  1256.                                 'bank_lock'             => $banklock,
  1257.                                 'bank_account'  => $has_account,
  1258.                                 // End Ultimate Points
  1259.  
  1260.                                 'sig'                                   => $user_sig,
  1261.                                 'sig_bbcode_uid'                => (!empty($row['user_sig_bbcode_uid'])) ? $row['user_sig_bbcode_uid'] : '',
  1262.                                 'sig_bbcode_bitfield'   => (!empty($row['user_sig_bbcode_bitfield'])) ? $row['user_sig_bbcode_bitfield'] : '',
  1263.  
  1264.                                 'viewonline'    => $row['user_allow_viewonline'],
  1265.                                 'allow_pm'              => $row['user_allow_pm'],
  1266.  
  1267.  
  1268.                                 'flag_country'  => '',
  1269.                                 'flag_code'             => '',
  1270.                                 'flag_img'              => '',
  1271.                                 'flag_img_src'  => '',
  1272.                                 'avatar'                => ($user->optionget('viewavatars')) ? get_user_avatar($row['user_avatar'], $row['user_avatar_type'], $row['user_avatar_width'], $row['user_avatar_height']) : '',
  1273.                                 'age'                   => '',
  1274.  
  1275.                                 'rank_title'            => '',
  1276.                                 'rank_image'            => '',
  1277.                                 'rank_image_src'        => '',
  1278.  
  1279.                                 'username'                      => $row['username'],
  1280.                                 'user_colour'           => $row['user_colour'],
  1281.  
  1282.                                 'online'                => false,
  1283.                                 'profile'               => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=viewprofile&amp;u=$poster_id"),
  1284.                                 'www'                   => $row['user_website'],
  1285.                                 'aim'                   => ($row['user_aim'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=aim&amp;u=$poster_id") : '',
  1286.                                 'msn'                   => ($row['user_msnm'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=msnm&amp;u=$poster_id") : '',
  1287.                                 'yim'                   => ($row['user_yim']) ? 'http://edit.yahoo.com/config/send_webmesg?.target=' . urlencode($row['user_yim']) . '&amp;.src=pg' : '',
  1288.                                 'jabber'                => ($row['user_jabber'] && $auth->acl_get('u_sendim')) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=contact&amp;action=jabber&amp;u=$poster_id") : '',
  1289.                                 'search'                => ($auth->acl_get('u_search')) ? append_sid("{$phpbb_root_path}search.$phpEx", "author_id=$poster_id&amp;sr=posts") : '',
  1290.  
  1291.                                 'author_full'           => get_username_string('full', $poster_id, $row['username'], $row['user_colour']),
  1292.                                 'author_colour'         => get_username_string('colour', $poster_id, $row['username'], $row['user_colour']),
  1293.                                 'author_username'       => get_username_string('username', $poster_id, $row['username'], $row['user_colour']),
  1294.                                 'author_profile'        => get_username_string('profile', $poster_id, $row['username'], $row['user_colour']),
  1295.                         );
  1296.  
  1297.  
  1298.                         get_user_flag($row['user_flag'], $user_cache[$poster_id]['flag_country'], $user_cache[$poster_id]['flag_code'], $user_cache[$poster_id]['flag_img'], $user_cache[$poster_id]['flag_img_src']);
  1299.                         get_user_rank($row['user_rank'], $row['user_posts'], $user_cache[$poster_id]['rank_title'], $user_cache[$poster_id]['rank_image'], $user_cache[$poster_id]['rank_image_src']);
  1300.  
  1301.                         if (!empty($row['user_allow_viewemail']) || $auth->acl_get('a_email'))
  1302.                         {
  1303.                                 $user_cache[$poster_id]['email'] = ($config['board_email_form'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=email&amp;u=$poster_id") : (($config['board_hide_emails'] && !$auth->acl_get('a_email')) ? '' : 'mailto:' . $row['user_email']);
  1304.                         }
  1305.                         else
  1306.                         {
  1307.                                 $user_cache[$poster_id]['email'] = '';
  1308.                         }
  1309.  
  1310.                         if (!empty($row['user_icq']))
  1311.                         {
  1312.                                 $user_cache[$poster_id]['icq'] = 'http://www.icq.com/people/webmsg.php?to=' . $row['user_icq'];
  1313.                                 $user_cache[$poster_id]['icq_status_img'] = '<img src="http://web.icq.com/whitepages/online?icq=' . $row['user_icq'] . '&amp;img=5" width="18" height="18" alt="" />';
  1314.                         }
  1315.                         else
  1316.                         {
  1317.                                 $user_cache[$poster_id]['icq_status_img'] = '';
  1318.                                 $user_cache[$poster_id]['icq'] = '';
  1319.                         }
  1320.  
  1321.                         if ($config['allow_birthdays'] && !empty($row['user_birthday']))
  1322.                         {
  1323.                                 list($bday_day, $bday_month, $bday_year) = array_map('intval', explode('-', $row['user_birthday']));
  1324.  
  1325.                                 if ($bday_year)
  1326.                                 {
  1327.                                         $diff = $now['mon'] - $bday_month;
  1328.                                         if ($diff == 0)
  1329.                                         {
  1330.                                                 $diff = ($now['mday'] - $bday_day < 0) ? 1 : 0;
  1331.                                         }
  1332.                                         else
  1333.                                         {
  1334.                                                 $diff = ($diff < 0) ? 1 : 0;
  1335.                                         }
  1336.  
  1337.                                         $user_cache[$poster_id]['age'] = (int) ($now['year'] - $bday_year - $diff);
  1338.                                 }
  1339.                         }
  1340.                 }
  1341.         }
  1342. }
  1343. $db->sql_freeresult($result);
  1344.  
  1345. // Load custom profile fields
  1346. if ($config['load_cpf_viewtopic'])
  1347. {
  1348.         if (!class_exists('custom_profile'))
  1349.         {
  1350.                 include($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx);
  1351.         }
  1352.         $cp = new custom_profile();
  1353.  
  1354.         // Grab all profile fields from users in id cache for later use - similar to the poster cache
  1355.         $profile_fields_tmp = $cp->generate_profile_fields_template('grab', $id_cache);
  1356.  
  1357.         // filter out fields not to be displayed on viewtopic. Yes, it's a hack, but this shouldn't break any MODs.
  1358.         $profile_fields_cache = array();
  1359.         foreach ($profile_fields_tmp as $profile_user_id => $profile_fields)
  1360.         {
  1361.                 $profile_fields_cache[$profile_user_id] = array();
  1362.                 foreach ($profile_fields as $used_ident => $profile_field)
  1363.                 {
  1364.                         if ($profile_field['data']['field_show_on_vt'])
  1365.                         {
  1366.                                 $profile_fields_cache[$profile_user_id][$used_ident] = $profile_field;
  1367.                         }
  1368.                 }
  1369.         }
  1370.         unset($profile_fields_tmp);
  1371. }
  1372.  
  1373. // Generate online information for user
  1374. if ($config['load_onlinetrack'] && sizeof($id_cache))
  1375. {
  1376.         $sql = 'SELECT session_user_id, MAX(session_time) as online_time, MIN(session_viewonline) AS viewonline
  1377.                 FROM ' . SESSIONS_TABLE . '
  1378.                 WHERE ' . $db->sql_in_set('session_user_id', $id_cache) . '
  1379.                 GROUP BY session_user_id';
  1380.         $result = $db->sql_query($sql);
  1381.  
  1382.         $update_time = $config['load_online_time'] * 60;
  1383.         while ($row = $db->sql_fetchrow($result))
  1384.         {
  1385.                 $user_cache[$row['session_user_id']]['online'] = (time() - $update_time < $row['online_time'] && (($row['viewonline']) || $auth->acl_get('u_viewonline'))) ? true : false;
  1386.         }
  1387.         $db->sql_freeresult($result);
  1388. }
  1389. unset($id_cache);
  1390.  
  1391. // Pull attachment data
  1392. if (sizeof($attach_list))
  1393. {
  1394.         if ($auth->acl_get('u_download') && $auth->acl_get('f_download', $forum_id))
  1395.         {
  1396.                 $sql = 'SELECT *
  1397.                         FROM ' . ATTACHMENTS_TABLE . '
  1398.                         WHERE ' . $db->sql_in_set('post_msg_id', $attach_list) . '
  1399.                                 AND in_message = 0
  1400.                         ORDER BY filetime DESC, post_msg_id ASC';
  1401.                 $result = $db->sql_query($sql);
  1402.  
  1403.                 while ($row = $db->sql_fetchrow($result))
  1404.                 {
  1405.                         $attachments[$row['post_msg_id']][] = $row;
  1406.                 }
  1407.                 $db->sql_freeresult($result);
  1408.  
  1409.                 // No attachments exist, but post table thinks they do so go ahead and reset post_attach flags
  1410.                 if (!sizeof($attachments))
  1411.                 {
  1412.                         $sql = 'UPDATE ' . POSTS_TABLE . '
  1413.                                 SET post_attachment = 0
  1414.                                 WHERE ' . $db->sql_in_set('post_id', $attach_list);
  1415.                         $db->sql_query($sql);
  1416.  
  1417.                         // We need to update the topic indicator too if the complete topic is now without an attachment
  1418.                         if (sizeof($rowset) != $total_posts)
  1419.                         {
  1420.                                 // Not all posts are displayed so we query the db to find if there's any attachment for this topic
  1421.                                 $sql = 'SELECT a.post_msg_id as post_id
  1422.                                         FROM ' . ATTACHMENTS_TABLE . ' a, ' . POSTS_TABLE . " p
  1423.                                         WHERE p.topic_id = $topic_id
  1424.                                                 AND p.post_approved = 1
  1425.                                                 AND p.topic_id = a.topic_id";
  1426.                                 $result = $db->sql_query_limit($sql, 1);
  1427.                                 $row = $db->sql_fetchrow($result);
  1428.                                 $db->sql_freeresult($result);
  1429.  
  1430.                                 if (!$row)
  1431.                                 {
  1432.                                         $sql = 'UPDATE ' . TOPICS_TABLE . "
  1433.                                                 SET topic_attachment = 0
  1434.                                                 WHERE topic_id = $topic_id";
  1435.                                         $db->sql_query($sql);
  1436.                                 }
  1437.                         }
  1438.                         else
  1439.                         {
  1440.                                 $sql = 'UPDATE ' . TOPICS_TABLE . "
  1441.                                         SET topic_attachment = 0
  1442.                                         WHERE topic_id = $topic_id";
  1443.                                 $db->sql_query($sql);
  1444.                         }
  1445.                 }
  1446.                 else if ($has_attachments && !$topic_data['topic_attachment'])
  1447.                 {
  1448.                         // Topic has approved attachments but its flag is wrong
  1449.                         $sql = 'UPDATE ' . TOPICS_TABLE . "
  1450.                                 SET topic_attachment = 1
  1451.                                 WHERE topic_id = $topic_id";
  1452.                         $db->sql_query($sql);
  1453.  
  1454.                         $topic_data['topic_attachment'] = 1;
  1455.                 }
  1456.         }
  1457.         else
  1458.         {
  1459.                 $display_notice = true;
  1460.         }
  1461. }
  1462.  
  1463. // Instantiate BBCode if need be
  1464. if ($bbcode_bitfield !== '')
  1465. {
  1466.         $bbcode = new bbcode(base64_encode($bbcode_bitfield));
  1467. }
  1468.  
  1469. $i_total = sizeof($rowset) - 1;
  1470. $prev_post_id = '';
  1471.  
  1472. $template->assign_vars(array(
  1473.         'S_NUM_POSTS' => sizeof($post_list))
  1474. );
  1475.  
  1476. // Output the posts
  1477. $first_unread = $post_unread = false;
  1478. for ($i = 0, $end = sizeof($post_list); $i < $end; ++$i)
  1479. {
  1480.         // A non-existing rowset only happens if there was no user present for the entered poster_id
  1481.         // This could be a broken posts table.
  1482.         if (!isset($rowset[$post_list[$i]]))
  1483.         {
  1484.                 continue;
  1485.         }
  1486.  
  1487.         $row =& $rowset[$post_list[$i]];
  1488.         $poster_id = $row['user_id'];
  1489.  
  1490.         // End signature parsing, only if needed
  1491.         if ($user_cache[$poster_id]['sig'] && $row['enable_sig'] && empty($user_cache[$poster_id]['sig_parsed']))
  1492.         {
  1493.                 $user_cache[$poster_id]['sig'] = censor_text($user_cache[$poster_id]['sig']);
  1494.  
  1495.                 if ($user_cache[$poster_id]['sig_bbcode_bitfield'])
  1496.                 {
  1497.                         $bbcode->bbcode_second_pass($user_cache[$poster_id]['sig'], $user_cache[$poster_id]['sig_bbcode_uid'], $user_cache[$poster_id]['sig_bbcode_bitfield']);
  1498.                 }
  1499.  
  1500.                 $user_cache[$poster_id]['sig'] = bbcode_nl2br($user_cache[$poster_id]['sig']);
  1501.                 $user_cache[$poster_id]['sig'] = smiley_text($user_cache[$poster_id]['sig']);
  1502.                 $user_cache[$poster_id]['sig_parsed'] = true;
  1503.         }
  1504.  
  1505.         // Parse the message and subject
  1506.         $message = censor_text($row['post_text']);
  1507.  
  1508.         // Second parse bbcode here
  1509.         if ($row['bbcode_bitfield'])
  1510.         {
  1511.                 $bbcode->bbcode_second_pass($message, $row['bbcode_uid'], $row['bbcode_bitfield']);
  1512.         }
  1513.  
  1514.         $message = bbcode_nl2br($message);
  1515.         $message = smiley_text($message);
  1516.  
  1517.         if (!empty($attachments[$row['post_id']]))
  1518.         {
  1519.                 parse_attachments($forum_id, $message, $attachments[$row['post_id']], $update_count);
  1520.         }
  1521.  
  1522.         // Replace naughty words such as farty pants
  1523.         $row['post_subject'] = censor_text($row['post_subject']);
  1524.  
  1525.         // Highlight active words (primarily for search)
  1526.         if ($highlight_match)
  1527.         {
  1528.                 $message = preg_replace('#(?!<.*)(?<!\w)(' . $highlight_match . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">\1</span>', $message);
  1529.                 $row['post_subject'] = preg_replace('#(?!<.*)(?<!\w)(' . $highlight_match . ')(?!\w|[^<>]*(?:</s(?:cript|tyle))?>)#is', '<span class="posthilit">\1</span>', $row['post_subject']);
  1530.         }
  1531.  
  1532.         // Editing information
  1533.         if (($row['post_edit_count'] && $config['display_last_edited']) || $row['post_edit_reason'])
  1534.         {
  1535.                 // Get usernames for all following posts if not already stored
  1536.                 if (!sizeof($post_edit_list) && ($row['post_edit_reason'] || ($row['post_edit_user'] && !isset($user_cache[$row['post_edit_user']]))))
  1537.                 {
  1538.                         // Remove all post_ids already parsed (we do not have to check them)
  1539.                         $post_storage_list = (!$store_reverse) ? array_slice($post_list, $i) : array_slice(array_reverse($post_list), $i);
  1540.  
  1541.                         $sql = 'SELECT DISTINCT u.user_id, u.username, u.user_colour
  1542.                                 FROM ' . POSTS_TABLE . ' p, ' . USERS_TABLE . ' u
  1543.                                 WHERE ' . $db->sql_in_set('p.post_id', $post_storage_list) . '
  1544.                                         AND p.post_edit_count <> 0
  1545.                                         AND p.post_edit_user <> 0
  1546.                                         AND p.post_edit_user = u.user_id';
  1547.                         $result2 = $db->sql_query($sql);
  1548.                         while ($user_edit_row = $db->sql_fetchrow($result2))
  1549.                         {
  1550.                                 $post_edit_list[$user_edit_row['user_id']] = $user_edit_row;
  1551.                         }
  1552.                         $db->sql_freeresult($result2);
  1553.  
  1554.                         unset($post_storage_list);
  1555.                 }
  1556.  
  1557.                 $l_edit_time_total = ($row['post_edit_count'] == 1) ? $user->lang['EDITED_TIME_TOTAL'] : $user->lang['EDITED_TIMES_TOTAL'];
  1558.  
  1559.                 if ($row['post_edit_reason'])
  1560.                 {
  1561.                         // User having edited the post also being the post author?
  1562.                         if (!$row['post_edit_user'] || $row['post_edit_user'] == $poster_id)
  1563.                         {
  1564.                                 $display_username = get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']);
  1565.                         }
  1566.                         else
  1567.                         {
  1568.                                 $display_username = get_username_string('full', $row['post_edit_user'], $post_edit_list[$row['post_edit_user']]['username'], $post_edit_list[$row['post_edit_user']]['user_colour']);
  1569.                         }
  1570.  
  1571.                         $l_edited_by = sprintf($l_edit_time_total, $display_username, $user->format_date($row['post_edit_time'], false, true), $row['post_edit_count']);
  1572.                 }
  1573.                 else
  1574.                 {
  1575.                         if ($row['post_edit_user'] && !isset($user_cache[$row['post_edit_user']]))
  1576.                         {
  1577.                                 $user_cache[$row['post_edit_user']] = $post_edit_list[$row['post_edit_user']];
  1578.                         }
  1579.  
  1580.                         // User having edited the post also being the post author?
  1581.                         if (!$row['post_edit_user'] || $row['post_edit_user'] == $poster_id)
  1582.                         {
  1583.                                 $display_username = get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']);
  1584.                         }
  1585.                         else
  1586.                         {
  1587.                                 $display_username = get_username_string('full', $row['post_edit_user'], $user_cache[$row['post_edit_user']]['username'], $user_cache[$row['post_edit_user']]['user_colour']);
  1588.                         }
  1589.  
  1590.                         $l_edited_by = sprintf($l_edit_time_total, $display_username, $user->format_date($row['post_edit_time'], false, true), $row['post_edit_count']);
  1591.                 }
  1592.         }
  1593.         else
  1594.         {
  1595.                 $l_edited_by = '';
  1596.         }
  1597.  
  1598.         // Bump information
  1599.         if ($topic_data['topic_bumped'] && $row['post_id'] == $topic_data['topic_last_post_id'] && isset($user_cache[$topic_data['topic_bumper']]) )
  1600.         {
  1601.                 // It is safe to grab the username from the user cache array, we are at the last
  1602.                 // post and only the topic poster and last poster are allowed to bump.
  1603.                 // Admins and mods are bound to the above rules too...
  1604.                 $l_bumped_by = sprintf($user->lang['BUMPED_BY'], $user_cache[$topic_data['topic_bumper']]['username'], $user->format_date($topic_data['topic_last_post_time'], false, true));
  1605.         }
  1606.         else
  1607.         {
  1608.                 $l_bumped_by = '';
  1609.         }
  1610.  
  1611.         $cp_row = array();
  1612.  
  1613.         //
  1614.         if ($config['load_cpf_viewtopic'])
  1615.         {
  1616.                 $cp_row = (isset($profile_fields_cache[$poster_id])) ? $cp->generate_profile_fields_template('show', false, $profile_fields_cache[$poster_id]) : array();
  1617.         }
  1618.  
  1619.         $post_unread = (isset($topic_tracking_info[$topic_id]) && $row['post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
  1620.  
  1621.         $s_first_unread = false;
  1622.         if (!$first_unread && $post_unread)
  1623.         {
  1624.                 $s_first_unread = $first_unread = true;
  1625.         }
  1626.        
  1627.         // Start Ultimate Points
  1628.         $holding = ( empty($holding) ) ? array() : $holding;
  1629.         if ( empty($holding[$poster_id]) )
  1630.         {
  1631.                 $sql = "SELECT holding
  1632.                         FROM " . POINTS_BANK_TABLE . "
  1633.                         WHERE user_id = '$poster_id'";
  1634.                 $result = $db->sql_query($sql);
  1635.                 $bank_row = $db->sql_fetchrow($result);
  1636.                 $holding[$poster_id] = ( $bank_row['holding'] ) ? $bank_row['holding'] : '0';
  1637.                 $bank_row = '';
  1638.         }
  1639.         // End Ultimate Points
  1640.  
  1641.         $edit_allowed = ($user->data['is_registered'] && ($auth->acl_get('m_edit', $forum_id) || (
  1642.                 $user->data['user_id'] == $poster_id &&
  1643.                 $auth->acl_get('f_edit', $forum_id) &&
  1644.                 !$row['post_edit_locked'] &&
  1645.                 ($row['post_time'] > time() - ($config['edit_time'] * 60) || !$config['edit_time'])
  1646.         )));
  1647.  
  1648.         $delete_allowed = ($user->data['is_registered'] && ($auth->acl_get('m_delete', $forum_id) || (
  1649.                 $user->data['user_id'] == $poster_id &&
  1650.                 $auth->acl_get('f_delete', $forum_id) &&
  1651.                 $topic_data['topic_last_post_id'] == $row['post_id'] &&
  1652.                 ($row['post_time'] > time() - ($config['delete_time'] * 60) || !$config['delete_time']) &&
  1653.                 // we do not want to allow removal of the last post if a moderator locked it!
  1654.                 !$row['post_edit_locked']
  1655.         )));
  1656.  
  1657.         //
  1658.         $postrow = array(
  1659.                 'POST_AUTHOR_FULL'              => ($poster_id != ANONYMOUS) ? $user_cache[$poster_id]['author_full'] : get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1660.                 'POST_AUTHOR_COLOUR'    => ($poster_id != ANONYMOUS) ? $user_cache[$poster_id]['author_colour'] : get_username_string('colour', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1661.                 'POST_AUTHOR'                   => ($poster_id != ANONYMOUS) ? $user_cache[$poster_id]['author_username'] : get_username_string('username', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1662.                 'U_POST_AUTHOR'                 => ($poster_id != ANONYMOUS) ? $user_cache[$poster_id]['author_profile'] : get_username_string('profile', $poster_id, $row['username'], $row['user_colour'], $row['post_username']),
  1663.  
  1664.  
  1665.                 'FLAG_COUNTRY'          => $user_cache[$poster_id]['flag_country'],
  1666.                 'FLAG_CODE'                     => $user_cache[$poster_id]['flag_code'],
  1667.                 'FLAG_IMG'                      => $user_cache[$poster_id]['flag_img'],
  1668.                 'FLAG_IMG_SRC'          => $user_cache[$poster_id]['flag_img_src'],
  1669.                 'RANK_TITLE'            => $user_cache[$poster_id]['rank_title'],
  1670.                 'RANK_IMG'                      => $user_cache[$poster_id]['rank_image'],
  1671.                 'RANK_IMG_SRC'          => $user_cache[$poster_id]['rank_image_src'],
  1672.                 'POSTER_JOINED'         => $user_cache[$poster_id]['joined'],
  1673.                 'POSTER_POSTS'          => $user_cache[$poster_id]['posts'],
  1674.                 'POSTER_FROM'           => $user_cache[$poster_id]['from'],
  1675.                 'POSTER_AVATAR'         => $user_cache[$poster_id]['avatar'],
  1676.                 'POSTER_WARNINGS'       => $user_cache[$poster_id]['warnings'],
  1677.                 'POSTER_AGE'            => $user_cache[$poster_id]['age'],
  1678.                
  1679.                 // Start Ultimate Points
  1680.                 'POSTER_POINTS'         => number_format_points($user_cache[$poster_id]['points']),
  1681.                 'POSTER_LOCK'           => $user_cache[$poster_id]['points_lock'],
  1682.                 'POSTER_BANK_LOCK'      => $user_cache[$poster_id]['bank_lock'],
  1683.                 'USER_ID'                       => $poster_id,
  1684.                 'BANK_GOLD'                     => number_format_points($holding[$poster_id]),
  1685.                 'BANK_ACCOUNT'          => $user_cache[$poster_id]['bank_account'],
  1686.                 // End Ultimate Points
  1687.  
  1688.                 'POST_DATE'                     => $user->format_date($row['post_time'], false, ($view == 'print') ? true : false),
  1689.                 'POST_SUBJECT'          => $row['post_subject'],
  1690.                 'MESSAGE'                       => $message,
  1691.                 'SIGNATURE'                     => ($row['enable_sig']) ? $user_cache[$poster_id]['sig'] : '',
  1692.                 'EDITED_MESSAGE'        => $l_edited_by,
  1693.                 'EDIT_REASON'           => $row['post_edit_reason'],
  1694.                 'BUMPED_MESSAGE'        => $l_bumped_by,
  1695.  
  1696.                 'MINI_POST_IMG'                 => ($post_unread) ? $user->img('icon_post_target_unread', 'NEW_POST') : $user->img('icon_post_target', 'POST'),
  1697.                 'POST_ICON_IMG'                 => ($topic_data['enable_icons'] && !empty($row['icon_id'])) ? $icons[$row['icon_id']]['img'] : '',
  1698.                 'POST_ICON_IMG_WIDTH'   => ($topic_data['enable_icons'] && !empty($row['icon_id'])) ? $icons[$row['icon_id']]['width'] : '',
  1699.                 'POST_ICON_IMG_HEIGHT'  => ($topic_data['enable_icons'] && !empty($row['icon_id'])) ? $icons[$row['icon_id']]['height'] : '',
  1700.                 'ICQ_STATUS_IMG'                => $user_cache[$poster_id]['icq_status_img'],
  1701.                 'ONLINE_IMG'                    => ($poster_id == ANONYMOUS || !$config['load_onlinetrack']) ? '' : (($user_cache[$poster_id]['online']) ? $user->img('icon_user_online', 'ONLINE') : $user->img('icon_user_offline', 'OFFLINE')),
  1702.                 'S_ONLINE'                              => ($poster_id == ANONYMOUS || !$config['load_onlinetrack']) ? false : (($user_cache[$poster_id]['online']) ? true : false),
  1703.  
  1704.                 'U_EDIT'                        => ($edit_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=edit&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
  1705.                 'U_QUOTE'                       => ($auth->acl_get('f_reply', $forum_id)) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=quote&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
  1706.                 'U_INFO'                        => ($auth->acl_get('m_info', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "i=main&amp;mode=post_details&amp;f=$forum_id&amp;p=" . $row['post_id'], true, $user->session_id) : '',
  1707.                 'U_DELETE'                      => ($delete_allowed) ? append_sid("{$phpbb_root_path}posting.$phpEx", "mode=delete&amp;f=$forum_id&amp;p={$row['post_id']}") : '',
  1708.  
  1709.                 'U_PROFILE'             => $user_cache[$poster_id]['profile'],
  1710.                 'U_SEARCH'              => $user_cache[$poster_id]['search'],
  1711.                 'U_PM'                  => ($poster_id != ANONYMOUS && $config['allow_privmsg'] && $auth->acl_get('u_sendpm') && ($user_cache[$poster_id]['allow_pm'] || $auth->acl_gets('a_', 'm_') || $auth->acl_getf_global('m_'))) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&amp;mode=compose&amp;action=quotepost&amp;p=' . $row['post_id']) : '',
  1712.                 'U_EMAIL'               => $user_cache[$poster_id]['email'],
  1713.                 'U_WWW'                 => $user_cache[$poster_id]['www'],
  1714.                 'U_ICQ'                 => $user_cache[$poster_id]['icq'],
  1715.                 'U_AIM'                 => $user_cache[$poster_id]['aim'],
  1716.                 'U_MSN'                 => $user_cache[$poster_id]['msn'],
  1717.                 'U_YIM'                 => $user_cache[$poster_id]['yim'],
  1718.                 'U_JABBER'              => $user_cache[$poster_id]['jabber'],
  1719.  
  1720.                 'U_REPORT'                      => ($auth->acl_get('f_report', $forum_id)) ? append_sid("{$phpbb_root_path}report.$phpEx", 'f=' . $forum_id . '&amp;p=' . $row['post_id']) : '',
  1721.                 'U_MCP_REPORT'          => ($auth->acl_get('m_report', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=report_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
  1722.                 'U_MCP_APPROVE'         => ($auth->acl_get('m_approve', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=approve_details&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
  1723.                 'U_MINI_POST'           => append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['post_id']) . (($topic_data['topic_type'] == POST_GLOBAL) ? '&amp;f=' . $forum_id : '') . '#p' . $row['post_id'],
  1724.                 'U_NEXT_POST_ID'        => ($i < $i_total && isset($rowset[$post_list[$i + 1]])) ? $rowset[$post_list[$i + 1]]['post_id'] : '',
  1725.                 'U_PREV_POST_ID'        => $prev_post_id,
  1726.                 'U_NOTES'                       => ($auth->acl_getf_global('m_')) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=notes&amp;mode=user_notes&amp;u=' . $poster_id, true, $user->session_id) : '',
  1727.                 'U_WARN'                        => ($auth->acl_get('m_warn') && $poster_id != $user->data['user_id'] && $poster_id != ANONYMOUS) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=warn&amp;mode=warn_post&amp;f=' . $forum_id . '&amp;p=' . $row['post_id'], true, $user->session_id) : '',
  1728.  
  1729.                 'POST_ID'                       => $row['post_id'],
  1730.                 'POSTER_ID'                     => $poster_id,
  1731.  
  1732.                 'S_HAS_ATTACHMENTS'     => (!empty($attachments[$row['post_id']])) ? true : false,
  1733.                 'S_POST_UNAPPROVED'     => ($row['post_approved']) ? false : true,
  1734.                 'S_POST_REPORTED'       => ($row['post_reported'] && $auth->acl_get('m_report', $forum_id)) ? true : false,
  1735.                 'S_DISPLAY_NOTICE'      => $display_notice && $row['post_attachment'],
  1736.                 'S_FRIEND'                      => ($row['friend']) ? true : false,
  1737.                 'S_UNREAD_POST'         => $post_unread,
  1738.                 'S_FIRST_UNREAD'        => $s_first_unread,
  1739.                 'S_CUSTOM_FIELDS'       => (isset($cp_row['row']) && sizeof($cp_row['row'])) ? true : false,
  1740.                 'S_TOPIC_POSTER'        => ($topic_data['topic_poster'] == $poster_id) ? true : false,
  1741.  
  1742.                 'S_IGNORE_POST'         => ($row['hide_post']) ? true : false,
  1743.                 // www.phpBB-SEO.com SEO TOOLKIT BEGIN
  1744.                 'L_IGNORE_POST'         => ($row['hide_post']) ? sprintf($user->lang['POST_BY_FOE'], get_username_string('full', $poster_id, $row['username'], $row['user_colour'], $row['post_username']), '<a href="' . append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;p={$row['post_id']}&amp;view=show") . '#p' . $row['post_id'] . '">', '</a>') : '',
  1745.                 // www.phpBB-SEO.com SEO TOOLKIT END
  1746.                                 // Start Ultimate Points
  1747.                 'L_MOD_USER_POINTS'             => ($auth->acl_get('a_') || $auth->acl_get('m_chg_points')) ? sprintf($user->lang['POINTS_MODIFY']) : '',
  1748.                 'U_POINTS_MODIFY'               => ($auth->acl_get('a_') || $auth->acl_get('m_chg_points')) ? append_sid("{$phpbb_root_path}points.$phpEx", "mode=points_edit&amp;user_id=".$poster_id."&amp;adm_points=1&amp;post_id=".$row['post_id'])  : '',
  1749.                 'L_BANK_USER_POINTS'    => ($auth->acl_get('a_') || $auth->acl_get('m_chg_bank')) ? sprintf($user->lang['POINTS_MODIFY']) : '',
  1750.                 'U_BANK_MODIFY'                 => ($auth->acl_get('a_') || $auth->acl_get('m_chg_bank')) ? append_sid("{$phpbb_root_path}points.$phpEx", "mode=bank_edit&amp;user_id=".$poster_id."&amp;adm_points=1&amp;post_id=".$row['post_id'])  : '',
  1751.                 'L_DONATE'                              => ($auth->acl_get('u_use_points')) ? sprintf($user->lang['POINTS_DONATE']) : '',
  1752.                 'U_POINTS_DONATE'               => ($auth->acl_get('u_use_points')) ? append_sid("{$phpbb_root_path}points.$phpEx", "mode=transfer&amp;i=".$poster_id."&amp;adm_points=1&amp;post_id=".$row['post_id'])  : '',
  1753.                 'S_IS_OWN_POST'                 => ($poster_id == $user->data['user_id']) ? true : false,
  1754.                 // End Ultimate Points
  1755.         );
  1756.  
  1757.         if (isset($cp_row['row']) && sizeof($cp_row['row']))
  1758.         {
  1759.                 $postrow = array_merge($postrow, $cp_row['row']);
  1760.         }
  1761.  
  1762.         // Dump vars into template
  1763.         $template->assign_block_vars('postrow', $postrow);
  1764.  
  1765.         if (!empty($cp_row['blockrow']))
  1766.         {
  1767.                 foreach ($cp_row['blockrow'] as $field_data)
  1768.                 {
  1769.                         $template->assign_block_vars('postrow.custom_fields', $field_data);
  1770.                 }
  1771.         }
  1772.  
  1773.         // Display not already displayed Attachments for this post, we already parsed them. ;)
  1774.         if (!empty($attachments[$row['post_id']]))
  1775.         {
  1776.                 foreach ($attachments[$row['post_id']] as $attachment)
  1777.                 {
  1778.                         $template->assign_block_vars('postrow.attachment', array(
  1779.                                 'DISPLAY_ATTACHMENT'    => $attachment)
  1780.                         );
  1781.                 }
  1782.         }
  1783.  
  1784.         $prev_post_id = $row['post_id'];
  1785.  
  1786.         unset($rowset[$post_list[$i]]);
  1787.         unset($attachments[$row['post_id']]);
  1788. }
  1789. unset($rowset, $user_cache);
  1790.  
  1791. // Update topic view and if necessary attachment view counters ... but only for humans and if this is the first 'page view'
  1792. if (isset($user->data['session_page']) && !$user->data['is_bot'] && (strpos($user->data['session_page'], '&t=' . $topic_id) === false || isset($user->data['session_created'])))
  1793. {
  1794.         $sql = 'UPDATE ' . TOPICS_TABLE . '
  1795.                 SET topic_views = topic_views + 1, topic_last_view_time = ' . time() . "
  1796.                 WHERE topic_id = $topic_id";
  1797.         $db->sql_query($sql);
  1798.  
  1799.         // Update the attachment download counts
  1800.         if (sizeof($update_count))
  1801.         {
  1802.                 $sql = 'UPDATE ' . ATTACHMENTS_TABLE . '
  1803.                         SET download_count = download_count + 1
  1804.                         WHERE ' . $db->sql_in_set('attach_id', array_unique($update_count));
  1805.                 $db->sql_query($sql);
  1806.         }
  1807. }
  1808.  
  1809. // Get last post time for all global announcements
  1810. // to keep proper forums tracking
  1811. if ($topic_data['topic_type'] == POST_GLOBAL)
  1812. {
  1813.         $sql = 'SELECT topic_last_post_time as forum_last_post_time
  1814.                 FROM ' . TOPICS_TABLE . '
  1815.                 WHERE forum_id = 0
  1816.                 ORDER BY topic_last_post_time DESC';
  1817.         $result = $db->sql_query_limit($sql, 1);
  1818.         $topic_data['forum_last_post_time'] = (int) $db->sql_fetchfield('forum_last_post_time');
  1819.         $db->sql_freeresult($result);
  1820.  
  1821.         $sql = 'SELECT mark_time as forum_mark_time
  1822.                 FROM ' . FORUMS_TRACK_TABLE . '
  1823.                 WHERE forum_id = 0
  1824.                         AND user_id = ' . $user->data['user_id'];
  1825.         $result = $db->sql_query($sql);
  1826.         $topic_data['forum_mark_time'] = (int) $db->sql_fetchfield('forum_mark_time');
  1827.         $db->sql_freeresult($result);
  1828. }
  1829.  
  1830. // Only mark topic if it's currently unread. Also make sure we do not set topic tracking back if earlier pages are viewed.
  1831. if (isset($topic_tracking_info[$topic_id]) && $topic_data['topic_last_post_time'] > $topic_tracking_info[$topic_id] && $max_post_time > $topic_tracking_info[$topic_id])
  1832. {
  1833.         markread('topic', (($topic_data['topic_type'] == POST_GLOBAL) ? 0 : $forum_id), $topic_id, $max_post_time);
  1834.  
  1835.         // Update forum info
  1836.         $all_marked_read = update_forum_tracking_info((($topic_data['topic_type'] == POST_GLOBAL) ? 0 : $forum_id), $topic_data['forum_last_post_time'], (isset($topic_data['forum_mark_time'])) ? $topic_data['forum_mark_time'] : false, false);
  1837. }
  1838. else
  1839. {
  1840.         $all_marked_read = true;
  1841. }
  1842.  
  1843. // If there are absolutely no more unread posts in this forum and unread posts shown, we can savely show the #unread link
  1844. if ($all_marked_read)
  1845. {
  1846.         if ($post_unread)
  1847.         {
  1848.                 $template->assign_vars(array(
  1849.                         'U_VIEW_UNREAD_POST'    => '#unread',
  1850.                 ));
  1851.         }
  1852.         else if (isset($topic_tracking_info[$topic_id]) && $topic_data['topic_last_post_time'] > $topic_tracking_info[$topic_id])
  1853.         {
  1854.                 $template->assign_vars(array(
  1855.                         'U_VIEW_UNREAD_POST'    => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;view=unread") . '#unread',
  1856.                 ));
  1857.         }
  1858. }
  1859. else if (!$all_marked_read)
  1860. {
  1861.         $last_page = ((floor($start / $config['posts_per_page']) + 1) == max(ceil($total_posts / $config['posts_per_page']), 1)) ? true : false;
  1862.  
  1863.         // What can happen is that we are at the last displayed page. If so, we also display the #unread link based in $post_unread
  1864.         if ($last_page && $post_unread)
  1865.         {
  1866.                 $template->assign_vars(array(
  1867.                         'U_VIEW_UNREAD_POST'    => '#unread',
  1868.                 ));
  1869.         }
  1870.         else if (!$last_page)
  1871.         {
  1872.                 $template->assign_vars(array(
  1873.                         'U_VIEW_UNREAD_POST'    => append_sid("{$phpbb_root_path}viewtopic.$phpEx", "f=$forum_id&amp;t=$topic_id&amp;view=unread") . '#unread',
  1874.                 ));
  1875.         }
  1876. }
  1877.  
  1878. // let's set up quick_reply
  1879. $s_quick_reply = false;
  1880. if ($user->data['is_registered'] && $config['allow_quick_reply'] && ($topic_data['forum_flags'] & FORUM_FLAG_QUICK_REPLY) && $auth->acl_get('f_reply', $forum_id))
  1881. {
  1882.         // Quick reply enabled forum
  1883.         $s_quick_reply = (($topic_data['forum_status'] == ITEM_UNLOCKED && $topic_data['topic_status'] == ITEM_UNLOCKED) || $auth->acl_get('m_edit', $forum_id)) ? true : false;
  1884. }
  1885.  
  1886. if ($s_can_vote || $s_quick_reply)
  1887. {
  1888.         add_form_key('posting');
  1889.  
  1890.         if ($s_quick_reply)
  1891.         {
  1892.                 $s_attach_sig   = $config['allow_sig'] && $user->optionget('attachsig') && $auth->acl_get('f_sigs', $forum_id) && $auth->acl_get('u_sig');
  1893.                 $s_smilies              = $config['allow_smilies'] && $user->optionget('smilies') && $auth->acl_get('f_smilies', $forum_id);
  1894.                 $s_bbcode               = $config['allow_bbcode'] && $user->optionget('bbcode') && $auth->acl_get('f_bbcode', $forum_id);
  1895.                 $s_notify               = $config['allow_topic_notify'] && ($user->data['user_notify'] || $s_watching_topic['is_watching']);
  1896.  
  1897.                 $qr_hidden_fields = array(
  1898.                         'topic_cur_post_id'             => (int) $topic_data['topic_last_post_id'],
  1899.                         'lastclick'                             => (int) time(),
  1900.                         'topic_id'                              => (int) $topic_data['topic_id'],
  1901.                         'forum_id'                              => (int) $forum_id,
  1902.                 );
  1903.  
  1904.                 // Originally we use checkboxes and check with isset(), so we only provide them if they would be checked
  1905.                 (!$s_bbcode)                                    ? $qr_hidden_fields['disable_bbcode'] = 1               : true;
  1906.                 (!$s_smilies)                                   ? $qr_hidden_fields['disable_smilies'] = 1              : true;
  1907.                 (!$config['allow_post_links'])  ? $qr_hidden_fields['disable_magic_url'] = 1    : true;
  1908.                 ($s_attach_sig)                                 ? $qr_hidden_fields['attach_sig'] = 1                   : true;
  1909.                 ($s_notify)                                             ? $qr_hidden_fields['notify'] = 1                               : true;
  1910.                 ($topic_data['topic_status'] == ITEM_LOCKED) ? $qr_hidden_fields['lock_topic'] = 1 : true;
  1911.  
  1912.                 $template->assign_vars(array(
  1913.                         'S_QUICK_REPLY'                 => true,
  1914.                         'U_QR_ACTION'                   => append_sid("{$phpbb_root_path}posting.$phpEx", "mode=reply&amp;f=$forum_id&amp;t=$topic_id"),
  1915.                         'QR_HIDDEN_FIELDS'              => build_hidden_fields($qr_hidden_fields),
  1916.                         'SUBJECT'                               => 'Re: ' . censor_text($topic_data['topic_title']),
  1917.                 ));
  1918.         }
  1919. }
  1920. // now I have the urge to wash my hands :(
  1921.  
  1922.  
  1923. // We overwrite $_REQUEST['f'] if there is no forum specified
  1924. // to be able to display the correct online list.
  1925. // One downside is that the user currently viewing this topic/post is not taken into account.
  1926. if (empty($_REQUEST['f']))
  1927. {
  1928.         $_REQUEST['f'] = $forum_id;
  1929. }
  1930.  
  1931. // We need to do the same with the topic_id. See #53025.
  1932. if (empty($_REQUEST['t']) && !empty($topic_id))
  1933. {
  1934.         $_REQUEST['t'] = $topic_id;
  1935. }
  1936.  
  1937. // Output the page
  1938. page_header($user->lang['VIEW_TOPIC'] . ' - ' . $topic_data['topic_title'], true, $forum_id);
  1939.  
  1940. $template->set_filenames(array(
  1941.         'body' => ($view == 'print') ? 'viewtopic_print.html' : 'viewtopic_body.html')
  1942. );
  1943. make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"), $forum_id);
  1944.  
  1945. page_footer();
  1946.  
  1947. ?>