Issues (1065)

Sources/ModerationCenter.php (3 issues)

1
<?php
2
3
/**
4
 * Moderation Center.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines https://www.simplemachines.org
10
 * @copyright 2025 Simple Machines and individual contributors
11
 * @license https://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1.5
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * Entry point for the moderation center.
21
 *
22
 * @param bool $dont_call If true, doesn't call the function for the appropriate mod area
23
 */
24
function ModerationMain($dont_call = false)
25
{
26
	global $smcFunc, $txt, $context, $scripturl, $modSettings, $user_info, $sourcedir, $options;
27
28
	// Don't run this twice... and don't conflict with the admin bar.
29
	if (isset($context['admin_area']))
30
		return;
31
32
	$context['can_moderate_boards'] = $user_info['mod_cache']['bq'] != '0=1';
33
	$context['can_moderate_groups'] = $user_info['mod_cache']['gq'] != '0=1';
34
	$context['can_moderate_approvals'] = $modSettings['postmod_active'] && !empty($user_info['mod_cache']['ap']);
35
	$context['can_moderate_users'] = allowedTo('moderate_forum');
36
37
	// Everyone using this area must be allowed here!
38
	if (!$context['can_moderate_boards'] && !$context['can_moderate_groups'] && !$context['can_moderate_approvals'] && !$context['can_moderate_users'])
39
		isAllowedTo('access_mod_center');
40
41
	// We're gonna want a menu of some kind.
42
	require_once($sourcedir . '/Subs-Menu.php');
43
44
	// Load the language, and the template.
45
	loadLanguage('ModerationCenter');
46
	loadTemplate(false, 'admin');
0 ignored issues
show
false of type false is incompatible with the type string expected by parameter $template_name of loadTemplate(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
	loadTemplate(/** @scrutinizer ignore-type */ false, 'admin');
Loading history...
47
48
	$context['admin_preferences'] = !empty($options['admin_preferences']) ? $smcFunc['json_decode']($options['admin_preferences'], true) : array();
49
	$context['robot_no_index'] = true;
50
51
	// This is the menu structure - refer to Subs-Menu.php for the details.
52
	$moderation_areas = array(
53
		'main' => array(
54
			'title' => $txt['mc_main'],
55
			'areas' => array(
56
				'index' => array(
57
					'label' => $txt['moderation_center'],
58
					'function' => 'ModerationHome',
59
					'icon' => 'administration',
60
				),
61
				'settings' => array(
62
					'label' => $txt['mc_settings'],
63
					'function' => 'ModerationSettings',
64
					'icon' => 'features',
65
				),
66
				'modlogoff' => array(
67
					'label' => $txt['mc_logoff'],
68
					'function' => 'ModEndSession',
69
					'enabled' => empty($modSettings['securityDisable_moderate']),
70
					'icon' => 'exit',
71
				),
72
				'notice' => array(
73
					'file' => 'ModerationCenter.php',
74
					'function' => 'ShowNotice',
75
					'select' => 'index'
76
				),
77
			),
78
		),
79
		'logs' => array(
80
			'title' => $txt['mc_logs'],
81
			'areas' => array(
82
				'modlog' => array(
83
					'label' => $txt['modlog_view'],
84
					'enabled' => !empty($modSettings['modlog_enabled']) && $context['can_moderate_boards'],
85
					'file' => 'Modlog.php',
86
					'function' => 'ViewModlog',
87
					'icon' => 'logs',
88
				),
89
				'warnings' => array(
90
					'label' => $txt['mc_warnings'],
91
					'enabled' => $modSettings['warning_settings'][0] == 1 && allowedTo(array('issue_warning', 'view_warning_any')),
92
					'function' => 'ViewWarnings',
93
					'icon' => 'warning',
94
					'subsections' => array(
95
						'log' => array($txt['mc_warning_log'], array('view_warning_any', 'moderate_forum')),
96
						'templates' => array($txt['mc_warning_templates'], 'issue_warning'),
97
					),
98
				),
99
			),
100
		),
101
		'posts' => array(
102
			'title' => $txt['mc_posts'],
103
			'enabled' => $context['can_moderate_boards'] || $context['can_moderate_approvals'],
104
			'areas' => array(
105
				'postmod' => array(
106
					'label' => $txt['mc_unapproved_posts'],
107
					'enabled' => $context['can_moderate_approvals'],
108
					'file' => 'PostModeration.php',
109
					'function' => 'PostModerationMain',
110
					'icon' => 'posts',
111
					'custom_url' => $scripturl . '?action=moderate;area=postmod',
112
					'subsections' => array(
113
						'posts' => array($txt['mc_unapproved_replies']),
114
						'topics' => array($txt['mc_unapproved_topics']),
115
					),
116
				),
117
				'attachmod' => array(
118
					'label' => $txt['mc_unapproved_attachments'],
119
					'enabled' => $context['can_moderate_approvals'],
120
					'file' => 'PostModeration.php',
121
					'function' => 'PostModerationMain',
122
					'icon' => 'post_moderation_attach',
123
					'custom_url' => $scripturl . '?action=moderate;area=attachmod;sa=attachments',
124
				),
125
				'reportedposts' => array(
126
					'label' => $txt['mc_reported_posts'],
127
					'enabled' => $context['can_moderate_boards'],
128
					'file' => 'ReportedContent.php',
129
					'function' => 'ReportedContent',
130
					'icon' => 'reports',
131
					'subsections' => array(
132
						'show' => array($txt['mc_reportedp_active']),
133
						'closed' => array($txt['mc_reportedp_closed']),
134
					),
135
				),
136
			),
137
		),
138
		'groups' => array(
139
			'title' => $txt['mc_groups'],
140
			'enabled' => $context['can_moderate_groups'],
141
			'areas' => array(
142
				'groups' => array(
143
					'label' => $txt['mc_group_requests'],
144
					'file' => 'Groups.php',
145
					'function' => 'Groups',
146
					'icon' => 'members_request',
147
					'custom_url' => $scripturl . '?action=moderate;area=groups;sa=requests',
148
				),
149
				'viewgroups' => array(
150
					'label' => $txt['mc_view_groups'],
151
					'file' => 'Groups.php',
152
					'function' => 'Groups',
153
					'icon' => 'membergroups',
154
				),
155
			),
156
		),
157
		'members' => array(
158
			'title' => $txt['mc_members'],
159
			'enabled' => $context['can_moderate_users'] || ($modSettings['warning_settings'][0] == 1 && $context['can_moderate_boards']),
160
			'areas' => array(
161
				'userwatch' => array(
162
					'label' => $txt['mc_watched_users_title'],
163
					'enabled' => $modSettings['warning_settings'][0] == 1 && $context['can_moderate_boards'],
164
					'function' => 'ViewWatchedUsers',
165
					'icon' => 'members_watched',
166
					'subsections' => array(
167
						'member' => array($txt['mc_watched_users_member']),
168
						'post' => array($txt['mc_watched_users_post']),
169
					),
170
				),
171
				'reportedmembers' => array(
172
					'label' => $txt['mc_reported_members_title'],
173
					'enabled' => $context['can_moderate_users'],
174
					'file' => 'ReportedContent.php',
175
					'function' => 'ReportedContent',
176
					'icon' => 'members_watched',
177
					'subsections' => array(
178
						'open' => array($txt['mc_reportedp_active']),
179
						'closed' => array($txt['mc_reportedp_closed']),
180
					),
181
				),
182
			),
183
		)
184
	);
185
186
	// Make sure the administrator has a valid session...
187
	validateSession('moderate');
188
189
	// I don't know where we're going - I don't know where we've been...
190
	$menuOptions = array(
191
		'action' => 'moderate',
192
		'disable_url_session_check' => true,
193
	);
194
	$mod_include_data = createMenu($moderation_areas, $menuOptions);
195
	unset($moderation_areas);
196
197
	// We got something - didn't we? DIDN'T WE!
198
	if ($mod_include_data == false)
199
		fatal_lang_error('no_access', false);
200
201
	// Retain the ID information in case required by a subaction.
202
	$context['moderation_menu_id'] = $context['max_menu_id'];
203
	$context['moderation_menu_name'] = 'menu_data_' . $context['moderation_menu_id'];
204
205
	// @todo: html in here is not good
206
	$context[$context['moderation_menu_name']]['tab_data'] = array(
207
		'title' => $txt['moderation_center'],
208
		'help' => '',
209
		'description' => '
210
			<strong>' . $txt['hello_guest'] . ' ' . $context['user']['name'] . '!</strong>
211
			<br><br>
212
			' . $txt['mc_description']);
213
214
	// What a pleasant shortcut - even tho we're not *really* on the admin screen who cares...
215
	$context['admin_area'] = $mod_include_data['current_area'];
216
217
	// Build the link tree.
218
	$context['linktree'][] = array(
219
		'url' => $scripturl . '?action=moderate',
220
		'name' => $txt['moderation_center'],
221
	);
222
	if (isset($mod_include_data['current_area']) && $mod_include_data['current_area'] != 'index')
223
		$context['linktree'][] = array(
224
			'url' => $scripturl . '?action=moderate;area=' . $mod_include_data['current_area'],
225
			'name' => $mod_include_data['label'],
226
		);
227
	if (!empty($mod_include_data['current_subsection']) && $mod_include_data['subsections'][$mod_include_data['current_subsection']][0] != $mod_include_data['label'])
228
		$context['linktree'][] = array(
229
			'url' => $scripturl . '?action=moderate;area=' . $mod_include_data['current_area'] . ';sa=' . $mod_include_data['current_subsection'],
230
			'name' => $mod_include_data['subsections'][$mod_include_data['current_subsection']][0],
231
		);
232
233
	// Now - finally - the bit before the encore - the main performance of course!
234
	if (!$dont_call)
235
	{
236
		if (isset($mod_include_data['file']))
237
			require_once($sourcedir . '/' . $mod_include_data['file']);
238
239
		call_helper($mod_include_data['function']);
240
	}
241
}
242
243
/**
244
 * This function basically is the home page of the moderation center.
245
 */
246
function ModerationHome()
247
{
248
	global $smcFunc, $txt, $context, $options;
249
250
	loadTemplate('ModerationCenter');
251
	loadJavaScriptFile('admin.js', array('minimize' => true), 'smf_admin');
252
253
	$context['page_title'] = $txt['moderation_center'];
254
	$context['sub_template'] = 'moderation_center';
255
256
	// Handle moderators notes.
257
	ModBlockNotes();
258
259
	// Load what blocks the user actually can see...
260
	$valid_blocks = array();
261
262
	if ($context['can_moderate_groups'])
263
		$valid_blocks['g'] = 'GroupRequests';
264
	if ($context['can_moderate_boards'])
265
	{
266
		$valid_blocks['r'] = 'ReportedPosts';
267
		$valid_blocks['w'] = 'WatchedUsers';
268
	}
269
	if ($context['can_moderate_users'])
270
	{
271
		// This falls under the category of moderating users as well...
272
		if (!$context['can_moderate_boards'])
273
			$valid_blocks['w'] = 'WatchedUsers';
274
275
		$valid_blocks['rm'] = 'ReportedMembers';
276
	}
277
278
	call_integration_hook('integrate_mod_centre_blocks', array(&$valid_blocks));
279
280
	$context['mod_blocks'] = array();
281
	foreach ($valid_blocks as $k => $block)
282
	{
283
		$block = 'ModBlock' . $block;
284
		if (function_exists($block))
285
			$context['mod_blocks'][] = $block();
286
	}
287
288
	$context['admin_prefs'] = !empty($options['admin_preferences']) ? $smcFunc['json_decode']($options['admin_preferences'], true) : array();
289
}
290
291
/**
292
 * Show a list of the most active watched users.
293
 */
294
function ModBlockWatchedUsers()
295
{
296
	global $context, $smcFunc, $scripturl, $modSettings;
297
298
	if (($watched_users = cache_get_data('recent_user_watches', 240)) === null)
299
	{
300
		$modSettings['warning_watch'] = empty($modSettings['warning_watch']) ? 1 : $modSettings['warning_watch'];
301
		$request = $smcFunc['db_query']('', '
302
			SELECT id_member, real_name, last_login
303
			FROM {db_prefix}members
304
			WHERE warning >= {int:warning_watch}
305
			ORDER BY last_login DESC
306
			LIMIT 10',
307
			array(
308
				'warning_watch' => $modSettings['warning_watch'],
309
			)
310
		);
311
		$watched_users = array();
312
		while ($row = $smcFunc['db_fetch_assoc']($request))
313
			$watched_users[] = $row;
314
		$smcFunc['db_free_result']($request);
315
316
		cache_put_data('recent_user_watches', $watched_users, 240);
317
	}
318
319
	$context['watched_users'] = array();
320
	foreach ($watched_users as $user)
321
	{
322
		$context['watched_users'][] = array(
323
			'id' => $user['id_member'],
324
			'name' => $user['real_name'],
325
			'link' => '<a href="' . $scripturl . '?action=profile;u=' . $user['id_member'] . '">' . $user['real_name'] . '</a>',
326
			'href' => $scripturl . '?action=profile;u=' . $user['id_member'],
327
			'last_login' => !empty($user['last_login']) ? timeformat($user['last_login']) : '',
328
		);
329
	}
330
331
	return 'watched_users';
332
}
333
334
/**
335
 * Show an area for the moderator to type into.
336
 */
337
function ModBlockNotes()
338
{
339
	global $context, $smcFunc, $scripturl, $user_info;
340
341
	// Set a nice and informative message.
342
	$context['report_post_action'] = !empty($_SESSION['rc_confirmation']) ? $_SESSION['rc_confirmation'] : array();
343
	unset($_SESSION['rc_confirmation']);
344
345
	// Are we saving a note?
346
	if (isset($_GET['modnote']) && isset($_POST['makenote']) && isset($_POST['new_note']))
347
	{
348
		checkSession();
349
		validateToken('mod-modnote-add');
350
351
		$_POST['new_note'] = $smcFunc['htmlspecialchars'](trim($_POST['new_note']));
352
		// Make sure they actually entered something.
353
		if (!empty($_POST['new_note']))
354
		{
355
			// Insert it into the database then!
356
			$smcFunc['db_insert']('',
357
				'{db_prefix}log_comments',
358
				array(
359
					'id_member' => 'int', 'member_name' => 'string', 'comment_type' => 'string', 'recipient_name' => 'string',
360
					'body' => 'string', 'log_time' => 'int',
361
				),
362
				array(
363
					$user_info['id'], $user_info['name'], 'modnote', '', $_POST['new_note'], time(),
364
				),
365
				array('id_comment')
366
			);
367
368
			// Clear the cache.
369
			cache_put_data('moderator_notes', null, 240);
370
			cache_put_data('moderator_notes_total', null, 240);
371
		}
372
373
		// Everything went better than expected!
374
		$_SESSION['rc_confirmation'] = 'message_saved';
375
376
		// Redirect otherwise people can resubmit.
377
		redirectexit('action=moderate');
378
	}
379
380
	// Bye... bye...
381
	if (isset($_GET['notes']) && isset($_GET['delete']) && is_numeric($_GET['delete']))
382
	{
383
		checkSession('get');
384
		validateToken('mod-modnote-del', 'get');
385
386
		// No sneaky stuff now!
387
		if (!allowedTo('admin_forum'))
388
		{
389
			// Is this your note?
390
			$get_owner = $smcFunc['db_query']('', '
391
				SELECT id_member
392
				FROM {db_prefix}log_comments
393
				WHERE id_comment = {int:note}
394
					AND comment_type = {literal:modnote}
395
					AND id_member = {int:user}',
396
				array(
397
					'note' => $_GET['delete'],
398
					'user' => $user_info['id'],
399
				)
400
			);
401
402
			$note_owner = $smcFunc['db_num_rows']($get_owner);
403
			$smcFunc['db_free_result']($get_owner);
404
405
			if (empty($note_owner))
406
				fatal_lang_error('mc_notes_delete_own', false);
407
		}
408
409
		// Lets delete it.
410
		$smcFunc['db_query']('', '
411
			DELETE FROM {db_prefix}log_comments
412
			WHERE id_comment = {int:note}
413
				AND comment_type = {literal:modnote}',
414
			array(
415
				'note' => $_GET['delete'],
416
			)
417
		);
418
419
		// Clear the cache.
420
		cache_put_data('moderator_notes', null, 240);
421
		cache_put_data('moderator_notes_total', null, 240);
422
423
		// Tell them the message was deleted.
424
		$_SESSION['rc_confirmation'] = 'message_deleted';
425
426
		redirectexit('action=moderate');
427
	}
428
429
	// How many notes in total?
430
	if (($moderator_notes_total = cache_get_data('moderator_notes_total', 240)) === null)
431
	{
432
		$request = $smcFunc['db_query']('', '
433
			SELECT COUNT(*)
434
			FROM {db_prefix}log_comments AS lc
435
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lc.id_member)
436
			WHERE lc.comment_type = {literal:modnote}',
437
			array(
438
			)
439
		);
440
		list ($moderator_notes_total) = $smcFunc['db_fetch_row']($request);
441
		$smcFunc['db_free_result']($request);
442
443
		cache_put_data('moderator_notes_total', $moderator_notes_total, 240);
444
	}
445
446
	// Grab the current notes. We can only use the cache for the first page of notes.
447
	$offset = isset($_GET['notes']) && isset($_GET['start']) ? $_GET['start'] : 0;
448
	if ($offset != 0 || ($moderator_notes = cache_get_data('moderator_notes', 240)) === null)
449
	{
450
		$request = $smcFunc['db_query']('', '
451
			SELECT COALESCE(mem.id_member, 0) AS id_member, COALESCE(mem.real_name, lc.member_name) AS member_name,
452
				lc.log_time, lc.body, lc.id_comment AS id_note
453
			FROM {db_prefix}log_comments AS lc
454
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lc.id_member)
455
			WHERE lc.comment_type = {literal:modnote}
456
			ORDER BY id_comment DESC
457
			LIMIT {int:offset}, 10',
458
			array(
459
				'offset' => $offset,
460
			)
461
		);
462
		$moderator_notes = array();
463
		while ($row = $smcFunc['db_fetch_assoc']($request))
464
			$moderator_notes[] = $row;
465
		$smcFunc['db_free_result']($request);
466
467
		if ($offset == 0)
468
			cache_put_data('moderator_notes', $moderator_notes, 240);
469
	}
470
471
	// Lets construct a page index.
472
	$context['page_index'] = constructPageIndex($scripturl . '?action=moderate;area=index;notes', $_GET['start'], $moderator_notes_total, 10);
473
	$context['start'] = $_GET['start'];
474
475
	$context['notes'] = array();
476
	foreach ($moderator_notes as $note)
477
	{
478
		$context['notes'][] = array(
479
			'author' => array(
480
				'id' => $note['id_member'],
481
				'link' => $note['id_member'] ? ('<a href="' . $scripturl . '?action=profile;u=' . $note['id_member'] . '">' . $note['member_name'] . '</a>') : $note['member_name'],
482
			),
483
			'time' => timeformat($note['log_time']),
484
			'text' => parse_bbc($note['body']),
485
			'delete_href' => $scripturl . '?action=moderate;area=index;notes;delete=' . $note['id_note'] . ';' . $context['session_var'] . '=' . $context['session_id'],
486
			'can_delete' => allowedTo('admin_forum') || $note['id_member'] == $user_info['id'],
487
		);
488
	}
489
490
	// Couple tokens for add/delete modnotes
491
	createToken('mod-modnote-add');
492
	createToken('mod-modnote-del', 'get');
493
494
	return 'notes';
495
}
496
497
/**
498
 * Show a list of the most recent reported posts.
499
 */
