forum::main()   F
last analyzed

Complexity

Conditions 127
Paths > 20000

Duplication

Lines 0
Ratio 0 %

Size

Total Lines 694
Code Lines 366

Importance

Changes 0
Metric Value
dl 0
loc 694
rs 2
c 0
b 0
f 0
cc 127
eloc 366
nc 429496.7295
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
* This file is part of the VinaBB.vn package.
4
*
5
* @copyright (c) VinaBB <vinabb.vn>
6
* @license GNU General Public License, version 2 (GPL-2.0)
7
*/
8
9
namespace vinabb\web\controllers\board;
10
11
use vinabb\web\includes\constants;
12
13
/**
14
* Controller for the forum page
15
*/
16
class forum implements forum_interface
17
{
18
	/** @var \phpbb\auth\auth $auth */
19
	protected $auth;
20
21
	/** @var \phpbb\cache\service $cache */
22
	protected $cache;
23
24
	/** @var \phpbb\config\config $config */
25
	protected $config;
26
27
	/** @var \phpbb\content_visibility $content_visibility */
28
	protected $content_visibility;
29
30
	/** @var \phpbb\cron\manager $cron */
31
	protected $cron;
32
33
	/** @var \phpbb\db\driver\driver_interface $db */
34
	protected $db;
35
36
	/** @var \phpbb\language\language $language */
37
	protected $language;
38
39
	/** @var \vinabb\web\controllers\pagination $pagination */
40
	protected $pagination;
41
42
	/** @var \phpbb\request\request $request */
43
	protected $request;
44
45
	/** @var \phpbb\template\template $template */
46
	protected $template;
47
48
	/** @var \phpbb\user $user */
49
	protected $user;
50
51
	/** @var \phpbb\controller\helper $helper */
52
	protected $helper;
53
54
	/** @var string $root_path */
55
	protected $root_path;
56
57
	/** @var string $php_ext */
58
	protected $php_ext;
59
60
	/** @var array $forum_data */
61
	protected $forum_data;
62
63
	/** @var int $start */
64
	protected $start;
65
66
	/**
67
	* Constructor
68
	*
69
	* @param \phpbb\auth\auth							$auth				Authentication object
70
	* @param \phpbb\cache\service						$cache				Cache service
71
	* @param \phpbb\config\config						$config				Config object
72
	* @param \phpbb\content_visibility					$content_visibility	Content visibility
73
	* @param \phpbb\cron\manager						$cron				Cron manager
74
	* @param \phpbb\db\driver\driver_interface			$db					Database object
75
	* @param \phpbb\language\language					$language			Language object
76
	* @param \vinabb\web\controllers\pagination			$pagination			Pagination object
77
	* @param \phpbb\request\request						$request			Request object
78
	* @param \phpbb\template\template					$template			Template object
79
	* @param \phpbb\user								$user				User object
80
	* @param \phpbb\controller\helper					$helper				Controller helper
81
	* @param string										$root_path			phpBB root path
82
	* @param string										$php_ext			PHP file extension
83
	*/
84
	public function __construct(
85
		\phpbb\auth\auth $auth,
86
		\phpbb\cache\service $cache,
87
		\phpbb\config\config $config,
88
		\phpbb\content_visibility $content_visibility,
89
		\phpbb\cron\manager $cron,
90
		\phpbb\db\driver\driver_interface $db,
91
		\phpbb\language\language $language,
92
		\vinabb\web\controllers\pagination $pagination,
93
		\phpbb\request\request $request,
94
		\phpbb\template\template $template,
95
		\phpbb\user $user,
96
		\phpbb\controller\helper $helper,
97
		$root_path,
98
		$php_ext
99
	)
100
	{
101
		$this->auth = $auth;
102
		$this->cache = $cache;
103
		$this->config = $config;
104
		$this->content_visibility = $content_visibility;
105
		$this->cron = $cron;
106
		$this->db = $db;
107
		$this->language = $language;
108
		$this->pagination = $pagination;
109
		$this->request = $request;
110
		$this->template = $template;
111
		$this->user = $user;
112
		$this->helper = $helper;
113
		$this->root_path = $root_path;
114
		$this->php_ext = $php_ext;
115
	}
116
117
	/**
118
	* Main method
119
	*
120
	* @param int 	$forum_id	Forum ID
121
	* @param string $page		Page number
122
	*/
123
	public function main($forum_id, $page)
124
	{
125
		global $_SID, $_EXTRA_URL;
126
127
		// Common functions
128
		include "{$this->root_path}includes/functions_display.{$this->php_ext}";
129
130
		// Get forum data first
131
		$this->get_forum_data($forum_id);
132
133
		// Is a forum specific topic count required?
134
		if ($this->forum_data['forum_topics_per_page'])
135
		{
136
			$this->config['topics_per_page'] = $this->forum_data['forum_topics_per_page'];
137
		}
138
139
		$page = max(1, floor(str_replace(constants::REWRITE_URL_PAGE, '', $page)));
140
		$this->start = intval(($page - 1) * $this->config['topics_per_page']);
141
142
		// Start initial var setup
143
		$sort_days = $this->request->variable('st', $this->user->data['user_topic_show_days']);
144
		$sort_key = $this->request->variable('sk', $this->user->data['user_topic_sortby_type']);
145
		$sort_dir = $this->request->variable('sd', $this->user->data['user_topic_sortby_dir']);
146
147
		// Configure style, language, etc.
148
		$this->user->setup('viewforum', $this->forum_data['forum_style']);
149
150
		$this->require_login();
151
152
		// Is this forum a link? ... User got here either because the
153
		// number of clicks is being tracked or they guessed the id
154
		$this->update_click_counter();
155
156
		// Build navigation links
157
		generate_forum_nav($this->forum_data);
158
159
		// Forum Rules
160
		generate_forum_rules($this->forum_data);
161
162
		// Do we have subforums?
163
		$active_forum_ary = $moderators = [];
164
165
		if ($this->forum_data['left_id'] != $this->forum_data['right_id'] - 1)
166
		{
167
			list($active_forum_ary, $moderators) = display_forums($this->forum_data, $this->config['load_moderators'], $this->config['load_moderators']);
168
		}
169
		else
170
		{
171
			$this->template->assign_var('S_HAS_SUBFORUM', false);
172
173
			if ($this->config['load_moderators'])
174
			{
175
				get_moderators($moderators, $forum_id);
176
			}
177
		}
178
179
		// Dump out the page header and load viewforum template
180
		$topics_count = $this->content_visibility->get_count('forum_topics', $this->forum_data, $forum_id);
181
		$this->start = (int) $this->pagination->validate_start($this->start, $this->config['topics_per_page'], $topics_count);
182
183
		page_header($this->forum_data['forum_name'] . ($this->start ? ' - ' . $this->language->lang('PAGE_TITLE_NUMBER', $this->pagination->get_on_page($this->config['topics_per_page'], $this->start)) : ''), true, $forum_id);
184
185
		$this->template->set_filenames([
186
			'body'	=> 'viewforum_body.html'
187
		]);
188
189
		$this->template->assign_vars([
190
			'S_VIEWFORUM'	=> true,
191
			'U_VIEW_FORUM'	=> $this->helper->route('vinabb_web_board_forum_route', ($this->start == 0) ? ['forum_id' => $forum_id] : ['forum_id' => $forum_id, 'seo' => $this->forum_data['forum_name_seo'] . constants::REWRITE_URL_SEO, 'page' => constants::REWRITE_URL_PAGE . $this->pagination->get_on_page($this->config['topics_per_page'], $this->start)])
192
		]);
193
194
		// Not postable forum or showing active topics?
195
		if (!($this->forum_data['forum_type'] == FORUM_POST || (($this->forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS) && $this->forum_data['forum_type'] == FORUM_CAT)))
196
		{
197
			page_footer();
198
		}
199
200
		// Ok, if someone has only list-access, we only display the forum list.
201
		// We also make this circumstance available to the template in case we want to display a notice. ;)
202
		if (!$this->auth->acl_get('f_read', $forum_id))
203
		{
204
			$this->template->assign_var('S_NO_READ_ACCESS', true);
205
206
			page_footer();
207
		}
208
209
		// Handle marking topics
210
		$this->mark_topics();
211
212
		// Do the forum Prune thang - cron type job...
213
		$this->run_cron_tasks();
214
215
		// Forum subscription
216
		$this->subscribe_forum();
217
218
		// Forum posting permission list
219
		gen_forum_auth_level('forum', $forum_id, $this->forum_data['forum_status']);
220
221
		// Topic ordering options
222
		$limit_days = [
223
			0	=> $this->language->lang('ALL_TOPICS'),
224
			1	=> $this->language->lang('1_DAY'),
225
			7	=> $this->language->lang('7_DAYS'),
226
			14	=> $this->language->lang('2_WEEKS'),
227
			30	=> $this->language->lang('1_MONTH'),
228
			90	=> $this->language->lang('3_MONTHS'),
229
			180	=> $this->language->lang('6_MONTHS'),
230
			365	=> $this->language->lang('1_YEAR')
231
		];
232
233
		$sort_by_text = [
234
			'a'	=> $this->language->lang('AUTHOR'),
235
			't'	=> $this->language->lang('POST_TIME'),
236
			'r'	=> $this->language->lang('REPLIES'),
237
			's'	=> $this->language->lang('SUBJECT'),
238
			'v'	=> $this->language->lang('VIEWS')
239
		];
240
241
		$sort_by_sql = [
242
			'a'	=> 't.topic_first_poster_name',
243
			't'	=> ['t.topic_last_post_time', 't.topic_last_post_id'],
244
			'r'	=> (($this->auth->acl_get('m_approve', $forum_id)) ? 't.topic_posts_approved + t.topic_posts_unapproved + t.topic_posts_softdeleted' : 't.topic_posts_approved'),
245
			's'	=> $this->db->sql_lower_text('t.topic_title'),
246
			'v'	=> 't.topic_views'
247
		];
248
249
		$s_limit_days = $s_sort_key = $s_sort_dir = $u_sort_param = '';
250
251
		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, $this->user->data['user_topic_show_days'], $this->user->data['user_topic_sortby_type'], $this->user->data['user_topic_sortby_dir']);
252
253
		// Convert $u_sort_param from string to array
254
		$u_sort_param_ary = [];
255
256
		if ($u_sort_param != '')
257
		{
258
			$u_sort_param = htmlspecialchars_decode($u_sort_param);
259
			$u_sort_param_raw_ary = explode('&', $u_sort_param);
260
261
			foreach ($u_sort_param_raw_ary as $u_sort_param_raw)
262
			{
263
				list($u_sort_param_raw_key, $u_sort_param_raw_value) = explode('=', $u_sort_param_raw);
264
				$u_sort_param_ary[$u_sort_param_raw_key] = $u_sort_param_raw_value;
265
			}
266
		}
267
268
		// Limit topics to certain time frame, obtain correct topic count
269
		if ($sort_days)
270
		{
271
			$min_post_time = time() - ($sort_days * 86400);
272
273
			$sql_array = [
274
				'SELECT'	=> 'COUNT(t.topic_id) AS num_topics',
275
				'FROM'		=> [TOPICS_TABLE => 't'],
276
				'WHERE'		=> 't.forum_id = ' . $forum_id . '
277
					AND (t.topic_last_post_time >= ' . $min_post_time . '
278
						OR t.topic_type = ' . POST_ANNOUNCE . '
279
						OR t.topic_type = ' . POST_GLOBAL . ')
280
					AND ' . $this->content_visibility->get_visibility_sql('topic', $forum_id, 't.')
281
			];
282
			$result = $this->db->sql_query($this->db->sql_build_query('SELECT', $sql_array));
283
			$topics_count = (int) $this->db->sql_fetchfield('num_topics');
284
			$this->db->sql_freeresult($result);
285
286
			if ($this->request->is_set_post('sort'))
287
			{
288
				$this->start = 0;
289
			}
290
291
			$sql_limit_time = "AND t.topic_last_post_time >= $min_post_time";
292
293
			// Make sure we have information about day selection ready
294
			$this->template->assign_var('S_SORT_DAYS', true);
295
		}
296
		else
297
		{
298
			$sql_limit_time = '';
299
		}
300
301
		// Display active topics?
302
		$s_display_active = ($this->forum_data['forum_type'] == FORUM_CAT && ($this->forum_data['forum_flags'] & FORUM_FLAG_ACTIVE_TOPICS)) ? true : false;
303
304
		// Search hidden fields
305
		$s_search_hidden_fields = ['fid' => [$forum_id]];
306
307
		if (!empty($_SID))
308
		{
309
			$s_search_hidden_fields['sid'] = $_SID;
310
		}
311
312
		if (!empty($_EXTRA_URL))
313
		{
314
			foreach ($_EXTRA_URL as $url_param)
315
			{
316
				$url_param = explode('=', $url_param, 2);
317
				$s_search_hidden_fields[$url_param[0]] = $url_param[1];
318
			}
319
		}
320
321
		// Build forum URL with parameters
322
		$forum_url_params = ['forum_id' => $forum_id];
323
324
		if ($this->start)
325
		{
326
			$forum_url_params['page'] = constants::REWRITE_URL_PAGE . $this->pagination->get_on_page($this->config['topics_per_page'], $this->start);
327
		}
328
329
		$forum_url_params['seo'] = $this->forum_data['forum_name_seo'] . constants::REWRITE_URL_SEO;
330
		$forum_url_sort_params = $forum_url_params;
331
332
		if (!empty($u_sort_param_ary))
333
		{
334
			$forum_url_sort_params = array_merge($forum_url_sort_params, $u_sort_param_ary);
335
		}
336
337
		// Output
338
		$this->template->assign_vars([
339
			'MODERATORS'	=> (!empty($moderators[$forum_id])) ? implode($this->language->lang('COMMA_SEPARATOR'), $moderators[$forum_id]) : '',
340
341
			'L_NO_TOPICS' 			=> ($this->forum_data['forum_status'] == ITEM_LOCKED) ? $this->language->lang('POST_FORUM_LOCKED') : $this->language->lang('NO_TOPICS'),
342
343
			'S_DISPLAY_POST_INFO'	=> ($this->forum_data['forum_type'] == FORUM_POST && ($this->auth->acl_get('f_post', $forum_id) || $this->user->data['user_id'] == ANONYMOUS)) ? true : false,
344
345
			'S_IS_POSTABLE'					=> $this->forum_data['forum_type'] == FORUM_POST,
346
			'S_USER_CAN_POST'				=> $this->auth->acl_get('f_post', $forum_id),
347
			'S_DISPLAY_ACTIVE'				=> $s_display_active,
348
			'S_SELECT_SORT_DIR'				=> $s_sort_dir,
349
			'S_SELECT_SORT_KEY'				=> $s_sort_key,
350
			'S_SELECT_SORT_DAYS'			=> $s_limit_days,
351
			'S_TOPIC_ICONS'					=> ($s_display_active && !empty($active_forum_ary)) ? max($active_forum_ary['enable_icons']) : $this->forum_data['enable_icons'],
352
			'S_FORUM_ACTION'				=> $this->helper->route('vinabb_web_board_forum_route', $forum_url_params),
353
			'S_DISPLAY_SEARCHBOX'			=> ($this->auth->acl_get('u_search') && $this->auth->acl_get('f_search', $forum_id) && $this->config['load_search']),
354
			'S_SEARCHBOX_ACTION'			=> append_sid("{$this->root_path}search.{$this->php_ext}"),
355
			'S_SEARCH_LOCAL_HIDDEN_FIELDS'	=> build_hidden_fields($s_search_hidden_fields),
356
			'S_SINGLE_MODERATOR'			=> isset($moderators[$forum_id]) && (count($moderators[$forum_id]) == 1),
357
			'S_IS_LOCKED'					=> $this->forum_data['forum_status'] == ITEM_LOCKED,
358
			'S_VIEWFORUM'					=> true,
359
360
			'U_MCP'				=> ($this->auth->acl_get('m_', $forum_id)) ? $this->helper->route('vinabb_web_mcp_route', ['id' => 'main', 'mode' => 'forum_view', 'f' => $forum_id], true, $this->user->session_id) : '',
361
			'U_POST_NEW_TOPIC'	=> ($this->auth->acl_get('f_post', $forum_id) || $this->user->data['user_id'] == ANONYMOUS) ? append_sid("{$this->root_path}posting.{$this->php_ext}", 'mode=post&amp;f=' . $forum_id) : '',
362
			'U_VIEW_FORUM'		=> $this->helper->route('vinabb_web_board_forum_route', $forum_url_sort_params),
363
			'U_CANONICAL'		=> generate_board_url(true) . htmlspecialchars_decode($this->helper->route('vinabb_web_board_forum_route', $forum_url_params)),
364
			'U_MARK_TOPICS'		=> ($this->user->data['is_registered'] || $this->config['load_anon_lastread']) ? $this->helper->route('vinabb_web_board_forum_route', ['forum_id' => $forum_id, 'seo' => $this->forum_data['forum_name_seo'] . constants::REWRITE_URL_SEO, 'hash' => generate_link_hash('global'), 'mark' => 'topics', 'mark_time' => time()]) : '',
365
		]);
366
367
		// Grab icons
368
		$icons = $this->cache->obtain_icons();
369
370
		// Grab all topic data
371
		$rowset = $announcement_list = $topic_list = $global_announce_forums = [];
372
373
		$sql_array = [
374
			'SELECT'	=> 't.*',
375
			'FROM'		=> [TOPICS_TABLE => 't'],
376
			'LEFT_JOIN'	=> []
377
		];
378
379
		$sql_approved = ' AND ' . $this->content_visibility->get_visibility_sql('topic', $forum_id, 't.');
380
381
		if ($this->user->data['is_registered'])
382
		{
383
			if ($this->config['load_db_track'])
384
			{
385
				$sql_array['LEFT_JOIN'][] = ['FROM' => [TOPICS_POSTED_TABLE => 'tp'], 'ON' => 'tp.topic_id = t.topic_id AND tp.user_id = ' . $this->user->data['user_id']];
386
				$sql_array['SELECT'] .= ', tp.topic_posted';
387
			}
388
389
			if ($this->config['load_db_lastread'])
390
			{
391
				$sql_array['LEFT_JOIN'][] = ['FROM' => [TOPICS_TRACK_TABLE => 'tt'], 'ON' => 'tt.topic_id = t.topic_id AND tt.user_id = ' . $this->user->data['user_id']];
392
				$sql_array['SELECT'] .= ', tt.mark_time';
393
394
				if ($s_display_active && !empty($active_forum_ary))
395
				{
396
					$sql_array['LEFT_JOIN'][] = ['FROM' => [FORUMS_TRACK_TABLE => 'ft'], 'ON' => 'ft.forum_id = t.forum_id AND ft.user_id = ' . $this->user->data['user_id']];
397
					$sql_array['SELECT'] .= ', ft.mark_time AS forum_mark_time';
398
				}
399
			}
400
		}
401
402
		if ($this->forum_data['forum_type'] == FORUM_POST)
403
		{
404
			// Get global announcement forums
405
			$g_forum_ary = $this->auth->acl_getf('f_read', true);
406
			$g_forum_ary = array_unique(array_keys($g_forum_ary));
407
408
			$sql_anounce_array['LEFT_JOIN'] = $sql_array['LEFT_JOIN'];
409
			$sql_anounce_array['LEFT_JOIN'][] = ['FROM' => [FORUMS_TABLE => 'f'], 'ON' => 'f.forum_id = t.forum_id'];
410
			$sql_anounce_array['SELECT'] = $sql_array['SELECT'] . ', f.forum_name';
411
412
			// Obtain announcements ... removed sort ordering, sort by time in all cases
413
			$sql_ary = [
414
				'SELECT'	=> $sql_anounce_array['SELECT'],
415
				'FROM'		=> $sql_array['FROM'],
416
				'LEFT_JOIN'	=> $sql_anounce_array['LEFT_JOIN'],
417
418
				'WHERE'		=> '(t.forum_id = ' . $forum_id . '
419
					AND t.topic_type = ' . POST_ANNOUNCE . ') OR
420
						(' . $this->db->sql_in_set('t.forum_id', $g_forum_ary) . '
421
					AND t.topic_type = ' . POST_GLOBAL . ')',
422
423
				'ORDER_BY'	=> 't.topic_time DESC'
424
			];
425
			$sql = $this->db->sql_build_query('SELECT', $sql_ary);
426
			$result = $this->db->sql_query($sql);
427
428
			while ($row = $this->db->sql_fetchrow($result))
429
			{
430
				if ($row['topic_visibility'] != ITEM_APPROVED && !$this->auth->acl_get('m_approve', $row['forum_id']))
431
				{
432
					// Do not display announcements that are waiting for approval or soft deleted.
433
					continue;
434
				}
435
436
				$rowset[$row['topic_id']] = $row;
437
				$announcement_list[] = $row['topic_id'];
438
439
				if ($forum_id != $row['forum_id'])
440
				{
441
					$topics_count++;
442
					$global_announce_forums[] = $row['forum_id'];
443
				}
444
			}
445
			$this->db->sql_freeresult($result);
446
		}
