[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/ -> viewtopic.php (source)

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


Generated: Wed Oct 2 15:03:47 2013 Cross-referenced by PHPXref 0.7.1