500
function ModBlockReportedPosts()
501
{
502
	global $context, $user_info, $scripturl, $smcFunc;
503
504
	// Got the info already?
505
	$cachekey = md5($smcFunc['json_encode']($user_info['mod_cache']['bq']));
506
	$context['reported_posts'] = array();
507
	if ($user_info['mod_cache']['bq'] == '0=1')
508
		return 'reported_posts_block';
509
510
	if (($reported_posts = cache_get_data('reported_posts_' . $cachekey, 90)) === null)
511
	{
512
		// By George, that means we in a position to get the reports, jolly good.
513
		$request = $smcFunc['db_query']('', '
514
			SELECT lr.id_report, lr.id_msg, lr.id_topic, lr.id_board, lr.id_member, lr.subject,
515
				lr.num_reports, COALESCE(mem.real_name, lr.membername) AS author_name,
516
				COALESCE(mem.id_member, 0) AS id_author
517
			FROM {db_prefix}log_reported AS lr
518
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lr.id_member)
519
			WHERE ' . ($user_info['mod_cache']['bq'] == '1=1' || $user_info['mod_cache']['bq'] == '0=1' ? $user_info['mod_cache']['bq'] : 'lr.' . $user_info['mod_cache']['bq']) . '
520
				AND lr.id_board != {int:not_a_reported_post}
521
				AND lr.closed = {int:not_closed}
522
				AND lr.ignore_all = {int:not_ignored}
523
			ORDER BY lr.time_updated DESC
524
			LIMIT 10',
525
			array(
526
				'not_a_reported_post' => 0,
527
				'not_closed' => 0,
528
				'not_ignored' => 0,
529
			)
530
		);
531
		$reported_posts = array();
532
		while ($row = $smcFunc['db_fetch_assoc']($request))
533
			$reported_posts[] = $row;
534
		$smcFunc['db_free_result']($request);
535
536
		// Cache it.
537
		cache_put_data('reported_posts_' . $cachekey, $reported_posts, 90);
538
	}
