Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

viewforum.php

Zuletzt modifiziert: 02.04.2025, 15:01 - Dateigröße: 41.02 KiB


0001  <?php
0002  /**
0003  *
0004  * This file is part of the phpBB Forum Software package.
0005  *
0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
0007  * @license GNU General Public License, version 2 (GPL-2.0)
0008  *
0009  * For full copyright and license information, please see
0010  * the docs/CREDITS.txt file.
0011  *
0012  */
0013   
0014  /**
0015  * @ignore
0016  */
0017  define('IN_PHPBB', true);
0018  $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
0019  $phpEx = substr(strrchr(__FILE__, '.'), 1);
0020  include($phpbb_root_path . 'common.' . $phpEx);
0021  include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
0022   
0023  // Start session
0024  $user->session_begin();
0025  $auth->acl($user->data);
0026   
0027  // Start initial var setup
0028  $forum_id    = $request->variable('f', 0);
0029  $mark_read    = $request->variable('mark', '');
0030  $start        = $request->variable('start', 0);
0031   
0032  $default_sort_days    = (!empty($user->data['user_topic_show_days'])) ? $user->data['user_topic_show_days'] : 0;
0033  $default_sort_key    = (!empty($user->data['user_topic_sortby_type'])) ? $user->data['user_topic_sortby_type'] : 't';
0034  $default_sort_dir    = (!empty($user->data['user_topic_sortby_dir'])) ? $user->data['user_topic_sortby_dir'] : 'd';
0035   
0036  $sort_days    = $request->variable('st', $default_sort_days);
0037  $sort_key    = $request->variable('sk', $default_sort_key);
0038  $sort_dir    = $request->variable('sd', $default_sort_dir);
0039   
0040  /* @var $pagination \phpbb\pagination */
0041  $pagination = $phpbb_container->get('pagination');
0042   
0043  // Check if the user has actually sent a forum ID with his/her request
0044  // If not give them a nice error page.
0045  if (!$forum_id)
0046  {
0047      trigger_error('NO_FORUM');
0048  }
0049   
0050  $sql_ary = [
0051      'SELECT'    => 'f.*',
0052      'FROM'        => [
0053          FORUMS_TABLE        => 'f',
0054      ],
0055      'WHERE'        => 'f.forum_id = ' . $forum_id,
0056  ];
0057   
0058  $lastread_select = '';
0059   
0060  // Grab appropriate forum data
0061  if ($config['load_db_lastread'] && $user->data['is_registered'])
0062  {
0063      $sql_ary['LEFT_JOIN'][] = [
0064          'FROM' => [FORUMS_TRACK_TABLE => 'ft'],
0065          'ON' => 'ft.user_id = ' . $user->data['user_id'] . ' AND ft.forum_id = f.forum_id',
0066      ];
0067      $sql_ary['SELECT'] .= ', ft.mark_time';
0068  }
0069   
0070  if ($user->data['is_registered'])
0071  {
0072      $sql_ary['LEFT_JOIN'][] = [
0073          'FROM' => [FORUMS_WATCH_TABLE => 'fw'],
0074          'ON' => 'fw.forum_id = f.forum_id AND fw.user_id = ' . $user->data['user_id'],
0075      ];
0076      $sql_ary['SELECT'] .= ', fw.notify_status';
0077  }
0078   
0079  /**
0080   * You can use this event to modify the sql that selects the forum on the viewforum page.
0081   *
0082   * @event core.viewforum_modify_sql
0083   * @var array    sql_ary        The SQL array to get the data for a forum
0084   * @since 3.3.14-RC1
0085   */
0086  $vars = ['sql_ary'];
0087  extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_sql', compact($vars)));
0088  $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
0089  $forum_data = $db->sql_fetchrow($result);
0090  $db->sql_freeresult($result);
0091   
0092  if (!$forum_data)
0093  {
0094      trigger_error('NO_FORUM');
0095  }
0096   
0097   
0098  // Configure style, language, etc.
0099  $user->setup('viewforum', $forum_data['forum_style']);
0100   
0101  // Redirect to login upon emailed notification links
0102  if (isset($_GET['e']) && !$user->data['is_registered'])
0103  {
0104      login_box('', $user->lang['LOGIN_NOTIFY_FORUM']);
0105  }
0106   
0107  // Permissions check
0108  if (!$auth->acl_gets('f_list', 'f_list_topics', 'f_read', $forum_id) || ($forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'] && !$auth->acl_get('f_read', $forum_id)))
0109  {
0110      if ($user->data['user_id'] != ANONYMOUS)
0111      {
0112          send_status_line(403, 'Forbidden');
0113          trigger_error('SORRY_AUTH_READ');
0114      }
0115   
0116      login_box('', $user->lang['LOGIN_VIEWFORUM']);
0117  }
0118   
0119  // Forum is passworded ... check whether access has been granted to this
0120  // user this session, if not show login box
0121  if ($forum_data['forum_password'])
0122  {
0123      login_forum_box($forum_data);
0124  }
0125   
0126  // Is this forum a link? ... User got here either because the
0127  // number of clicks is being tracked or they guessed the id
0128  if ($forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'])
0129  {
0130      // Does it have click tracking enabled?
0131      if ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK)
0132      {
0133          $sql = 'UPDATE ' . FORUMS_TABLE . '
0134              SET forum_posts_approved = forum_posts_approved + 1
0135              WHERE forum_id = ' . $forum_id;
0136          $db->sql_query($sql);
0137      }
0138   
0139      // We redirect to the url. The third parameter indicates that external redirects are allowed.
0140      redirect($forum_data['forum_link'], false, true);
0141      return;
0142  }
0143   
0144  // Build navigation links
0145  generate_forum_nav($forum_data);
0146   
0147  // Forum Rules
0148  if ($auth->acl_get('f_read', $forum_id))
0149  {
0150      generate_forum_rules($forum_data);
0151  }
0152   
0153  // Do we have subforums?
0154  $active_forum_ary = $moderators = array();
0155   
0156  if ($forum_data['left_id'] != $forum_data['right_id'] - 1)
0157  {
0158      list($active_forum_ary, $moderators) = display_forums($forum_data, $config['load_moderators'], $config['load_moderators']);
0159  }
0160  else
0161  {
0162      $template->assign_var('S_HAS_SUBFORUM', false);
0163      if ($config['load_moderators'])
0164      {
0165          get_moderators($moderators, $forum_id);
0166      }
0167  }
0168   
0169  // Is a forum specific topic count required?
0170  if ($forum_data['forum_topics_per_page'])
0171  {
0172      $config['topics_per_page'] = $forum_data['forum_topics_per_page'];
0173  }
0174   
0175  /* @var $phpbb_content_visibility \phpbb\content_visibility */
0176  $phpbb_content_visibility = $phpbb_container->get('content.visibility');
0177   
0178  // Dump out the page header and load viewforum template
0179  $topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id);
0180  $start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count);
0181   
0182  $page_title = $forum_data['forum_name'] . ($start ? ' - ' . $user->lang('PAGE_TITLE_NUMBER', $pagination->get_on_page($config['topics_per_page'], $start)) : '');
0183   
0184  /**
0185  * You can use this event to modify the page title of the viewforum page
0186  *
0187  * @event core.viewforum_modify_page_title
0188  * @var    string    page_title        Title of the viewforum page
0189  * @var    array    forum_data        Array with forum data
0190  * @var    int        forum_id        The forum ID
0191  * @var    int        start            Start offset used to calculate the page
0192  * @since 3.2.2-RC1
0193  */
0194  $vars = array('page_title', 'forum_data', 'forum_id', 'start');
0195  extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_page_title', compact($vars)));
0196   
0197  page_header($page_title, true, $forum_id);
0198   
0199  $template->set_filenames(array(
0200      'body' => 'viewforum_body.html')
0201  );
0202   
0203  make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"), $forum_id);
0204   
0205  $template->assign_vars(array(
0206      'U_VIEW_FORUM'            => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . (($start == 0) ? '' : "&amp;start=$start")),
0207  ));
0208   
0209  // Not postable forum or showing active topics?
0210  if (!($forum_data['forum_type'] == FORUM_POST || (($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && $forum_data['forum_type'] == FORUM_CAT)))
0211  {
0212      page_footer();
0213  }
0214   
0215  // Ok, if someone has only list-access, we only display the forum list.
0216  // We also make this circumstance available to the template in case we want to display a notice. ;)
0217  if (!$auth->acl_gets('f_read', 'f_list_topics', $forum_id))
0218  {
0219      $template->assign_vars(array(
0220          'S_NO_READ_ACCESS'        => true,
0221      ));
0222   
0223      page_footer();
0224  }
0225   
0226  // Handle marking posts
0227  if ($mark_read == 'topics')
0228  {
0229      $token = $request->variable('hash', '');
0230      if (check_link_hash($token, 'global'))
0231      {
0232          markread('topics', array($forum_id), false, $request->variable('mark_time', 0));
0233      }
0234      $redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id);
0235      meta_refresh(3, $redirect_url);
0236   
0237      if ($request->is_ajax())
0238      {
0239          // Tell the ajax script what language vars and URL need to be replaced
0240          $data = array(
0241              'NO_UNREAD_POSTS'    => $user->lang['NO_UNREAD_POSTS'],
0242              'UNREAD_POSTS'        => $user->lang['UNREAD_POSTS'],
0243              'U_MARK_TOPICS'        => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&f=$forum_id&mark=topics&mark_time=" . time(), false) : '',
0244              'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
0245              'MESSAGE_TEXT'        => $user->lang['TOPICS_MARKED']
0246          );
0247          $json_response = new \phpbb\json_response();
0248          $json_response->send($data);
0249      }
0250   
0251      trigger_error($user->lang['TOPICS_MARKED'] . '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect_url . '">', '</a>'));
0252  }
0253   
0254  // Do the forum Prune thang - cron type job ...
0255  if (!$config['use_system_cron'])
0256  {
0257      /* @var $cron \phpbb\cron\manager */
0258      $cron = $phpbb_container->get('cron.manager');
0259   
0260      $task = $cron->find_task('cron.task.core.prune_forum');
0261      $task->set_forum_data($forum_data);
0262   
0263      if ($task->is_ready())
0264      {
0265          $cron_task_tag = $task->get_html_tag();
0266          $template->assign_var('RUN_CRON_TASK', $cron_task_tag);
0267      }
0268      else
0269      {
0270          // See if we should prune the shadow topics instead
0271          $task = $cron->find_task('cron.task.core.prune_shadow_topics');
0272          $task->set_forum_data($forum_data);
0273   
0274          if ($task->is_ready())
0275          {
0276              $cron_task_tag = $task->get_html_tag();
0277              $template->assign_var('RUN_CRON_TASK', $cron_task_tag);
0278          }
0279      }
0280  }
0281   
0282  // Forum rules and subscription info
0283  $s_watching_forum = array(
0284      'link'            => '',
0285      'link_toggle'    => '',
0286      'title'            => '',
0287      'title_toggle'    => '',
0288      'is_watching'    => false,
0289  );
0290   
0291  if ($config['allow_forum_notify'] && $forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_subscribe', $forum_id) || $user->data['user_id'] == ANONYMOUS))
0292  {
0293      $notify_status = (isset($forum_data['notify_status'])) ? $forum_data['notify_status'] : NULL;
0294      watch_topic_forum('forum', $s_watching_forum, $user->data['user_id'], $forum_id, 0, $notify_status, $start, $forum_data['forum_name']);
0295  }
0296   
0297  $s_forum_rules = '';
0298  gen_forum_auth_level('forum', $forum_id, $forum_data['forum_status']);
0299   
0300  // Topic ordering options
0301  $limit_days = array(0 => $user->lang['ALL_TOPICS'], 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']);
0302   
0303  $sort_by_text = array('a' => $user->lang['AUTHOR'], 't' => $user->lang['POST_TIME'], 'r' => $user->lang['REPLIES'], 's' => $user->lang['SUBJECT'], 'v' => $user->lang['VIEWS']);
0304  $sort_by_sql = array('a' => 't.topic_first_poster_name', 't' => array('t.topic_last_post_time', 't.topic_last_post_id'), 'r' => (($auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'), 's' => 'LOWER(t.topic_title)', 'v' => 't.topic_views');
0305   
0306  /**
0307   * Modify the topic ordering if needed
0308   *
0309   * @event core.viewforum_modify_topic_ordering
0310   * @var array    sort_by_text    Topic ordering options
0311   * @var array    sort_by_sql        Topic orderings options SQL equivalent
0312   * @since 3.2.5-RC1
0313   */
0314  $vars = array(
0315      'sort_by_text',
0316      'sort_by_sql',
0317  );
0318  extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topic_ordering', compact($vars)));
0319   
0320  $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
0321  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);
0322   
0323  // Limit topics to certain time frame, obtain correct topic count
0324  if ($sort_days)
0325  {
0326      $min_post_time = time() - ($sort_days * 86400);
0327   
0328      $sql_array = array(
0329          'SELECT'    => 'COUNT(t.topic_id) AS num_topics',
0330          'FROM'        => array(
0331              TOPICS_TABLE    => 't',
0332          ),
0333          'WHERE'        => 't.forum_id = ' . $forum_id . '
0334              AND (t.topic_last_post_time >= ' . $min_post_time . '
0335                  OR t.topic_type = ' . POST_ANNOUNCE . '
0336                  OR t.topic_type = ' . POST_GLOBAL . ')
0337              AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.'),
0338      );
0339   
0340      /**
0341      * Modify the sort data SQL query for getting additional fields if needed
0342      *
0343      * @event core.viewforum_modify_sort_data_sql
0344      * @var int        forum_id        The forum_id whose topics are being listed
0345      * @var int        start            Variable containing start for pagination
0346      * @var int        sort_days        The oldest topic displayable in elapsed days
0347      * @var string    sort_key        The sorting by. It is one of the first character of (in low case):
0348      *                                Author, Post time, Replies, Subject, Views
0349      * @var string    sort_dir        Either "a" for ascending or "d" for descending
0350      * @var array    sql_array        The SQL array to get the data of all topics
0351      * @since 3.1.9-RC1
0352      */
0353      $vars = array(
0354          'forum_id',
0355          'start',
0356          'sort_days',
0357          'sort_key',
0358          'sort_dir',
0359          'sql_array',
0360      );
0361      extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_sort_data_sql', compact($vars)));
0362   
0363      $result = $db->sql_query($db->sql_build_query('SELECT', $sql_array));
0364      $topics_count = (int) $db->sql_fetchfield('num_topics');
0365      $db->sql_freeresult($result);
0366   
0367      if (isset($_POST['sort']))
0368      {
0369          $start = 0;
0370      }
0371      $sql_limit_time = "AND t.topic_last_post_time >= $min_post_time";
0372   
0373      // Make sure we have information about day selection ready
0374      $template->assign_var('S_SORT_DAYS', true);
0375  }
0376  else
0377  {
0378      $sql_limit_time = '';
0379  }
0380   
0381  // Basic pagewide vars
0382  $post_alt = ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['FORUM_LOCKED'] : $user->lang['POST_NEW_TOPIC'];
0383   
0384  // Display active topics?
0385  $s_display_active = ($forum_data['forum_type'] == FORUM_CAT && ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS)) ? true : false;
0386   
0387  $s_search_hidden_fields = array('fid' => array($forum_id));
0388  if ($_SID)
0389  {
0390      $s_search_hidden_fields['sid'] = $_SID;
0391  }
0392   
0393  if (!empty($_EXTRA_URL))
0394  {
0395      foreach ($_EXTRA_URL as $url_param)
0396      {
0397          $url_param = explode('=', $url_param, 2);
0398          $s_search_hidden_fields[$url_param[0]] = $url_param[1];
0399      }
0400  }
0401   
0402  $template->assign_vars(array(
0403      'MODERATORS'    => (!empty($moderators[$forum_id])) ? implode($user->lang['COMMA_SEPARATOR'], $moderators[$forum_id]) : '',
0404   
0405      'POST_IMG'                    => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', $post_alt) : $user->img('button_topic_new', $post_alt),
0406      'NEWEST_POST_IMG'            => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
0407      'LAST_POST_IMG'                => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
0408      'FOLDER_IMG'                => $user->img('topic_read', 'NO_UNREAD_POSTS'),
0409      'FOLDER_UNREAD_IMG'            => $user->img('topic_unread', 'UNREAD_POSTS'),
0410      'FOLDER_HOT_IMG'            => $user->img('topic_read_hot', 'NO_UNREAD_POSTS_HOT'),
0411      'FOLDER_HOT_UNREAD_IMG'        => $user->img('topic_unread_hot', 'UNREAD_POSTS_HOT'),
0412      'FOLDER_LOCKED_IMG'            => $user->img('topic_read_locked', 'NO_UNREAD_POSTS_LOCKED'),
0413      'FOLDER_LOCKED_UNREAD_IMG'    => $user->img('topic_unread_locked', 'UNREAD_POSTS_LOCKED'),
0414      'FOLDER_STICKY_IMG'            => $user->img('sticky_read', 'POST_STICKY'),
0415      'FOLDER_STICKY_UNREAD_IMG'    => $user->img('sticky_unread', 'POST_STICKY'),
0416      'FOLDER_ANNOUNCE_IMG'        => $user->img('announce_read', 'POST_ANNOUNCEMENT'),
0417      'FOLDER_ANNOUNCE_UNREAD_IMG'=> $user->img('announce_unread', 'POST_ANNOUNCEMENT'),
0418      'FOLDER_MOVED_IMG'            => $user->img('topic_moved', 'TOPIC_MOVED'),
0419      'REPORTED_IMG'                => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
0420      'UNAPPROVED_IMG'            => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
0421      'DELETED_IMG'                => $user->img('icon_topic_deleted', 'TOPIC_DELETED'),
0422      'POLL_IMG'                    => $user->img('icon_topic_poll', 'TOPIC_POLL'),
0423      'GOTO_PAGE_IMG'                => $user->img('icon_post_target', 'GOTO_PAGE'),
0424   
0425      'L_NO_TOPICS'             => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['POST_FORUM_LOCKED'] : $user->lang['NO_TOPICS'],
0426   
0427      'S_DISPLAY_POST_INFO'    => ($forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false,
0428   
0429      'S_IS_POSTABLE'            => ($forum_data['forum_type'] == FORUM_POST) ? true : false,
0430      'S_USER_CAN_POST'        => ($auth->acl_get('f_post', $forum_id)) ? true : false,
0431      'S_DISPLAY_ACTIVE'        => $s_display_active,
0432      'S_SELECT_SORT_DIR'        => $s_sort_dir,
0433      'S_SELECT_SORT_KEY'        => $s_sort_key,
0434      'S_SELECT_SORT_DAYS'    => $s_limit_days,
0435      'S_TOPIC_ICONS'            => ($s_display_active && count($active_forum_ary)) ? max($active_forum_ary['enable_icons']) : (($forum_data['enable_icons']) ? true : false),
0436      'U_WATCH_FORUM_LINK'    => $s_watching_forum['link'],
0437      'U_WATCH_FORUM_TOGGLE'    => $s_watching_forum['link_toggle'],
0438      'S_WATCH_FORUM_TITLE'    => $s_watching_forum['title'],
0439      'S_WATCH_FORUM_TOGGLE'    => $s_watching_forum['title_toggle'],
0440      'S_WATCHING_FORUM'        => $s_watching_forum['is_watching'],
0441      'S_FORUM_ACTION'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . (($start == 0) ? '' : "&amp;start=$start")),
0442      'S_DISPLAY_SEARCHBOX'    => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false,
0443      'S_SEARCHBOX_ACTION'    => append_sid("{$phpbb_root_path}search.$phpEx"),
0444      'S_SEARCH_LOCAL_HIDDEN_FIELDS'    => build_hidden_fields($s_search_hidden_fields),
0445      'S_SINGLE_MODERATOR'    => (!empty($moderators[$forum_id]) && count($moderators[$forum_id]) > 1) ? false : true,
0446      'S_IS_LOCKED'            => ($forum_data['forum_status'] == ITEM_LOCKED) ? true : false,
0447      'S_VIEWFORUM'            => true,
0448   
0449      'U_MCP'                => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&amp;i=main&amp;mode=forum_view", true, $user->session_id) : '',
0450      '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) : '',
0451      'U_VIEW_FORUM'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : '') . (($start == 0) ? '' : "&amp;start=$start")),
0452      'U_CANONICAL'        => generate_board_url() . '/' . append_sid("viewforum.$phpEx", "f=$forum_id" . (($start) ? "&amp;start=$start" : ''), true, ''),
0453      'U_MARK_TOPICS'        => ($user->data['is_registered'] || $config['load_anon_lastread']) ? append_sid("{$phpbb_root_path}viewforum.$phpEx", 'hash=' . generate_link_hash('global') . "&amp;f=$forum_id&amp;mark=topics&amp;mark_time=" . time()) : '',
0454      'U_SEARCH_FORUM'    => append_sid("{$phpbb_root_path}search.$phpEx", 'fid%5B%5D=' . $forum_id),
0455  ));
0456   
0457  // Grab icons
0458  $icons = $cache->obtain_icons();
0459   
0460  // Grab all topic data
0461  $rowset = $announcement_list = $topic_list = $global_announce_forums = array();
0462   
0463  $sql_array = array(
0464      'SELECT'    => 't.*',
0465      'FROM'        => array(
0466          TOPICS_TABLE        => 't'
0467      ),
0468      'LEFT_JOIN'    => array(),
0469  );
0470   
0471  /**
0472  * Event to modify the SQL query before the topic data is retrieved
0473  *
0474  * It may also be used to override the above assigned template vars
0475  *
0476  * @event core.viewforum_get_topic_data
0477  * @var    array    forum_data            Array with forum data
0478  * @var    array    sql_array            The SQL array to get the data of all topics
0479  * @var    int        forum_id            The forum_id whose topics are being listed
0480  * @var    int        topics_count        The total number of topics for display
0481  * @var    int        sort_days            The oldest topic displayable in elapsed days
0482  * @var    string    sort_key            The sorting by. It is one of the first character of (in low case):
0483  *                                    Author, Post time, Replies, Subject, Views
0484  * @var    string    sort_dir            Either "a" for ascending or "d" for descending
0485  * @since 3.1.0-a1
0486  * @changed 3.1.0-RC4 Added forum_data var
0487  * @changed 3.1.4-RC1 Added forum_id, topics_count, sort_days, sort_key and sort_dir vars
0488  * @changed 3.1.9-RC1 Fix types of properties
0489  */
0490  $vars = array(
0491      'forum_data',
0492      'sql_array',
0493      'forum_id',
0494      'topics_count',
0495      'sort_days',
0496      'sort_key',
0497      'sort_dir',
0498  );
0499  extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_data', compact($vars)));
0500   
0501  $sql_approved = ' AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.');
0502   
0503  if ($user->data['is_registered'])
0504  {
0505      if ($config['load_db_track'])
0506      {
0507          $sql_array['LEFT_JOIN'][] = array('FROM' => array(TOPICS_POSTED_TABLE => 'tp'), 'ON' => 'tp.topic_id = t.topic_id AND tp.user_id = ' . $user->data['user_id']);
0508          $sql_array['SELECT'] .= ', tp.topic_posted';
0509      }
0510   
0511      if ($config['load_db_lastread'])
0512      {
0513          $sql_array['LEFT_JOIN'][] = array('FROM' => array(TOPICS_TRACK_TABLE => 'tt'), 'ON' => 'tt.topic_id = t.topic_id AND tt.user_id = ' . $user->data['user_id']);
0514          $sql_array['SELECT'] .= ', tt.mark_time';
0515   
0516          if ($s_display_active && count($active_forum_ary))
0517          {
0518              $sql_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TRACK_TABLE => 'ft'), 'ON' => 'ft.forum_id = t.forum_id AND ft.user_id = ' . $user->data['user_id']);
0519              $sql_array['SELECT'] .= ', ft.mark_time AS forum_mark_time';
0520          }
0521      }
0522  }
0523   
0524  if ($forum_data['forum_type'] == FORUM_POST)
0525  {
0526      // Get global announcement forums
0527      $g_forum_ary = $auth->acl_getf('f_read', true);
0528      $g_forum_ary = array_unique(array_keys($g_forum_ary));
0529   
0530      $sql_anounce_array['LEFT_JOIN'] = $sql_array['LEFT_JOIN'];
0531      $sql_anounce_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TABLE => 'f'), 'ON' => 'f.forum_id = t.forum_id');
0532      $sql_anounce_array['SELECT'] = $sql_array['SELECT'] . ', f.forum_name';
0533   
0534      // Obtain announcements ... removed sort ordering, sort by time in all cases
0535      $sql_ary = array(
0536          'SELECT'    => $sql_anounce_array['SELECT'],
0537          'FROM'        => $sql_array['FROM'],
0538          'LEFT_JOIN'    => $sql_anounce_array['LEFT_JOIN'],
0539   
0540          'WHERE'        => '(t.forum_id = ' . $forum_id . '
0541                  AND t.topic_type = ' . POST_ANNOUNCE . ') OR
0542              (' . $db->sql_in_set('t.forum_id', $g_forum_ary, false, true) . '
0543                  AND t.topic_type = ' . POST_GLOBAL . ')',
0544   
0545          'ORDER_BY'    => 't.topic_time DESC',
0546      );
0547   
0548      /**
0549      * Event to modify the SQL query before the announcement topic ids data is retrieved
0550      *
0551      * @event core.viewforum_get_announcement_topic_ids_data
0552      * @var    array    forum_data            Data about the forum
0553      * @var    array    g_forum_ary            Global announcement forums array
0554      * @var    array    sql_anounce_array    SQL announcement array
0555      * @var    array    sql_ary                SQL query array to get the announcement topic ids data
0556      * @var    int        forum_id            The forum ID
0557      *
0558      * @since 3.1.10-RC1
0559      */
0560      $vars = array(
0561          'forum_data',
0562          'g_forum_ary',
0563          'sql_anounce_array',
0564          'sql_ary',
0565          'forum_id',
0566      );
0567      extract($phpbb_dispatcher->trigger_event('core.viewforum_get_announcement_topic_ids_data', compact($vars)));
0568   
0569      $sql = $db->sql_build_query('SELECT', $sql_ary);
0570      $result = $db->sql_query($sql);
0571   
0572      while ($row = $db->sql_fetchrow($result))
0573      {
0574          if (!$phpbb_content_visibility->is_visible('topic', $row['forum_id'], $row))
0575          {
0576              // Do not display announcements that are waiting for approval or soft deleted.
0577              continue;
0578          }
0579   
0580          $rowset[$row['topic_id']] = $row;
0581          $announcement_list[] = $row['topic_id'];
0582   
0583          if ($forum_id != $row['forum_id'])
0584          {
0585              $topics_count++;
0586              $global_announce_forums[] = $row['forum_id'];
0587          }
0588      }
0589      $db->sql_freeresult($result);
0590  }
0591   
0592  $forum_tracking_info = array();
0593   
0594  if ($user->data['is_registered'] && $config['load_db_lastread'])
0595  {
0596      $forum_tracking_info[$forum_id] = $forum_data['mark_time'];
0597   
0598      if (!empty($global_announce_forums))
0599      {
0600          $sql = 'SELECT forum_id, mark_time
0601              FROM ' . FORUMS_TRACK_TABLE . '
0602              WHERE ' . $db->sql_in_set('forum_id', $global_announce_forums) . '
0603                  AND user_id = ' . $user->data['user_id'];
0604          $result = $db->sql_query($sql);
0605   
0606          while ($row = $db->sql_fetchrow($result))
0607          {
0608              $forum_tracking_info[$row['forum_id']] = $row['mark_time'];
0609          }
0610          $db->sql_freeresult($result);
0611      }
0612  }
0613   
0614  // If the user is trying to reach late pages, start searching from the end
0615  $store_reverse = false;
0616  $sql_limit = $config['topics_per_page'];
0617  if ($start > $topics_count / 2)
0618  {
0619      $store_reverse = true;
0620   
0621      // Select the sort order
0622      $direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
0623   
0624      $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count - count($announcement_list));
0625      $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count - count($announcement_list));
0626  }
0627  else
0628  {
0629      // Select the sort order
0630      $direction = (($sort_dir == 'd') ? 'DESC' : 'ASC');
0631      $sql_start = $start;
0632  }
0633   
0634  /**
0635   * Modify the topics sort ordering if needed
0636   *
0637   * @event core.viewforum_modify_sort_direction
0638   * @var string    direction    Topics sort order
0639   * @since 3.2.5-RC1
0640   */
0641  $vars = array(
0642      'direction',
0643  );
0644  extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_sort_direction', compact($vars)));
0645   
0646  if (is_array($sort_by_sql[$sort_key]))
0647  {
0648      $sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
0649  }
0650  else
0651  {
0652      $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
0653  }
0654   
0655  if ($forum_data['forum_type'] == FORUM_POST || !count($active_forum_ary))
0656  {
0657      $sql_where = 't.forum_id = ' . $forum_id;
0658  }
0659  else if (empty($active_forum_ary['exclude_forum_id']))
0660  {
0661      $sql_where = $db->sql_in_set('t.forum_id', $active_forum_ary['forum_id']);
0662  }
0663  else
0664  {
0665      $get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']);
0666      $sql_where = (count($get_forum_ids)) ? $db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id;
0667  }
0668   
0669  // Grab just the sorted topic ids
0670  $sql_ary = array(
0671      'SELECT'    => 't.topic_id',
0672      'FROM'        => array(
0673          TOPICS_TABLE => 't',
0674      ),
0675      'WHERE'        => "$sql_where
0676          AND t.topic_type IN (" . POST_NORMAL . ', ' . POST_STICKY . ")
0677          $sql_approved
0678          $sql_limit_time",
0679      'ORDER_BY'    => 't.topic_type ' . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order,
0680  );
0681   
0682  /**
0683  * Event to modify the SQL query before the topic ids data is retrieved
0684  *
0685  * @event core.viewforum_get_topic_ids_data
0686  * @var    array    forum_data        Data about the forum
0687  * @var    array    sql_ary            SQL query array to get the topic ids data
0688  * @var    string    sql_approved    Topic visibility SQL string
0689  * @var    int        sql_limit        Number of records to select
0690  * @var    string    sql_limit_time    SQL string to limit topic_last_post_time data
0691  * @var    array    sql_sort_order    SQL sorting string
0692  * @var    int        sql_start        Offset point to start selection from
0693  * @var    string    sql_where        SQL WHERE clause string
0694  * @var    bool    store_reverse    Flag indicating if we select from the late pages
0695  *
0696  * @since 3.1.0-RC4
0697  *
0698  * @changed 3.1.3 Added forum_data
0699  */
0700  $vars = array(
0701      'forum_data',
0702      'sql_ary',
0703      'sql_approved',
0704      'sql_limit',
0705      'sql_limit_time',
0706      'sql_sort_order',
0707      'sql_start',
0708      'sql_where',
0709      'store_reverse',
0710  );
0711  extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_ids_data', compact($vars)));
0712   
0713  $sql = $db->sql_build_query('SELECT', $sql_ary);
0714  $result = $db->sql_query_limit($sql, $sql_limit, $sql_start);
0715   
0716  while ($row = $db->sql_fetchrow($result))
0717  {
0718      $topic_list[] = (int) $row['topic_id'];
0719  }
0720  $db->sql_freeresult($result);
0721   
0722  // For storing shadow topics
0723  $shadow_topic_list = array();
0724   
0725  if (count($topic_list))
0726  {
0727      // SQL array for obtaining topics/stickies
0728      $sql_array = array(
0729          'SELECT'        => $sql_array['SELECT'],
0730          'FROM'            => $sql_array['FROM'],
0731          'LEFT_JOIN'        => $sql_array['LEFT_JOIN'],
0732          'WHERE'            => $db->sql_in_set('t.topic_id', $topic_list),
0733      );
0734   
0735      /**
0736      * Event to modify the SQL query before obtaining topics/stickies
0737      *
0738      * @event core.viewforum_modify_topic_list_sql
0739      * @var    int        forum_id            The forum ID
0740      * @var    array    forum_data            Data about the forum
0741      * @var    array    topic_list            Topic ids array
0742      * @var    array    sql_array            SQL query array for obtaining topics/stickies
0743      *
0744      * @since 3.2.10-RC1
0745      * @since 3.3.1-RC1
0746      */
0747      $vars = [
0748          'forum_id',
0749          'forum_data',
0750          'topic_list',
0751          'sql_array',
0752      ];
0753      extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topic_list_sql', compact($vars)));
0754   
0755      // If store_reverse, then first obtain topics, then stickies, else the other way around...
0756      // Funnily enough you typically save one query if going from the last page to the middle (store_reverse) because
0757      // the number of stickies are not known
0758      $sql = $db->sql_build_query('SELECT', $sql_array);
0759      $result = $db->sql_query($sql);
0760   
0761      while ($row = $db->sql_fetchrow($result))
0762      {
0763          if ($row['topic_status'] == ITEM_MOVED)
0764          {
0765              $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
0766          }
0767   
0768          $rowset[$row['topic_id']] = $row;
0769      }
0770      $db->sql_freeresult($result);
0771  }
0772   
0773  // If we have some shadow topics, update the rowset to reflect their topic information
0774  if (count($shadow_topic_list))
0775  {
0776      // SQL array for obtaining shadow topics
0777      $sql_array = array(
0778          'SELECT'    => 't.*',
0779          'FROM'        => array(
0780              TOPICS_TABLE        => 't'
0781          ),
0782          'WHERE'        => $db->sql_in_set('t.topic_id', array_keys($shadow_topic_list)),
0783      );
0784   
0785      /**
0786      * Event to modify the SQL query before the shadowtopic data is retrieved
0787      *
0788      * @event core.viewforum_get_shadowtopic_data
0789      * @var    array    sql_array        SQL array to get the data of any shadowtopics
0790      * @since 3.1.0-a1
0791      */
0792      $vars = array('sql_array');
0793      extract($phpbb_dispatcher->trigger_event('core.viewforum_get_shadowtopic_data', compact($vars)));
0794   
0795      $sql = $db->sql_build_query('SELECT', $sql_array);
0796      $result = $db->sql_query($sql);
0797   
0798      while ($row = $db->sql_fetchrow($result))
0799      {
0800          $orig_topic_id = $shadow_topic_list[$row['topic_id']];
0801   
0802          // If the shadow topic is already listed within the rowset (happens for active topics for example), then do not include it...
0803          if (isset($rowset[$row['topic_id']]))
0804          {
0805              // We need to remove any trace regarding this topic. :)
0806              unset($rowset[$orig_topic_id]);
0807              unset($topic_list[array_search($orig_topic_id, $topic_list)]);
0808              $topics_count--;
0809   
0810              continue;
0811          }
0812   
0813          // Do not include those topics the user has no permission to access
0814          if (!$auth->acl_gets('f_read', 'f_list_topics', $row['forum_id']))
0815          {
0816              // We need to remove any trace regarding this topic. :)
0817              unset($rowset[$orig_topic_id]);
0818              unset($topic_list[array_search($orig_topic_id, $topic_list)]);
0819              $topics_count--;
0820   
0821              continue;
0822          }
0823   
0824          // We want to retain some values
0825          $row = array_merge($row, array(
0826              'topic_moved_id'    => $rowset[$orig_topic_id]['topic_moved_id'],
0827              'topic_status'        => $rowset[$orig_topic_id]['topic_status'],
0828              'topic_type'        => $rowset[$orig_topic_id]['topic_type'],
0829              'topic_title'        => $rowset[$orig_topic_id]['topic_title'],
0830          ));
0831   
0832          // Shadow topics are never reported
0833          $row['topic_reported'] = 0;
0834   
0835          $rowset[$orig_topic_id] = $row;
0836      }
0837      $db->sql_freeresult($result);
0838  }
0839  unset($shadow_topic_list);
0840   
0841  // Ok, adjust topics count for active topics list
0842  if ($s_display_active)
0843  {
0844      $topics_count = 1;
0845  }
0846   
0847  // We need to remove the global announcements from the forums total topic count,
0848  // otherwise the number is different from the one on the forum list
0849  $total_topic_count = $topics_count - count($announcement_list);
0850   
0851  $base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : ''));
0852  $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_topic_count, $config['topics_per_page'], $start);
0853   
0854  $template->assign_vars(array(
0855      'TOTAL_TOPICS'    => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count),
0856  ));
0857   
0858  $topic_list = ($store_reverse) ? array_merge($announcement_list, array_reverse($topic_list)) : array_merge($announcement_list, $topic_list);
0859  $topic_tracking_info = $tracking_topics = array();
0860   
0861  /**
0862  * Modify topics data before we display the viewforum page
0863  *
0864  * @event core.viewforum_modify_topics_data
0865  * @var    array    topic_list            Array with current viewforum page topic ids
0866  * @var    array    rowset                Array with topics data (in topic_id => topic_data format)
0867  * @var    int        total_topic_count    Forum's total topic count
0868  * @var    int        forum_id            Forum identifier
0869  * @since 3.1.0-b3
0870  * @changed 3.1.11-RC1 Added forum_id
0871  */
0872  $vars = array('topic_list', 'rowset', 'total_topic_count', 'forum_id');
0873  extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topics_data', compact($vars)));
0874   
0875  // Okay, lets dump out the page ...
0876  if (count($topic_list))
0877  {
0878      $mark_forum_read = true;
0879      $mark_time_forum = 0;
0880   
0881      // Generate topic forum list...
0882      $topic_forum_list = array();
0883      foreach ($rowset as $t_id => $row)
0884      {
0885          if (isset($forum_tracking_info[$row['forum_id']]))
0886          {
0887              $row['forum_mark_time'] = $forum_tracking_info[$row['forum_id']];
0888          }
0889   
0890          $topic_forum_list[$row['forum_id']]['forum_mark_time'] = ($config['load_db_lastread'] && $user->data['is_registered'] && isset($row['forum_mark_time'])) ? $row['forum_mark_time'] : 0;
0891          $topic_forum_list[$row['forum_id']]['topics'][] = (int) $t_id;
0892      }
0893   
0894      if ($config['load_db_lastread'] && $user->data['is_registered'])
0895      {
0896          foreach ($topic_forum_list as $f_id => $topic_row)
0897          {
0898              $topic_tracking_info += get_topic_tracking($f_id, $topic_row['topics'], $rowset, array($f_id => $topic_row['forum_mark_time']));
0899          }
0900      }
0901      else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0902      {
0903          foreach ($topic_forum_list as $f_id => $topic_row)
0904          {
0905              $topic_tracking_info += get_complete_topic_tracking($f_id, $topic_row['topics']);
0906          }
0907      }
0908   
0909      unset($topic_forum_list);
0910   
0911      if (!$s_display_active)
0912      {
0913          if ($config['load_db_lastread'] && $user->data['is_registered'])
0914          {
0915              $mark_time_forum = (!empty($forum_data['mark_time'])) ? $forum_data['mark_time'] : $user->data['user_lastmark'];
0916          }
0917          else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0918          {
0919              if (!$user->data['is_registered'])
0920              {
0921                  $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
0922              }
0923              $mark_time_forum = (isset($tracking_topics['f'][$forum_id])) ? (int) (base_convert($tracking_topics['f'][$forum_id], 36, 10) + $config['board_startdate']) : $user->data['user_lastmark'];
0924          }
0925      }
0926   
0927      $s_type_switch = 0;
0928      foreach ($topic_list as $topic_id)
0929      {
0930          $row = &$rowset[$topic_id];
0931   
0932          $topic_forum_id = ($row['forum_id']) ? (int) $row['forum_id'] : $forum_id;
0933   
0934          // This will allow the style designer to output a different header
0935          // or even separate the list of announcements from sticky and normal topics
0936          $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
0937   
0938          // Replies
0939          $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1;
0940          // Correction for case of unapproved topic visible to poster
0941          if ($replies < 0)
0942          {
0943              $replies = 0;
0944          }
0945   
0946          if ($row['topic_status'] == ITEM_MOVED)
0947          {
0948              $topic_id = $row['topic_moved_id'];
0949              $unread_topic = false;
0950          }
0951          else
0952          {
0953              $unread_topic = (isset($topic_tracking_info[$topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
0954          }
0955   
0956          // Get folder img, topic status/type related information
0957          $folder_img = $folder_alt = $topic_type = '';
0958          topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
0959   
0960          // Generate all the URIs ...
0961          $view_topic_url_params = 't=' . $topic_id;
0962          $view_topic_url = $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params) : false;
0963   
0964          $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id']));
0965          $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id']));
0966          $topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
0967   
0968          $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&amp;t=$topic_id", true, $user->session_id) : '';
0969          $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&amp;mode=deleted_topics&amp;t=' . $topic_id, true, $user->session_id) : $u_mcp_queue;
0970   
0971          // Send vars to template
0972          $topic_row = array(
0973              'FORUM_ID'                    => $row['forum_id'],
0974              'TOPIC_ID'                    => $topic_id,
0975              'TOPIC_AUTHOR'                => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0976              'TOPIC_AUTHOR_COLOUR'        => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0977              'TOPIC_AUTHOR_FULL'            => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0978              'FIRST_POST_TIME'            => $user->format_date($row['topic_time']),
0979              'FIRST_POST_TIME_RFC3339'    => gmdate(DATE_RFC3339, $row['topic_time']),
0980              'LAST_POST_SUBJECT'            => censor_text($row['topic_last_post_subject']),
0981              'LAST_POST_TIME'            => $user->format_date($row['topic_last_post_time']),
0982              'LAST_POST_TIME_RFC3339'    => gmdate(DATE_RFC3339, $row['topic_last_post_time']),
0983              'LAST_VIEW_TIME'            => $user->format_date($row['topic_last_view_time']),
0984              'LAST_VIEW_TIME_RFC3339'    => gmdate(DATE_RFC3339, $row['topic_last_view_time']),
0985              'LAST_POST_AUTHOR'            => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
0986              'LAST_POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
0987              'LAST_POST_AUTHOR_FULL'        => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
0988   
0989              'REPLIES'            => $replies,
0990              'VIEWS'                => $row['topic_views'],
0991              'TOPIC_TITLE'        => censor_text($row['topic_title']),
0992              'TOPIC_TYPE'        => $topic_type,
0993              'FORUM_NAME'        => (isset($row['forum_name'])) ? $row['forum_name'] : $forum_data['forum_name'],
0994   
0995              'TOPIC_IMG_STYLE'        => $folder_img,
0996              'TOPIC_FOLDER_IMG'        => $user->img($folder_img, $folder_alt),
0997              'TOPIC_FOLDER_IMG_ALT'    => $user->lang[$folder_alt],
0998   
0999              'TOPIC_ICON_IMG'        => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
1000              'TOPIC_ICON_IMG_WIDTH'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
1001              'TOPIC_ICON_IMG_HEIGHT'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
1002              'ATTACH_ICON_IMG'        => ($auth->acl_get('u_download') && $auth->acl_get('f_download', $row['forum_id']) && $row['topic_attachment']) ? $user->img('icon_topic_attach', $user->lang['TOTAL_ATTACHMENTS']) : '',
1003              'UNAPPROVED_IMG'        => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
1004   
1005              'S_TOPIC_TYPE'            => $row['topic_type'],
1006              'S_USER_POSTED'            => (isset($row['topic_posted']) && $row['topic_posted']) ? true : false,
1007              'S_UNREAD_TOPIC'        => $unread_topic,
1008              'S_TOPIC_REPORTED'        => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $row['forum_id'])) ? true : false,
1009              'S_TOPIC_UNAPPROVED'    => $topic_unapproved,
1010              'S_POSTS_UNAPPROVED'    => $posts_unapproved,
1011              'S_TOPIC_DELETED'        => $topic_deleted,
1012              'S_HAS_POLL'            => ($row['poll_start']) ? true : false,
1013              'S_POST_ANNOUNCE'        => ($row['topic_type'] == POST_ANNOUNCE) ? true : false,
1014              'S_POST_GLOBAL'            => ($row['topic_type'] == POST_GLOBAL) ? true : false,
1015              'S_POST_STICKY'            => ($row['topic_type'] == POST_STICKY) ? true : false,
1016              'S_TOPIC_LOCKED'        => ($row['topic_status'] == ITEM_LOCKED) ? true : false,
1017              'S_TOPIC_MOVED'            => ($row['topic_status'] == ITEM_MOVED) ? true : false,
1018   
1019              'U_NEWEST_POST'            => $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;view=unread') . '#unread' : false,
1020              'U_LAST_POST'            => $auth->acl_get('f_read', $forum_id)  ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", 'p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'] : false,
1021              'U_LAST_POST_AUTHOR'    => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1022              'U_TOPIC_AUTHOR'        => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1023              'U_VIEW_TOPIC'            => $view_topic_url,
1024              'U_VIEW_FORUM'            => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),
1025              'U_MCP_REPORT'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=reports&amp;t=' . $topic_id, true, $user->session_id),
1026              'U_MCP_QUEUE'            => $u_mcp_queue,
1027   
1028              'S_TOPIC_TYPE_SWITCH'    => ($s_type_switch == $s_type_switch_test) ? -1 : $s_type_switch_test,
1029          );
1030   
1031          /**
1032          * Modify the topic data before it is assigned to the template
1033          *
1034          * @event core.viewforum_modify_topicrow
1035          * @var    array    row                    Array with topic data
1036          * @var    array    topic_row            Template array with topic data
1037          * @var    bool    s_type_switch        Flag indicating if the topic type is [global] announcement
1038          * @var    bool    s_type_switch_test    Flag indicating if the test topic type is [global] announcement
1039          * @since 3.1.0-a1
1040          *
1041          * @changed 3.1.10-RC1 Added s_type_switch, s_type_switch_test
1042          */
1043          $vars = array('row', 'topic_row', 's_type_switch', 's_type_switch_test');
1044          extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topicrow', compact($vars)));
1045   
1046          $template->assign_block_vars('topicrow', $topic_row);
1047   
1048          $pagination->generate_template_pagination($topic_row['U_VIEW_TOPIC'], 'topicrow.pagination', 'start', (int) $topic_row['REPLIES'] + 1, $config['posts_per_page'], 1, true, true);
1049   
1050          $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
1051   
1052          /**
1053          * Event after the topic data has been assigned to the template
1054          *
1055          * @event core.viewforum_topic_row_after
1056          * @var    array    row                Array with the topic data
1057          * @var    array    rowset            Array with topics data (in topic_id => topic_data format)
1058          * @var    bool    s_type_switch    Flag indicating if the topic type is [global] announcement
1059          * @var    int        topic_id        The topic ID
1060          * @var    array    topic_list        Array with current viewforum page topic ids
1061          * @var    array    topic_row        Template array with topic data
1062          * @since 3.1.3-RC1
1063          */
1064          $vars = array(
1065              'row',
1066              'rowset',
1067              's_type_switch',
1068              'topic_id',
1069              'topic_list',
1070              'topic_row',
1071          );
1072          extract($phpbb_dispatcher->trigger_event('core.viewforum_topic_row_after', compact($vars)));
1073   
1074          if ($unread_topic)
1075          {
1076              $mark_forum_read = false;
1077          }
1078   
1079          unset($rowset[$topic_id]);
1080      }
1081  }
1082   
1083  /**
1084  * This event is to perform additional actions on viewforum page
1085  *
1086  * @event core.viewforum_generate_page_after
1087  * @var    array    forum_data    Array with the forum data
1088  * @since 3.2.2-RC1
1089  */
1090  $vars = array('forum_data');
1091  extract($phpbb_dispatcher->trigger_event('core.viewforum_generate_page_after', compact($vars)));
1092   
1093  // This is rather a fudge but it's the best I can think of without requiring information
1094  // on all topics (as we do in 2.0.x). It looks for unread or new topics, if it doesn't find
1095  // any it updates the forum last read cookie. This requires that the user visit the forum
1096  // after reading a topic
1097  if ($forum_data['forum_type'] == FORUM_POST && count($topic_list) && $mark_forum_read)
1098  {
1099      update_forum_tracking_info($forum_id, $forum_data['forum_last_post_time'], false, $mark_time_forum);
1100  }
1101   
1102  page_footer();
1103