447
448
		$forum_tracking_info = [];
449
450
		if ($this->user->data['is_registered'] && $this->config['load_db_lastread'])
451
		{
452
			$forum_tracking_info[$forum_id] = $this->forum_data['mark_time'];
453
454
			if (!empty($global_announce_forums))
455
			{
456
				$sql = 'SELECT forum_id, mark_time
457
					FROM ' . FORUMS_TRACK_TABLE . '
458
					WHERE ' . $this->db->sql_in_set('forum_id', $global_announce_forums) . '
459
						AND user_id = ' . $this->user->data['user_id'];
460
				$result = $this->db->sql_query($sql);
461
462
				while ($row = $this->db->sql_fetchrow($result))
463
				{
464
					$forum_tracking_info[$row['forum_id']] = $row['mark_time'];
465
				}
466
				$this->db->sql_freeresult($result);
467
			}
468
		}
469
470
		// If the user is trying to reach late pages, start searching from the end
471
		$store_reverse = false;
472
		$sql_limit = $this->config['topics_per_page'];
473
474
		if ($this->start > $topics_count / 2)
475
		{
476
			$store_reverse = true;
477
478
			// Select the sort order
479
			$direction = (($sort_dir == 'd') ? 'ASC' : 'DESC');
480
481
			$sql_limit = $this->pagination->reverse_limit($this->start, $sql_limit, $topics_count - count($announcement_list));
482
			$sql_start = $this->pagination->reverse_start($this->start, $sql_limit, $topics_count - count($announcement_list));
483
		}