539
540
	$context['reported_posts'] = array();
541
	foreach ($reported_posts as $i => $row)
542
	{
543
		$context['reported_posts'][] = array(
544
			'id' => $row['id_report'],
545
			'topic_href' => $scripturl . '?topic=' . $row['id_topic'] . '.msg' . $row['id_msg'] . '#msg' . $row['id_msg'],
546
			'report_href' => $scripturl . '?action=moderate;area=reportedposts;sa=details;rid=' . $row['id_report'],
547
			'report_link' => '<a href="' . $scripturl . '?action=moderate;area=reportedposts;sa=details;rid=' . $row['id_report'] . '">' . $row['subject'] . '</a>',
548
			'author' => array(
549
				'id' => $row['id_author'],
550
				'name' => $row['author_name'],
551
				'link' => $row['id_author'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_author'] . '">' . $row['author_name'] . '</a>' : $row['author_name'],
552
				'href' => $scripturl . '?action=profile;u=' . $row['id_author'],
553
			),
554
			'subject' => $row['subject'],
555
			'num_reports' => $row['num_reports'],
556
		);
557
	}
558
559
	return 'reported_posts_block';
560
}
561
562
/**
563
 * Show a list of all the group requests they can see.
564
 */
565
function ModBlockGroupRequests()
566
{
567
	global $context, $user_info, $scripturl, $smcFunc;
568
569
	$context['group_requests'] = array();
570
	// Make sure they can even moderate someone!
571
	if ($user_info['mod_cache']['gq'] == '0=1')
572
		return 'group_requests_block';
573
574
	// What requests are outstanding?
575
	$request = $smcFunc['db_query']('', '
576
		SELECT lgr.id_request, lgr.id_member, lgr.id_group, lgr.time_applied, mem.member_name, mg.group_name, mem.real_name
577
		FROM {db_prefix}log_group_requests AS lgr
578
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = lgr.id_member)
579
			INNER JOIN {db_prefix}membergroups AS mg ON (mg.id_group = lgr.id_group)
580
		WHERE ' . ($user_info['mod_cache']['gq'] == '1=1' || $user_info['mod_cache']['gq'] == '0=1' ? $user_info['mod_cache']['gq'] : 'lgr.' . $user_info['mod_cache']['gq']) . '
581
			AND lgr.status = {int:status_open}
582
		ORDER BY lgr.id_request DESC
583
		LIMIT 10',
584
		array(
585
			'status_open' => 0,
586
		)
587
	);
588
	for ($i = 0; $row = $smcFunc['db_fetch_assoc']($request); $i++)
589
	{
590
		$context['group_requests'][] = array(
591
			'id' => $row['id_request'],
592
			'request_href' => $scripturl . '?action=groups;sa=requests;gid=' . $row['id_group'],
593
			'member' => array(
594
				'id' => $row['id_member'],
595
				'name' => $row['real_name'],
596
				'link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
597
				'href' => $scripturl . '?action=profile;u=' . $row['id_member'],
598
			),
599
			'group' => array(
600
				'id' => $row['id_group'],
601
				'name' => $row['group_name'],
602
			),
603
			'time_submitted' => timeformat($row['time_applied']),
604
		);
605
	}
606
	$smcFunc['db_free_result']($request);
607
608
	return 'group_requests_block';
609
}
610
611
/**
612
 * Show a list of the most recent reported posts.
613
 */
614
function ModBlockReportedMembers()
615
{
616
	global $context, $scripturl, $smcFunc;
617
618
	// Got the info already?
619
	$cachekey = md5($smcFunc['json_encode']((int) allowedTo('moderate_forum')));
620
	$context['reported_users'] = array();
621
	if (!allowedTo('moderate_forum'))
622
		return 'reported_users_block';
623
624
	if (($reported_users = cache_get_data('reported_users_' . $cachekey, 90)) === null)
625
	{
626
		// By George, that means we in a position to get the reports, jolly good.
627
		$request = $smcFunc['db_query']('', '
628
			SELECT lr.id_report, lr.id_member,
629
				lr.num_reports, COALESCE(mem.real_name, lr.membername) AS user_name,
630
				COALESCE(mem.id_member, 0) AS id_user
631
			FROM {db_prefix}log_reported AS lr
632
				LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lr.id_member)
633
			WHERE lr.id_board = {int:not_a_reported_post}
634
				AND lr.closed = {int:not_closed}
635
				AND lr.ignore_all = {int:not_ignored}
636
			ORDER BY lr.time_updated DESC
637
			LIMIT 10',
638
			array(
639
				'not_a_reported_post' => 0,
640
				'not_closed' => 0,
641
				'not_ignored' => 0,
642
			)
643
		);
644
		$reported_users = array();
645
		while ($row = $smcFunc['db_fetch_assoc']($request))
646
			$reported_users[] = $row;
647
		$smcFunc['db_free_result']($request);
648
649
		// Cache it.
650
		cache_put_data('reported_users_' . $cachekey, $reported_users, 90);
651
	}
652
653
	$context['reported_users'] = array();
654
	foreach ($reported_users as $i => $row)
655
	{
656
		$context['reported_users'][] = array(
657
			'id' => $row['id_report'],
658
			'report_href' => $scripturl . '?action=moderate;area=reportedmembers;report=' . $row['id_report'],
659
			'user' => array(
660
				'id' => $row['id_user'],
661
				'name' => $row['user_name'],
662
				'link' => $row['id_user'] ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_user'] . '">' . $row['user_name'] . '</a>' : $row['user_name'],
663
				'href' => $scripturl . '?action=profile;u=' . $row['id_user'],
664
			),
665
			'num_reports' => $row['num_reports'],
666
		);
667
	}
668
669
	return 'reported_users_block';
670
}
671
672
/**
673
 * Act as an entrace for all group related activity.
674
 *
675
 * @todo As for most things in this file, this needs to be moved somewhere appropriate?
676
 */
677
function ModerateGroups()
678
{
679
	global $context, $user_info;
680
681
	// You need to be allowed to moderate groups...
682
	if ($user_info['mod_cache']['gq'] == '0=1')
683
		isAllowedTo('manage_membergroups');
684
685
	// Load the group templates.
686
	loadTemplate('ModerationCenter');
687
688
	// Setup the subactions...
689
	$subActions = array(
690
		'requests' => 'GroupRequests',
691
		'view' => 'ViewGroups',
692
	);
693
694
	if (!isset($_GET['sa']) || !isset($subActions[$_GET['sa']]))
695
		$_GET['sa'] = 'view';
696
	$context['sub_action'] = $_GET['sa'];
697
698
	// Call the relevant function.
699
	call_helper($subActions[$context['sub_action']]);
700
}
701
702
/**
703
 * Show a notice sent to a user.
704
 */
