Failed Conditions
Branch release-2.1 (4e22cf)
by Rick
06:39
created

MessageIndex.php ➔ MessageIndex()   F

Complexity

Conditions 207
Paths > 20000

Size

Total Lines 735
Code Lines 437

Duplication

Lines 146
Ratio 19.86 %

Importance

Changes 0
Metric Value
cc 207
eloc 437
nc 429496.7295
nop 0
dl 146
loc 735
rs 2
c 0
b 0
f 0

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
/**
4
 * This file is what shows the listing of topics in a board.
5
 * It's just one or two functions, but don't under estimate it ;).
6
 *
7
 * Simple Machines Forum (SMF)
8
 *
9
 * @package SMF
10
 * @author Simple Machines http://www.simplemachines.org
11
 * @copyright 2017 Simple Machines and individual contributors
12
 * @license http://www.simplemachines.org/about/smf/license.php BSD
13
 *
14
 * @version 2.1 Beta 4
15
 */
16
17
if (!defined('SMF'))
18
	die('No direct access...');
19
20
/**
21
 * Show the list of topics in this board, along with any child boards.
22
 */
23
function MessageIndex()
24
{
25
	global $txt, $scripturl, $board, $modSettings, $context;
26
	global $options, $settings, $board_info, $user_info, $smcFunc, $sourcedir;
27
28
	// If this is a redirection board head off.
29
	if ($board_info['redirect'])
30
	{
31
		$smcFunc['db_query']('', '
32
			UPDATE {db_prefix}boards
33
			SET num_posts = num_posts + 1
34
			WHERE id_board = {int:current_board}',
35
			array(
36
				'current_board' => $board,
37
			)
38
		);
39
40
		redirectexit($board_info['redirect']);
41
	}
42
43
	loadTemplate('MessageIndex');
44
45 View Code Duplication
	if (!$user_info['is_guest'])
46
	{
47
		// We can't know they read it if we allow prefetches.
48
		// But we'll actually mark it read later after we've done everything else.
49
		if (isset($_SERVER['HTTP_X_MOZ']) && $_SERVER['HTTP_X_MOZ'] == 'prefetch')
50
		{
51
			ob_end_clean();
52
			header('HTTP/1.1 403 Prefetch Forbidden');
53
			die;
54
		}
55
	}
56
57
	$context['name'] = $board_info['name'];
58
	$context['description'] = $board_info['description'];
59
	if (!empty($board_info['description']))
60
		$context['meta_description'] = strip_tags($board_info['description']);
61
62
	// How many topics do we have in total?
63
	$board_info['total_topics'] = allowedTo('approve_posts') ? $board_info['num_topics'] + $board_info['unapproved_topics'] : $board_info['num_topics'] + $board_info['unapproved_user_topics'];
64
65
	// View all the topics, or just a few?
66
	$context['topics_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['topics_per_page']) ? $options['topics_per_page'] : $modSettings['defaultMaxTopics'];
67
	$context['messages_per_page'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
68
	$maxindex = isset($_REQUEST['all']) && !empty($modSettings['enableAllMessages']) ? $board_info['total_topics'] : $context['topics_per_page'];
69
70
	// Right, let's only index normal stuff!
71 View Code Duplication
	if (count($_GET) > 1)
72
	{
73
		$session_name = session_name();
74
		foreach ($_GET as $k => $v)
75
		{
76
			if (!in_array($k, array('board', 'start', $session_name)))
77
				$context['robot_no_index'] = true;
78
		}
79
	}
80 View Code Duplication
	if (!empty($_REQUEST['start']) && (!is_numeric($_REQUEST['start']) || $_REQUEST['start'] % $context['messages_per_page'] != 0))
81
		$context['robot_no_index'] = true;
82
83
	// If we can view unapproved messages and there are some build up a list.
84
	if (allowedTo('approve_posts') && ($board_info['unapproved_topics'] || $board_info['unapproved_posts']))
85
	{
86
		$untopics = $board_info['unapproved_topics'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=topics;brd=' . $board . '">' . $board_info['unapproved_topics'] . '</a>' : 0;
87
		$unposts = $board_info['unapproved_posts'] ? '<a href="' . $scripturl . '?action=moderate;area=postmod;sa=posts;brd=' . $board . '">' . ($board_info['unapproved_posts'] - $board_info['unapproved_topics']) . '</a>' : 0;
88
		$context['unapproved_posts_message'] = sprintf($txt['there_are_unapproved_topics'], $untopics, $unposts, $scripturl . '?action=moderate;area=postmod;sa=' . ($board_info['unapproved_topics'] ? 'topics' : 'posts') . ';brd=' . $board);
89
	}
90
91
	// We only know these.
92
	if (isset($_REQUEST['sort']) && !in_array($_REQUEST['sort'], array('subject', 'starter', 'last_poster', 'replies', 'views', 'first_post', 'last_post')))
93
		$_REQUEST['sort'] = 'last_post';
94
95
	// Make sure the starting place makes sense and construct the page index.
96
	if (isset($_REQUEST['sort']))
97
		$context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d;sort=' . $_REQUEST['sort'] . (isset($_REQUEST['desc']) ? ';desc' : ''), $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
98
	else
99
		$context['page_index'] = constructPageIndex($scripturl . '?board=' . $board . '.%1$d', $_REQUEST['start'], $board_info['total_topics'], $maxindex, true);
100
	$context['start'] = &$_REQUEST['start'];
101
102
	// Set a canonical URL for this page.
103
	$context['canonical_url'] = $scripturl . '?board=' . $board . '.' . $context['start'];
104
105
	$can_show_all = !empty($modSettings['enableAllMessages']) && $maxindex > $modSettings['enableAllMessages'];
106
107
	if (!($can_show_all && isset($_REQUEST['all'])))
108
	{
109
		$context['links'] = array(
110
			'first' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.0' : '',
111
			'prev' => $_REQUEST['start'] >= $context['topics_per_page'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] - $context['topics_per_page']) : '',
112
			'next' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . ($_REQUEST['start'] + $context['topics_per_page']) : '',
113
			'last' => $_REQUEST['start'] + $context['topics_per_page'] < $board_info['total_topics'] ? $scripturl . '?board=' . $board . '.' . (floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) * $context['topics_per_page']) : '',
114
			'up' => $board_info['parent'] == 0 ? $scripturl . '?' : $scripturl . '?board=' . $board_info['parent'] . '.0'
115
		);
116
	}
117
118
	$context['page_info'] = array(
119
		'current_page' => $_REQUEST['start'] / $context['topics_per_page'] + 1,
120
		'num_pages' => floor(($board_info['total_topics'] - 1) / $context['topics_per_page']) + 1
121
	);
122
123
	if (isset($_REQUEST['all']) && $can_show_all)
124
	{
125
		$maxindex = $modSettings['enableAllMessages'];
126
		$_REQUEST['start'] = 0;
127
	}
128
129
	// Build a list of the board's moderators.
130
	$context['moderators'] = &$board_info['moderators'];
131
	$context['moderator_groups'] = &$board_info['moderator_groups'];
132
	$context['link_moderators'] = array();
133 View Code Duplication
	if (!empty($board_info['moderators']))
134
	{
135
		foreach ($board_info['moderators'] as $mod)
136
			$context['link_moderators'][] = '<a href="' . $scripturl . '?action=profile;u=' . $mod['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod['name'] . '</a>';
137
	}
138 View Code Duplication
	if (!empty($board_info['moderator_groups']))
139
	{
140
		// By default just tack the moderator groups onto the end of the members
141
		foreach ($board_info['moderator_groups'] as $mod_group)
142
			$context['link_moderators'][] = '<a href="' . $scripturl . '?action=groups;sa=members;group=' . $mod_group['id'] . '" title="' . $txt['board_moderator'] . '">' . $mod_group['name'] . '</a>';
143
	}
144
145
	// Now we tack the info onto the end of the linktree
146 View Code Duplication
	if (!empty($context['link_moderators']))
147
	{
148
	 	$context['linktree'][count($context['linktree']) - 1]['extra_after'] = '<span class="board_moderators">(' . (count($context['link_moderators']) == 1 ? $txt['moderator'] : $txt['moderators']) . ': ' . implode(', ', $context['link_moderators']) . ')</span>';
149
	}
150
151
	// 'Print' the header and board info.
152
	$context['page_title'] = strip_tags($board_info['name']);
153
154
	// Set the variables up for the template.
155
	$context['can_mark_notify'] = !$user_info['is_guest'];
156
	$context['can_post_new'] = allowedTo('post_new') || ($modSettings['postmod_active'] && allowedTo('post_unapproved_topics'));
157
	$context['can_post_poll'] = $modSettings['pollMode'] == '1' && allowedTo('poll_post') && $context['can_post_new'];
158
	$context['can_moderate_forum'] = allowedTo('moderate_forum');
159
	$context['can_approve_posts'] = allowedTo('approve_posts');
160
161
	require_once($sourcedir . '/Subs-BoardIndex.php');
162
	$boardIndexOptions = array(
163
		'include_categories' => false,
164
		'base_level' => $board_info['child_level'] + 1,
165
		'parent_id' => $board_info['id'],
166
		'set_latest_post' => false,
167
		'countChildPosts' => !empty($modSettings['countChildPosts']),
168
	);
169
	$context['boards'] = getBoardIndex($boardIndexOptions);
170
171
	// Nosey, nosey - who's viewing this topic?
172 View Code Duplication
	if (!empty($settings['display_who_viewing']))
173
	{
174
		$context['view_members'] = array();
175
		$context['view_members_list'] = array();
176
		$context['view_num_hidden'] = 0;
177
178
		$request = $smcFunc['db_query']('', '
179
			SELECT
180
				lo.id_member, lo.log_time, mem.real_name, mem.member_name, mem.show_online,
181
				mg.online_color, mg.id_group, mg.group_name
182
			FROM {db_prefix}log_online AS lo
183
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lo.id_member)
184
				LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_member_group} THEN mem.id_post_group ELSE mem.id_group END)
185
			WHERE INSTR(lo.url, {string:in_url_string}) > 0 OR lo.session = {string:session}',
186
			array(
187
				'reg_member_group' => 0,
188
				'in_url_string' => '"board":' . $board,
189
				'session' => $user_info['is_guest'] ? 'ip' . $user_info['ip'] : session_id(),
190
			)
191
		);
192
		while ($row = $smcFunc['db_fetch_assoc']($request))
193
		{
194
			if (empty($row['id_member']))
195
				continue;
196
197
			if (!empty($row['online_color']))
198
				$link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '" style="color: ' . $row['online_color'] . ';">' . $row['real_name'] . '</a>';
199
			else
200
				$link = '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>';
201
202
			$is_buddy = in_array($row['id_member'], $user_info['buddies']);
203
			if ($is_buddy)
204
				$link = '<strong>' . $link . '</strong>';
205
206
			if (!empty($row['show_online']) || allowedTo('moderate_forum'))
207
				$context['view_members_list'][$row['log_time'] . $row['member_name']] = empty($row['show_online']) ? '<em>' . $link . '</em>' : $link;
208
			// @todo why are we filling this array of data that are just counted (twice) and discarded? ???
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
209
			$context['view_members'][$row['log_time'] . $row['member_name']] = array(
210
				'id' => $row['id_member'],
211
				'username' => $row['member_name'],
212
				'name' => $row['real_name'],
213
				'group' => $row['id_group'],
214
				'href' => $scripturl . '?action=profile;u=' . $row['id_member'],
215
				'link' => $link,
216
				'is_buddy' => $is_buddy,
217
				'hidden' => empty($row['show_online']),
218
			);
219
220
			if (empty($row['show_online']))
221
				$context['view_num_hidden']++;
222
		}
223
		$context['view_num_guests'] = $smcFunc['db_num_rows']($request) - count($context['view_members']);
224
		$smcFunc['db_free_result']($request);
225
226
		// Put them in "last clicked" order.
227
		krsort($context['view_members_list']);
228
		krsort($context['view_members']);
229
	}