484
		else
485
		{
486
			// Select the sort order
487
			$direction = (($sort_dir == 'd') ? 'DESC' : 'ASC');
488
			$sql_start = $this->start;
489
		}
490
491
		if (is_array($sort_by_sql[$sort_key]))
492
		{
493
			$sql_sort_order = implode(' ' . $direction . ', ', $sort_by_sql[$sort_key]) . ' ' . $direction;
494
		}
495
		else
496
		{
497
			$sql_sort_order = $sort_by_sql[$sort_key] . ' ' . $direction;
498
		}
499
500
		if ($this->forum_data['forum_type'] == FORUM_POST || empty($active_forum_ary))
501
		{
502
			$sql_where = 't.forum_id = ' . $forum_id;
503
		}
504
		else if (empty($active_forum_ary['exclude_forum_id']))
505
		{
506
			$sql_where = $this->db->sql_in_set('t.forum_id', $active_forum_ary['forum_id']);
507
		}
508
		else
509
		{
510
			$get_forum_ids = array_diff($active_forum_ary['forum_id'], $active_forum_ary['exclude_forum_id']);
511
			$sql_where = !empty($get_forum_ids) ? $this->db->sql_in_set('t.forum_id', $get_forum_ids) : 't.forum_id = ' . $forum_id;
512
		}