705
function ShowNotice()
706
{
707
	global $smcFunc, $txt, $context;
708
709
	$context['page_title'] = $txt['show_notice'];
710
	$context['sub_template'] = 'show_notice';
711
	$context['template_layers'] = array();
712
713
	loadTemplate('ModerationCenter');
714
715
	// @todo Assumes nothing needs permission more than accessing moderation center!
716
	$id_notice = (int) $_GET['nid'];
717
	$request = $smcFunc['db_query']('', '
718
		SELECT body, subject
719
		FROM {db_prefix}log_member_notices
720
		WHERE id_notice = {int:id_notice}',
721
		array(
722
			'id_notice' => $id_notice,
723
		)
724
	);
725
	if ($smcFunc['db_num_rows']($request) == 0)
726
		fatal_lang_error('no_access', false);
727
	list ($context['notice_body'], $context['notice_subject']) = $smcFunc['db_fetch_row']($request);
728
	$smcFunc['db_free_result']($request);
729
730
	$context['notice_body'] = parse_bbc($context['notice_body'], false);
731
}
732
733
/**
734
 * View watched users.
735
 */
736
function ViewWatchedUsers()
737
{
738
	global $modSettings, $context, $txt, $scripturl, $sourcedir;
739
740
	// Some important context!
741
	$context['page_title'] = $txt['mc_watched_users_title'];
742
	$context['view_posts'] = isset($_GET['sa']) && $_GET['sa'] == 'post';
743
	$context['start'] = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
744
745
	loadTemplate('ModerationCenter');
746
747
	// Get some key settings!
748
	$modSettings['warning_watch'] = empty($modSettings['warning_watch']) ? 1 : $modSettings['warning_watch'];
749
750
	// Put some pretty tabs on cause we're gonna be doing hot stuff here...
751
	$context[$context['moderation_menu_name']]['tab_data'] = array(
752
		'title' => $txt['mc_watched_users_title'],
753
		'help' => '',
754
		'description' => $txt['mc_watched_users_desc'],
755
	);
756
757
	// First off - are we deleting?
758
	if (!empty($_REQUEST['delete']))
759
	{
760
		checkSession(!is_array($_REQUEST['delete']) ? 'get' : 'post');
761
762
		$toDelete = array();
763
		if (!is_array($_REQUEST['delete']))
764
			$toDelete[] = (int) $_REQUEST['delete'];
765
		else
766
			foreach ($_REQUEST['delete'] as $did)
767
				$toDelete[] = (int) $did;
768
769
		if (!empty($toDelete))
770
		{
771
			require_once($sourcedir . '/RemoveTopic.php');
772
			// If they don't have permission we'll let it error - either way no chance of a security slip here!
773
			foreach ($toDelete as $did)
774
				removeMessage($did);
775
		}
776
	}
777
778
	// Start preparing the list by grabbing relevant permissions.
779
	if (!$context['view_posts'])
780
	{
781
		$approve_query = '';
782
		$delete_boards = array();
783
	}
784
	else
785
	{
786
		// Still obey permissions!
787
		$approve_boards = boardsAllowedTo('approve_posts');
788
		$delete_boards = boardsAllowedTo('delete_any');
789
790
		if ($approve_boards == array(0))
791
			$approve_query = '';
792
		elseif (!empty($approve_boards))
793
			$approve_query = ' AND m.id_board IN (' . implode(',', $approve_boards) . ')';
794
		// Nada, zip, etc...
795
		else
796
			$approve_query = ' AND 1=0';
797
	}
798
799
	require_once($sourcedir . '/Subs-List.php');
800
801
	// This is all the information required for a watched user listing.
802
	$listOptions = array(
803
		'id' => 'watch_user_list',
804
		'title' => $txt['mc_watched_users_title'] . ' - ' . ($context['view_posts'] ? $txt['mc_watched_users_post'] : $txt['mc_watched_users_member']),
805
		'items_per_page' => $modSettings['defaultMaxListItems'],
806
		'no_items_label' => $context['view_posts'] ? $txt['mc_watched_users_no_posts'] : $txt['mc_watched_users_none'],
807
		'base_href' => $scripturl . '?action=moderate;area=userwatch;sa=' . ($context['view_posts'] ? 'post' : 'member'),
808
		'default_sort_col' => $context['view_posts'] ? '' : 'member',
809
		'get_items' => array(
810
			'function' => $context['view_posts'] ? 'list_getWatchedUserPosts' : 'list_getWatchedUsers',
811
			'params' => array(
812
				$approve_query,
813
				$delete_boards,
814
			),
815
		),
816
		'get_count' => array(
817
			'function' => $context['view_posts'] ? 'list_getWatchedUserPostsCount' : 'list_getWatchedUserCount',
818
			'params' => array(
819
				$approve_query,
820
			),
821
		),
822
		// This assumes we are viewing by user.
823
		'columns' => array(
824
			'member' => array(
825
				'header' => array(
826
					'value' => $txt['mc_watched_users_member'],
827
				),
828
				'data' => array(
829
					'sprintf' => array(
830
						'format' => '<a href="' . $scripturl . '?action=profile;u=%1$d">%2$s</a>',
831
						'params' => array(
832
							'id' => false,
833
							'name' => false,
834
						),
835
					),
836
				),
837
				'sort' => array(
838
					'default' => 'real_name',
839
					'reverse' => 'real_name DESC',
840
				),
841
			),
842
			'warning' => array(
843
				'header' => array(
844
					'value' => $txt['mc_watched_users_warning'],
845
				),
846
				'data' => array(
847
					'function' => function($member) use ($scripturl)
848
					{
849
						return allowedTo('issue_warning') ? '<a href="' . $scripturl . '?action=profile;area=issuewarning;u=' . $member['id'] . '">' . $member['warning'] . '%</a>' : $member['warning'] . '%';
850
					},
851
				),
852
				'sort' => array(
853
					'default' => 'warning',
854
					'reverse' => 'warning DESC',
855
				),
856
			),
857
			'posts' => array(
858
				'header' => array(
859
					'value' => $txt['posts'],
860
				),
861
				'data' => array(
862
					'sprintf' => array(
863
						'format' => '<a href="' . $scripturl . '?action=profile;u=%1$d;area=showposts;sa=messages">%2$s</a>',
864
						'params' => array(
865
							'id' => false,
866
							'posts' => false,
867
						),
868
					),
869
				),
870
				'sort' => array(
871
					'default' => 'posts',
872
					'reverse' => 'posts DESC',
873
				),
874
			),
875
			'last_login' => array(
876
				'header' => array(
877
					'value' => $txt['mc_watched_users_last_login'],
878
				),
879
				'data' => array(
880
					'db' => 'last_login',
881
				),
882
				'sort' => array(
883
					'default' => 'last_login',
884
					'reverse' => 'last_login DESC',
885
				),
886
			),
887
			'last_post' => array(
888
				'header' => array(
889
					'value' => $txt['mc_watched_users_last_post'],
890
				),
891
				'data' => array(
892
					'function' => function($member) use ($scripturl)
893
					{
894
						if ($member['last_post_id'])
895
							return '<a href="' . $scripturl . '?msg=' . $member['last_post_id'] . '">' . $member['last_post'] . '</a>';
896
						else
897
							return $member['last_post'];
898
					},
899
				),
900
			),
901
		),
902
		'form' => array(
903
			'href' => $scripturl . '?action=moderate;area=userwatch;sa=post',
904
			'include_sort' => true,
905
			'include_start' => true,
906
			'hidden_fields' => array(
907
				$context['session_var'] => $context['session_id'],
908
			),
909
		),
910
		'additional_rows' => array(
911
			$context['view_posts'] ?
912
				array(
913
					'position' => 'bottom_of_list',
914
					'value' => '
915
					<input type="submit" name="delete_selected" value="' . $txt['quickmod_delete_selected'] . '" class="button">',
916
					'class' => 'floatright',
917
				) : array(),
918
		),
919
	);
920
921
	// If this is being viewed by posts we actually change the columns to call a template each time.
922
	if ($context['view_posts'])
923
	{
924
		$listOptions['columns'] = array(
925
			'posts' => array(
926
				'data' => array(
927
					'function' => function($post)
928
					{
929
						return template_user_watch_post_callback($post);
930
					},
931
					'class' => 'unique'
932
				),
933
			),
934
		);
935
	}
936
937
	// Create the watched user list.
938
	createList($listOptions);
939
940
	$context['sub_template'] = 'show_list';
941
	$context['default_list'] = 'watch_user_list';
942
}
943
944
/**
945
 * Callback for createList().
946
 *
947
 * @param string $approve_query Not used here
948
 * @return int The number of users on the watch list
949
 */