230
231
	// Default sort methods.
232
	$sort_methods = array(
233
		'subject' => 'mf.subject',
234
		'starter' => 'COALESCE(memf.real_name, mf.poster_name)',
235
		'last_poster' => 'COALESCE(meml.real_name, ml.poster_name)',
236
		'replies' => 't.num_replies',
237
		'views' => 't.num_views',
238
		'first_post' => 't.id_topic',
239
		'last_post' => 't.id_last_msg'
240
	);
241
242
	// They didn't pick one, default to by last post descending.
243
	if (!isset($_REQUEST['sort']) || !isset($sort_methods[$_REQUEST['sort']]))
244
	{
245
		$context['sort_by'] = 'last_post';
246
		$_REQUEST['sort'] = 'id_last_msg';
247
		$ascending = isset($_REQUEST['asc']);
248
	}
249
	// Otherwise default to ascending.
250 View Code Duplication
	else
251
	{
252
		$context['sort_by'] = $_REQUEST['sort'];
253
		$_REQUEST['sort'] = $sort_methods[$_REQUEST['sort']];
254
		$ascending = !isset($_REQUEST['desc']);
255
	}
256
257
	$context['sort_direction'] = $ascending ? 'up' : 'down';
258
	$txt['starter'] = $txt['started_by'];
259
260
	foreach ($sort_methods as $key => $val)
261
		$context['topics_headers'][$key] = '<a href="' . $scripturl . '?board=' . $context['current_board'] . '.' . $context['start'] . ';sort=' . $key . ($context['sort_by'] == $key && $context['sort_direction'] == 'up' ? ';desc' : '') . '">' . $txt[$key] . ($context['sort_by'] == $key ? '<span class="sort sort_' . $context['sort_direction'] . '"></span>' : '') . '</a>';
262
263
	// Calculate the fastest way to get the topics.
264
	$start = (int) $_REQUEST['start'];
265
	if ($start > ($board_info['total_topics'] - 1) / 2)
266
	{
267
		$ascending = !$ascending;
268
		$fake_ascending = true;
269
		$maxindex = $board_info['total_topics'] < $start + $maxindex + 1 ? $board_info['total_topics'] - $start : $maxindex;
270
		$start = $board_info['total_topics'] < $start + $maxindex + 1 ? 0 : $board_info['total_topics'] - $start - $maxindex;
271
	}
272
	else
273
		$fake_ascending = false;
274
275
	// Setup the default topic icons...
276
	$context['icon_sources'] = array();
277
	foreach ($context['stable_icons'] as $icon)
278
		$context['icon_sources'][$icon] = 'images_url';
279
280
	$topic_ids = array();
281
	$context['topics'] = array();
282
283
	// Sequential pages are often not optimized, so we add an additional query.
284
	$pre_query = $start > 0;
285
	if ($pre_query && $maxindex > 0)
286
	{
287
		$request = $smcFunc['db_query']('', '
288
			SELECT t.id_topic
289
			FROM {db_prefix}topics AS t' . ($context['sort_by'] === 'last_poster' ? '
290
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)' : (in_array($context['sort_by'], array('starter', 'subject')) ? '
291
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)' : '')) . ($context['sort_by'] === 'starter' ? '
292
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' : '') . ($context['sort_by'] === 'last_poster' ? '
293
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)' : '') . '
294
			WHERE t.id_board = {int:current_board}' . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
295
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
296
			ORDER BY is_sticky' . ($fake_ascending ? '' : ' DESC') . ', {raw:sort}' . ($ascending ? '' : ' DESC') . '
297
			LIMIT {int:start}, {int:maxindex}',
298
			array(
299
				'current_board' => $board,
300
				'current_member' => $user_info['id'],
301
				'is_approved' => 1,
302
				'id_member_guest' => 0,
303
				'start' => $start,
304
				'maxindex' => $maxindex,
305
				'sort' => $_REQUEST['sort'],
306
			)
307
		);
308
		$topic_ids = array();
309
		while ($row = $smcFunc['db_fetch_assoc']($request))
310
			$topic_ids[] = $row['id_topic'];
311
	}
312
313
	// Grab the appropriate topic information...
314
	if (!$pre_query || !empty($topic_ids))