513
514
		// Grab just the sorted topic ids
515
		$sql_ary = [
516
			'SELECT'	=> 't.topic_id',
517
			'FROM'		=> [TOPICS_TABLE => 't'],
518
			'WHERE'		=> "$sql_where
519
				AND " . $this->db->sql_in_set('t.topic_type', [POST_NORMAL, POST_STICKY]) . "
520
				$sql_approved
521
				$sql_limit_time",
522
			'ORDER_BY'	=> 't.topic_type ' . ((!$store_reverse) ? 'DESC' : 'ASC') . ', ' . $sql_sort_order,
523
		];
524
		$sql = $this->db->sql_build_query('SELECT', $sql_ary);
525
		$result = $this->db->sql_query_limit($sql, $sql_limit, $sql_start);
526
527
		while ($row = $this->db->sql_fetchrow($result))
528
		{
529
			$topic_list[] = (int) $row['topic_id'];
530
		}
531
		$this->db->sql_freeresult($result);
532
533
		// For storing shadow topics
534
		$shadow_topic_list = [];
535
536
		if (!empty($topic_list))
537
		{
538
			// SQL array for obtaining topics/stickies
539
			$sql_array = [
540
				'SELECT'	=> $sql_array['SELECT'],
541
				'FROM'		=> $sql_array['FROM'],
542
				'LEFT_JOIN'	=> $sql_array['LEFT_JOIN'],
543
				'WHERE'		=> $this->db->sql_in_set('t.topic_id', $topic_list)
544
			];
545
546
			// If store_reverse, then first obtain topics, then stickies, else the other way around...
547
			// Funnily enough you typically save one query if going from the last page to the middle (store_reverse) because
548
			// the number of stickies are not known
549
			$sql = $this->db->sql_build_query('SELECT', $sql_array);
550
			$result = $this->db->sql_query($sql);
551
552
			while ($row = $this->db->sql_fetchrow($result))
553
			{
554
				if ($row['topic_status'] == ITEM_MOVED)
555
				{
556
					$shadow_topic_list[$row['topic_moved_id']] = $row['topic_id'];
557
				}
558
559
				$rowset[$row['topic_id']] = $row;
560
			}
561
			$this->db->sql_freeresult($result);
562
		}