950
function list_getWatchedUserCount($approve_query)
951
{
952
	global $smcFunc, $modSettings;
953
954
	$request = $smcFunc['db_query']('', '
955
		SELECT COUNT(*)
956
		FROM {db_prefix}members
957
		WHERE warning >= {int:warning_watch}',
958
		array(
959
			'warning_watch' => $modSettings['warning_watch'],
960
		)
961
	);
962
	list ($totalMembers) = $smcFunc['db_fetch_row']($request);
963
	$smcFunc['db_free_result']($request);
964
965
	return $totalMembers;
966
}
967
968
/**
969
 * Callback for createList().
970
 *
971
 * @param int $start The item to start with (for pagination purposes)
972
 * @param int $items_per_page The number of items to show per page
973
 * @param string $sort A string indicating how to sort things
974
 * @param string $approve_query A query for approving things. Not used here.
975
 * @param string $dummy Not used here.
976
 */
977
function list_getWatchedUsers($start, $items_per_page, $sort, $approve_query, $dummy)
978
{
979
	global $smcFunc, $txt, $modSettings, $user_info;
980
981
	$request = $smcFunc['db_query']('', '
982
		SELECT id_member, real_name, last_login, posts, warning
983
		FROM {db_prefix}members
984
		WHERE warning >= {int:warning_watch}
985
		ORDER BY {raw:sort}
986
		LIMIT {int:start}, {int:max}',
987
		array(
988
			'warning_watch' => $modSettings['warning_watch'],
989
			'sort' => $sort,
990
			'start' => $start,
991
			'max' => $items_per_page,
992
		)
993
	);
994
	$watched_users = array();
995
	$members = array();
996
	while ($row = $smcFunc['db_fetch_assoc']($request))
997
	{
998
		$watched_users[$row['id_member']] = array(
999
			'id' => $row['id_member'],
1000
			'name' => $row['real_name'],
1001
			'last_login' => $row['last_login'] ? timeformat($row['last_login']) : $txt['never'],
1002
			'last_post' => $txt['not_applicable'],
1003
			'last_post_id' => 0,
1004
			'warning' => $row['warning'],
1005
			'posts' => $row['posts'],
1006
		);
1007
		$members[] = $row['id_member'];
1008
	}
1009
	$smcFunc['db_free_result']($request);
1010
1011
	if (!empty($members))
1012
	{
1013
		// First get the latest messages from these users.
1014
		$request = $smcFunc['db_query']('', '
1015
			SELECT m.id_member, MAX(m.id_msg) AS last_post_id
1016
			FROM {db_prefix}messages AS m' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
1017
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)') . '
1018
			WHERE {query_see_message_board}
1019
				AND m.id_member IN ({array_int:member_list})' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
1020
				AND m.approved = {int:is_approved}
1021
				AND t.approved = {int:is_approved}') . '
1022
			GROUP BY m.id_member',
1023
			array(
1024
				'member_list' => $members,
1025
				'is_approved' => 1,
1026
			)
1027
		);
1028
		$latest_posts = array();
1029
		while ($row = $smcFunc['db_fetch_assoc']($request))
1030
			$latest_posts[$row['id_member']] = $row['last_post_id'];
1031
1032
		if (!empty($latest_posts))
1033
		{
1034
			// Now get the time those messages were posted.
1035
			$request = $smcFunc['db_query']('', '
1036
				SELECT id_member, poster_time
1037
				FROM {db_prefix}messages
1038
				WHERE id_msg IN ({array_int:message_list})',
1039
				array(
1040
					'message_list' => $latest_posts,
1041
				)
1042
			);
1043
			while ($row = $smcFunc['db_fetch_assoc']($request))
1044
			{
1045
				$watched_users[$row['id_member']]['last_post'] = timeformat($row['poster_time']);
1046
				$watched_users[$row['id_member']]['last_post_id'] = $latest_posts[$row['id_member']];
1047
			}
1048
1049
			$smcFunc['db_free_result']($request);
1050
		}
1051
1052
		$request = $smcFunc['db_query']('', '
1053
			SELECT MAX(m.poster_time) AS last_post, MAX(m.id_msg) AS last_post_id, m.id_member
1054
			FROM {db_prefix}messages AS m
1055
			WHERE {query_see_message_board}
1056
				AND m.id_member IN ({array_int:member_list})' . (!$modSettings['postmod_active'] || allowedTo('approve_posts') ? '' : '
1057
				AND m.approved = {int:is_approved}') . '
1058
			GROUP BY m.id_member',
1059
			array(
1060
				'member_list' => $members,
1061
				'is_approved' => 1,
1062
			)
1063
		);
1064
		while ($row = $smcFunc['db_fetch_assoc']($request))
1065
		{
1066
			$watched_users[$row['id_member']]['last_post'] = timeformat($row['last_post']);
1067
			$watched_users[$row['id_member']]['last_post_id'] = $row['last_post_id'];
1068
		}
1069
		$smcFunc['db_free_result']($request);
1070
	}
1071
1072
	return $watched_users;
1073
}
1074
1075
/**
1076
 * Callback for createList().
1077
 *
1078
 * @param string $approve_query A query to pull only approved items
1079
 * @return int The total number of posts by watched users
1080
 */
1081
function list_getWatchedUserPostsCount($approve_query)
1082
{
1083
	global $smcFunc, $modSettings;
1084
1085
	$request = $smcFunc['db_query']('', '
1086
		SELECT COUNT(*)
1087
		FROM {db_prefix}messages AS m
1088
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
1089
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
1090
		WHERE mem.warning >= {int:warning_watch}
1091
			AND {query_see_board}
1092
			' . $approve_query,
1093
		array(
1094
			'warning_watch' => $modSettings['warning_watch'],
1095
		)
1096
	);
1097
	list ($totalMemberPosts) = $smcFunc['db_fetch_row']($request);
1098
	$smcFunc['db_free_result']($request);
1099
1100
	return $totalMemberPosts;
1101
}
1102
1103
/**
1104
 * Callback for createList().
1105
 *
1106
 * @param int $start The item to start with (for pagination purposes)
1107
 * @param int $items_per_page The number of items to show per page
1108
 * @param string $sort A string indicating how to sort the results (not used here)
1109
 * @param string $approve_query A query to only pull approved items
1110
 * @param int[] $delete_boards An array containing the IDs of boards we can delete posts in
1111
 * @return array An array of info about posts by watched users
1112
 */
1113
function list_getWatchedUserPosts($start, $items_per_page, $sort, $approve_query, $delete_boards)
1114
{
1115
	global $smcFunc, $scripturl, $modSettings;
1116
1117
	$request = $smcFunc['db_query']('', '
1118
		SELECT m.id_msg, m.id_topic, m.id_board, m.id_member, m.subject, m.body, m.poster_time,
1119
			m.approved, mem.real_name, m.smileys_enabled
1120
		FROM {db_prefix}messages AS m
1121
			INNER JOIN {db_prefix}members AS mem ON (mem.id_member = m.id_member)
1122
			INNER JOIN {db_prefix}boards AS b ON (b.id_board = m.id_board)
1123
		WHERE mem.warning >= {int:warning_watch}
1124
			AND {query_see_board}
1125
			' . $approve_query . '
1126
		ORDER BY m.id_msg DESC
1127
		LIMIT {int:start}, {int:max}',
1128
		array(
1129
			'warning_watch' => $modSettings['warning_watch'],
1130
			'start' => $start,
1131
			'max' => $items_per_page,
1132
		)
1133
	);
1134
	$member_posts = array();
1135
	while ($row = $smcFunc['db_fetch_assoc']($request))
1136
	{
1137
		$row['subject'] = censorText($row['subject']);
1138
		$row['body'] = censorText($row['body']);
1139
1140
		$member_posts[$row['id_msg']] = array(
1141
			'id' => $row['id_msg'],
1142
			'id_topic' => $row['id_topic'],
1143
			'author_link' => '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['real_name'] . '</a>',
1144
			'subject' => $row['subject'],
1145
			'body' => parse_bbc($row['body'], $row['smileys_enabled'], $row['id_msg']),
1146
			'poster_time' => timeformat($row['poster_time']),
1147
			'approved' => $row['approved'],
1148
			'can_delete' => $delete_boards == array(0) || in_array($row['id_board'], $delete_boards),
1149
		);
1150
	}
1151
	$smcFunc['db_free_result']($request);
1152
1153
	return $member_posts;
1154
}
1155
1156
/**
1157
 * Entry point for viewing warning related stuff.
1158
 */
1159
function ViewWarnings()
1160
{
1161
	global $context, $txt;
1162
1163
	$subActions = array(
1164
		'log' => array('ViewWarningLog', array('view_warning_any', 'moderate_forum')),
1165
		'templates' => array('ViewWarningTemplates', 'issue_warning'),
1166
		'templateedit' => array('ModifyWarningTemplate', 'issue_warning'),
1167
	);
1168
1169
	call_integration_hook('integrate_warning_log_actions', array(&$subActions));
1170
1171
	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) && (empty($subActions[$_REQUEST['sa']][1]) || allowedTo($subActions[$_REQUEST['sa']][1])) ? $_REQUEST['sa'] : '';
1172
1173
	// In theory, 'log' is the default subaction. But if this user can't view the log, more work is needed.
1174
	if (empty($_REQUEST['sa']))
1175
	{
1176
		foreach ($subActions as $sa => $subAction)
1177
		{
1178
			if (empty($subAction[1]) || allowedTo($subAction[1]))
1179
			{
1180
				// If they can view the log, we can proceed as usual.
1181
				if ($sa === 'log')
1182
					$_REQUEST['sa'] = $sa;
1183
1184
				// Otherwise, redirect them to the first allowed subaction.
1185
				else
1186
					redirectexit('action=moderate;area=warnings;sa=' . $sa);
1187
			}
1188
		}
1189
1190
		// This shouldn't happen, but just in case...
1191
		if (empty($_REQUEST['sa']))
1192
			redirectexit('action=moderate;area=index');
1193
	}
