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