Verzeichnisstruktur phpBB-3.3.16
- Veröffentlicht
- 27.04.2026
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. |
|
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
viewforum.php
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) ? '' : "&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 // Send the forum id... and maybe some other fields, depending on permissions
0388 $s_search_hidden_fields = [
0389 'fid' => [$forum_id],
0390 ];
0391
0392 if ($auth->acl_get('f_list_topics', $forum_id) && !$auth->acl_get('f_read', $forum_id))
0393 {
0394 // If the user has list access but not read access, then force the search to only be a topic title search
0395 $s_search_hidden_fields['sr'] = 'topics';
0396 $s_search_hidden_fields['sf'] = 'titleonly';
0397 }
0398
0399 if ($_SID)
0400 {
0401 $s_search_hidden_fields['sid'] = $_SID;
0402 }
0403
0404 if (!empty($_EXTRA_URL))
0405 {
0406 foreach ($_EXTRA_URL as $url_param)
0407 {
0408 $url_param = explode('=', $url_param, 2);
0409 $s_search_hidden_fields[$url_param[0]] = $url_param[1];
0410 }
0411 }
0412
0413 $template->assign_vars(array(
0414 'MODERATORS' => (!empty($moderators[$forum_id])) ? implode($user->lang['COMMA_SEPARATOR'], $moderators[$forum_id]) : '',
0415
0416 'POST_IMG' => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->img('button_topic_locked', $post_alt) : $user->img('button_topic_new', $post_alt),
0417 'NEWEST_POST_IMG' => $user->img('icon_topic_newest', 'VIEW_NEWEST_POST'),
0418 'LAST_POST_IMG' => $user->img('icon_topic_latest', 'VIEW_LATEST_POST'),
0419 'FOLDER_IMG' => $user->img('topic_read', 'NO_UNREAD_POSTS'),
0420 'FOLDER_UNREAD_IMG' => $user->img('topic_unread', 'UNREAD_POSTS'),
0421 'FOLDER_HOT_IMG' => $user->img('topic_read_hot', 'NO_UNREAD_POSTS_HOT'),
0422 'FOLDER_HOT_UNREAD_IMG' => $user->img('topic_unread_hot', 'UNREAD_POSTS_HOT'),
0423 'FOLDER_LOCKED_IMG' => $user->img('topic_read_locked', 'NO_UNREAD_POSTS_LOCKED'),
0424 'FOLDER_LOCKED_UNREAD_IMG' => $user->img('topic_unread_locked', 'UNREAD_POSTS_LOCKED'),
0425 'FOLDER_STICKY_IMG' => $user->img('sticky_read', 'POST_STICKY'),
0426 'FOLDER_STICKY_UNREAD_IMG' => $user->img('sticky_unread', 'POST_STICKY'),
0427 'FOLDER_ANNOUNCE_IMG' => $user->img('announce_read', 'POST_ANNOUNCEMENT'),
0428 'FOLDER_ANNOUNCE_UNREAD_IMG'=> $user->img('announce_unread', 'POST_ANNOUNCEMENT'),
0429 'FOLDER_MOVED_IMG' => $user->img('topic_moved', 'TOPIC_MOVED'),
0430 'REPORTED_IMG' => $user->img('icon_topic_reported', 'TOPIC_REPORTED'),
0431 'UNAPPROVED_IMG' => $user->img('icon_topic_unapproved', 'TOPIC_UNAPPROVED'),
0432 'DELETED_IMG' => $user->img('icon_topic_deleted', 'TOPIC_DELETED'),
0433 'POLL_IMG' => $user->img('icon_topic_poll', 'TOPIC_POLL'),
0434 'GOTO_PAGE_IMG' => $user->img('icon_post_target', 'GOTO_PAGE'),
0435
0436 'L_NO_TOPICS' => ($forum_data['forum_status'] == ITEM_LOCKED) ? $user->lang['POST_FORUM_LOCKED'] : $user->lang['NO_TOPICS'],
0437
0438 'S_DISPLAY_POST_INFO' => ($forum_data['forum_type'] == FORUM_POST && ($auth->acl_get('f_post', $forum_id) || $user->data['user_id'] == ANONYMOUS)) ? true : false,
0439
0440 'S_IS_POSTABLE' => ($forum_data['forum_type'] == FORUM_POST) ? true : false,
0441 'S_USER_CAN_POST' => ($auth->acl_get('f_post', $forum_id)) ? true : false,
0442 'S_DISPLAY_ACTIVE' => $s_display_active,
0443 'S_SELECT_SORT_DIR' => $s_sort_dir,
0444 'S_SELECT_SORT_KEY' => $s_sort_key,
0445 'S_SELECT_SORT_DAYS' => $s_limit_days,
0446 'S_TOPIC_ICONS' => ($s_display_active && count($active_forum_ary)) ? max($active_forum_ary['enable_icons']) : (($forum_data['enable_icons']) ? true : false),
0447 'U_WATCH_FORUM_LINK' => $s_watching_forum['link'],
0448 'U_WATCH_FORUM_TOGGLE' => $s_watching_forum['link_toggle'],
0449 'S_WATCH_FORUM_TITLE' => $s_watching_forum['title'],
0450 'S_WATCH_FORUM_TOGGLE' => $s_watching_forum['title_toggle'],
0451 'S_WATCHING_FORUM' => $s_watching_forum['is_watching'],
0452 'S_FORUM_ACTION' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . (($start == 0) ? '' : "&start=$start")),
0453 'S_DISPLAY_SEARCHBOX' => ($auth->acl_get('u_search') && $auth->acl_get('f_search', $forum_id) && $config['load_search']) ? true : false,
0454 'S_SEARCHBOX_ACTION' => append_sid("{$phpbb_root_path}search.$phpEx"),
0455 'S_SEARCH_LOCAL_HIDDEN_FIELDS' => build_hidden_fields($s_search_hidden_fields),
0456 'S_SINGLE_MODERATOR' => (!empty($moderators[$forum_id]) && count($moderators[$forum_id]) > 1) ? false : true,
0457 'S_IS_LOCKED' => ($forum_data['forum_status'] == ITEM_LOCKED) ? true : false,
0458 'S_VIEWFORUM' => true,
0459
0460 'U_MCP' => ($auth->acl_get('m_', $forum_id)) ? append_sid("{$phpbb_root_path}mcp.$phpEx", "f=$forum_id&i=main&mode=forum_view", true, $user->session_id) : '',
0461 '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&f=' . $forum_id) : '',
0462 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : '') . (($start == 0) ? '' : "&start=$start")),
0463 'U_CANONICAL' => generate_board_url() . '/' . append_sid("viewforum.$phpEx", "f=$forum_id" . (($start) ? "&start=$start" : ''), true, ''),
0464 '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()) : '',
0465 'U_SEARCH_FORUM' => append_sid("{$phpbb_root_path}search.$phpEx", 'fid%5B%5D=' . $forum_id),
0466 ));
0467
0468 // Grab icons
0469 $icons = $cache->obtain_icons();
0470
0471 // Grab all topic data
0472 $rowset = $announcement_list = $topic_list = $global_announce_forums = array();
0473
0474 $sql_array = array(
0475 'SELECT' => 't.*',
0476 'FROM' => array(
0477 TOPICS_TABLE => 't'
0478 ),
0479 'LEFT_JOIN' => array(),
0480 );
0481
0482 /**
0483 * Event to modify the SQL query before the topic data is retrieved
0484 *
0485 * It may also be used to override the above assigned template vars
0486 *
0487 * @event core.viewforum_get_topic_data
0488 * @var array forum_data Array with forum data
0489 * @var array sql_array The SQL array to get the data of all topics
0490 * @var int forum_id The forum_id whose topics are being listed
0491 * @var int topics_count The total number of topics for display
0492 * @var int sort_days The oldest topic displayable in elapsed days
0493 * @var string sort_key The sorting by. It is one of the first character of (in low case):
0494 * Author, Post time, Replies, Subject, Views
0495 * @var string sort_dir Either "a" for ascending or "d" for descending
0496 * @since 3.1.0-a1
0497 * @changed 3.1.0-RC4 Added forum_data var
0498 * @changed 3.1.4-RC1 Added forum_id, topics_count, sort_days, sort_key and sort_dir vars
0499 * @changed 3.1.9-RC1 Fix types of properties
0500 */
0501 $vars = array(
0502 'forum_data',
0503 'sql_array',
0504 'forum_id',
0505 'topics_count',
0506 'sort_days',
0507 'sort_key',
0508 'sort_dir',
0509 );
0510 extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_data', compact($vars)));
0511
0512 $sql_approved = ' AND ' . $phpbb_content_visibility->get_visibility_sql('topic', $forum_id, 't.');
0513
0514 if ($user->data['is_registered'])
0515 {
0516 if ($config['load_db_track'])
0517 {
0518 $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']);
0519 $sql_array['SELECT'] .= ', tp.topic_posted';
0520 }
0521
0522 if ($config['load_db_lastread'])
0523 {
0524 $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']);
0525 $sql_array['SELECT'] .= ', tt.mark_time';
0526
0527 if ($s_display_active && count($active_forum_ary))
0528 {
0529 $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']);
0530 $sql_array['SELECT'] .= ', ft.mark_time AS forum_mark_time';
0531 }
0532 }
0533 }
0534
0535 if ($forum_data['forum_type'] == FORUM_POST)
0536 {
0537 // Get global announcement forums
0538 $g_forum_ary = $auth->acl_getf('f_read', true);
0539 $g_forum_ary = array_unique(array_keys($g_forum_ary));
0540
0541 $sql_anounce_array['LEFT_JOIN'] = $sql_array['LEFT_JOIN'];
0542 $sql_anounce_array['LEFT_JOIN'][] = array('FROM' => array(FORUMS_TABLE => 'f'), 'ON' => 'f.forum_id = t.forum_id');
0543 $sql_anounce_array['SELECT'] = $sql_array['SELECT'] . ', f.forum_name';
0544
0545 // Obtain announcements ... removed sort ordering, sort by time in all cases
0546 $sql_ary = array(
0547 'SELECT' => $sql_anounce_array['SELECT'],
0548 'FROM' => $sql_array['FROM'],
0549 'LEFT_JOIN' => $sql_anounce_array['LEFT_JOIN'],
0550
0551 'WHERE' => '(t.forum_id = ' . $forum_id . '
0552 AND t.topic_type = ' . POST_ANNOUNCE . ') OR
0553 (' . $db->sql_in_set('t.forum_id', $g_forum_ary, false, true) . '
0554 AND t.topic_type = ' . POST_GLOBAL . ')',
0555
0556 'ORDER_BY' => 't.topic_time DESC',
0557 );
0558
0559 /**
0560 * Event to modify the SQL query before the announcement topic ids data is retrieved
0561 *
0562 * @event core.viewforum_get_announcement_topic_ids_data
0563 * @var array forum_data Data about the forum
0564 * @var array g_forum_ary Global announcement forums array
0565 * @var array sql_anounce_array SQL announcement array
0566 * @var array sql_ary SQL query array to get the announcement topic ids data
0567 * @var int forum_id The forum ID
0568 *
0569 * @since 3.1.10-RC1
0570 */
0571 $vars = array(
0572 'forum_data',
0573 'g_forum_ary',
0574 'sql_anounce_array',
0575 'sql_ary',
0576 'forum_id',
0577 );
0578 extract($phpbb_dispatcher->trigger_event('core.viewforum_get_announcement_topic_ids_data', compact($vars)));
0579
0580 $sql = $db->sql_build_query('SELECT', $sql_ary);
0581 $result = $db->sql_query($sql);
0582
0583 while ($row = $db->sql_fetchrow($result))
0584 {
0585 if (!$phpbb_content_visibility->is_visible('topic', $row['forum_id'], $row))
0586 {
0587 // Do not display announcements that are waiting for approval or soft deleted.
0588 continue;
0589 }
0590
0591 $rowset[$row['topic_id']] = $row;
0592 $announcement_list[] = $row['topic_id'];
0593
0594 if ($forum_id != $row['forum_id'])
0595 {
0596 $topics_count++;
0597 $global_announce_forums[] = $row['forum_id'];
0598 }
0599 }
0600 $db->sql_freeresult($result);
0601 }
0602
0603 $forum_tracking_info = array();
0604
0605 if ($user->data['is_registered'] && $config['load_db_lastread'])
0606 {
0607 $forum_tracking_info[$forum_id] = $forum_data['mark_time'];
0608
0609 if (!empty($global_announce_forums))
0610 {
0611 $sql = 'SELECT forum_id, mark_time
0612 FROM ' . FORUMS_TRACK_TABLE . '
0613 WHERE ' . $db->sql_in_set('forum_id', $global_announce_forums) . '
0614 AND user_id = ' . $user->data['user_id'];
0615 $result = $db->sql_query($sql);
0616
0617 while ($row = $db->sql_fetchrow($result))
0618 {
0619 $forum_tracking_info[$row['forum_id']] = $row['mark_time'];
0620 }
0621 $db->sql_freeresult($result);
0622 }
0623 }
0624
0625 // If the user is trying to reach late pages, start searching from the end
0626 $store_reverse = false;
0627 $sql_limit = $config['topics_per_page'];
0628 if ($start > $topics_count / 2)
0629 {
0630 $store_reverse = true;
0631
0632 // Select the sort order
0633 $direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
0634
0635 $sql_limit = $pagination->reverse_limit($start, $sql_limit, $topics_count - count($announcement_list));
0636 $sql_start = $pagination->reverse_start($start, $sql_limit, $topics_count - count($announcement_list));
0637 }
0638 else
0639 {
0640 // Select the sort order
0641 $direction = (($sort_dir == 'd') ? 'DESC' : 'ASC');
0642 $sql_start = $start;
0643 }
0644
0645 /**
0646 * Modify the topics sort ordering if needed
0647 *
0648 * @event core.viewforum_modify_sort_direction
0649 * @var string direction Topics sort order
0650 * @since 3.2.5-RC1
0651 */
0652 $vars = array(
0653 'direction',
0654 );
0655 extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_sort_direction', compact($vars)));
0656
0657 if (is_array($sort_by_sql[$sort_key]))
0658 {
0659 $sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
0660 }
0661 else
0662 {
0663 $sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
0664 }
0665
0666 if ($forum_data['forum_type'] == FORUM_POST || !count($active_forum_ary))
0667 {
0668 $sql_where = 't.forum_id = ' . $forum_id;
0669 }
0670 else if (empty($active_forum_ary['exclude_forum_id']))
0671 {
0672 $sql_where = $db->sql_in_set('t.forum_id', $active_forum_ary['forum_id']);
0673 }
0674 else
0675 {
0676 $get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']);
0677 $sql_where = (count($get_forum_ids)) ? $db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id;
0678 }
0679
0680 // Grab just the sorted topic ids
0681 $sql_ary = array(
0682 'SELECT' => 't.topic_id',
0683 'FROM' => array(
0684 TOPICS_TABLE => 't',
0685 ),
0686 'WHERE' => "$sql_where
0687 AND t.topic_type IN (" . POST_NORMAL . ', ' . POST_STICKY . ")
0688 $sql_approved
0689 $sql_limit_time",
0690 'ORDER_BY' => 't.topic_type ' . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order,
0691 );
0692
0693 /**
0694 * Event to modify the SQL query before the topic ids data is retrieved
0695 *
0696 * @event core.viewforum_get_topic_ids_data
0697 * @var array forum_data Data about the forum
0698 * @var array sql_ary SQL query array to get the topic ids data
0699 * @var string sql_approved Topic visibility SQL string
0700 * @var int sql_limit Number of records to select
0701 * @var string sql_limit_time SQL string to limit topic_last_post_time data
0702 * @var array sql_sort_order SQL sorting string
0703 * @var int sql_start Offset point to start selection from
0704 * @var string sql_where SQL WHERE clause string
0705 * @var bool store_reverse Flag indicating if we select from the late pages
0706 *
0707 * @since 3.1.0-RC4
0708 *
0709 * @changed 3.1.3 Added forum_data
0710 */
0711 $vars = array(
0712 'forum_data',
0713 'sql_ary',
0714 'sql_approved',
0715 'sql_limit',
0716 'sql_limit_time',
0717 'sql_sort_order',
0718 'sql_start',
0719 'sql_where',
0720 'store_reverse',
0721 );
0722 extract($phpbb_dispatcher->trigger_event('core.viewforum_get_topic_ids_data', compact($vars)));
0723
0724 $sql = $db->sql_build_query('SELECT', $sql_ary);
0725 $result = $db->sql_query_limit($sql, $sql_limit, $sql_start);
0726
0727 while ($row = $db->sql_fetchrow($result))
0728 {
0729 $topic_list[] = (int) $row['topic_id'];
0730 }
0731 $db->sql_freeresult($result);
0732
0733 // For storing shadow topics
0734 $shadow_topic_list = array();
0735
0736 if (count($topic_list))
0737 {
0738 // SQL array for obtaining topics/stickies
0739 $sql_array = array(
0740 'SELECT' => $sql_array['SELECT'],
0741 'FROM' => $sql_array['FROM'],
0742 'LEFT_JOIN' => $sql_array['LEFT_JOIN'],
0743 'WHERE' => $db->sql_in_set('t.topic_id', $topic_list),
0744 );
0745
0746 /**
0747 * Event to modify the SQL query before obtaining topics/stickies
0748 *
0749 * @event core.viewforum_modify_topic_list_sql
0750 * @var int forum_id The forum ID
0751 * @var array forum_data Data about the forum
0752 * @var array topic_list Topic ids array
0753 * @var array sql_array SQL query array for obtaining topics/stickies
0754 *
0755 * @since 3.2.10-RC1
0756 * @since 3.3.1-RC1
0757 */
0758 $vars = [
0759 'forum_id',
0760 'forum_data',
0761 'topic_list',
0762 'sql_array',
0763 ];
0764 extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topic_list_sql', compact($vars)));
0765
0766 // If store_reverse, then first obtain topics, then stickies, else the other way around...
0767 // Funnily enough you typically save one query if going from the last page to the middle (store_reverse) because
0768 // the number of stickies are not known
0769 $sql = $db->sql_build_query('SELECT', $sql_array);
0770 $result = $db->sql_query($sql);
0771
0772 while ($row = $db->sql_fetchrow($result))
0773 {
0774 if ($row['topic_status'] == ITEM_MOVED)
0775 {
0776 $shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
0777 }
0778
0779 $rowset[$row['topic_id']] = $row;
0780 }
0781 $db->sql_freeresult($result);
0782 }
0783
0784 // If we have some shadow topics, update the rowset to reflect their topic information
0785 if (count($shadow_topic_list))
0786 {
0787 // SQL array for obtaining shadow topics
0788 $sql_array = array(
0789 'SELECT' => 't.*',
0790 'FROM' => array(
0791 TOPICS_TABLE => 't'
0792 ),
0793 'WHERE' => $db->sql_in_set('t.topic_id', array_keys($shadow_topic_list)),
0794 );
0795
0796 /**
0797 * Event to modify the SQL query before the shadowtopic data is retrieved
0798 *
0799 * @event core.viewforum_get_shadowtopic_data
0800 * @var array sql_array SQL array to get the data of any shadowtopics
0801 * @since 3.1.0-a1
0802 */
0803 $vars = array('sql_array');
0804 extract($phpbb_dispatcher->trigger_event('core.viewforum_get_shadowtopic_data', compact($vars)));
0805
0806 $sql = $db->sql_build_query('SELECT', $sql_array);
0807 $result = $db->sql_query($sql);
0808
0809 while ($row = $db->sql_fetchrow($result))
0810 {
0811 $orig_topic_id = $shadow_topic_list[$row['topic_id']];
0812
0813 // If the shadow topic is already listed within the rowset (happens for active topics for example), then do not include it...
0814 if (isset($rowset[$row['topic_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 // Do not include those topics the user has no permission to access
0825 if (!$auth->acl_gets('f_read', 'f_list_topics', $row['forum_id']))
0826 {
0827 // We need to remove any trace regarding this topic. :)
0828 unset($rowset[$orig_topic_id]);
0829 unset($topic_list[array_search($orig_topic_id, $topic_list)]);
0830 $topics_count--;
0831
0832 continue;
0833 }
0834
0835 // We want to retain some values
0836 $row = array_merge($row, array(
0837 'topic_moved_id' => $rowset[$orig_topic_id]['topic_moved_id'],
0838 'topic_status' => $rowset[$orig_topic_id]['topic_status'],
0839 'topic_type' => $rowset[$orig_topic_id]['topic_type'],
0840 'topic_title' => $rowset[$orig_topic_id]['topic_title'],
0841 ));
0842
0843 // Shadow topics are never reported
0844 $row['topic_reported'] = 0;
0845
0846 $rowset[$orig_topic_id] = $row;
0847 }
0848 $db->sql_freeresult($result);
0849 }
0850 unset($shadow_topic_list);
0851
0852 // Ok, adjust topics count for active topics list
0853 if ($s_display_active)
0854 {
0855 $topics_count = 1;
0856 }
0857
0858 // We need to remove the global announcements from the forums total topic count,
0859 // otherwise the number is different from the one on the forum list
0860 $total_topic_count = $topics_count - count($announcement_list);
0861
0862 $base_url = append_sid("{$phpbb_root_path}viewforum.$phpEx", "f=$forum_id" . ((strlen($u_sort_param)) ? "&$u_sort_param" : ''));
0863 $pagination->generate_template_pagination($base_url, 'pagination', 'start', $total_topic_count, $config['topics_per_page'], $start);
0864
0865 $template->assign_vars(array(
0866 'TOTAL_TOPICS' => ($s_display_active) ? false : $user->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count),
0867 ));
0868
0869 $topic_list = ($store_reverse) ? array_merge($announcement_list, array_reverse($topic_list)) : array_merge($announcement_list, $topic_list);
0870 $topic_tracking_info = $tracking_topics = array();
0871
0872 /**
0873 * Modify topics data before we display the viewforum page
0874 *
0875 * @event core.viewforum_modify_topics_data
0876 * @var array topic_list Array with current viewforum page topic ids
0877 * @var array rowset Array with topics data (in topic_id => topic_data format)
0878 * @var int total_topic_count Forum's total topic count
0879 * @var int forum_id Forum identifier
0880 * @since 3.1.0-b3
0881 * @changed 3.1.11-RC1 Added forum_id
0882 */
0883 $vars = array('topic_list', 'rowset', 'total_topic_count', 'forum_id');
0884 extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topics_data', compact($vars)));
0885
0886 // Okay, lets dump out the page ...
0887 if (count($topic_list))
0888 {
0889 $mark_forum_read = true;
0890 $mark_time_forum = 0;
0891
0892 // Generate topic forum list...
0893 $topic_forum_list = array();
0894 foreach ($rowset as $t_id => $row)
0895 {
0896 if (isset($forum_tracking_info[$row['forum_id']]))
0897 {
0898 $row['forum_mark_time'] = $forum_tracking_info[$row['forum_id']];
0899 }
0900
0901 $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;
0902 $topic_forum_list[$row['forum_id']]['topics'][] = (int) $t_id;
0903 }
0904
0905 if ($config['load_db_lastread'] && $user->data['is_registered'])
0906 {
0907 foreach ($topic_forum_list as $f_id => $topic_row)
0908 {
0909 $topic_tracking_info += get_topic_tracking($f_id, $topic_row['topics'], $rowset, array($f_id => $topic_row['forum_mark_time']));
0910 }
0911 }
0912 else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0913 {
0914 foreach ($topic_forum_list as $f_id => $topic_row)
0915 {
0916 $topic_tracking_info += get_complete_topic_tracking($f_id, $topic_row['topics']);
0917 }
0918 }
0919
0920 unset($topic_forum_list);
0921
0922 if (!$s_display_active)
0923 {
0924 if ($config['load_db_lastread'] && $user->data['is_registered'])
0925 {
0926 $mark_time_forum = (!empty($forum_data['mark_time'])) ? $forum_data['mark_time'] : $user->data['user_lastmark'];
0927 }
0928 else if ($config['load_anon_lastread'] || $user->data['is_registered'])
0929 {
0930 if (!$user->data['is_registered'])
0931 {
0932 $user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
0933 }
0934 $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'];
0935 }
0936 }
0937
0938 $s_type_switch = 0;
0939 foreach ($topic_list as $topic_id)
0940 {
0941 $row = &$rowset[$topic_id];
0942
0943 $topic_forum_id = ($row['forum_id']) ? (int) $row['forum_id'] : $forum_id;
0944
0945 // This will allow the style designer to output a different header
0946 // or even separate the list of announcements from sticky and normal topics
0947 $s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
0948
0949 // Replies
0950 $replies = $phpbb_content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1;
0951 // Correction for case of unapproved topic visible to poster
0952 if ($replies < 0)
0953 {
0954 $replies = 0;
0955 }
0956
0957 if ($row['topic_status'] == ITEM_MOVED)
0958 {
0959 $topic_id = $row['topic_moved_id'];
0960 $unread_topic = false;
0961 }
0962 else
0963 {
0964 $unread_topic = (isset($topic_tracking_info[$topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
0965 }
0966
0967 // Get folder img, topic status/type related information
0968 $folder_img = $folder_alt = $topic_type = '';
0969 topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
0970
0971 // Generate all the URIs ...
0972 $view_topic_url_params = 't=' . $topic_id;
0973 $view_topic_url = $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params) : false;
0974
0975 $topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $auth->acl_get('m_approve', $row['forum_id']));
0976 $posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $auth->acl_get('m_approve', $row['forum_id']));
0977 $topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
0978
0979 $u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=' . (($topic_unapproved) ? 'approve_details' : 'unapproved_posts') . "&t=$topic_id", true, $user->session_id) : '';
0980 $u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=queue&mode=deleted_topics&t=' . $topic_id, true, $user->session_id) : $u_mcp_queue;
0981
0982 // Send vars to template
0983 $topic_row = array(
0984 'FORUM_ID' => $row['forum_id'],
0985 'TOPIC_ID' => $topic_id,
0986 'TOPIC_AUTHOR' => get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0987 'TOPIC_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0988 'TOPIC_AUTHOR_FULL' => get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
0989 'FIRST_POST_TIME' => $user->format_date($row['topic_time']),
0990 'FIRST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_time']),
0991 'LAST_POST_SUBJECT' => censor_text($row['topic_last_post_subject']),
0992 'LAST_POST_TIME' => $user->format_date($row['topic_last_post_time']),
0993 'LAST_POST_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_post_time']),
0994 'LAST_VIEW_TIME' => $user->format_date($row['topic_last_view_time']),
0995 'LAST_VIEW_TIME_RFC3339' => gmdate(DATE_RFC3339, $row['topic_last_view_time']),
0996 'LAST_POST_AUTHOR' => get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
0997 'LAST_POST_AUTHOR_COLOUR' => get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
0998 'LAST_POST_AUTHOR_FULL' => get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
0999
1000 'REPLIES' => $replies,
1001 'VIEWS' => $row['topic_views'],
1002 'TOPIC_TITLE' => censor_text($row['topic_title']),
1003 'TOPIC_TYPE' => $topic_type,
1004 'FORUM_NAME' => (isset($row['forum_name'])) ? $row['forum_name'] : $forum_data['forum_name'],
1005
1006 'TOPIC_IMG_STYLE' => $folder_img,
1007 'TOPIC_FOLDER_IMG' => $user->img($folder_img, $folder_alt),
1008 'TOPIC_FOLDER_IMG_ALT' => $user->lang[$folder_alt],
1009
1010 'TOPIC_ICON_IMG' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
1011 'TOPIC_ICON_IMG_WIDTH' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
1012 'TOPIC_ICON_IMG_HEIGHT' => (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
1013 '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']) : '',
1014 'UNAPPROVED_IMG' => ($topic_unapproved || $posts_unapproved) ? $user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
1015
1016 'S_TOPIC_TYPE' => $row['topic_type'],
1017 'S_USER_POSTED' => (isset($row['topic_posted']) && $row['topic_posted']) ? true : false,
1018 'S_UNREAD_TOPIC' => $unread_topic,
1019 'S_TOPIC_REPORTED' => (!empty($row['topic_reported']) && $auth->acl_get('m_report', $row['forum_id'])) ? true : false,
1020 'S_TOPIC_UNAPPROVED' => $topic_unapproved,
1021 'S_POSTS_UNAPPROVED' => $posts_unapproved,
1022 'S_TOPIC_DELETED' => $topic_deleted,
1023 'S_HAS_POLL' => ($row['poll_start']) ? true : false,
1024 'S_POST_ANNOUNCE' => ($row['topic_type'] == POST_ANNOUNCE) ? true : false,
1025 'S_POST_GLOBAL' => ($row['topic_type'] == POST_GLOBAL) ? true : false,
1026 'S_POST_STICKY' => ($row['topic_type'] == POST_STICKY) ? true : false,
1027 'S_TOPIC_LOCKED' => ($row['topic_status'] == ITEM_LOCKED) ? true : false,
1028 'S_TOPIC_MOVED' => ($row['topic_status'] == ITEM_MOVED) ? true : false,
1029
1030 'U_NEWEST_POST' => $auth->acl_get('f_read', $forum_id) ? append_sid("{$phpbb_root_path}viewtopic.$phpEx", $view_topic_url_params . '&view=unread') . '#unread' : false,
1031 '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,
1032 'U_LAST_POST_AUTHOR' => get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
1033 'U_TOPIC_AUTHOR' => get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
1034 'U_VIEW_TOPIC' => $view_topic_url,
1035 'U_VIEW_FORUM' => append_sid("{$phpbb_root_path}viewforum.$phpEx", 'f=' . $row['forum_id']),
1036 'U_MCP_REPORT' => append_sid("{$phpbb_root_path}mcp.$phpEx", 'i=reports&mode=reports&t=' . $topic_id, true, $user->session_id),
1037 'U_MCP_QUEUE' => $u_mcp_queue,
1038
1039 'S_TOPIC_TYPE_SWITCH' => ($s_type_switch == $s_type_switch_test) ? -1 : $s_type_switch_test,
1040 );
1041
1042 /**
1043 * Modify the topic data before it is assigned to the template
1044 *
1045 * @event core.viewforum_modify_topicrow
1046 * @var array row Array with topic data
1047 * @var array topic_row Template array with topic data
1048 * @var bool s_type_switch Flag indicating if the topic type is [global] announcement
1049 * @var bool s_type_switch_test Flag indicating if the test topic type is [global] announcement
1050 * @since 3.1.0-a1
1051 *
1052 * @changed 3.1.10-RC1 Added s_type_switch, s_type_switch_test
1053 */
1054 $vars = array('row', 'topic_row', 's_type_switch', 's_type_switch_test');
1055 extract($phpbb_dispatcher->trigger_event('core.viewforum_modify_topicrow', compact($vars)));
1056
1057 $template->assign_block_vars('topicrow', $topic_row);
1058
1059 $pagination->generate_template_pagination($topic_row['U_VIEW_TOPIC'], 'topicrow.pagination', 'start', (int) $topic_row['REPLIES'] + 1, $config['posts_per_page'], 1, true, true);
1060
1061 $s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
1062
1063 /**
1064 * Event after the topic data has been assigned to the template
1065 *
1066 * @event core.viewforum_topic_row_after
1067 * @var array row Array with the topic data
1068 * @var array rowset Array with topics data (in topic_id => topic_data format)
1069 * @var bool s_type_switch Flag indicating if the topic type is [global] announcement
1070 * @var int topic_id The topic ID
1071 * @var array topic_list Array with current viewforum page topic ids
1072 * @var array topic_row Template array with topic data
1073 * @since 3.1.3-RC1
1074 */
1075 $vars = array(
1076 'row',
1077 'rowset',
1078 's_type_switch',
1079 'topic_id',
1080 'topic_list',
1081 'topic_row',
1082 );
1083 extract($phpbb_dispatcher->trigger_event('core.viewforum_topic_row_after', compact($vars)));
1084
1085 if ($unread_topic)
1086 {
1087 $mark_forum_read = false;
1088 }
1089
1090 unset($rowset[$topic_id]);
1091 }
1092 }
1093
1094 /**
1095 * This event is to perform additional actions on viewforum page
1096 *
1097 * @event core.viewforum_generate_page_after
1098 * @var array forum_data Array with the forum data
1099 * @since 3.2.2-RC1
1100 */
1101 $vars = array('forum_data');
1102 extract($phpbb_dispatcher->trigger_event('core.viewforum_generate_page_after', compact($vars)));
1103
1104 // This is rather a fudge but it's the best I can think of without requiring information
1105 // on all topics (as we do in 2.0.x). It looks for unread or new topics, if it doesn't find
1106 // any it updates the forum last read cookie. This requires that the user visit the forum
1107 // after reading a topic
1108 if ($forum_data['forum_type'] == FORUM_POST && count($topic_list) && $mark_forum_read)
1109 {
1110 update_forum_tracking_info($forum_id, $forum_data['forum_last_post_time'], false, $mark_time_forum);
1111 }
1112
1113 page_footer();
1114