1194
1195
	// Some of this stuff is overseas, so to speak.
1196
	loadTemplate('ModerationCenter');
1197
	loadLanguage('Profile');
1198
1199
	// Setup the admin tabs.
1200
	$context[$context['moderation_menu_name']]['tab_data'] = array(
1201
		'title' => $txt['mc_warnings'],
1202
		'description' => $txt['mc_warnings_description'],
1203
	);
1204
1205
	// Call the right function.
1206
	call_helper($subActions[$_REQUEST['sa']][0]);
1207
}
1208
1209
/**
1210
 * Simply put, look at the warning log!
1211
 */
1212
function ViewWarningLog()
1213
{
1214
	global $smcFunc, $modSettings, $context, $txt, $scripturl, $sourcedir;
1215
1216
	// Setup context as always.
1217
	$context['page_title'] = $txt['mc_warning_log_title'];
1218
1219
	loadLanguage('Modlog');
1220
1221
	// If we're coming from a search, get the variables.
1222
	if (!empty($_REQUEST['params']) && empty($_REQUEST['is_search']))
1223
	{
1224
		$search_params = base64_decode(strtr($_REQUEST['params'], array(' ' => '+')));
1225
		$search_params = $smcFunc['json_decode']($search_params, true);
1226
	}
1227
1228
	// This array houses all the valid search types.
1229
	$searchTypes = array(
1230
		'member' => array('sql' => 'member_name_col', 'label' => $txt['profile_warning_previous_issued']),
1231
		'recipient' => array('sql' => 'recipient_name', 'label' => $txt['mc_warnings_recipient']),
1232
	);
1233
1234
	// Do the column stuff!
1235
	$sort_types = array(
1236
		'member' => 'member_name_col',
1237
		'recipient' => 'recipient_name',
1238
	);
1239
1240
	// Setup the direction stuff...
1241
	$context['order'] = isset($_REQUEST['sort']) && isset($sort_types[$_REQUEST['sort']]) ? $_REQUEST['sort'] : 'member';
1242
1243
	if (!isset($search_params['string']) || (!empty($_REQUEST['search']) && $search_params['string'] != $_REQUEST['search']))
1244
		$search_params_string = empty($_REQUEST['search']) ? '' : $_REQUEST['search'];
1245
	else
1246
		$search_params_string = $search_params['string'];
1247
1248
	if (isset($_REQUEST['search_type']) || empty($search_params['type']) || !isset($searchTypes[$search_params['type']]))
1249
		$search_params_type = isset($_REQUEST['search_type']) && isset($searchTypes[$_REQUEST['search_type']]) ? $_REQUEST['search_type'] : (isset($searchTypes[$context['order']]) ? $context['order'] : 'member');
1250
	else
1251
		$search_params_type = $search_params['type'];
1252
1253
	$search_params = array(
1254
		'string' => $search_params_string,
1255
		'type' => $search_params_type,
1256
	);
1257
1258
	$context['url_start'] = '?action=moderate;area=warnings;sa=log;sort=' . $context['order'];
1259
1260
	// Setup the search context.
1261
	$context['search_params'] = empty($search_params['string']) ? '' : base64_encode($smcFunc['json_encode']($search_params));
1262
	$context['search'] = array(
1263
		'string' => $search_params['string'],
1264
		'type' => $search_params['type'],
1265
		'label' => $searchTypes[$search_params_type]['label'],
1266
	);
1267
1268
	require_once($sourcedir . '/Subs-List.php');
1269
1270
	// This is all the information required for a watched user listing.
1271
	$listOptions = array(
1272
		'id' => 'warning_list',
1273
		'title' => $txt['mc_warning_log_title'],
1274
		'items_per_page' => $modSettings['defaultMaxListItems'],
1275
		'no_items_label' => $txt['mc_warnings_none'],
1276
		'base_href' => $scripturl . '?action=moderate;area=warnings;sa=log;' . $context['session_var'] . '=' . $context['session_id'],
1277
		'default_sort_col' => 'time',
1278
		'get_items' => array(
1279
			'function' => 'list_getWarnings',
1280
		),
1281
		'get_count' => array(
1282
			'function' => 'list_getWarningCount',
1283
		),
1284
		// This assumes we are viewing by user.
1285
		'columns' => array(
1286
			'issuer' => array(
1287
				'header' => array(
1288
					'value' => $txt['profile_warning_previous_issued'],
1289
				),
1290
				'data' => array(
1291
					'db' => 'issuer_link',
1292
				),
1293
				'sort' => array(
1294
					'default' => 'member_name_col',
1295
					'reverse' => 'member_name_col DESC',
1296
				),
1297
			),
1298
			'recipient' => array(
1299
				'header' => array(
1300
					'value' => $txt['mc_warnings_recipient'],
1301
				),
1302
				'data' => array(
1303
					'db' => 'recipient_link',
1304
				),
1305
				'sort' => array(
1306
					'default' => 'recipient_name',
1307
					'reverse' => 'recipient_name DESC',
1308
				),
1309
			),
1310
			'time' => array(
1311
				'header' => array(
1312
					'value' => $txt['profile_warning_previous_time'],
1313
				),
1314
				'data' => array(
1315
					'db' => 'time',
1316
				),
1317
				'sort' => array(
1318
					'default' => 'lc.log_time DESC',
1319
					'reverse' => 'lc.log_time',
1320
				),
1321
			),
1322
			'reason' => array(
1323
				'header' => array(
1324
					'value' => $txt['profile_warning_previous_reason'],
1325
				),
1326
				'data' => array(
1327
					'function' => function($rowData) use ($scripturl, $txt)
1328
					{
1329
						$output = '
1330
							<div class="floatleft">
1331
								' . $rowData['reason'] . '
1332
							</div>';
1333
1334
						if (!empty($rowData['id_notice']))
1335
							$output .= '
1336
								&nbsp;<a href="' . $scripturl . '?action=moderate;area=notice;nid=' . $rowData['id_notice'] . '" onclick="window.open(this.href, \'\', \'scrollbars=yes,resizable=yes,width=400,height=250\');return false;" target="_blank" rel="noopener" title="' . $txt['profile_warning_previous_notice'] . '"><span class="main_icons filter centericon"></span></a>';
1337
						return $output;
1338
					},
1339
				),
1340
			),
1341
			'points' => array(
1342
				'header' => array(
1343
					'value' => $txt['profile_warning_previous_level'],
1344
				),
1345
				'data' => array(
1346
					'db' => 'counter',
1347
				),
1348
			),
1349
		),
1350
		'form' => array(
1351
			'href' => $scripturl . $context['url_start'],
1352
			'include_sort' => true,
1353
			'include_start' => true,
1354
			'hidden_fields' => array(
1355
				$context['session_var'] => $context['session_id'],
1356
				'params' => false
1357
			),
1358
		),
1359
		'additional_rows' => array(
1360
			array(
1361
				'position' => 'below_table_data',
1362
				'value' => '
1363
					' . $txt['modlog_search'] . ':
1364
					<input type="text" name="search" size="18" value="' . $smcFunc['htmlspecialchars']($context['search']['string']) . '">
1365
					<input type="submit" name="is_search" value="' . $txt['modlog_go'] . '" class="button">',
1366
				'class' => 'floatright',
1367
			),
1368
		),
1369
	);
1370
1371
	// Create the watched user list.
1372
	createList($listOptions);
1373
1374
	$context['sub_template'] = 'show_list';
1375
	$context['default_list'] = 'warning_list';
1376
}
1377
1378
/**
1379
 * Callback for createList().
1380
 *
1381
 * @return int The total number of warnings that have been issued
1382
 */
1383
function list_getWarningCount()
1384
{
1385
	global $smcFunc;
1386
1387
	$request = $smcFunc['db_query']('', '
1388
		SELECT COUNT(*)
1389
		FROM {db_prefix}log_comments
1390
		WHERE comment_type = {string:warning}',
1391
		array(
1392
			'warning' => 'warning',
1393
		)
1394
	);
1395
	list ($totalWarns) = $smcFunc['db_fetch_row']($request);
1396
	$smcFunc['db_free_result']($request);
1397
1398
	return $totalWarns;
1399
}
1400
1401
/**
1402
 * Callback for createList().
1403
 *
1404
 * @param int $start The item to start with (for pagination purposes)
1405
 * @param int $items_per_page The number of items to show per page
1406
 * @param string $sort A string indicating how to sort the results
1407
 * @return array An array of data about warning log entries
1408
 */
1409
function list_getWarnings($start, $items_per_page, $sort)
1410
{
1411
	global $smcFunc, $scripturl;
1412
1413
	$request = $smcFunc['db_query']('', '
1414
		SELECT COALESCE(mem.id_member, 0) AS id_member, COALESCE(mem.real_name, lc.member_name) AS member_name_col,
1415
			COALESCE(mem2.id_member, 0) AS id_recipient, COALESCE(mem2.real_name, lc.recipient_name) AS recipient_name,
1416
			lc.log_time, lc.body, lc.id_notice, lc.counter
1417
		FROM {db_prefix}log_comments AS lc
1418
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lc.id_member)
1419
			LEFT JOIN {db_prefix}members AS mem2 ON (mem2.id_member = lc.id_recipient)
1420
		WHERE lc.comment_type = {string:warning}
1421
		ORDER BY {raw:sort}
1422
		LIMIT {int:start}, {int:max}',
1423
		array(
1424
			'warning' => 'warning',
1425
			'start' => $start,
1426
			'max' => $items_per_page,
1427
			'sort' => $sort,
1428
		)
1429
	);