315
	{
316
		// For search engine effectiveness we'll link guests differently.
317
		$context['pageindex_multiplier'] = empty($modSettings['disableCustomPerPage']) && !empty($options['messages_per_page']) ? $options['messages_per_page'] : $modSettings['defaultMaxMessages'];
318
319
		$message_index_parameters = array(
320
			'current_board' => $board,
321
			'current_member' => $user_info['id'],
322
			'topic_list' => $topic_ids,
323
			'is_approved' => 1,
324
			'find_set_topics' => implode(',', $topic_ids),
325
			'start' => $start,
326
			'maxindex' => $maxindex,
327
		);
328
		$message_index_selects = array();
329
		$message_index_tables = array();
330
		call_integration_hook('integrate_message_index', array(&$message_index_selects, &$message_index_tables, &$message_index_parameters));
331
332
		$result = $smcFunc['db_query']('substring', '
333
			SELECT
334
				t.id_topic, t.num_replies, t.locked, t.num_views, t.is_sticky, t.id_poll, t.id_previous_board,
335
				' . ($user_info['is_guest'] ? '0' : 'COALESCE(lt.id_msg, COALESCE(lmr.id_msg, -1)) + 1') . ' AS new_from,
336
				t.id_last_msg, t.approved, t.unapproved_posts, ml.poster_time AS last_poster_time, t.id_redirect_topic,
337
				ml.id_msg_modified, ml.subject AS last_subject, ml.icon AS last_icon,
338
				ml.poster_name AS last_member_name, ml.id_member AS last_id_member,' . (!empty($settings['avatars_on_indexes']) ? ' meml.avatar, meml.email_address, memf.avatar AS first_member_avatar, memf.email_address AS first_member_mail, COALESCE(af.id_attach, 0) AS first_member_id_attach, af.filename AS first_member_filename, af.attachment_type AS first_member_attach_type, COALESCE(al.id_attach, 0) AS last_member_id_attach, al.filename AS last_member_filename, al.attachment_type AS last_member_attach_type,' : '') . '
339
				COALESCE(meml.real_name, ml.poster_name) AS last_display_name, t.id_first_msg,
340
				mf.poster_time AS first_poster_time, mf.subject AS first_subject, mf.icon AS first_icon,
341
				mf.poster_name AS first_member_name, mf.id_member AS first_id_member,
342
				COALESCE(memf.real_name, mf.poster_name) AS first_display_name, ' . (!empty($modSettings['preview_characters']) ? '
343
				SUBSTRING(ml.body, 1, ' . ($modSettings['preview_characters'] + 256) . ') AS last_body,
344
				SUBSTRING(mf.body, 1, ' . ($modSettings['preview_characters'] + 256) . ') AS first_body,' : '') . 'ml.smileys_enabled AS last_smileys, mf.smileys_enabled AS first_smileys
345
				' . (!empty($message_index_selects) ? (', ' . implode(', ', $message_index_selects)) : '') . '
346
			FROM {db_prefix}topics AS t
347
				INNER JOIN {db_prefix}messages AS ml ON (ml.id_msg = t.id_last_msg)
348
				INNER JOIN {db_prefix}messages AS mf ON (mf.id_msg = t.id_first_msg)
349
				LEFT JOIN {db_prefix}members AS meml ON (meml.id_member = ml.id_member)
350
				LEFT JOIN {db_prefix}members AS memf ON (memf.id_member = mf.id_member)' . (!empty($settings['avatars_on_indexes']) ? '
351
				LEFT JOIN {db_prefix}attachments AS af ON (af.id_member = memf.id_member)
352
				LEFT JOIN {db_prefix}attachments AS al ON (al.id_member = meml.id_member)' : '') . '' . ($user_info['is_guest'] ? '' : '
353
				LEFT JOIN {db_prefix}log_topics AS lt ON (lt.id_topic = t.id_topic AND lt.id_member = {int:current_member})
354
				LEFT JOIN {db_prefix}log_mark_read AS lmr ON (lmr.id_board = {int:current_board} AND lmr.id_member = {int:current_member})') . '
355
				' . (!empty($message_index_tables) ? implode("\n\t", $message_index_tables) : '') . '
356
			WHERE ' . ($pre_query ? 't.id_topic IN ({array_int:topic_list})' : 't.id_board = {int:current_board}') . (!$modSettings['postmod_active'] || $context['can_approve_posts'] ? '' : '
357
				AND (t.approved = {int:is_approved}' . ($user_info['is_guest'] ? '' : ' OR t.id_member_started = {int:current_member}') . ')') . '
358
			ORDER BY ' . ($pre_query ? 'FIND_IN_SET(t.id_topic, {string:find_set_topics})' : 'is_sticky' . ($fake_ascending ? '' : ' DESC') . ', ' . $_REQUEST['sort'] . ($ascending ? '' : ' DESC')) . '
359
			LIMIT ' . ($pre_query ? '' : '{int:start}, ') . '{int:maxindex}',
360
			$message_index_parameters
361
		);
362
363
		// Begin 'printing' the message index for current board.
364
		while ($row = $smcFunc['db_fetch_assoc']($result))
365
		{
366
			if ($row['id_poll'] > 0 && $modSettings['pollMode'] == '0')
367
				continue;
368
369
			if (!$pre_query)
370
				$topic_ids[] = $row['id_topic'];
371
372
			// Reference the main color class.
373
			$colorClass = 'windowbg';
374
375
			// Does the theme support message previews?
376
			if (!empty($modSettings['preview_characters']))
377
			{
378
				// Limit them to $modSettings['preview_characters'] characters
379
				$row['first_body'] = strip_tags(strtr(parse_bbc($row['first_body'], $row['first_smileys'], $row['id_first_msg']), array('<br>' => '&#10;')));
380 View Code Duplication
				if ($smcFunc['strlen']($row['first_body']) > $modSettings['preview_characters'])
381
					$row['first_body'] = $smcFunc['substr']($row['first_body'], 0, $modSettings['preview_characters']) . '...';
382
383
				// Censor the subject and message preview.
384
				censorText($row['first_subject']);
385
				censorText($row['first_body']);
386
387
				// Don't censor them twice!
388
				if ($row['id_first_msg'] == $row['id_last_msg'])
389
				{
390
					$row['last_subject'] = $row['first_subject'];
391
					$row['last_body'] = $row['first_body'];
392
				}
393
				else
394
				{
395
					$row['last_body'] = strip_tags(strtr(parse_bbc($row['last_body'], $row['last_smileys'], $row['id_last_msg']), array('<br>' => '&#10;')));
396 View Code Duplication
					if ($smcFunc['strlen']($row['last_body']) > $modSettings['preview_characters'])
397
						$row['last_body'] = $smcFunc['substr']($row['last_body'], 0, $modSettings['preview_characters']) . '...';
398
399
					censorText($row['last_subject']);
400
					censorText($row['last_body']);
401
				}
402
			}
403 View Code Duplication
			else
404
			{
405
				$row['first_body'] = '';
406
				$row['last_body'] = '';
407
				censorText($row['first_subject']);
408
409
				if ($row['id_first_msg'] == $row['id_last_msg'])
410
					$row['last_subject'] = $row['first_subject'];
411
				else
412
					censorText($row['last_subject']);
413
			}
414
415
			// Decide how many pages the topic should have.
416
			if ($row['num_replies'] + 1 > $context['messages_per_page'])
417
			{
418
				// We can't pass start by reference.
419
				$start = -1;
420
				$pages = constructPageIndex($scripturl . '?topic=' . $row['id_topic'] . '.%1$d', $start, $row['num_replies'] + 1, $context['messages_per_page'], true, false);
421
422
				// If we can use all, show all.
423 View Code Duplication
				if (!empty($modSettings['enableAllMessages']) && $row['num_replies'] + 1 < $modSettings['enableAllMessages'])
424
					$pages .= ' &nbsp;<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0;all">' . $txt['all'] . '</a>';
425
			}
426
			else
427
				$pages = '';
428
429
			// We need to check the topic icons exist...
430
			if (!empty($modSettings['messageIconChecks_enable']))
431
			{
432 View Code Duplication
				if (!isset($context['icon_sources'][$row['first_icon']]))
433
					$context['icon_sources'][$row['first_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['first_icon'] . '.png') ? 'images_url' : 'default_images_url';
434 View Code Duplication
				if (!isset($context['icon_sources'][$row['last_icon']]))
435
					$context['icon_sources'][$row['last_icon']] = file_exists($settings['theme_dir'] . '/images/post/' . $row['last_icon'] . '.png') ? 'images_url' : 'default_images_url';
436
			}
437
			else
438
			{
439 View Code Duplication
				if (!isset($context['icon_sources'][$row['first_icon']]))
440
					$context['icon_sources'][$row['first_icon']] = 'images_url';
441 View Code Duplication
				if (!isset($context['icon_sources'][$row['last_icon']]))
442
					$context['icon_sources'][$row['last_icon']] = 'images_url';
443
			}
444
445
			if (!empty($board_info['recycle']))
446
				$row['first_icon'] = 'recycled';
447
448
			// Is this topic pending approval, or does it have any posts pending approval?
449
			if ($context['can_approve_posts'] && $row['unapproved_posts'])
450
				$colorClass .= (!$row['approved'] ? ' approvetopic' : ' approvepost');
451
452
			// Sticky topics should get a different color, too.
453
			if ($row['is_sticky'])
454
				$colorClass .= ' sticky';
455
456
			// Locked topics get special treatment as well.
457
			if ($row['locked'])
458
				$colorClass .= ' locked';
459
460
			// 'Print' the topic info.
461
			$context['topics'][$row['id_topic']] = array_merge($row, array(
462
				'id' => $row['id_topic'],
463
				'first_post' => array(
464
					'id' => $row['id_first_msg'],
465
					'member' => array(
466
						'username' => $row['first_member_name'],
467
						'name' => $row['first_display_name'],
468
						'id' => $row['first_id_member'],
469
						'href' => !empty($row['first_id_member']) ? $scripturl . '?action=profile;u=' . $row['first_id_member'] : '',
470
						'link' => !empty($row['first_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['first_id_member'] . '" title="' . $txt['profile_of'] . ' ' . $row['first_display_name'] . '" class="preview">' . $row['first_display_name'] . '</a>' : $row['first_display_name']
471
					),
472
					'time' => timeformat($row['first_poster_time']),
473
					'timestamp' => forum_time(true, $row['first_poster_time']),
474
					'subject' => $row['first_subject'],
475
					'preview' => $row['first_body'],
476
					'icon' => $row['first_icon'],
477
					'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.png',
478
					'href' => $scripturl . '?topic=' . $row['id_topic'] . '.0',
479
					'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . '.0">' . $row['first_subject'] . '</a>',
480
				),
481
				'last_post' => array(
482
					'id' => $row['id_last_msg'],
483
					'member' => array(
484
						'username' => $row['last_member_name'],
485
						'name' => $row['last_display_name'],
486
						'id' => $row['last_id_member'],
487
						'href' => !empty($row['last_id_member']) ? $scripturl . '?action=profile;u=' . $row['last_id_member'] : '',
488
						'link' => !empty($row['last_id_member']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['last_id_member'] . '">' . $row['last_display_name'] . '</a>' : $row['last_display_name']
489
					),
490
					'time' => timeformat($row['last_poster_time']),
491
					'timestamp' => forum_time(true, $row['last_poster_time']),
492
					'subject' => $row['last_subject'],
493
					'preview' => $row['last_body'],
494
					'icon' => $row['last_icon'],
495
					'icon_url' => $settings[$context['icon_sources'][$row['last_icon']]] . '/post/' . $row['last_icon'] . '.png',
496
					'href' => $scripturl . '?topic=' . $row['id_topic'] . ($user_info['is_guest'] ? ('.' . (!empty($options['view_newest_first']) ? 0 : ((int) (($row['num_replies']) / $context['pageindex_multiplier'])) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg']) : (($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new')),
497
					'link' => '<a href="' . $scripturl . '?topic=' . $row['id_topic'] . ($user_info['is_guest'] ? ('.' . (!empty($options['view_newest_first']) ? 0 : ((int) (($row['num_replies']) / $context['pageindex_multiplier'])) * $context['pageindex_multiplier']) . '#msg' . $row['id_last_msg']) : (($row['num_replies'] == 0 ? '.0' : '.msg' . $row['id_last_msg']) . '#new')) . '" ' . ($row['num_replies'] == 0 ? '' : 'rel="nofollow"') . '>' . $row['last_subject'] . '</a>'
498
				),
499
				'is_sticky' => !empty($row['is_sticky']),
500
				'is_locked' => !empty($row['locked']),
501
				'is_redirect' => !empty($row['id_redirect_topic']),
502
				'is_poll' => $modSettings['pollMode'] == '1' && $row['id_poll'] > 0,
503
				'is_posted_in' => false,
504
				'is_watched' => false,
505
				'icon' => $row['first_icon'],
506
				'icon_url' => $settings[$context['icon_sources'][$row['first_icon']]] . '/post/' . $row['first_icon'] . '.png',
507
				'subject' => $row['first_subject'],
508
				'new' => $row['new_from'] <= $row['id_msg_modified'],
509
				'new_from' => $row['new_from'],
510
				'newtime' => $row['new_from'],
511
				'new_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['new_from'] . '#new',
512
				'pages' => $pages,
513
				'replies' => comma_format($row['num_replies']),
514
				'views' => comma_format($row['num_views']),
515
				'approved' => $row['approved'],
516
				'unapproved_posts' => $row['unapproved_posts'],
517
				'css_class' => $colorClass,
518
			));
519
			if (!empty($settings['avatars_on_indexes']))
520
			{
521
				// Last post member avatar
522
				$context['topics'][$row['id_topic']]['last_post']['member']['avatar'] = set_avatar_data(array(
523
					'avatar' => $row['avatar'],
524
					'email' => $row['email_address'],
525
					'filename' => !empty($row['last_member_filename']) ? $row['last_member_filename'] : '',
526
				));
527
528
				// First post member avatar
529
				$context['topics'][$row['id_topic']]['first_post']['member']['avatar'] = set_avatar_data(array(
530
					'avatar' => $row['first_member_avatar'],
531
					'email' => $row['first_member_mail'],
532
					'filename' => !empty($row['first_member_filename']) ? $row['first_member_filename'] : '',
533
				));
534
			}
535
		}
536
		$smcFunc['db_free_result']($result);
537
538
		// Fix the sequence of topics if they were retrieved in the wrong order. (for speed reasons...)
539
		if ($fake_ascending)
540
			$context['topics'] = array_reverse($context['topics'], true);
541
542
		if (!empty($modSettings['enableParticipation']) && !$user_info['is_guest'] && !empty($topic_ids))
543
		{
544
			$result = $smcFunc['db_query']('', '
545
				SELECT id_topic
546
				FROM {db_prefix}messages
547
				WHERE id_topic IN ({array_int:topic_list})
548
					AND id_member = {int:current_member}
549
				GROUP BY id_topic
550
				LIMIT {int:limit}',
551
				array(
552
					'current_member' => $user_info['id'],
553
					'topic_list' => $topic_ids,
554
					'limit' => count($topic_ids),
555
				)
556
			);
557
			while ($row = $smcFunc['db_fetch_assoc']($result))
558
				$context['topics'][$row['id_topic']]['is_posted_in'] = true;
559
			$smcFunc['db_free_result']($result);
560
		}
561
	}
562
563
	$context['jump_to'] = array(
564
		'label' => addslashes(un_htmlspecialchars($txt['jump_to'])),
565
		'board_name' => $smcFunc['htmlspecialchars'](strtr(strip_tags($board_info['name']), array('&amp;' => '&'))),
566
		'child_level' => $board_info['child_level'],
567
	);
568
569
	// Is Quick Moderation active/needed?
570
	if (!empty($options['display_quick_mod']) && !empty($context['topics']))
571
	{
572
		$context['can_markread'] = $context['user']['is_logged'];
573
		$context['can_lock'] = allowedTo('lock_any');
574
		$context['can_sticky'] = allowedTo('make_sticky');
575
		$context['can_move'] = allowedTo('move_any');
576
		$context['can_remove'] = allowedTo('remove_any');
577
		$context['can_merge'] = allowedTo('merge_any');
578
		// Ignore approving own topics as it's unlikely to come up...
579
		$context['can_approve'] = $modSettings['postmod_active'] && allowedTo('approve_posts') && !empty($board_info['unapproved_topics']);
580
		// Can we restore topics?
581
		$context['can_restore'] = allowedTo('move_any') && !empty($board_info['recycle']);
582
583
		if ($user_info['is_admin'] || $modSettings['topic_move_any'])
584
			$context['can_move_any'] = true;
585
		else
586
		{
587
			// We'll use this in a minute
588
			$boards_allowed = boardsAllowedTo('post_new');
589
590
			// How many boards can you do this on besides this one?
591
			$context['can_move_any'] = count($boards_allowed) > 1;
592
		}
593
594
		// Set permissions for all the topics.
595
		foreach ($context['topics'] as $t => $topic)
596
		{
597
			$started = $topic['first_post']['member']['id'] == $user_info['id'];
598
			$context['topics'][$t]['quick_mod'] = array(
599
				'lock' => allowedTo('lock_any') || ($started && allowedTo('lock_own')),
600
				'sticky' => allowedTo('make_sticky'),
601
				'move' => (allowedTo('move_any') || ($started && allowedTo('move_own')) && $context['can_move_any']),
602
				'modify' => allowedTo('modify_any') || ($started && allowedTo('modify_own')),
603
				'remove' => allowedTo('remove_any') || ($started && allowedTo('remove_own')),
604
				'approve' => $context['can_approve'] && $topic['unapproved_posts']
605
			);
606
			$context['can_lock'] |= ($started && allowedTo('lock_own'));
607
			$context['can_move'] |= ($started && allowedTo('move_own') && $context['can_move_any']);
608
			$context['can_remove'] |= ($started && allowedTo('remove_own'));
609
		}
610
611
		// Can we use quick moderation checkboxes?
612
		if ($options['display_quick_mod'] == 1)
613
			$context['can_quick_mod'] = $context['user']['is_logged'] || $context['can_approve'] || $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'] || $context['can_merge'] || $context['can_restore'];
614
		// Or the icons?
615
		else
616
			$context['can_quick_mod'] = $context['can_remove'] || $context['can_lock'] || $context['can_sticky'] || $context['can_move'];
617
	}
618
619
	if (!empty($context['can_quick_mod']) && $options['display_quick_mod'] == 1)
620
	{
621
		$context['qmod_actions'] = array('approve', 'remove', 'lock', 'sticky', 'move', 'merge', 'restore', 'markread');
622
		call_integration_hook('integrate_quick_mod_actions');
623
	}
624
625
	// Mark current and parent boards as seen.
626
	if (!$user_info['is_guest'])
627
	{
628
		$smcFunc['db_insert']('replace',
629
			'{db_prefix}log_boards',
630
			array('id_msg' => 'int', 'id_member' => 'int', 'id_board' => 'int'),
631
			array($modSettings['maxMsgID'], $user_info['id'], $board),
632
			array('id_member', 'id_board')
633
		);
634
635
		if (!empty($board_info['parent_boards']))
636
		{
637
			$smcFunc['db_query']('', '
638
				UPDATE {db_prefix}log_boards
639
				SET id_msg = {int:id_msg}
640
				WHERE id_member = {int:current_member}
641
					AND id_board IN ({array_int:board_list})',
642
				array(
643
					'current_member' => $user_info['id'],
644
					'board_list' => array_keys($board_info['parent_boards']),
645
					'id_msg' => $modSettings['maxMsgID'],
646
				)
647
			);
648
649
			// We've seen all these boards now!
650
			foreach ($board_info['parent_boards'] as $k => $dummy)
651
				if (isset($_SESSION['topicseen_cache'][$k]))
652
					unset($_SESSION['topicseen_cache'][$k]);
653
		}
654
655
		if (isset($_SESSION['topicseen_cache'][$board]))
656
			unset($_SESSION['topicseen_cache'][$board]);
657
658
		$request = $smcFunc['db_query']('', '
659
			SELECT id_topic, id_board, sent
660
			FROM {db_prefix}log_notify
661
			WHERE id_member = {int:current_member}
662
				AND (' . (!empty($context['topics']) ? 'id_topic IN ({array_int:topics}) OR ' : '') . 'id_board = {int:current_board})',
663
			array(
664
				'current_board' => $board,
665
				'topics' => !empty($context['topics']) ? array_keys($context['topics']) : array(),
666
				'current_member' => $user_info['id'],
667
			)
668
		);
669
		$context['is_marked_notify'] = false; // this is for the *board* only
670
		while ($row = $smcFunc['db_fetch_assoc']($request))
671
		{
672
			if (!empty($row['id_board']))
673
			{
674
				$context['is_marked_notify'] = true;
675
				$board_sent = $row['sent'];
676
			}
677
			if (!empty($row['id_topic']))
678
				$context['topics'][$row['id_topic']]['is_watched'] = true;
679
		}
680
		$smcFunc['db_free_result']($request);
681
682 View Code Duplication
		if ($context['is_marked_notify'] && !empty($board_sent))
683
		{
684
			$smcFunc['db_query']('', '
685
				UPDATE {db_prefix}log_notify
686
				SET sent = {int:is_sent}
687
				WHERE id_member = {int:current_member}
688
					AND id_board = {int:current_board}',
689
				array(
690
					'current_board' => $board,
691
					'current_member' => $user_info['id'],
692
					'is_sent' => 0,
693
				)
694
			);
695
		}
696
697
		require_once($sourcedir . '/Subs-Notify.php');
698
		$pref = getNotifyPrefs($user_info['id'], array('board_notify', 'board_notify_' . $board), true);
699
		$pref = !empty($pref[$user_info['id']]) ? $pref[$user_info['id']] : array();
700
		$pref = isset($pref['board_notify_' . $board]) ? $pref['board_notify_' . $board] : (!empty($pref['board_notify']) ? $pref['board_notify'] : 0);
701
		$context['board_notification_mode'] = !$context['is_marked_notify'] ? 1 : ($pref & 0x02 ? 3 : ($pref & 0x01 ? 2 : 1));
702
	}
703
	else
704
	{
705
		$context['is_marked_notify'] = false;
706
		$context['board_notification_mode'] = 1;
707
	}
708
709
	// If there are children, but no topics and no ability to post topics...
710
	$context['no_topic_listing'] = !empty($context['boards']) && empty($context['topics']) && !$context['can_post_new'];
711
712
	// Show a message in case a recently posted message became unapproved.
713
	$context['becomesUnapproved'] = !empty($_SESSION['becomesUnapproved']) ? true : false;
714
715
	// Don't want to show this forever...
716
	if ($context['becomesUnapproved'])
717
		unset($_SESSION['becomesUnapproved']);
718
719
	// Build the message index button array.
720
	$context['normal_buttons'] = array();
721
722 View Code Duplication
	if ($context['can_post_new'])
723
		$context['normal_buttons']['new_topic'] = array('text' => 'new_topic', 'image' => 'new_topic.png', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0', 'active' => true);
724
725 View Code Duplication
	if ($context['can_post_poll'])
726
		$context['normal_buttons']['post_poll'] = array('text' => 'new_poll', 'image' => 'new_poll.png', 'lang' => true, 'url' => $scripturl . '?action=post;board=' . $context['current_board'] . '.0;poll');
727
728 View Code Duplication
	if (!$context['user']['is_logged'])
729
		$context['normal_buttons']['markread'] = array('text' => 'mark_read_short', 'image' => 'markread.png', 'lang' => true, 'custom' => 'data-confirm="' . $txt['are_sure_mark_read'] . '"', 'class' => 'you_sure', 'url' => $scripturl . '?action=markasread;sa=board;board=' . $context['current_board'] . '.0;' . $context['session_var'] . '=' . $context['session_id']);
730
731
	if ($context['can_mark_notify'])
732
		$context['normal_buttons']['notify'] = array(
733
			'lang' => true,
734
			'text' => 'notify_board_' . $context['board_notification_mode'],
735
			'sub_buttons' => array(
736
				array(
737
					'text' => 'notify_board_1',
738
					'url' => $scripturl . '?action=notifyboard;board=' . $board . ';mode=1;' . $context['session_var'] . '=' . $context['session_id'],
739
				),
740
				array(
741
					'text' => 'notify_board_2',
742
					'url' => $scripturl . '?action=notifyboard;board=' . $board . ';mode=2;' . $context['session_var'] . '=' . $context['session_id'],
743
				),
744
				array(
745
					'text' => 'notify_board_3',
746
					'url' => $scripturl . '?action=notifyboard;board=' . $board . ';mode=3;' . $context['session_var'] . '=' . $context['session_id'],
747
				),
748
			),
749
		);
750
751
	// Javascript for inline editing.
752
	loadJavaScriptFile('topic.js', array('defer' => false), 'smf_topic');
753
754
	// Allow adding new buttons easily.
755
	// Note: $context['normal_buttons'] is added for backward compatibility with 2.0, but is deprecated and should not be used
756
	call_integration_hook('integrate_messageindex_buttons', array(&$context['normal_buttons']));
757
}
758
759
/**
760
 * Handles moderation from the message index.
761
 * @todo refactor this...
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
762
 */
763
function QuickModeration()
764
{
765
	global $sourcedir, $board, $user_info, $modSettings, $smcFunc, $context;
766
767
	// Check the session = get or post.
768
	checkSession('request');
769
770
	// Lets go straight to the restore area.
771 View Code Duplication
	if (isset($_REQUEST['qaction']) && $_REQUEST['qaction'] == 'restore' && !empty($_REQUEST['topics']))
772
		redirectexit('action=restoretopic;topics=' . implode(',', $_REQUEST['topics']) . ';' . $context['session_var'] . '=' . $context['session_id']);
773
774
	if (isset($_SESSION['topicseen_cache']))
775
		$_SESSION['topicseen_cache'] = array();
776
777
	// This is going to be needed to send off the notifications and for updateLastMessages().
778
	require_once($sourcedir . '/Subs-Post.php');
779
780
	// Remember the last board they moved things to.
781
	if (isset($_REQUEST['move_to']))
782
		$_SESSION['move_to_topic'] = $_REQUEST['move_to'];
783
784
	// Only a few possible actions.
785
	$possibleActions = array();
786
787
	if (!empty($board))
788
	{
789
		$boards_can = array(
790
			'make_sticky' => allowedTo('make_sticky') ? array($board) : array(),
791
			'move_any' => allowedTo('move_any') ? array($board) : array(),
792
			'move_own' => allowedTo('move_own') ? array($board) : array(),
793
			'remove_any' => allowedTo('remove_any') ? array($board) : array(),
794
			'remove_own' => allowedTo('remove_own') ? array($board) : array(),
795
			'lock_any' => allowedTo('lock_any') ? array($board) : array(),
796
			'lock_own' => allowedTo('lock_own') ? array($board) : array(),
797
			'merge_any' => allowedTo('merge_any') ? array($board) : array(),
798
			'approve_posts' => allowedTo('approve_posts') ? array($board) : array(),
799
		);
800
801
		$redirect_url = 'board=' . $board . '.' . $_REQUEST['start'];
802
	}
803
	else
804
	{
805
		/**
806
		 * @todo Ugly. There's no getting around this, is there?
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
807
		 * @todo Maybe just do this on the actions people want to use?
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

Loading history...
808
		 */
809
		$boards_can = boardsAllowedTo(array('make_sticky', 'move_any', 'move_own', 'remove_any', 'remove_own', 'lock_any', 'lock_own', 'merge_any', 'approve_posts'), true, false);
810
811
		$redirect_url = isset($_POST['redirect_url']) ? $_POST['redirect_url'] : (isset($_SESSION['old_url']) ? $_SESSION['old_url'] : '');
812
	}
813
814
	// Are we enforcing the "no moving topics to boards where you can't post new ones" rule?
815
	if (!$user_info['is_admin'] && !$modSettings['topic_move_any'])
816
	{
817
		// Don't count this board, if it's specified
818 View Code Duplication
		if (!empty($board))
819
		{
820
			$boards_can['post_new'] = array_diff(boardsAllowedTo('post_new'), array($board));
821
		}
822
		else
823
		{
824
			$boards_can['post_new'] = boardsAllowedTo('post_new');
825
		}
826
827
		if (empty($boards_can['post_new']))
828
		{
829
			$boards_can['move_any'] = $boards_can['move_own'] = array();
830
		}
831
	}
832
833
	if (!$user_info['is_guest'])
834
		$possibleActions[] = 'markread';
835
	if (!empty($boards_can['make_sticky']))
836
		$possibleActions[] = 'sticky';
837
	if (!empty($boards_can['move_any']) || !empty($boards_can['move_own']))
838
		$possibleActions[] = 'move';
839
	if (!empty($boards_can['remove_any']) || !empty($boards_can['remove_own']))
840
		$possibleActions[] = 'remove';
841
	if (!empty($boards_can['lock_any']) || !empty($boards_can['lock_own']))
842
		$possibleActions[] = 'lock';
843
	if (!empty($boards_can['merge_any']))
844
		$possibleActions[] = 'merge';
845
	if (!empty($boards_can['approve_posts']))
846
		$possibleActions[] = 'approve';
847
848
	// Two methods: $_REQUEST['actions'] (id_topic => action), and $_REQUEST['topics'] and $_REQUEST['qaction'].
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
849
	// (if action is 'move', $_REQUEST['move_to'] or $_REQUEST['move_tos'][$topic] is used.)
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
850
	if (!empty($_REQUEST['topics']))
851
	{
852
		// If the action isn't valid, just quit now.
853
		if (empty($_REQUEST['qaction']) || !in_array($_REQUEST['qaction'], $possibleActions))
854
			redirectexit($redirect_url);
855
856
		// Merge requires all topics as one parameter and can be done at once.
857
		if ($_REQUEST['qaction'] == 'merge')
858
		{
859
			// Merge requires at least two topics.
860
			if (empty($_REQUEST['topics']) || count($_REQUEST['topics']) < 2)
861
				redirectexit($redirect_url);
862
863
			require_once($sourcedir . '/SplitTopics.php');
864
			return MergeExecute($_REQUEST['topics']);
865
		}
866
867
		// Just convert to the other method, to make it easier.
868
		foreach ($_REQUEST['topics'] as $topic)
869
			$_REQUEST['actions'][(int) $topic] = $_REQUEST['qaction'];
870
	}
871
872
	// Weird... how'd you get here?
873
	if (empty($_REQUEST['actions']))
874
		redirectexit($redirect_url);
875
876
	// Validate each action.
877
	$temp = array();
878
	foreach ($_REQUEST['actions'] as $topic => $action)
879
	{
880
		if (in_array($action, $possibleActions))
881
			$temp[(int) $topic] = $action;
882
	}
883
	$_REQUEST['actions'] = $temp;
884
885
	if (!empty($_REQUEST['actions']))
886
	{
887
		// Find all topics...
888
		$request = $smcFunc['db_query']('', '
889
			SELECT id_topic, id_member_started, id_board, locked, approved, unapproved_posts
890
			FROM {db_prefix}topics
891
			WHERE id_topic IN ({array_int:action_topic_ids})
892
			LIMIT {int:limit}',
893
			array(
894
				'action_topic_ids' => array_keys($_REQUEST['actions']),
895
				'limit' => count($_REQUEST['actions']),
896
			)
897
		);
898
		while ($row = $smcFunc['db_fetch_assoc']($request))
899
		{
900
			if (!empty($board))
901
			{
902
				if ($row['id_board'] != $board || ($modSettings['postmod_active'] && !$row['approved'] && !allowedTo('approve_posts')))
903
					unset($_REQUEST['actions'][$row['id_topic']]);
904
			}
905
			else
906
			{
907
				// Don't allow them to act on unapproved posts they can't see...
908
				if ($modSettings['postmod_active'] && !$row['approved'] && !in_array(0, $boards_can['approve_posts']) && !in_array($row['id_board'], $boards_can['approve_posts']))
909
					unset($_REQUEST['actions'][$row['id_topic']]);
910
				// Goodness, this is fun.  We need to validate the action.
911 View Code Duplication
				elseif ($_REQUEST['actions'][$row['id_topic']] == 'sticky' && !in_array(0, $boards_can['make_sticky']) && !in_array($row['id_board'], $boards_can['make_sticky']))
912
					unset($_REQUEST['actions'][$row['id_topic']]);
913 View Code Duplication
				elseif ($_REQUEST['actions'][$row['id_topic']] == 'move' && !in_array(0, $boards_can['move_any']) && !in_array($row['id_board'], $boards_can['move_any']) && ($row['id_member_started'] != $user_info['id'] || (!in_array(0, $boards_can['move_own']) && !in_array($row['id_board'], $boards_can['move_own']))))
914
					unset($_REQUEST['actions'][$row['id_topic']]);
915 View Code Duplication
				elseif ($_REQUEST['actions'][$row['id_topic']] == 'remove' && !in_array(0, $boards_can['remove_any']) && !in_array($row['id_board'], $boards_can['remove_any']) && ($row['id_member_started'] != $user_info['id'] || (!in_array(0, $boards_can['remove_own']) && !in_array($row['id_board'], $boards_can['remove_own']))))
916
					unset($_REQUEST['actions'][$row['id_topic']]);
917
				// @todo $locked is not set, what are you trying to do? (taking the change it is supposed to be $row['locked'])
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
918 View Code Duplication
				elseif ($_REQUEST['actions'][$row['id_topic']] == 'lock' && !in_array(0, $boards_can['lock_any']) && !in_array($row['id_board'], $boards_can['lock_any']) && ($row['id_member_started'] != $user_info['id'] || $row['locked'] == 1 || (!in_array(0, $boards_can['lock_own']) && !in_array($row['id_board'], $boards_can['lock_own']))))
919
					unset($_REQUEST['actions'][$row['id_topic']]);
920
				// If the topic is approved then you need permission to approve the posts within.
921 View Code Duplication
				elseif ($_REQUEST['actions'][$row['id_topic']] == 'approve' && (!$row['unapproved_posts'] || (!in_array(0, $boards_can['approve_posts']) && !in_array($row['id_board'], $boards_can['approve_posts']))))
922
					unset($_REQUEST['actions'][$row['id_topic']]);
923
			}
924
		}
925
		$smcFunc['db_free_result']($request);
926
	}
927
928
	$stickyCache = array();
929
	$moveCache = array(0 => array(), 1 => array());
930
	$removeCache = array();
931
	$lockCache = array();
932
	$markCache = array();
933
	$approveCache = array();
934
935
	// Separate the actions.
936
	foreach ($_REQUEST['actions'] as $topic => $action)
937
	{
938
		$topic = (int) $topic;
939
940
		if ($action == 'markread')
941
			$markCache[] = $topic;
942
		elseif ($action == 'sticky')
943
			$stickyCache[] = $topic;
944
		elseif ($action == 'move')
945
		{
946
			require_once($sourcedir . '/MoveTopic.php');
947
			moveTopicConcurrence();
948
949
			// $moveCache[0] is the topic, $moveCache[1] is the board to move to.
950
			$moveCache[1][$topic] = (int) (isset($_REQUEST['move_tos'][$topic]) ? $_REQUEST['move_tos'][$topic] : $_REQUEST['move_to']);
951
952
			if (empty($moveCache[1][$topic]))
953
				continue;
954
955
			$moveCache[0][] = $topic;
956
		}
957
		elseif ($action == 'remove')
958
			$removeCache[] = $topic;
959
		elseif ($action == 'lock')
960
			$lockCache[] = $topic;
961
		elseif ($action == 'approve')
962
			$approveCache[] = $topic;
963
	}
964
965
	if (empty($board))
966
		$affectedBoards = array();
967
	else
968
		$affectedBoards = array($board => array(0, 0));
969
970
	// Do all the stickies...
971
	if (!empty($stickyCache))
972
	{
973
		$smcFunc['db_query']('', '
974
			UPDATE {db_prefix}topics
975
			SET is_sticky = CASE WHEN is_sticky = {int:is_sticky} THEN 0 ELSE 1 END
976
			WHERE id_topic IN ({array_int:sticky_topic_ids})',
977
			array(
978
				'sticky_topic_ids' => $stickyCache,
979
				'is_sticky' => 1,
980
			)
981
		);
982
983
		// Get the board IDs and Sticky status
984
		$request = $smcFunc['db_query']('', '
985
			SELECT id_topic, id_board, is_sticky
986
			FROM {db_prefix}topics
987
			WHERE id_topic IN ({array_int:sticky_topic_ids})
988
			LIMIT {int:limit}',
989
			array(
990
				'sticky_topic_ids' => $stickyCache,
991
				'limit' => count($stickyCache),
992
			)
993
		);
994
		$stickyCacheBoards = array();
995
		$stickyCacheStatus = array();
996 View Code Duplication
		while ($row = $smcFunc['db_fetch_assoc']($request))
997
		{
998
			$stickyCacheBoards[$row['id_topic']] = $row['id_board'];
999
			$stickyCacheStatus[$row['id_topic']] = empty($row['is_sticky']);
1000
		}
1001
		$smcFunc['db_free_result']($request);
1002
	}
1003
1004
	// Move sucka! (this is, by the by, probably the most complicated part....)
1005
	if (!empty($moveCache[0]))
1006
	{
1007
		// I know - I just KNOW you're trying to beat the system.  Too bad for you... we CHECK :P.
1008
		$request = $smcFunc['db_query']('', '
1009
			SELECT t.id_topic, t.id_board, b.count_posts
1010
			FROM {db_prefix}topics AS t
1011
				LEFT JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board)
1012
			WHERE t.id_topic IN ({array_int:move_topic_ids})' . (!empty($board) && !allowedTo('move_any') ? '
1013
				AND t.id_member_started = {int:current_member}' : '') . '
1014
			LIMIT {int:limit}',
1015
			array(
1016
				'current_member' => $user_info['id'],
1017
				'move_topic_ids' => $moveCache[0],
1018
				'limit' => count($moveCache[0])
1019
			)
1020
		);
1021
		$moveTos = array();
1022
		$moveCache2 = array();
1023
		$countPosts = array();
1024
		while ($row = $smcFunc['db_fetch_assoc']($request))
1025
		{
1026
			$to = $moveCache[1][$row['id_topic']];
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $to. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1027
1028
			if (empty($to))
1029
				continue;
1030
1031
			// Does this topic's board count the posts or not?
1032
			$countPosts[$row['id_topic']] = empty($row['count_posts']);
1033
1034
			if (!isset($moveTos[$to]))
1035
				$moveTos[$to] = array();
1036
1037
			$moveTos[$to][] = $row['id_topic'];
1038
1039
			// For reporting...
1040
			$moveCache2[] = array($row['id_topic'], $row['id_board'], $to);
1041
		}
1042
		$smcFunc['db_free_result']($request);
1043
1044
		$moveCache = $moveCache2;
1045
1046
		require_once($sourcedir . '/MoveTopic.php');
1047
1048
		// Do the actual moves...
1049
		foreach ($moveTos as $to => $topics)
1050
			moveTopics($topics, $to);
1051
1052
		// Does the post counts need to be updated?
1053
		if (!empty($moveTos))
1054
		{
1055
			$topicRecounts = array();
1056
			$request = $smcFunc['db_query']('', '
1057
				SELECT id_board, count_posts
1058
				FROM {db_prefix}boards
1059
				WHERE id_board IN ({array_int:move_boards})',
1060
				array(
1061
					'move_boards' => array_keys($moveTos),
1062
				)
1063
			);
1064
1065
			while ($row = $smcFunc['db_fetch_assoc']($request))
1066
			{
1067
				$cp = empty($row['count_posts']);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $cp. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
1068
1069
				// Go through all the topics that are being moved to this board.
1070
				foreach ($moveTos[$row['id_board']] as $topic)
1071
				{
1072
					// If both boards have the same value for post counting then no adjustment needs to be made.
1073
					if ($countPosts[$topic] != $cp)
1074
					{
1075
						// If the board being moved to does count the posts then the other one doesn't so add to their post count.
1076
						$topicRecounts[$topic] = $cp ? '+' : '-';
1077
					}
1078
				}
1079
			}
1080
1081
			$smcFunc['db_free_result']($request);
1082
1083
			if (!empty($topicRecounts))
1084
			{
1085
				$members = array();
1086
1087
				// Get all the members who have posted in the moved topics.
1088
				$request = $smcFunc['db_query']('', '
1089
					SELECT id_member, id_topic
1090
					FROM {db_prefix}messages
1091
					WHERE id_topic IN ({array_int:moved_topic_ids})',
1092
					array(
1093
						'moved_topic_ids' => array_keys($topicRecounts),
1094
					)
1095
				);
1096
1097
				while ($row = $smcFunc['db_fetch_assoc']($request))
1098
				{
1099
					if (!isset($members[$row['id_member']]))
1100
						$members[$row['id_member']] = 0;
1101
1102
					if ($topicRecounts[$row['id_topic']] === '+')
1103
						$members[$row['id_member']] += 1;
1104
					else
1105
						$members[$row['id_member']] -= 1;
1106
				}
1107
1108
				$smcFunc['db_free_result']($request);
1109
1110
				// And now update them member's post counts
1111
				foreach ($members as $id_member => $post_adj)
1112
					updateMemberData($id_member, array('posts' => 'posts + ' . $post_adj));
1113
1114
			}
1115
		}
1116
	}
1117
1118
	// Now delete the topics...
1119
	if (!empty($removeCache))
1120
	{
1121
		// They can only delete their own topics. (we wouldn't be here if they couldn't do that..)
1122
		$result = $smcFunc['db_query']('', '
1123
			SELECT id_topic, id_board
1124
			FROM {db_prefix}topics
1125
			WHERE id_topic IN ({array_int:removed_topic_ids})' . (!empty($board) && !allowedTo('remove_any') ? '
1126
				AND id_member_started = {int:current_member}' : '') . '
1127
			LIMIT {int:limit}',
1128
			array(
1129
				'current_member' => $user_info['id'],
1130
				'removed_topic_ids' => $removeCache,
1131
				'limit' => count($removeCache),
1132
			)
1133
		);
1134
1135
		$removeCache = array();
1136
		$removeCacheBoards = array();
1137
		while ($row = $smcFunc['db_fetch_assoc']($result))
1138
		{
1139
			$removeCache[] = $row['id_topic'];
1140
			$removeCacheBoards[$row['id_topic']] = $row['id_board'];
1141
		}
1142
		$smcFunc['db_free_result']($result);
1143
1144
		// Maybe *none* were their own topics.
1145
		if (!empty($removeCache))
1146
		{
1147
			// Gotta send the notifications *first*!
1148
			foreach ($removeCache as $topic)
1149
			{
1150
				// Only log the topic ID if it's not in the recycle board.
1151
				logAction('remove', array((empty($modSettings['recycle_enable']) || $modSettings['recycle_board'] != $removeCacheBoards[$topic] ? 'topic' : 'old_topic_id') => $topic, 'board' => $removeCacheBoards[$topic]));
1152
				sendNotifications($topic, 'remove');
1153
			}
1154
1155
			require_once($sourcedir . '/RemoveTopic.php');
1156
			removeTopics($removeCache);
1157
		}
1158
	}
1159
1160
	// Approve the topics...
1161
	if (!empty($approveCache))
1162
	{
1163
		// We need unapproved topic ids and their authors!
1164
		$request = $smcFunc['db_query']('', '
1165
			SELECT id_topic, id_member_started
1166
			FROM {db_prefix}topics
1167
			WHERE id_topic IN ({array_int:approve_topic_ids})
1168
				AND approved = {int:not_approved}
1169
			LIMIT {int:limit}',
1170
			array(
1171
				'approve_topic_ids' => $approveCache,
1172
				'not_approved' => 0,
1173
				'limit' => count($approveCache),
1174
			)
1175
		);
1176
		$approveCache = array();
1177
		$approveCacheMembers = array();
1178
		while ($row = $smcFunc['db_fetch_assoc']($request))
1179
		{
1180
			$approveCache[] = $row['id_topic'];
1181
			$approveCacheMembers[$row['id_topic']] = $row['id_member_started'];
1182
		}
1183
		$smcFunc['db_free_result']($request);
1184
1185
		// Any topics to approve?
1186
		if (!empty($approveCache))
1187
		{
1188
			// Handle the approval part...
1189
			approveTopics($approveCache);
1190
1191
			// Time for some logging!
1192
			foreach ($approveCache as $topic)
1193
				logAction('approve_topic', array('topic' => $topic, 'member' => $approveCacheMembers[$topic]));
1194
		}
1195
	}
1196
1197
	// And (almost) lastly, lock the topics...
1198
	if (!empty($lockCache))
1199
	{
1200
		$lockStatus = array();
1201
1202
		// Gotta make sure they CAN lock/unlock these topics...
1203
		if (!empty($board) && !allowedTo('lock_any'))
1204
		{
1205
			// Make sure they started the topic AND it isn't already locked by someone with higher priv's.
1206
			$result = $smcFunc['db_query']('', '
1207
				SELECT id_topic, locked, id_board
1208
				FROM {db_prefix}topics
1209
				WHERE id_topic IN ({array_int:locked_topic_ids})
1210
					AND id_member_started = {int:current_member}
1211
					AND locked IN (2, 0)
1212
				LIMIT {int:limit}',
1213
				array(
1214
					'current_member' => $user_info['id'],
1215
					'locked_topic_ids' => $lockCache,
1216
					'limit' => count($lockCache),
1217
				)
1218
			);
1219
			$lockCache = array();
1220
			$lockCacheBoards = array();
1221
			while ($row = $smcFunc['db_fetch_assoc']($result))
1222
			{
1223
				$lockCache[] = $row['id_topic'];
1224
				$lockCacheBoards[$row['id_topic']] = $row['id_board'];
1225
				$lockStatus[$row['id_topic']] = empty($row['locked']);
1226
			}
1227
			$smcFunc['db_free_result']($result);
1228
		}
1229
		else
1230
		{
1231
			$result = $smcFunc['db_query']('', '
1232
				SELECT id_topic, locked, id_board
1233
				FROM {db_prefix}topics
1234
				WHERE id_topic IN ({array_int:locked_topic_ids})
1235
				LIMIT {int:limit}',
1236
				array(
1237
					'locked_topic_ids' => $lockCache,
1238
					'limit' => count($lockCache)
1239
				)
1240
			);
1241
			$lockCacheBoards = array();
1242 View Code Duplication
			while ($row = $smcFunc['db_fetch_assoc']($result))
1243
			{
1244
				$lockStatus[$row['id_topic']] = empty($row['locked']);
1245
				$lockCacheBoards[$row['id_topic']] = $row['id_board'];
1246
			}
1247
			$smcFunc['db_free_result']($result);
1248
		}
1249
1250
		// It could just be that *none* were their own topics...
1251
		if (!empty($lockCache))
1252
		{
1253
			// Alternate the locked value.
1254
			$smcFunc['db_query']('', '
1255
				UPDATE {db_prefix}topics
1256
				SET locked = CASE WHEN locked = {int:is_locked} THEN ' . (allowedTo('lock_any') ? '1' : '2') . ' ELSE 0 END
1257
				WHERE id_topic IN ({array_int:locked_topic_ids})',
1258
				array(
1259
					'locked_topic_ids' => $lockCache,
1260
					'is_locked' => 0,
1261
				)
1262
			);
1263
		}
1264
	}
1265
1266
	if (!empty($markCache))
1267
	{
1268
		$smcFunc['db_query']('', '
1269
			SELECT id_topic, unwatched
1270
			FROM {db_prefix}log_topics
1271
			WHERE id_topic IN ({array_int:selected_topics})
1272
				AND id_member = {int:current_user}',
1273
			array(
1274
				'selected_topics' => $markCache,
1275
				'current_user' => $user_info['id'],
1276
			)
1277
		);
1278
		$logged_topics = array();
1279 View Code Duplication
		while ($row = $smcFunc['db_fetch_assoc']($request))
0 ignored issues
show
Bug introduced by
The variable $request does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1280
			$logged_topics[$row['id_topic']] = $row['unwatched'];
1281
		$smcFunc['db_free_result']($request);
1282
1283
		$markArray = array();
1284 View Code Duplication
		foreach ($markCache as $topic)
1285
			$markArray[] = array($modSettings['maxMsgID'], $user_info['id'], $topic, (isset($logged_topics[$topic]) ? $logged_topics[$topic] : 0));
1286
1287
		$smcFunc['db_insert']('replace',
1288
			'{db_prefix}log_topics',
1289
			array('id_msg' => 'int', 'id_member' => 'int', 'id_topic' => 'int', 'unwatched' => 'int'),
1290
			$markArray,
1291
			array('id_member', 'id_topic')
1292
		);
1293
	}
1294
1295
	foreach ($moveCache as $topic)
1296
	{
1297
		// Didn't actually move anything!
1298
		if (!isset($topic[0]))
1299
			break;
1300
1301
		logAction('move', array('topic' => $topic[0], 'board_from' => $topic[1], 'board_to' => $topic[2]));
1302
		sendNotifications($topic[0], 'move');
1303
	}
1304 View Code Duplication
	foreach ($lockCache as $topic)
1305
	{
1306
		logAction($lockStatus[$topic] ? 'lock' : 'unlock', array('topic' => $topic, 'board' => $lockCacheBoards[$topic]));
0 ignored issues
show
Bug introduced by
The variable $lockStatus does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $lockCacheBoards does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1307
		sendNotifications($topic, $lockStatus[$topic] ? 'lock' : 'unlock');
1308
	}
1309 View Code Duplication
	foreach ($stickyCache as $topic)
1310
	{
1311
		logAction($stickyCacheStatus[$topic] ? 'unsticky' : 'sticky', array('topic' => $topic, 'board' => $stickyCacheBoards[$topic]));
0 ignored issues
show
Bug introduced by
The variable $stickyCacheStatus does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $stickyCacheBoards does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1312
		sendNotifications($topic, 'sticky');
1313
	}
1314
1315
	updateStats('topic');
1316
	updateStats('message');
1317
	updateSettings(array(
1318
		'calendar_updated' => time(),
1319
	));
1320
1321
	if (!empty($affectedBoards))
1322
		updateLastMessages(array_keys($affectedBoards));
1323
1324
	redirectexit($redirect_url);
1325
}
1326
1327
?>