563
564
		// If we have some shadow topics, update the rowset to reflect their topic information
565
		if (!empty($shadow_topic_list))
566
		{
567
			// SQL array for obtaining shadow topics
568
			$sql_array = [
569
				'SELECT'	=> 't.*',
570
				'FROM'		=> [TOPICS_TABLE => 't'],
571
				'WHERE'		=> $this->db->sql_in_set('t.topic_id', array_keys($shadow_topic_list))
572
			];
573
			$sql = $this->db->sql_build_query('SELECT', $sql_array);
574
			$result = $this->db->sql_query($sql);
575
576
			while ($row = $this->db->sql_fetchrow($result))
577
			{
578
				$orig_topic_id = $shadow_topic_list[$row['topic_id']];
579
580
				// If the shadow topic is already listed within the rowset (happens for active topics for example), then do not include it...
581
				if (isset($rowset[$row['topic_id']]))
582
				{
583
					// We need to remove any trace regarding this topic. :)
584
					unset($rowset[$orig_topic_id]);
585
					unset($topic_list[array_search($orig_topic_id, $topic_list)]);
586
587
					$topics_count--;
588
589
					continue;
590
				}
591
592
				// Do not include those topics the user has no permission to access
593
				if (!$this->auth->acl_get('f_read', $row['forum_id']))
594
				{
595
					// We need to remove any trace regarding this topic. :)
596
					unset($rowset[$orig_topic_id]);
597
					unset($topic_list[array_search($orig_topic_id, $topic_list)]);
598
599
					$topics_count--;
600
601
					continue;
602
				}
603
604
				// We want to retain some values
605
				$row = array_merge($row, [
606
					'topic_moved_id'	=> $rowset[$orig_topic_id]['topic_moved_id'],
607
					'topic_status'		=> $rowset[$orig_topic_id]['topic_status'],
608
					'topic_type'		=> $rowset[$orig_topic_id]['topic_type'],
609
					'topic_title'		=> $rowset[$orig_topic_id]['topic_title']
610
				]);
611
612
				// Shadow topics are never reported
613
				$row['topic_reported'] = 0;
614
615
				$rowset[$orig_topic_id] = $row;
616
			}
617
			$this->db->sql_freeresult($result);
618
		}
619
		unset($shadow_topic_list);
620
621
		// Ok, adjust topics count for active topics list
622
		if ($s_display_active)
623
		{
624
			$topics_count = 1;
625
		}
626
627
		// We need to remove the global announcements from the forums total topic count,
628
		// otherwise the number is different from the one on the forum list
629
		$total_topic_count = $topics_count - count($announcement_list);
630
631
		// Remove start=...
632
		unset($forum_url_sort_params['page']);
633
		$this->pagination->generate_template_pagination('vinabb_web_board_forum_route', $forum_url_sort_params, 'pagination', $total_topic_count, $this->config['topics_per_page'], $this->start);
634
635
		$this->template->assign_vars([
636
			'TOTAL_TOPICS'	=> ($s_display_active) ? false : $this->language->lang('VIEW_FORUM_TOPICS', (int) $total_topic_count)
637
		]);
638
639
		$topic_list = ($store_reverse) ? array_merge($announcement_list, array_reverse($topic_list)) : array_merge($announcement_list, $topic_list);
640
		$topic_tracking_info = $tracking_topics = [];
641
642
		// Okay, lets dump out the page ...
643
		if (!empty($topic_list))
644
		{
645
			$mark_forum_read = true;
646
			$mark_time_forum = 0;
647
648
			// Generate topic forum list...
649
			$topic_forum_list = [];
650
651
			foreach ($rowset as $t_id => $row)
652
			{
653
				if (isset($forum_tracking_info[$row['forum_id']]))
654
				{
655
					$row['forum_mark_time'] = $forum_tracking_info[$row['forum_id']];
656
				}
657
658
				$topic_forum_list[$row['forum_id']]['forum_mark_time'] = ($this->config['load_db_lastread'] && $this->user->data['is_registered'] && isset($row['forum_mark_time'])) ? $row['forum_mark_time'] : 0;
659
				$topic_forum_list[$row['forum_id']]['topics'][] = (int) $t_id;
660
			}
661
662
			if ($this->config['load_db_lastread'] && $this->user->data['is_registered'])
663
			{
664
				foreach ($topic_forum_list as $f_id => $topic_row)
665
				{
666
					$topic_tracking_info += get_topic_tracking($f_id, $topic_row['topics'], $rowset, [$f_id => $topic_row['forum_mark_time']]);
667
				}
668
			}
669
			else if ($this->config['load_anon_lastread'] || $this->user->data['is_registered'])
670
			{
671
				foreach ($topic_forum_list as $f_id => $topic_row)
672
				{
673
					$topic_tracking_info += get_complete_topic_tracking($f_id, $topic_row['topics']);
674
				}
675
			}
676
677
			unset($topic_forum_list);
678
679
			if (!$s_display_active)
680
			{
681
				if ($this->config['load_db_lastread'] && $this->user->data['is_registered'])
682
				{
683
					$mark_time_forum = (!empty($this->forum_data['mark_time'])) ? $this->forum_data['mark_time'] : $this->user->data['user_lastmark'];
684
				}
685
				else if ($this->config['load_anon_lastread'] || $this->user->data['is_registered'])
686
				{
687
					if (!$this->user->data['is_registered'])
688
					{
689
						$this->user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $this->config['board_startdate']) : 0;
690
					}
691
692
					$mark_time_forum = (isset($tracking_topics['f'][$forum_id])) ? (int) (base_convert($tracking_topics['f'][$forum_id], 36, 10) + $this->config['board_startdate']) : $this->user->data['user_lastmark'];
693
				}
694
			}