1430
	$warnings = array();
1431
	while ($row = $smcFunc['db_fetch_assoc']($request))
1432
	{
1433
		$warnings[] = array(
1434
			'issuer_link' => $row['id_member'] ? ('<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['member_name_col'] . '</a>') : $row['member_name_col'],
1435
			'recipient_link' => $row['id_recipient'] ? ('<a href="' . $scripturl . '?action=profile;u=' . $row['id_recipient'] . '">' . $row['recipient_name'] . '</a>') : $row['recipient_name'],
1436
			'time' => timeformat($row['log_time']),
1437
			'reason' => $row['body'],
1438
			'counter' => $row['counter'] > 0 ? '+' . $row['counter'] : $row['counter'],
1439
			'id_notice' => $row['id_notice'],
1440
		);
1441
	}
1442
	$smcFunc['db_free_result']($request);
1443
1444
	return $warnings;
1445
}
1446
1447
/**
1448
 * Load all the warning templates.
1449
 */
1450
function ViewWarningTemplates()
1451
{
1452
	global $smcFunc, $modSettings, $context, $txt, $scripturl, $sourcedir, $user_info;
1453
1454
	// Submitting a new one?
1455
	if (isset($_POST['add']))
1456
		return ModifyWarningTemplate();
0 ignored issues
show
Are you sure the usage of ModifyWarningTemplate() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
1457
	elseif (isset($_POST['delete']) && !empty($_POST['deltpl']))
1458
	{
1459
		checkSession();
1460
		validateToken('mod-wt');
1461
1462
		// Log the actions.
1463
		$request = $smcFunc['db_query']('', '
1464
			SELECT recipient_name
1465
			FROM {db_prefix}log_comments
1466
			WHERE id_comment IN ({array_int:delete_ids})
1467
				AND comment_type = {string:warntpl}
1468
				AND (id_recipient = {int:generic} OR id_recipient = {int:current_member})',
1469
			array(
1470
				'delete_ids' => $_POST['deltpl'],
1471
				'warntpl' => 'warntpl',
1472
				'generic' => 0,
1473
				'current_member' => $user_info['id'],
1474
			)
1475
		);
1476
		while ($row = $smcFunc['db_fetch_assoc']($request))
1477
			logAction('delete_warn_template', array('template' => $row['recipient_name']));
1478
		$smcFunc['db_free_result']($request);
1479
1480
		// Do the deletes.
1481
		$smcFunc['db_query']('', '
1482
			DELETE FROM {db_prefix}log_comments
1483
			WHERE id_comment IN ({array_int:delete_ids})
1484
				AND comment_type = {string:warntpl}
1485
				AND (id_recipient = {int:generic} OR id_recipient = {int:current_member})',
1486
			array(
1487
				'delete_ids' => $_POST['deltpl'],
1488
				'warntpl' => 'warntpl',
1489
				'generic' => 0,
1490
				'current_member' => $user_info['id'],
1491
			)
1492
		);
1493
	}
1494
1495
	// Setup context as always.
1496
	$context['page_title'] = $txt['mc_warning_templates_title'];
1497
1498
	require_once($sourcedir . '/Subs-List.php');
1499
1500
	// This is all the information required for a watched user listing.
1501
	$listOptions = array(
1502
		'id' => 'warning_template_list',
1503
		'title' => $txt['mc_warning_templates_title'],
1504
		'items_per_page' => $modSettings['defaultMaxListItems'],
1505
		'no_items_label' => $txt['mc_warning_templates_none'],
1506
		'base_href' => $scripturl . '?action=moderate;area=warnings;sa=templates;' . $context['session_var'] . '=' . $context['session_id'],
1507
		'default_sort_col' => 'title',
1508
		'get_items' => array(
1509
			'function' => 'list_getWarningTemplates',
1510
		),
1511
		'get_count' => array(
1512
			'function' => 'list_getWarningTemplateCount',
1513
		),
1514
		// This assumes we are viewing by user.
1515
		'columns' => array(
1516
			'title' => array(
1517
				'header' => array(
1518
					'value' => $txt['mc_warning_templates_name'],
1519
				),
1520
				'data' => array(
1521
					'sprintf' => array(
1522
						'format' => '<a href="' . $scripturl . '?action=moderate;area=warnings;sa=templateedit;tid=%1$d">%2$s</a>',
1523
						'params' => array(
1524
							'id_comment' => false,
1525
							'title' => false,
1526
							'body' => false,
1527
						),
1528
					),
1529
				),
1530
				'sort' => array(
1531
					'default' => 'template_title',
1532
					'reverse' => 'template_title DESC',
1533
				),
1534
			),
1535
			'creator' => array(
1536
				'header' => array(
1537
					'value' => $txt['mc_warning_templates_creator'],
1538
				),
1539
				'data' => array(
1540
					'db' => 'creator',
1541
				),
1542
				'sort' => array(
1543
					'default' => 'creator_name',
1544
					'reverse' => 'creator_name DESC',
1545
				),
1546
			),
1547
			'time' => array(
1548
				'header' => array(
1549
					'value' => $txt['mc_warning_templates_time'],
1550
				),
1551
				'data' => array(
1552
					'db' => 'time',
1553
				),
1554
				'sort' => array(
1555
					'default' => 'lc.log_time DESC',
1556
					'reverse' => 'lc.log_time',
1557
				),
1558
			),
1559
			'delete' => array(
1560
				'header' => array(
1561
					'value' => '<input type="checkbox" onclick="invertAll(this, this.form);">',
1562
					'style' => 'width: 4%;',
1563
					'class' => 'centercol',
1564
				),
1565
				'data' => array(
1566
					'function' => function($rowData)
1567
					{
1568
						return '<input type="checkbox" name="deltpl[]" value="' . $rowData['id_comment'] . '">';
1569
					},
1570
					'class' => 'centercol',
1571
				),
1572
			),
1573
		),
1574
		'form' => array(
1575
			'href' => $scripturl . '?action=moderate;area=warnings;sa=templates',
1576
			'token' => 'mod-wt',
1577
		),
1578
		'additional_rows' => array(
1579
			array(
1580
				'position' => 'bottom_of_list',
1581
				'value' => '&nbsp;<input type="submit" name="delete" value="' . $txt['mc_warning_template_delete'] . '" data-confirm="' . $txt['mc_warning_template_delete_confirm'] . '" class="button you_sure">',
1582
			),
1583
			array(
1584
				'position' => 'bottom_of_list',
1585
				'value' => '<input type="submit" name="add" value="' . $txt['mc_warning_template_add'] . '" class="button">',
1586
			),
1587
		),
1588
	);
1589
1590
	// Create the watched user list.
1591
	createToken('mod-wt');
1592
	createList($listOptions);
1593
1594
	$context['sub_template'] = 'show_list';
1595
	$context['default_list'] = 'warning_template_list';
1596
}
1597
1598
/**
1599
 * Callback for createList().
1600
 *
1601
 * @return int The total number of warning templates
1602
 */
1603
function list_getWarningTemplateCount()
1604
{
1605
	global $smcFunc, $user_info;
1606
1607
	$request = $smcFunc['db_query']('', '
1608
		SELECT COUNT(*)
1609
		FROM {db_prefix}log_comments
1610
		WHERE comment_type = {string:warntpl}
1611
			AND (id_recipient = {string:generic} OR id_recipient = {int:current_member})',
1612
		array(
1613
			'warntpl' => 'warntpl',
1614
			'generic' => 0,
1615
			'current_member' => $user_info['id'],
1616
		)
1617
	);
1618
	list ($totalWarns) = $smcFunc['db_fetch_row']($request);
1619
	$smcFunc['db_free_result']($request);
1620
1621
	return $totalWarns;
1622
}
1623
1624
/**
1625
 * Callback for createList().
1626
 *
1627
 * @param int $start The item to start with (for pagination purposes)
1628
 * @param int $items_per_page The number of items to show per page
1629
 * @param string $sort A string indicating how to sort the results
1630
 * @return array An arrray of info about the available warning templates
1631
 */
1632
function list_getWarningTemplates($start, $items_per_page, $sort)
1633
{
1634
	global $smcFunc, $scripturl, $user_info;
1635
1636
	$request = $smcFunc['db_query']('', '
1637
		SELECT lc.id_comment, COALESCE(mem.id_member, 0) AS id_member,
1638
			COALESCE(mem.real_name, lc.member_name) AS creator_name, recipient_name AS template_title,
1639
			lc.log_time, lc.body
1640
		FROM {db_prefix}log_comments AS lc
1641
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = lc.id_member)
1642
		WHERE lc.comment_type = {string:warntpl}
1643
			AND (id_recipient = {string:generic} OR id_recipient = {int:current_member})
1644
		ORDER BY ' . $sort . '
1645
		LIMIT ' . $start . ', ' . $items_per_page,
1646
		array(
1647
			'warntpl' => 'warntpl',
1648
			'generic' => 0,
1649
			'current_member' => $user_info['id'],
1650
		)
1651
	);
1652
	$templates = array();
