Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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: 09.10.2024, 12:50 - Dateigröße: 34.41 KiB


 001  <?php
 002  /**
 003  *
 004  * This file is part of the phpBB Forum Software package.
 005  *
 006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 007  * @license GNU General Public License, version 2 (GPL-2.0)
 008  *
 009  * For full copyright and license information, please see
 010  * the docs/CREDITS.txt file.
 011  *
 012  */
 013   
 014  /**
 015  * @ignore
 016  */
 017  define('IN_PHPBB', true);
 018  $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './';
 019  $phpEx = substr(strrchr(__FILE__, '.'), 1);
 020  include($phpbb_root_path . 'common.' . $phpEx);
 021  include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
 022   
 023  // Start session
 024  $user->session_begin();
 025  $auth->acl($user->data);
 026   
 027  // Start initial var setup
 028  $forum_id    = request_var('f', 0);
 029  $mark_read    = request_var('mark', '');
 030  $start        = request_var('start', 0);
 031   
 032  $default_sort_days    = (!empty($user->data['user_topic_show_days'])) ? $user->data['user_topic_show_days'] : 0;
 033  $default_sort_key    = (!empty($user->data['user_topic_sortby_type'])) ? $user->data['user_topic_sortby_type'] : 't';
 034  $default_sort_dir    = (!empty($user->data['user_topic_sortby_dir'])) ? $user->data['user_topic_sortby_dir'] : 'd';
 035   
 036  $sort_days    = request_var('st', $default_sort_days);
 037  $sort_key    = request_var('sk', $default_sort_key);
 038  $sort_dir    = request_var('sd', $default_sort_dir);
 039   
 040  $pagination = $phpbb_container->get('pagination');
 041   
 042  // Check if the user has actually sent a forum ID with his/her request
 043  // If not give them a nice error page.
 044  if (!$forum_id)
 045  {
 046      trigger_error('NO_FORUM');
 047  }
 048   
 049  $sql_from = FORUMS_TABLE . ' f';
 050  $lastread_select = '';
 051   
 052  // Grab appropriate forum data
 053  if ($config['load_db_lastread'] && $user->data['is_registered'])
 054  {
 055      $sql_from .= ' LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft ON (ft.user_id = ' . $user->data['user_id'] . '
 056          AND ft.forum_id = f.forum_id)';
 057      $lastread_select .= ', ft.mark_time';
 058  }
 059   
 060  if ($user->data['is_registered'])
 061  {
 062      $sql_from .= ' LEFT JOIN ' . FORUMS_WATCH_TABLE . ' fw ON (fw.forum_id = f.forum_id AND fw.user_id = ' . $user->data['user_id'] . ')';
 063      $lastread_select .= ', fw.notify_status';
 064  }
 065   
 066  $sql = "SELECT f.* $lastread_select
 067      FROM $sql_from
 068      WHERE f.forum_id = $forum_id";
 069  $result = $db->sql_query($sql);
 070  $forum_data = $db->sql_fetchrow($result);
 071  $db->sql_freeresult($result);
 072   
 073  if (!$forum_data)
 074  {
 075      trigger_error('NO_FORUM');
 076  }
 077   
 078   
 079  // Configure style, language, etc.
 080  $user->setup('viewforum', $forum_data['forum_style']);
 081   
 082  // Redirect to login upon emailed notification links
 083  if (isset($_GET['e']) && !$user->data['is_registered'])
 084  {
 085      login_box('', $user->lang['LOGIN_NOTIFY_FORUM']);
 086  }
 087   
 088  // Permissions check
 089  if (!$auth->acl_gets('f_list', 'f_read', $forum_id) || ($forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'] && !$auth->acl_get('f_read', $forum_id)))
 090  {
 091      if ($user->data['user_id'] != ANONYMOUS)
 092      {
 093          trigger_error('SORRY_AUTH_READ');
 094      }
 095   
 096      login_box('', $user->lang['LOGIN_VIEWFORUM']);
 097  }
 098   
 099  // Forum is passworded ... check whether access has been granted to this
 100  // user this session, if not show login box
 101  if ($forum_data['forum_password'])
 102  {
 103      login_forum_box($forum_data);
 104  }
 105   
 106  // Is this forum a link? ... User got here either because the
 107  // number of clicks is being tracked or they guessed the id
 108  if ($forum_data['forum_type'] == FORUM_LINK && $forum_data['forum_link'])
 109  {
 110      // Does it have click tracking enabled?
 111      if ($forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK)
 112      {
 113          $sql = 'UPDATE ' . FORUMS_TABLE . '
 114              SET forum_posts_approved = forum_posts_approved + 1
 115              WHERE forum_id = ' . $forum_id;
 116          $db->sql_query($sql);
 117      }
 118   
 119      // We redirect to the url. The third parameter indicates that external redirects are allowed.
 120      redirect($forum_data['forum_link'], false, true);
 121      return;
 122  }
 123   
 124  // Build navigation links
 125  generate_forum_nav($forum_data);
 126   
 127  // Forum Rules
 128  if ($auth->acl_get('f_read', $forum_id))
 129  {
 130      generate_forum_rules($forum_data);
 131  }
 132   
 133  // Do we have subforums?
 134  $active_forum_ary = $moderators = array();
 135   
 136  if ($forum_data['left_id'] != $forum_data['right_id'] - 1)
 137  {
 138      list($active_forum_ary, $moderators) = display_forums($forum_data, $config['load_moderators'], $config['load_moderators']);
 139  }
 140  else
 141  {
 142      $template->assign_var('S_HAS_SUBFORUM', false);
 143      if ($config['load_moderators'])
 144      {
 145          get_moderators($moderators, $forum_id);
 146      }
 147  }
 148   
 149  $phpbb_content_visibility = $phpbb_container->get('content.visibility');
 150   
 151  // Dump out the page header and load viewforum template
 152  $topics_count = $phpbb_content_visibility->get_count('forum_topics', $forum_data, $forum_id);
 153  $start = $pagination->validate_start($start, $config['topics_per_page'], $topics_count);
 154   
 155  page_header($forum_data['forum_name'] . ($start ? ' - ' . $user->lang('PAGE_TITLE_NUMBER', $pagination->get_on_page($config['topics_per_page'], $start)) : ''), true, $forum_id);
 156   
 157  $template->set_filenames(array(
 158      'body' => 'viewforum_body.html')
 159  );
 160   
 161  make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"), $forum_id);
 162   
 163  $template->assign_vars(array(
 164      'U_VIEW_FORUM'            => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . (($start == 0) ? '' : "&amp;start=$start")),
 165  ));
 166   
 167  // Not postable forum or showing active topics?
 168  if (!($forum_data['forum_type'] == FORUM_POST || (($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && $forum_data['forum_type'] == FORUM_CAT)))
 169  {
 170      page_footer();
 171  }
 172   
 173  // Ok, if someone has only list-access, we only display the forum list.
 174  // We also make this circumstance available to the template in case we want to display a notice. ;)
 175  if (!$auth->acl_get('f_read', $forum_id))
 176  {
 177      $template->assign_vars(array(
 178          'S_NO_READ_ACCESS'        => true,
 179      ));
 180   
 181      page_footer();
 182  }
 183   
 184  // Handle marking posts
 185  if ($mark_read == 'topics')
 186  {
 187      $token = request_var('hash', '');
 188      if (check_link_hash($token, 'global'))
 189      {
 190          markread('topics', array($forum_id), false, request_var('mark_time', 0));
 191      }
 192      $redirect_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $forum_id);
 193      meta_refresh(3, $redirect_url);
 194   
 195      if ($request->is_ajax())
 196      {
 197          // Tell the ajax script what language vars and URL need to be replaced
 198          $data = array(
 199              'NO_UNREAD_POSTS'    => $user->lang['NO_UNREAD_POSTS'],
 200              'UNREAD_POSTS'        => $user->lang['UNREAD_POSTS'],
 201              '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()) : '',
 202              'MESSAGE_TITLE'        => $user->lang['INFORMATION'],
 203              'MESSAGE_TEXT'        => $user->lang['TOPICS_MARKED']
 204          );
 205          $json_response = new \phpbb\json_response();
 206          $json_response->send($data);
 207      }
 208   
 209      trigger_error($user->lang['TOPICS_MARKED'] . '<br /><br />' . sprintf($user->lang['RETURN_FORUM'], '<a href="' . $redirect_url . '">', '</a>'));
 210  }
 211   
 212  // Is a forum specific topic count required?
 213  if ($forum_data['forum_topics_per_page'])
 214  {
 215      $config['topics_per_page'] = $forum_data['forum_topics_per_page'];
 216  }
 217   
 218  // Do the forum Prune thang - cron type job ...
 219  if (!$config['use_system_cron'])
 220  {
 221      $cron = $phpbb_container->get('cron.manager');
 222   
 223      $task = $cron->find_task('cron.task.core.prune_forum');
 224      $task->set_forum_data($forum_data);
 225   
 226      if ($task->is_ready())
 227      {
 228          $url = $task->get_url();
 229          $template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />');
 230      }
 231      else
 232      {
 233          // See if we should prune the shadow topics instead
 234          $task = $cron->find_task('cron.task.core.prune_shadow_topics');
 235          $task->set_forum_data($forum_data);
 236   
 237          if ($task->is_ready())
 238          {
 239              $url = $task->get_url();
 240              $template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />');
 241          }
 242      }
 243  }
 244   
 245  // Forum rules and subscription info
 246  $s_watching_forum = array(
 247      'link'            => '',
 248      'link_toggle'    => '',
 249      'title'            => '',
 250      'title_toggle'    => '',
 251      'is_watching'    => false,
 252  );
 253   
 254  if ($config['allow_forum_notify'] && $forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_subscribe', $forum_id) || $user->data['user_id'] == ANONYMOUS))
 255  {
 256      $notify_status = (isset($forum_data['notify_status'])) ? $forum_data['notify_status'] : NULL;
 257      watch_topic_forum('forum', $s_watching_forum, $user->data['user_id'], $forum_id, 0, $notify_status, $start, $forum_data['forum_name']);
 258  }
 259   
 260  $s_forum_rules = '';
 261  gen_forum_auth_level('forum', $forum_id, $forum_data['forum_status']);
 262   
 263  // Topic ordering options
 264  $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']);
 265   
 266  $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']);
 267  $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' => 't.topic_title', 'v' => 't.topic_views');
 268   
 269  $s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
 270  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);
 271   
 272  // Limit topics to certain time frame, obtain correct topic count
 273  if ($sort_days)
 274  {
 275      $min_post_time = time() - ($sort_days * 86400);
 276   
 277      $sql = 'SELECT COUNT(topic_id) AS num_topics
 278          FROM ' . TOPICS_TABLE . "
 279          WHERE forum_id = $forum_id
 280              AND (topic_last_post_time >= $min_post_time
 281                  OR topic_type = " . POST_ANNOUNCE . '
 282                  OR topic_type = ' . POST_GLOBAL . ')
 283              AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id);
 284      $result = $db->sql_query($sql);
 285      $topics_count = (int) $db->sql_fetchfield('num_topics');
 286      $db->sql_freeresult($result);
 287   
 288      if (isset($_POST['sort']))
 289      {
 290          $start = 0;
 291      }
 292      $sql_limit_time = "AND t.topic_last_post_time >= $min_post_time";
 293   
 294      // Make sure we have information about day selection ready
 295      $template->assign_var('S_SORT_DAYS', true);
 296  }
 297  else
 298  {
 299      $sql_limit_time = '';
 300  }
 301   
 302  // Basic pagewide vars
 303  $post_alt = ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['FORUM_LOCKED'] : $user->lang['POST_NEW_TOPIC'];
 304   
 305  // Display active topics?
 306  $s_display_active = ($forum_data['forum_type'] == FORUM_CAT && ($forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS)) ? true : false;
 307   
 308  $s_search_hidden_fields = array('fid' => array($forum_id));
 309  if ($_SID)
 310  {
 311      $s_search_hidden_fields['sid'] = $_SID;
 312  }
 313   
 314  if (!empty($_EXTRA_URL))
 315  {
 316      foreach ($_EXTRA_URL as $url_param)
 317      {
 318          $url_param = explode('=', $url_param, 2);
 319          $s_search_hidden_fields[$url_param[0]] = $url_param[1];
 320      }
 321  }
 322   
 323  $template->assign_vars(array(
 324      'MODERATORS'    => (!empty($moderators[$forum_id])) ? implode($user->lang['COMMA_SEPARATOR'], $moderators[$forum_id]) : '',
 325   
 326      'POST_IMG'                    => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', $post_alt) : $user->img('button_topic_new', $post_alt),
 327      'NEWEST_POST_IMG'            => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
 328      'LAST_POST_IMG'                => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
 329      'FOLDER_IMG'                => $user->img('topic_read', 'NO_UNREAD_POSTS'),
 330      'FOLDER_UNREAD_IMG'            => $user->img('topic_unread', 'UNREAD_POSTS'),
 331      'FOLDER_HOT_IMG'            => $user->img('topic_read_hot', 'NO_UNREAD_POSTS_HOT'),
 332      'FOLDER_HOT_UNREAD_IMG'        => $user->img('topic_unread_hot', 'UNREAD_POSTS_HOT'),
 333      'FOLDER_LOCKED_IMG'            => $user->img('topic_read_locked', 'NO_UNREAD_POSTS_LOCKED'),
 334      'FOLDER_LOCKED_UNREAD_IMG'    => $user->img('topic_unread_locked', 'UNREAD_POSTS_LOCKED'),
 335      'FOLDER_STICKY_IMG'            => $user->img('sticky_read', 'POST_STICKY'),
 336      'FOLDER_STICKY_UNREAD_IMG'    => $user->img('sticky_unread', 'POST_STICKY'),
 337      'FOLDER_ANNOUNCE_IMG'        => $user->img('announce_read', 'POST_ANNOUNCEMENT'),
 338      'FOLDER_ANNOUNCE_UNREAD_IMG'=> $user->img('announce_unread', 'POST_ANNOUNCEMENT'),
 339      'FOLDER_MOVED_IMG'            => $user->img('topic_moved', 'TOPIC_MOVED'),
 340      'REPORTED_IMG'                => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
 341      'UNAPPROVED_IMG'            => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
 342      'DELETED_IMG'                => $user->img('icon_topic_deleted', 'TOPIC_DELETED'),
 343      'POLL_IMG'                    => $user->img('icon_topic_poll', 'TOPIC_POLL'),
 344      'GOTO_PAGE_IMG'                => $user->img('icon_post_target', 'GOTO_PAGE'),
 345   
 346      'L_NO_TOPICS'             => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['POST_FORUM_LOCKED'] : $user->lang['NO_TOPICS'],
 347   
 348      'S_DISPLAY_POST_INFO'    => ($forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false,
 349   
 350      'S_IS_POSTABLE'            => ($forum_data['forum_type'] == FORUM_POST) ? true : false,
 351      'S_USER_CAN_POST'        => ($auth->acl_get('f_post', $forum_id)) ? true : false,
 352      'S_DISPLAY_ACTIVE'        => $s_display_active,
 353      'S_SELECT_SORT_DIR'        => $s_sort_dir,
 354      'S_SELECT_SORT_KEY'        => $s_sort_key,
 355      'S_SELECT_SORT_DAYS'    => $s_limit_days,
 356      'S_TOPIC_ICONS'            => ($s_display_active && sizeof($active_forum_ary)) ? max($active_forum_ary['enable_icons']) : (($forum_data['enable_icons']) ? true : false),
 357      'U_WATCH_FORUM_LINK'    => $s_watching_forum['link'],
 358      'U_WATCH_FORUM_TOGGLE'    => $s_watching_forum['link_toggle'],
 359      'S_WATCH_FORUM_TITLE'    => $s_watching_forum['title'],
 360      'S_WATCH_FORUM_TOGGLE'    => $s_watching_forum['title_toggle'],
 361      'S_WATCHING_FORUM'        => $s_watching_forum['is_watching'],
 362      'S_FORUM_ACTION'        => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . (($start == 0) ? '' : "&amp;start=$start")),
 363      'S_DISPLAY_SEARCHBOX'    => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false,
 364      'S_SEARCHBOX_ACTION'    => append_sid("{$phpbb_root_path}search.$phpEx"),
 365      'S_SEARCH_LOCAL_HIDDEN_FIELDS'    => build_hidden_fields($s_search_hidden_fields),
 366      'S_SINGLE_MODERATOR'    => (!empty($moderators[$forum_id]) && sizeof($moderators[$forum_id]) > 1) ? false : true,
 367      'S_IS_LOCKED'            => ($forum_data['forum_status'] == ITEM_LOCKED) ? true : false,
 368      'S_VIEWFORUM'            => true,
 369   
 370      '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) : '',
 371      '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) : '',
 372      '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")),
 373      'U_CANONICAL'        => generate_board_url() . '/' . append_sid("viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : '') . (($start) ? "&amp;start=$start" : ''), true, ''),
 374      '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()) : '',
 375  ));
 376   
 377  // Grab icons
 378  $icons = $cache->obtain_icons();
 379   
 380  // Grab all topic data
 381  $rowset = $announcement_list = $topic_list = $global_announce_forums = array();
 382   
 383  $sql_array = array(
 384      'SELECT'    => 't.*',
 385      'FROM'        => array(
 386          TOPICS_TABLE        => 't'
 387      ),
 388      'LEFT_JOIN'    => array(),
 389  );
 390   
 391  /**
 392  * Event to modify the SQL query before the topic data is retrieved
 393  *
 394  * @event core.viewforum_get_topic_data
 395  * @var    array    forum_data            Array with forum data
 396  * @var    array    sql_array            The SQL array to get the data of all topics
 397  * @since 3.1.0-a1
 398  * @change 3.1.0-RC4 Added forum_data var 
 399  */
 400  $vars = array(
 401      'forum_data',
 402      'sql_array',
 403  );
 404  extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_data', compact($vars)));
 405   
 406  $sql_approved = ' AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.');
 407   
 408  if ($user->data['is_registered'])
 409  {
 410      if ($config['load_db_track'])
 411      {
 412          $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']);
 413          $sql_array['SELECT'] .= ', tp.topic_posted';
 414      }
 415   
 416      if ($config['load_db_lastread'])
 417      {
 418          $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']);
 419          $sql_array['SELECT'] .= ', tt.mark_time';
 420   
 421          if ($s_display_active && sizeof($active_forum_ary))
 422          {
 423              $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']);
 424              $sql_array['SELECT'] .= ', ft.mark_time AS forum_mark_time';
 425          }
 426      }
 427  }
 428   
 429  if ($forum_data['forum_type'] == FORUM_POST)
 430  {
 431      // Get global announcement forums
 432      $g_forum_ary = $auth->acl_getf('f_read', true);
 433      $g_forum_ary = array_unique(array_keys($g_forum_ary));
 434   
 435      $sql_anounce_array['LEFT_JOIN'] = $sql_array['LEFT_JOIN'];
 436      $sql_anounce_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TABLE => 'f'), 'ON' => 'f.forum_id = t.forum_id');
 437      $sql_anounce_array['SELECT'] = $sql_array['SELECT'] . ', f.forum_name';
 438   
 439      // Obtain announcements ... removed sort ordering, sort by time in all cases
 440      $sql_ary = array(
 441          'SELECT'    => $sql_anounce_array['SELECT'],
 442          'FROM'        => $sql_array['FROM'],
 443          'LEFT_JOIN'    => $sql_anounce_array['LEFT_JOIN'],
 444   
 445          'WHERE'        => '(t.forum_id = ' . $forum_id . '
 446                  AND t.topic_type = ' . POST_ANNOUNCE . ') OR
 447              (' . $db->sql_in_set('t.forum_id', $g_forum_ary) . '
 448                  AND t.topic_type = ' . POST_GLOBAL . ')',
 449   
 450          'ORDER_BY'    => 't.topic_time DESC',
 451      );
 452      $sql = $db->sql_build_query('SELECT', $sql_ary);
 453      $result = $db->sql_query($sql);
 454   
 455      while ($row = $db->sql_fetchrow($result))
 456      {
 457          if ($row['topic_visibility'] != ITEM_APPROVED && !$auth->acl_get('m_approve', $row['forum_id']))
 458          {
 459              // Do not display announcements that are waiting for approval or soft deleted.
 460              continue;
 461          }
 462   
 463          $rowset[$row['topic_id']] = $row;
 464          $announcement_list[] = $row['topic_id'];
 465   
 466          if ($forum_id != $row['forum_id'])
 467          {
 468              $topics_count++;
 469              $global_announce_forums[] = $row['forum_id'];
 470          }
 471      }
 472      $db->sql_freeresult($result);
 473  }
 474   
 475  $forum_tracking_info = array();
 476   
 477  if ($user->data['is_registered'] && $config['load_db_lastread'])
 478  {
 479      $forum_tracking_info[$forum_id] = $forum_data['mark_time'];
 480   
 481      if (!empty($global_announce_forums))
 482      {
 483          $sql = 'SELECT forum_id, mark_time
 484              FROM ' . FORUMS_TRACK_TABLE . '
 485              WHERE ' . $db->sql_in_set('forum_id', $global_announce_forums) . '
 486                  AND user_id = ' . $user->data['user_id'];
 487          $result = $db->sql_query($sql);
 488   
 489          while ($row = $db->sql_fetchrow($result))
 490          {
 491              $forum_tracking_info[$row['forum_id']] = $row['mark_time'];
 492          }
 493          $db->sql_freeresult($result);
 494      }
 495  }
 496   
 497  // If the user is trying to reach late pages, start searching from the end
 498  $store_reverse = false;
 499  $sql_limit = $config['topics_per_page'];
 500  if ($start > $topics_count / 2)
 501  {
 502      $store_reverse = true;
 503   
 504      // Select the sort order
 505      $direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
 506   
 507      $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count);
 508      $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count);
 509  }
 510  else
 511  {
 512      // Select the sort order
 513      $direction = (($sort_dir == 'd') ? 'DESC' : 'ASC');
 514      $sql_start = $start;
 515  }
 516   
 517  if (is_array($sort_by_sql[$sort_key]))
 518  {
 519      $sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
 520  }
 521  else
 522  {
 523      $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
 524  }
 525   
 526  if ($forum_data['forum_type'] == FORUM_POST || !sizeof($active_forum_ary))
 527  {
 528      $sql_where = 't.forum_id = ' . $forum_id;
 529  }
 530  else if (empty($active_forum_ary['exclude_forum_id']))
 531  {
 532      $sql_where = $db->sql_in_set('t.forum_id', $active_forum_ary['forum_id']);
 533  }
 534  else
 535  {
 536      $get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']);
 537      $sql_where = (sizeof($get_forum_ids)) ? $db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id;
 538  }
 539   
 540  // Grab just the sorted topic ids
 541  $sql_ary = array(
 542      'SELECT'    => 't.topic_id',
 543      'FROM'        => array(
 544          TOPICS_TABLE => 't',
 545      ),
 546      'WHERE'        => "$sql_where
 547          AND t.topic_type IN (" . POST_NORMAL . ', ' . POST_STICKY . ")
 548          $sql_approved
 549          $sql_limit_time",
 550      'ORDER_BY'    => 't.topic_type ' . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order,
 551  );
 552   
 553  /**
 554  * Event to modify the SQL query before the topic ids data is retrieved
 555  *
 556  * @event core.viewforum_get_topic_ids_data
 557  * @var    array    sql_ary            SQL query array to get the topic ids data
 558  * @var    string    sql_approved    Topic visibility SQL string
 559  * @var    int        sql_limit        Number of records to select
 560  * @var    string    sql_limit_time    SQL string to limit topic_last_post_time data
 561  * @var    array    sql_sort_order    SQL sorting string
 562  * @var    int        sql_start        Offset point to start selection from
 563  * @var    string    sql_where        SQL WHERE clause string
 564  * @var    bool    store_reverse    Flag indicating if we select from the late pages
 565  *
 566  * @since 3.1.0-RC4
 567  */
 568  $vars = array(
 569      'sql_ary',
 570      'sql_approved',
 571      'sql_limit',
 572      'sql_limit_time',
 573      'sql_sort_order',
 574      'sql_start',
 575      'sql_where',
 576      'store_reverse',
 577  );
 578  extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_ids_data', compact($vars)));
 579   
 580  $sql = $db->sql_build_query('SELECT', $sql_ary);
 581  $result = $db->sql_query_limit($sql, $sql_limit, $sql_start);
 582   
 583  while ($row = $db->sql_fetchrow($result))
 584  {
 585      $topic_list[] = (int) $row['topic_id'];
 586  }
 587  $db->sql_freeresult($result);
 588   
 589  // For storing shadow topics
 590  $shadow_topic_list = array();
 591   
 592  if (sizeof($topic_list))
 593  {
 594      // SQL array for obtaining topics/stickies
 595      $sql_array = array(
 596          'SELECT'        => $sql_array['SELECT'],
 597          'FROM'            => $sql_array['FROM'],
 598          'LEFT_JOIN'        => $sql_array['LEFT_JOIN'],
 599   
 600          'WHERE'            => $db->sql_in_set('t.topic_id', $topic_list),
 601      );
 602   
 603      // If store_reverse, then first obtain topics, then stickies, else the other way around...
 604      // Funnily enough you typically save one query if going from the last page to the middle (store_reverse) because
 605      // the number of stickies are not known
 606      $sql = $db->sql_build_query('SELECT', $sql_array);
 607      $result = $db->sql_query($sql);
 608   
 609      while ($row = $db->sql_fetchrow($result))
 610      {
 611          if ($row['topic_status'] == ITEM_MOVED)
 612          {
 613              $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
 614          }
 615   
 616          $rowset[$row['topic_id']] = $row;
 617      }
 618      $db->sql_freeresult($result);
 619  }
 620   
 621  // If we have some shadow topics, update the rowset to reflect their topic information
 622  if (sizeof($shadow_topic_list))
 623  {
 624      // SQL array for obtaining shadow topics
 625      $sql_array = array(
 626          'SELECT'    => 't.*',
 627          'FROM'        => array(
 628              TOPICS_TABLE        => 't'
 629          ),
 630          'WHERE'        => $db->sql_in_set('t.topic_id', array_keys($shadow_topic_list)),
 631      );
 632   
 633      /**
 634      * Event to modify the SQL query before the shadowtopic data is retrieved
 635      *
 636      * @event core.viewforum_get_shadowtopic_data
 637      * @var    array    sql_array        SQL array to get the data of any shadowtopics
 638      * @since 3.1.0-a1
 639      */
 640      $vars = array('sql_array');
 641      extract($phpbb_dispatcher->trigger_event('core.viewforum_get_shadowtopic_data', compact($vars)));
 642   
 643      $sql = $db->sql_build_query('SELECT', $sql_array);
 644      $result = $db->sql_query($sql);
 645   
 646      while ($row = $db->sql_fetchrow($result))
 647      {
 648          $orig_topic_id = $shadow_topic_list[$row['topic_id']];
 649   
 650          // If the shadow topic is already listed within the rowset (happens for active topics for example), then do not include it...
 651          if (isset($rowset[$row['topic_id']]))
 652          {
 653              // We need to remove any trace regarding this topic. :)
 654              unset($rowset[$orig_topic_id]);
 655              unset($topic_list[array_search($orig_topic_id, $topic_list)]);
 656              $topics_count--;
 657   
 658              continue;
 659          }
 660   
 661          // Do not include those topics the user has no permission to access
 662          if (!$auth->acl_get('f_read', $row['forum_id']))
 663          {
 664              // We need to remove any trace regarding this topic. :)
 665              unset($rowset[$orig_topic_id]);
 666              unset($topic_list[array_search($orig_topic_id, $topic_list)]);
 667              $topics_count--;
 668   
 669              continue;
 670          }
 671   
 672          // We want to retain some values
 673          $row = array_merge($row, array(
 674              'topic_moved_id'    => $rowset[$orig_topic_id]['topic_moved_id'],
 675              'topic_status'        => $rowset[$orig_topic_id]['topic_status'],
 676              'topic_type'        => $rowset[$orig_topic_id]['topic_type'],
 677              'topic_title'        => $rowset[$orig_topic_id]['topic_title'],
 678          ));
 679   
 680          // Shadow topics are never reported
 681          $row['topic_reported'] = 0;
 682   
 683          $rowset[$orig_topic_id] = $row;
 684      }
 685      $db->sql_freeresult($result);
 686  }
 687  unset($shadow_topic_list);
 688   
 689  // Ok, adjust topics count for active topics list
 690  if ($s_display_active)
 691  {
 692      $topics_count = 1;
 693  }
 694   
 695  // We need to remove the global announcements from the forums total topic count,
 696  // otherwise the number is different from the one on the forum list
 697  $total_topic_count = $topics_count - sizeof($global_announce_forums);
 698   
 699  $base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&amp;$u_sort_param" : ''));
 700  $pagination->generate_template_pagination($base_url, 'pagination', 'start', $topics_count, $config['topics_per_page'], $start);
 701   
 702  $template->assign_vars(array(
 703      'TOTAL_TOPICS'    => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count),
 704  ));
 705   
 706  $topic_list = ($store_reverse) ? array_merge($announcement_list, array_reverse($topic_list)) : array_merge($announcement_list, $topic_list);
 707  $topic_tracking_info = $tracking_topics = array();
 708   
 709  /**
 710  * Modify topics data before we display the viewforum page
 711  *
 712  * @event core.viewforum_modify_topics_data
 713  * @var    array    topic_list            Array with current viewforum page topic ids
 714  * @var    array    rowset                Array with topics data (in topic_id => topic_data format)
 715  * @var    int        total_topic_count    Forum's total topic count
 716  * @since 3.1.0-b3
 717  */
 718  $vars = array('topic_list', 'rowset', 'total_topic_count');
 719  extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topics_data', compact($vars)));
 720   
 721  // Okay, lets dump out the page ...
 722  if (sizeof($topic_list))
 723  {
 724      $mark_forum_read = true;
 725      $mark_time_forum = 0;
 726   
 727      // Generate topic forum list...
 728      $topic_forum_list = array();
 729      foreach ($rowset as $t_id => $row)
 730      {
 731          if (isset($forum_tracking_info[$row['forum_id']]))
 732          {
 733              $row['forum_mark_time'] = $forum_tracking_info[$row['forum_id']];
 734          }
 735   
 736          $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;
 737          $topic_forum_list[$row['forum_id']]['topics'][] = (int) $t_id;
 738      }
 739   
 740      if ($config['load_db_lastread'] && $user->data['is_registered'])
 741      {
 742          foreach ($topic_forum_list as $f_id => $topic_row)
 743          {
 744              $topic_tracking_info += get_topic_tracking($f_id, $topic_row['topics'], $rowset, array($f_id => $topic_row['forum_mark_time']));
 745          }
 746      }
 747      else if ($config['load_anon_lastread'] || $user->data['is_registered'])
 748      {
 749          foreach ($topic_forum_list as $f_id => $topic_row)
 750          {
 751              $topic_tracking_info += get_complete_topic_tracking($f_id, $topic_row['topics']);
 752          }
 753      }
 754   
 755      unset($topic_forum_list);
 756   
 757      if (!$s_display_active)
 758      {
 759          if ($config['load_db_lastread'] && $user->data['is_registered'])
 760          {
 761              $mark_time_forum = (!empty($forum_data['mark_time'])) ? $forum_data['mark_time'] : $user->data['user_lastmark'];
 762          }
 763          else if ($config['load_anon_lastread'] || $user->data['is_registered'])
 764          {
 765              if (!$user->data['is_registered'])
 766              {
 767                  $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
 768              }
 769              $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'];
 770          }
 771      }
 772   
 773      $s_type_switch = 0;
 774      foreach ($topic_list as $topic_id)
 775      {
 776          $row = &$rowset[$topic_id];
 777   
 778          $topic_forum_id = ($row['forum_id']) ? (int) $row['forum_id'] : $forum_id;
 779   
 780          // This will allow the style designer to output a different header
 781          // or even separate the list of announcements from sticky and normal topics
 782          $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
 783   
 784          // Replies
 785          $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1;
 786   
 787          if ($row['topic_status'] == ITEM_MOVED)
 788          {
 789              $topic_id = $row['topic_moved_id'];
 790              $unread_topic = false;
 791          }
 792          else
 793          {
 794              $unread_topic = (isset($topic_tracking_info[$topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
 795          }
 796   
 797          // Get folder img, topic status/type related information
 798          $folder_img = $folder_alt = $topic_type = '';
 799          topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
 800   
 801          // Generate all the URIs ...
 802          $view_topic_url_params = 'f=' . $row['forum_id'] . '&amp;t=' . $topic_id;
 803          $view_topic_url = append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params);
 804   
 805          $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id']));
 806          $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id']));
 807          $topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
 808   
 809          $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) : '';
 810          $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;
 811   
 812          // Send vars to template
 813          $topic_row = array(
 814              'FORUM_ID'                    => $row['forum_id'],
 815              'TOPIC_ID'                    => $topic_id,
 816              'TOPIC_AUTHOR'                => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
 817              'TOPIC_AUTHOR_COLOUR'        => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
 818              'TOPIC_AUTHOR_FULL'            => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
 819              'FIRST_POST_TIME'            => $user->format_date($row['topic_time']),
 820              'LAST_POST_SUBJECT'            => censor_text($row['topic_last_post_subject']),
 821              'LAST_POST_TIME'            => $user->format_date($row['topic_last_post_time']),
 822              'LAST_VIEW_TIME'            => $user->format_date($row['topic_last_view_time']),
 823              'LAST_POST_AUTHOR'            => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
 824              'LAST_POST_AUTHOR_COLOUR'    => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
 825              'LAST_POST_AUTHOR_FULL'        => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
 826   
 827              'REPLIES'            => $replies,
 828              'VIEWS'                => $row['topic_views'],
 829              'TOPIC_TITLE'        => censor_text($row['topic_title']),
 830              'TOPIC_TYPE'        => $topic_type,
 831              'FORUM_NAME'        => (isset($row['forum_name'])) ? $row['forum_name'] : $forum_data['forum_name'],
 832   
 833              'TOPIC_IMG_STYLE'        => $folder_img,
 834              'TOPIC_FOLDER_IMG'        => $user->img($folder_img, $folder_alt),
 835              'TOPIC_FOLDER_IMG_ALT'    => $user->lang[$folder_alt],
 836   
 837              'TOPIC_ICON_IMG'        => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
 838              'TOPIC_ICON_IMG_WIDTH'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
 839              'TOPIC_ICON_IMG_HEIGHT'    => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
 840              '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']) : '',
 841              'UNAPPROVED_IMG'        => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
 842   
 843              'S_TOPIC_TYPE'            => $row['topic_type'],
 844              'S_USER_POSTED'            => (isset($row['topic_posted']) && $row['topic_posted']) ? true : false,
 845              'S_UNREAD_TOPIC'        => $unread_topic,
 846              'S_TOPIC_REPORTED'        => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $row['forum_id'])) ? true : false,
 847              'S_TOPIC_UNAPPROVED'    => $topic_unapproved,
 848              'S_POSTS_UNAPPROVED'    => $posts_unapproved,
 849              'S_TOPIC_DELETED'        => $topic_deleted,
 850              'S_HAS_POLL'            => ($row['poll_start']) ? true : false,
 851              'S_POST_ANNOUNCE'        => ($row['topic_type'] == POST_ANNOUNCE) ? true : false,
 852              'S_POST_GLOBAL'            => ($row['topic_type'] == POST_GLOBAL) ? true : false,
 853              'S_POST_STICKY'            => ($row['topic_type'] == POST_STICKY) ? true : false,
 854              'S_TOPIC_LOCKED'        => ($row['topic_status'] == ITEM_LOCKED) ? true : false,
 855              'S_TOPIC_MOVED'            => ($row['topic_status'] == ITEM_MOVED) ? true : false,
 856   
 857              'U_NEWEST_POST'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;view=unread') . '#unread',
 858              'U_LAST_POST'            => append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&amp;p=' . $row['topic_last_post_id']) . '#p' . $row['topic_last_post_id'],
 859              'U_LAST_POST_AUTHOR'    => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
 860              'U_TOPIC_AUTHOR'        => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
 861              'U_VIEW_TOPIC'            => $view_topic_url,
 862              'U_VIEW_FORUM'            => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),
 863              'U_MCP_REPORT'            => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&amp;mode=reports&amp;f=' . $row['forum_id'] . '&amp;t=' . $topic_id, true, $user->session_id),
 864              'U_MCP_QUEUE'            => $u_mcp_queue,
 865   
 866              'S_TOPIC_TYPE_SWITCH'    => ($s_type_switch == $s_type_switch_test) ? -1 : $s_type_switch_test,
 867          );
 868   
 869          /**
 870          * Modify the topic data before it is assigned to the template
 871          *
 872          * @event core.viewforum_modify_topicrow
 873          * @var    array    row            Array with topic data
 874          * @var    array    topic_row    Template array with topic data
 875          * @since 3.1.0-a1
 876          */
 877          $vars = array('row', 'topic_row');
 878          extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topicrow', compact($vars)));
 879   
 880          $template->assign_block_vars('topicrow', $topic_row);
 881   
 882          $pagination->generate_template_pagination($view_topic_url, 'topicrow.pagination', 'start', $replies + 1, $config['posts_per_page'], 1, true, true);
 883   
 884          $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
 885   
 886          if ($unread_topic)
 887          {
 888              $mark_forum_read = false;
 889          }
 890   
 891          unset($rowset[$topic_id]);
 892      }
 893  }
 894   
 895  // This is rather a fudge but it's the best I can think of without requiring information
 896  // on all topics (as we do in 2.0.x). It looks for unread or new topics, if it doesn't find
 897  // any it updates the forum last read cookie. This requires that the user visit the forum
 898  // after reading a topic
 899  if ($forum_data['forum_type'] == FORUM_POST && sizeof($topic_list) && $mark_forum_read)
 900  {
 901      update_forum_tracking_info($forum_id, $forum_data['forum_last_post_time'], false, $mark_time_forum);
 902  }
 903   
 904  page_footer();
 905