695
696
			$s_type_switch = 0;
697
			foreach ($topic_list as $topic_id)
698
			{
699
				$row = &$rowset[$topic_id];
700
701
				$topic_forum_id = ($row['forum_id']) ? (int) $row['forum_id'] : $forum_id;
702
703
				// This will allow the style designer to output a different header
704
				// or even separate the list of announcements from sticky and normal topics
705
				$s_type_switch_test = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
706
707
				// Replies
708
				$replies = $this->content_visibility->get_count('topic_posts', $row, $topic_forum_id) - 1;
709
710
				if ($row['topic_status'] == ITEM_MOVED)
711
				{
712
					$topic_id = $row['topic_moved_id'];
713
					$unread_topic = false;
714
				}
715
				else
716
				{
717
					$unread_topic = (isset($topic_tracking_info[$topic_id]) && $row['topic_last_post_time'] > $topic_tracking_info[$topic_id]) ? true : false;
718
				}
719
720
				// Get folder img, topic status/type related information
721
				$folder_img = $folder_alt = $topic_type = '';
722
				topic_status($row, $replies, $unread_topic, $folder_img, $folder_alt, $topic_type);
723
724
				// Generate all the URIs...
725
				$view_topic_url = $this->helper->route('vinabb_web_board_topic_route', ['forum_id' => $forum_id, 'topic_id' => $topic_id, 'seo' => $row['topic_title_seo'] . constants::REWRITE_URL_SEO]);
726
727
				$topic_unapproved = (($row['topic_visibility'] == ITEM_UNAPPROVED || $row['topic_visibility'] == ITEM_REAPPROVE) && $this->auth->acl_get('m_approve', $row['forum_id']));
728
				$posts_unapproved = ($row['topic_visibility'] == ITEM_APPROVED && $row['topic_posts_unapproved'] && $this->auth->acl_get('m_approve', $row['forum_id']));
729
				$topic_deleted = $row['topic_visibility'] == ITEM_DELETED;
730
731
				$u_mcp_queue = ($topic_unapproved || $posts_unapproved) ? $this->helper->route('vinabb_web_mcp_route', ['id' => 'queue', 'mode' => (($topic_unapproved) ? 'approve_details' : 'unapproved_posts'), 't' => $topic_id], true, $this->user->session_id) : '';
732
				$u_mcp_queue = (!$u_mcp_queue && $topic_deleted) ? $this->helper->route('vinabb_web_mcp_route', ['id' => 'queue', 'mode' => 'deleted_topics', 't' => $topic_id], true, $this->user->session_id) : $u_mcp_queue;
733
734
				// Send vars to template
735
				$topic_row = [
736
					'FORUM_ID'					=> $row['forum_id'],
737
					'TOPIC_ID'					=> $topic_id,
738
					'TOPIC_AUTHOR'				=> get_username_string('username', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
739
					'TOPIC_AUTHOR_COLOUR'		=> get_username_string('colour', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
740
					'TOPIC_AUTHOR_FULL'			=> get_username_string('full', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
741
					'FIRST_POST_TIME'			=> $this->user->format_date($row['topic_time']),
742
					'LAST_POST_SUBJECT'			=> censor_text($row['topic_last_post_subject']),
743
					'LAST_POST_TIME'			=> $this->user->format_date($row['topic_last_post_time']),
744
					'LAST_VIEW_TIME'			=> $this->user->format_date($row['topic_last_view_time']),
745
					'LAST_POST_AUTHOR'			=> get_username_string('username', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
746
					'LAST_POST_AUTHOR_COLOUR'	=> get_username_string('colour', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
747
					'LAST_POST_AUTHOR_FULL'		=> get_username_string('full', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
748
749
					'REPLIES'			=> $replies,
750
					'VIEWS'				=> $row['topic_views'],
751
					'TOPIC_TITLE'		=> censor_text($row['topic_title']),
752
					'TOPIC_TYPE'		=> $topic_type,
753
					'FORUM_NAME'		=> (isset($row['forum_name'])) ? $row['forum_name'] : $this->forum_data['forum_name'],
754
755
					'TOPIC_IMG_STYLE'		=> $folder_img,
756
					'TOPIC_FOLDER_IMG'		=> $this->user->img($folder_img, $folder_alt),
757
					'TOPIC_FOLDER_IMG_ALT'	=> $this->language->lang($folder_alt),
758
759
					'TOPIC_ICON_IMG'		=> (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['img'] : '',
760
					'TOPIC_ICON_IMG_WIDTH'	=> (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['width'] : '',
761
					'TOPIC_ICON_IMG_HEIGHT'	=> (!empty($icons[$row['icon_id']])) ? $icons[$row['icon_id']]['height'] : '',
762
					'ATTACH_ICON_IMG'		=> ($this->auth->acl_get('u_download') && $this->auth->acl_get('f_download', $row['forum_id']) && $row['topic_attachment']) ? $this->user->img('icon_topic_attach', $this->language->lang('TOTAL_ATTACHMENTS')) : '',
763
					'UNAPPROVED_IMG'		=> ($topic_unapproved || $posts_unapproved) ? $this->user->img('icon_topic_unapproved', ($topic_unapproved) ? 'TOPIC_UNAPPROVED' : 'POSTS_UNAPPROVED') : '',
764
765
					'S_TOPIC_TYPE'			=> $row['topic_type'],
766
					'S_USER_POSTED'			=> isset($row['topic_posted']) && $row['topic_posted'],
767
					'S_UNREAD_TOPIC'		=> $unread_topic,
768
					'S_TOPIC_REPORTED'		=> !empty($row['topic_reported']) && $this->auth->acl_get('m_report', $row['forum_id']),
769
					'S_TOPIC_UNAPPROVED'	=> $topic_unapproved,
770
					'S_POSTS_UNAPPROVED'	=> $posts_unapproved,
771
					'S_TOPIC_DELETED'		=> $topic_deleted,
772
					'S_HAS_POLL'			=> $row['poll_start'],
773
					'S_POST_ANNOUNCE'		=> $row['topic_type'] == POST_ANNOUNCE,
774
					'S_POST_GLOBAL'			=> $row['topic_type'] == POST_GLOBAL,
775
					'S_POST_STICKY'			=> $row['topic_type'] == POST_STICKY,
776
					'S_TOPIC_LOCKED'		=> $row['topic_status'] == ITEM_LOCKED,
777
					'S_TOPIC_MOVED'			=> $row['topic_status'] == ITEM_MOVED,
778
779
					'U_NEWEST_POST'			=> $this->helper->route('vinabb_web_board_topic_route', ['topic_id' => $topic_id, 'view' => 'unread', '#' => 'unread']),
780
					'U_LAST_POST'			=> $this->helper->route('vinabb_web_board_topic_route', ['topic_id' => $topic_id, '#' => 'p' . $row['topic_last_post_id']]),
781
					'U_LAST_POST_AUTHOR'	=> get_username_string('profile', $row['topic_last_poster_id'], $row['topic_last_poster_name'], $row['topic_last_poster_colour']),
782
					'U_TOPIC_AUTHOR'		=> get_username_string('profile', $row['topic_poster'], $row['topic_first_poster_name'], $row['topic_first_poster_colour']),
783
					'U_VIEW_TOPIC'			=> $view_topic_url,
784
					'U_VIEW_FORUM'			=> $this->helper->route('vinabb_web_board_forum_route', ['forum_id' => $row['forum_id'], 'seo' => $this->forum_data['forum_name_seo'] . constants::REWRITE_URL_SEO]),
785
					'U_MCP_REPORT'			=> $this->helper->route('vinabb_web_mcp_route', ['id' => 'reports', 'mode' => 'reports', 'f' => $row['forum_id'], 't' => $topic_id], true, $this->user->session_id),
786
					'U_MCP_QUEUE'			=> $u_mcp_queue,
787
788
					'S_TOPIC_TYPE_SWITCH'	=> ($s_type_switch == $s_type_switch_test) ? -1 : $s_type_switch_test
789
				];
790
791
				$this->template->assign_block_vars('topicrow', $topic_row);
792
793
				$this->pagination->generate_template_pagination('vinabb_web_board_topic_route', ['forum_id' => $forum_id, 'topic_id' => $topic_id], 'topicrow.pagination', $replies + 1, $this->config['posts_per_page'], 1, true, true);
794
795
				$s_type_switch = ($row['topic_type'] == POST_ANNOUNCE || $row['topic_type'] == POST_GLOBAL) ? 1 : 0;
796
797
				if ($unread_topic)
798
				{
799
					$mark_forum_read = false;
800
				}
801
802
				unset($rowset[$topic_id]);
803
			}
804
		}
805
806
		// This is rather a fudge but it's the best I can think of without requiring information
807
		// on all topics (as we do in 2.0.x). It looks for unread or new topics, if it doesn't find
808
		// any it updates the forum last read cookie. This requires that the user visit the forum
809
		// after reading a topic
810
		if ($this->forum_data['forum_type'] == FORUM_POST && !empty($topic_list) && $mark_forum_read)
811
		{
812
			update_forum_tracking_info($forum_id, $this->forum_data['forum_last_post_time'], false, $mark_time_forum);
813
		}
814
815
		page_footer();
816
	}
817
818
	/**
819
	* Get forum data
820
	*
821
	* @param int $forum_id Forum ID
822
	*/
823
	protected function get_forum_data($forum_id)
824
	{
825
		$sql_from = FORUMS_TABLE . ' f';
826
		$lastread_select = '';
827
828
		// Grab appropriate forum data
829
		if ($this->config['load_db_lastread'] && $this->user->data['is_registered'])
830
		{
831
			$sql_from .= ' LEFT JOIN ' . FORUMS_TRACK_TABLE . ' ft
832
				ON (ft.user_id = ' . $this->user->data['user_id'] . '
833
					AND ft.forum_id = f.forum_id)';
834
			$lastread_select .= ', ft.mark_time';
835
		}
836
837
		if ($this->user->data['is_registered'])
838
		{
839
			$sql_from .= ' LEFT JOIN ' . FORUMS_WATCH_TABLE . ' fw
840
				ON (fw.forum_id = f.forum_id
841
					AND fw.user_id = ' . $this->user->data['user_id'] . ')';
842
			$lastread_select .= ', fw.notify_status';
843
		}
844
845
		$sql = "SELECT f.* $lastread_select
846
			FROM $sql_from
847
			WHERE f.forum_id = $forum_id";
848
		$result = $this->db->sql_query($sql);
849
		$this->forum_data = $this->db->sql_fetchrow($result);
850
		$this->db->sql_freeresult($result);
851
852
		if ($this->forum_data === false)
853
		{
854
			trigger_error('NO_FORUM');
855
		}
856
	}
857
858
	/**
859
	* Checking actions on the forum
860
	*/
861
	protected function require_login()
862
	{
863
		// Redirect to login upon emailed notification links
864
		if ($this->request->is_set('e') && !$this->user->data['is_registered'])
865
		{
866
			login_box('', $this->language->lang('LOGIN_NOTIFY_FORUM'));
867
		}
868
869
		// Permissions check
870
		$this->require_login_auth();
871
872
		// Forum is passworded ... check whether access has been granted to this
873
		// user this session, if not show login box
874
		if ($this->forum_data['forum_password'])
875
		{
876
			login_forum_box($this->forum_data);
877
		}
878
	}
879
880
	/**
881
	* Sub-method for the require_login()
882
	*/
883
	protected function require_login_auth()
884
	{
885
		if (!$this->auth->acl_gets('f_list', 'f_read', $this->forum_data['forum_id']) || ($this->forum_data['forum_type'] == FORUM_LINK && $this->forum_data['forum_link'] && !$this->auth->acl_get('f_read', $this->forum_data['forum_id'])))
886
		{
887
			if ($this->user->data['user_id'] != ANONYMOUS)
888
			{
889
				send_status_line(403, 'Forbidden');
890
				trigger_error('SORRY_AUTH_READ');
891
			}
892
893
			login_box('', $this->language->lang('LOGIN_VIEWFORUM'));
894
		}
895
	}
896
897
	/**
898
	* Click tracking for forum links
899
	*/
900
	protected function update_click_counter()
901
	{
902
		if ($this->forum_data['forum_type'] == FORUM_LINK && $this->forum_data['forum_link'])
903
		{
904
			// Does it have click tracking enabled?
905
			if ($this->forum_data['forum_flags'] & FORUM_FLAG_LINK_TRACK)
906
			{
907
				$sql = 'UPDATE ' . FORUMS_TABLE . '
908
					SET forum_posts_approved = forum_posts_approved + 1
909
					WHERE forum_id = ' . $this->forum_data['forum_id'];
910
				$this->db->sql_query($sql);
911
			}
912
913
			// We redirect to the url. The third parameter indicates that external redirects are allowed.
914
			redirect($this->forum_data['forum_link'], false, true);
915
916
			return;
917
		}
918
	}
919
920
	/**
921
	* Marking topics as read
922
	*/
923
	protected function mark_topics()
924
	{
925
		$mark_read = $this->request->variable('mark', '');
926
927
		if ($mark_read == 'topics')
928
		{
929
			$token = $this->request->variable('hash', '');
930
931
			if (check_link_hash($token, 'global'))
932
			{
933
				markread('topics', [$this->forum_data['forum_id']], false, $this->request->variable('mark_time', 0));
934
			}
935
936
			$redirect_url = $this->helper->route('vinabb_web_board_forum_route', ['forum_id' => $this->forum_data['forum_id'], 'seo' => $this->forum_data['forum_name_seo'] . constants::REWRITE_URL_SEO]);
937
			meta_refresh(3, $redirect_url);
938
939
			if ($this->request->is_ajax())
940
			{
941
				// Tell the ajax script what language vars and URL need to be replaced
942
				$data = [
943
					'NO_UNREAD_POSTS'	=> $this->language->lang('NO_UNREAD_POSTS'),
944
					'UNREAD_POSTS'		=> $this->language->lang('UNREAD_POSTS'),
945
					'U_MARK_TOPICS'		=> ($this->user->data['is_registered'] || $this->config['load_anon_lastread']) ? htmlspecialchars_decode($this->helper->route('vinabb_web_board_forum_route', ['forum_id' => $this->forum_data['forum_id'], 'seo' => $this->forum_data['forum_name_seo'] . constants::REWRITE_URL_SEO, 'hash' => generate_link_hash('global'), 'mark' => 'topics', 'mark_time' => time()])) : '',
946
					'MESSAGE_TITLE'		=> $this->language->lang('INFORMATION'),
947
					'MESSAGE_TEXT'		=> $this->language->lang('TOPICS_MARKED')
948
				];
949
950
				$json_response = new \phpbb\json_response();
951
				$json_response->send($data);
952
			}
953
954
			trigger_error($this->language->lang('TOPICS_MARKED') . '<br><br>' . $this->language->lang('RETURN_FORUM', '<a href="' . $redirect_url . '">', '</a>'));
955
		}
956
	}
957
958
	/**
959
	* Run cron tasks manually
960
	*/
961
	protected function run_cron_tasks()
962
	{
963
		if (!$this->config['use_system_cron'])
964
		{
965
			$task = $this->cron->find_task('cron.task.core.prune_forum');
966
			$task->set_forum_data($this->forum_data);
967
968
			if ($task->is_ready())
969
			{
970
				$url = $task->get_url();
971
				$this->template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron">');
972
			}
973
			else
974
			{
975
				// See if we should prune the shadow topics instead
976
				$task = $this->cron->find_task('cron.task.core.prune_shadow_topics');
977
				$task->set_forum_data($this->forum_data);
978
979
				if ($task->is_ready())
980
				{
981
					$url = $task->get_url();
982
					$this->template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron">');
983
				}
984
			}
985
		}
986
	}
987
988
	/**
989
	* Subscribe new posts from the forum
990
	*/
991
	protected function subscribe_forum()
992
	{
993
		$s_watching_forum = [
994
			'link'			=> '',
995
			'link_toggle'	=> '',
996
			'title'			=> '',
997
			'title_toggle'	=> '',
998
			'is_watching'	=> false
999
		];
1000
1001
		if ($this->config['allow_forum_notify'] && $this->forum_data['forum_type'] == FORUM_POST && ($this->auth->acl_get('f_subscribe', $this->forum_data['forum_id']) || $this->user->data['user_id'] == ANONYMOUS))
1002
		{
1003
			$notify_status = (isset($this->forum_data['notify_status'])) ? $this->forum_data['notify_status'] : null;
1004
			watch_topic_forum('forum', $s_watching_forum, $this->user->data['user_id'], $this->forum_data['forum_id'], 0, $notify_status, $this->start, $this->forum_data['forum_name']);
1005
		}
1006
1007
		$this->template->assign_vars([
1008
			'U_WATCH_FORUM_LINK'	=> $s_watching_forum['link'],
1009
			'U_WATCH_FORUM_TOGGLE'	=> $s_watching_forum['link_toggle'],
1010
			'S_WATCH_FORUM_TITLE'	=> $s_watching_forum['title'],
1011
			'S_WATCH_FORUM_TOGGLE'	=> $s_watching_forum['title_toggle'],
1012
			'S_WATCHING_FORUM'		=> $s_watching_forum['is_watching']
1013
		]);
1014
	}
1015
}
1016