1653
	while ($row = $smcFunc['db_fetch_assoc']($request))
1654
	{
1655
		$templates[] = array(
1656
			'id_comment' => $row['id_comment'],
1657
			'creator' => $row['id_member'] ? ('<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $row['creator_name'] . '</a>') : $row['creator_name'],
1658
			'time' => timeformat($row['log_time']),
1659
			'title' => $row['template_title'],
1660
			'body' => $smcFunc['htmlspecialchars']($row['body']),
1661
		);
1662
	}
1663
	$smcFunc['db_free_result']($request);
1664
1665
	return $templates;
1666
}
1667
1668
/**
1669
 * Edit a warning template.
1670
 */
1671
function ModifyWarningTemplate()
1672
{
1673
	global $smcFunc, $context, $txt, $user_info, $sourcedir;
1674
1675
	$context['id_template'] = isset($_REQUEST['tid']) ? (int) $_REQUEST['tid'] : 0;
1676
	$context['is_edit'] = $context['id_template'];
1677
1678
	// Standard template things.
1679
	$context['page_title'] = $context['is_edit'] ? $txt['mc_warning_template_modify'] : $txt['mc_warning_template_add'];
1680
	$context['sub_template'] = 'warn_template';
1681
	$context[$context['moderation_menu_name']]['current_subsection'] = 'templates';
1682
1683
	// Defaults.
1684
	$context['template_data'] = array(
1685
		'title' => '',
1686
		'body' => $txt['mc_warning_template_body_default'],
1687
		'personal' => false,
1688
		'can_edit_personal' => true,
1689
	);
1690
1691
	// If it's an edit load it.
1692
	if ($context['is_edit'])
1693
	{
1694
		$request = $smcFunc['db_query']('', '
1695
			SELECT id_member, id_recipient, recipient_name AS template_title, body
1696
			FROM {db_prefix}log_comments
1697
			WHERE id_comment = {int:id}
1698
				AND comment_type = {string:warntpl}
1699
				AND (id_recipient = {int:generic} OR id_recipient = {int:current_member})',
1700
			array(
1701
				'id' => $context['id_template'],
1702
				'warntpl' => 'warntpl',
1703
				'generic' => 0,
1704
				'current_member' => $user_info['id'],
1705
			)
1706
		);
1707
		while ($row = $smcFunc['db_fetch_assoc']($request))
1708
		{
1709
			$context['template_data'] = array(
1710
				'title' => $row['template_title'],
1711
				// Redo htmlspecialchars for the sake of old data that might have incorrectly encoded entities.
1712
				'body' => $smcFunc['htmlspecialchars'](un_htmlspecialchars($row['body'])),
1713
				'personal' => $row['id_recipient'],
1714
				'can_edit_personal' => $row['id_member'] == $user_info['id'],
1715
			);
1716
		}
1717
		$smcFunc['db_free_result']($request);
1718
	}
1719
1720
	// Wait, we are saving?
1721
	if (isset($_POST['save']))
1722
	{
1723
		checkSession();
1724
		validateToken('mod-wt');
1725
1726
		// To check the BBC is pretty good...
1727
		require_once($sourcedir . '/Subs-Post.php');
1728
1729
		// Bit of cleaning!
1730
		$_POST['template_body'] = trim($_POST['template_body']);
1731
		$_POST['template_title'] = trim($_POST['template_title']);
1732
1733
		// Need something in both boxes.
1734
		if (!empty($_POST['template_body']) && !empty($_POST['template_title']))
1735
		{
1736
			// Safety first.
1737
			$_POST['template_title'] = $smcFunc['htmlspecialchars']($_POST['template_title']);
1738
			$_POST['template_body'] = $smcFunc['htmlspecialchars']($_POST['template_body']);
1739
1740
			// Clean up BBC.
1741
			preparsecode($_POST['template_body']);
1742
			// But put line breaks back!
1743
			$_POST['template_body'] = strtr($_POST['template_body'], array('<br>' => "\n"));
1744
1745
			// Is this personal?
1746
			$recipient_id = !empty($_POST['make_personal']) ? $user_info['id'] : 0;
1747
1748
			// If we are this far it's save time.
1749
			if ($context['is_edit'])
1750
			{
1751
				// Simple update...
1752
				$smcFunc['db_query']('', '
1753
					UPDATE {db_prefix}log_comments
1754
					SET id_recipient = {int:personal}, recipient_name = {string:title}, body = {string:body}
1755
					WHERE id_comment = {int:id}
1756
						AND comment_type = {string:warntpl}
1757
						AND (id_recipient = {int:generic} OR id_recipient = {int:current_member})'.
1758
						($recipient_id ? ' AND id_member = {int:current_member}' : ''),
1759
					array(
1760
						'personal' => $recipient_id,
1761
						'title' => $_POST['template_title'],
1762
						'body' => $_POST['template_body'],
1763
						'id' => $context['id_template'],
1764
						'warntpl' => 'warntpl',
1765
						'generic' => 0,
1766
						'current_member' => $user_info['id'],
1767
					)
1768
				);
1769
1770
				// If it wasn't visible and now is they've effectively added it.
1771
				if ($context['template_data']['personal'] && !$recipient_id)
1772
					logAction('add_warn_template', array('template' => $_POST['template_title']));
1773
				// Conversely if they made it personal it's a delete.
1774
				elseif (!$context['template_data']['personal'] && $recipient_id)
1775
					logAction('delete_warn_template', array('template' => $_POST['template_title']));
1776
				// Otherwise just an edit.
1777
				else
1778
					logAction('modify_warn_template', array('template' => $_POST['template_title']));
1779
			}
1780
			else
1781
			{
1782
				$smcFunc['db_insert']('',
1783
					'{db_prefix}log_comments',
1784
					array(
1785
						'id_member' => 'int', 'member_name' => 'string', 'comment_type' => 'string', 'id_recipient' => 'int',
1786
						'recipient_name' => 'string-255', 'body' => 'string-65535', 'log_time' => 'int',
1787
					),
1788
					array(
1789
						$user_info['id'], $user_info['name'], 'warntpl', $recipient_id,
1790
						$_POST['template_title'], $_POST['template_body'], time(),
1791
					),
1792
					array('id_comment')
1793
				);
1794
1795
				logAction('add_warn_template', array('template' => $_POST['template_title']));
1796
			}
1797
1798
			// Get out of town...
1799
			redirectexit('action=moderate;area=warnings;sa=templates');
1800
		}
1801
		else
1802
		{
1803
			$context['warning_errors'] = array();
1804
			$context['template_data']['title'] = !empty($_POST['template_title']) ? $_POST['template_title'] : '';
1805
			$context['template_data']['body'] = !empty($_POST['template_body']) ? $_POST['template_body'] : $txt['mc_warning_template_body_default'];
1806
			$context['template_data']['personal'] = !empty($_POST['make_personal']);
1807
1808
			if (empty($_POST['template_title']))
1809
				$context['warning_errors'][] = $txt['mc_warning_template_error_no_title'];
1810
			if (empty($_POST['template_body']))
1811
				$context['warning_errors'][] = $txt['mc_warning_template_error_no_body'];
1812
		}
1813
	}
1814
1815
	createToken('mod-wt');
1816
}
1817
1818
/**
1819
 * Change moderation preferences.
1820
 */
1821
function ModerationSettings()
1822
{
1823
	global $context, $txt, $user_info;
1824
1825
	// Some useful context stuff.
1826
	loadTemplate('ModerationCenter');
1827
	$context['page_title'] = $txt['mc_settings'];
1828
	$context['sub_template'] = 'moderation_settings';
1829
	$context[$context['moderation_menu_name']]['tab_data'] = array(
1830
		'title' => $txt['mc_prefs_title'],
1831
		'help' => '',
1832
		'description' => $txt['mc_prefs_desc']
1833
	);
1834
1835
	$pref_binary = 5;
0 ignored issues
show
The assignment to $pref_binary is dead and can be removed.
Loading history...
1836
1837
	// Are we saving?
1838
	if (isset($_POST['save']))
1839
	{
1840
		checkSession();
1841
		validateToken('mod-set');
1842
1843
		/* Current format of mod_prefs is:
1844
			x|ABCD|yyy
1845
1846
			WHERE:
1847
				x = Show report count on forum header.
1848
				ABCD = Block indexes to show on moderation main page.
1849
				yyy = Integer with the following bit status:
1850
					- yyy & 4 = Notify about posts awaiting approval.
1851
		*/
1852
1853
		// Now check other options!
1854
		$pref_binary = 0;
1855
1856
		// Put it all together.
1857
		$mod_prefs = '0||' . $pref_binary;
1858
		updateMemberData($user_info['id'], array('mod_prefs' => $mod_prefs));
1859
	}
1860
1861
	// What blocks does the user currently have selected?
1862
	$context['mod_settings'] = array(
1863
	);
1864
1865
	createToken('mod-set');
1866
}
1867
1868
/**
1869
 * This ends a moderator session, requiring authentication to access the MCP again.
1870
 */
1871
function ModEndSession()
1872
{
1873
	// This is so easy!
1874
	unset($_SESSION['moderate_time']);
1875
1876
	// Clean any moderator tokens as well.
1877
	foreach ($_SESSION['token'] as $key => $token)
1878
		if (strpos($key, '-mod') !== false)
1879
			unset($_SESSION['token'][$key]);
1880
1881
	redirectexit();
1882
}
1883
1884
?>