Completed
Push — release-2.1 ( 121660...f19596 )
by Mathias
09:09
created

Sources/ManagePosts.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * This file contains all the administration settings for topics and posts.
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines http://www.simplemachines.org
10
 * @copyright 2017 Simple Machines and individual contributors
11
 * @license http://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 Beta 4
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * The main entrance point for the 'Posts and topics' screen.
21
 * Like all others, it checks permissions, then forwards to the right function
22
 * based on the given sub-action.
23
 * Defaults to sub-action 'posts'.
24
 * Accessed from ?action=admin;area=postsettings.
25
 * Requires (and checks for) the admin_forum permission.
26
 */
27
function ManagePostSettings()
28
{
29
	global $context, $txt;
30
31
	// Make sure you can be here.
32
	isAllowedTo('admin_forum');
33
	loadLanguage('Drafts');
34
35
	$subActions = array(
36
		'posts' => 'ModifyPostSettings',
37
		'censor' => 'SetCensor',
38
		'topics' => 'ModifyTopicSettings',
39
		'drafts' => 'ModifyDraftSettings',
40
	);
41
42
	// Default the sub-action to 'posts'.
43
	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'posts';
44
45
	$context['page_title'] = $txt['manageposts_title'];
46
47
	// Tabs for browsing the different post functions.
48
	$context[$context['admin_menu_name']]['tab_data'] = array(
49
		'title' => $txt['manageposts_title'],
50
		'help' => 'posts_and_topics',
51
		'description' => $txt['manageposts_description'],
52
		'tabs' => array(
53
			'posts' => array(
54
				'description' => $txt['manageposts_settings_description'],
55
			),
56
			'censor' => array(
57
				'description' => $txt['admin_censored_desc'],
58
			),
59
			'topics' => array(
60
				'description' => $txt['manageposts_topic_settings_description'],
61
			),
62
			'drafts' => array(
63
				'description' => $txt['drafts_show_desc'],
64
			),
65
		),
66
	);
67
68
	call_integration_hook('integrate_manage_posts', array(&$subActions));
69
70
	// Call the right function for this sub-action.
71
	call_helper($subActions[$_REQUEST['sa']]);
72
}
73
74
/**
75
 * Shows an interface to set and test censored words.
76
 * It uses the censor_vulgar, censor_proper, censorWholeWord, and censorIgnoreCase
77
 * settings.
78
 * Requires the admin_forum permission.
79
 * Accessed from ?action=admin;area=postsettings;sa=censor.
80
 *
81
 * @uses the Admin template and the edit_censored sub template.
82
 */
83
function SetCensor()
84
{
85
	global $txt, $modSettings, $context, $smcFunc, $sourcedir;
86
87
	if (!empty($_POST['save_censor']))
88
	{
89
		// Make sure censoring is something they can do.
90
		checkSession();
91
		validateToken('admin-censor');
92
93
		$censored_vulgar = array();
94
		$censored_proper = array();
95
96
		// Rip it apart, then split it into two arrays.
97
		if (isset($_POST['censortext']))
98
		{
99
			$_POST['censortext'] = explode("\n", strtr($_POST['censortext'], array("\r" => '')));
100
101
			foreach ($_POST['censortext'] as $c)
102
				list ($censored_vulgar[], $censored_proper[]) = array_pad(explode('=', trim($c)), 2, '');
103
		}
104
		elseif (isset($_POST['censor_vulgar'], $_POST['censor_proper']))
105
		{
106
			if (is_array($_POST['censor_vulgar']))
107
			{
108
				foreach ($_POST['censor_vulgar'] as $i => $value)
109
				{
110
					if (trim(strtr($value, '*', ' ')) == '')
111
						unset($_POST['censor_vulgar'][$i], $_POST['censor_proper'][$i]);
112
				}
113
114
				$censored_vulgar = $_POST['censor_vulgar'];
115
				$censored_proper = $_POST['censor_proper'];
116
			}
117
			else
118
			{
119
				$censored_vulgar = explode("\n", strtr($_POST['censor_vulgar'], array("\r" => '')));
120
				$censored_proper = explode("\n", strtr($_POST['censor_proper'], array("\r" => '')));
121
			}
122
		}
123
124
		// Set the new arrays and settings in the database.
125
		$updates = array(
126
			'censor_vulgar' => implode("\n", $censored_vulgar),
127
			'censor_proper' => implode("\n", $censored_proper),
128
			'allow_no_censored' => empty($_POST['allow_no_censored']) ? '0' : '1',
129
			'censorWholeWord' => empty($_POST['censorWholeWord']) ? '0' : '1',
130
			'censorIgnoreCase' => empty($_POST['censorIgnoreCase']) ? '0' : '1',
131
		);
132
133
		call_integration_hook('integrate_save_censors', array(&$updates));
134
135
		$context['saved_successful'] = true;
136
		updateSettings($updates);
137
	}
138
139
	if (isset($_POST['censortest']))
140
	{
141
		require_once($sourcedir . '/Subs-Post.php');
142
		$censorText = $smcFunc['htmlspecialchars']($_POST['censortest'], ENT_QUOTES);
143
		preparsecode($censorText);
144
		$context['censor_test'] = strtr(censorText($censorText), array('"' => '&quot;'));
145
	}
146
147
	// Set everything up for the template to do its thang.
148
	$censor_vulgar = explode("\n", $modSettings['censor_vulgar']);
149
	$censor_proper = explode("\n", $modSettings['censor_proper']);
150
151
	$context['censored_words'] = array();
152
	for ($i = 0, $n = count($censor_vulgar); $i < $n; $i++)
153
	{
154
		if (empty($censor_vulgar[$i]))
155
			continue;
156
157
		// Skip it, it's either spaces or stars only.
158
		if (trim(strtr($censor_vulgar[$i], '*', ' ')) == '')
159
			continue;
160
161
		$context['censored_words'][$smcFunc['htmlspecialchars'](trim($censor_vulgar[$i]))] = isset($censor_proper[$i]) ? $smcFunc['htmlspecialchars']($censor_proper[$i]) : '';
162
	}
163
164
	call_integration_hook('integrate_censors');
165
166
	// Since the "Allow users to disable the word censor" stuff was moved from a theme setting to a global one, we need this...
167
	loadLanguage('Themes');
168
169
	$context['sub_template'] = 'edit_censored';
170
	$context['page_title'] = $txt['admin_censored_words'];
171
172
	createToken('admin-censor');
173
}
174
175
/**
176
 * Modify any setting related to posts and posting.
177
 * Requires the admin_forum permission.
178
 * Accessed from ?action=admin;area=postsettings;sa=posts.
179
 *
180
 * @param bool $return_config Whether or not to return the $config_vars array (used for admin search)
181
 * @return void|array Returns nothing or returns the config_vars array if $return_config is true
182
 * @uses Admin template, edit_post_settings sub-template.
183
 */
184
function ModifyPostSettings($return_config = false)
185
{
186
	global $context, $txt, $modSettings, $scripturl, $sourcedir, $smcFunc, $db_type;
187
188
	// Make an inline conditional a little shorter...
189
	$can_spell_check = false;
190
	if (function_exists('pspell_new'))
191
		$can_spell_check = true;
192
	elseif (function_exists('enchant_broker_init') && ($txt['lang_charset'] == 'UTF-8' || function_exists('iconv')))
193
		$can_spell_check = true;
194
195
	// All the settings...
196
	$config_vars = array(
197
			// Simple post options...
198
			array('check', 'removeNestedQuotes'),
199
			array('check', 'enableEmbeddedFlash', 'subtext' => $txt['enableEmbeddedFlash_warning']),
200
			// Note show the warning as red if: pspell not installed and (enchant not installed or not using UTF-8 and iconv not installed)
201
			array('check', 'enableSpellChecking', 'subtext' => ($can_spell_check ? $txt['enableSpellChecking_warning'] : ('<span class="alert">' . $txt['enableSpellChecking_warning'] . '</span>'))),
202
			array('check', 'disable_wysiwyg'),
203
			array('check', 'additional_options_collapsable'),
204
		'',
205
			// Posting limits...
206
			array('int', 'max_messageLength', 'subtext' => $txt['max_messageLength_zero'], 'postinput' => $txt['manageposts_characters']),
207
			array('int', 'topicSummaryPosts', 'postinput' => $txt['manageposts_posts']),
208
		'',
209
			// Posting time limits...
210
			array('int', 'spamWaitTime', 'postinput' => $txt['manageposts_seconds']),
211
			array('int', 'edit_wait_time', 'postinput' => $txt['manageposts_seconds']),
212
			array('int', 'edit_disable_time', 'subtext' => $txt['zero_to_disable'], 'postinput' => $txt['manageposts_minutes']),
213
		'',
214
			// Automagic image resizing.
215
			array('int', 'max_image_width', 'subtext' => $txt['zero_for_no_limit']),
216
			array('int', 'max_image_height', 'subtext' => $txt['zero_for_no_limit']),
217
		'',
218
			// First & Last message preview lengths
219
			array('int', 'preview_characters', 'subtext' => $txt['zero_to_disable'], 'postinput' => $txt['preview_characters_units']),
220
	);
221
222
	call_integration_hook('integrate_modify_post_settings', array(&$config_vars));
223
224
	if ($return_config)
225
		return $config_vars;
226
227
	// We'll want this for our easy save.
228
	require_once($sourcedir . '/ManageServer.php');
229
230
	// Setup the template.
231
	$context['page_title'] = $txt['manageposts_settings'];
232
	$context['sub_template'] = 'show_settings';
233
234
	// Are we saving them - are we??
235
	if (isset($_GET['save']))
236
	{
237
		checkSession();
238
239
		// If we're changing the message length (and we are using MySQL) let's check the column is big enough.
240
		if (isset($_POST['max_messageLength']) && $_POST['max_messageLength'] != $modSettings['max_messageLength'] && ($db_type == 'mysql'))
241
		{
242
			db_extend('packages');
243
244
			$colData = $smcFunc['db_list_columns']('{db_prefix}messages', true);
245
			foreach ($colData as $column)
246
				if ($column['name'] == 'body')
247
					$body_type = $column['type'];
248
249
			if (isset($body_type) && ($_POST['max_messageLength'] > 65535 || $_POST['max_messageLength'] == 0) && $body_type == 'text')
250
				fatal_lang_error('convert_to_mediumtext', false, array($scripturl . '?action=admin;area=maintain;sa=database'));
251
		}
252
253
		// If we're changing the post preview length let's check its valid
254
		if (!empty($_POST['preview_characters']))
255
			$_POST['preview_characters'] = (int) min(max(0, $_POST['preview_characters']), 512);
256
257
		call_integration_hook('integrate_save_post_settings');
258
259
		saveDBSettings($config_vars);
260
		$_SESSION['adm-save'] = true;
261
		redirectexit('action=admin;area=postsettings;sa=posts');
262
	}
263
264
	// Final settings...
265
	$context['post_url'] = $scripturl . '?action=admin;area=postsettings;save;sa=posts';
266
	$context['settings_title'] = $txt['manageposts_settings'];
267
268
	// Prepare the settings...
269
	prepareDBSettingContext($config_vars);
270
}
271
272
/**
273
 * Modify any setting related to topics.
274
 * Requires the admin_forum permission.
275
 * Accessed from ?action=admin;area=postsettings;sa=topics.
276
277
 * @param bool $return_config Whether or not to return the config_vars array (used for admin search)
278
 * @return void|array Returns nothing or returns $config_vars if $return_config is true
279
 * @uses Admin template, edit_topic_settings sub-template.
280
 */
281
function ModifyTopicSettings($return_config = false)
282
{
283
	global $context, $txt, $sourcedir, $scripturl;
284
285
	// Here are all the topic settings.
286
	$config_vars = array(
287
			// Some simple bools...
288
			array('check', 'enableParticipation'),
289
		'',
290
			// Pagination etc...
291
			array('int', 'oldTopicDays', 'postinput' => $txt['manageposts_days'], 'subtext' => $txt['zero_to_disable']),
292
			array('int', 'defaultMaxTopics', 'postinput' => $txt['manageposts_topics']),
293
			array('int', 'defaultMaxMessages', 'postinput' => $txt['manageposts_posts']),
294
			array('check', 'disable_print_topic'),
295
		'',
296
			// All, next/prev...
297
			array('int', 'enableAllMessages', 'postinput' => $txt['manageposts_posts'], 'subtext' => $txt['enableAllMessages_zero']),
298
			array('check', 'disableCustomPerPage'),
299
			array('check', 'enablePreviousNext'),
300
		'',
301
			// Topic related settings (show gender icon/avatars etc...)
302
			array('check', 'subject_toggle'),
303
			array('check', 'show_modify'),
304
			array('check', 'show_profile_buttons'),
305
			array('check', 'show_user_images'),
306
			array('check', 'show_blurb'),
307
			array('check', 'hide_post_group', 'subtext' => $txt['hide_post_group_desc']),
308
		'',
309
			// First & Last message preview lengths
310
			array('int', 'preview_characters', 'subtext' => $txt['zero_to_disable'], 'postinput' => $txt['preview_characters_units']),
311
			array('check', 'message_index_preview_first', 'subtext' => $txt['message_index_preview_first_desc']),
312
	);
313
314
	call_integration_hook('integrate_modify_topic_settings', array(&$config_vars));
315
316
	if ($return_config)
317
		return $config_vars;
318
319
	// Get the settings template ready.
320
	require_once($sourcedir . '/ManageServer.php');
321
322
	// Setup the template.
323
	$context['page_title'] = $txt['manageposts_topic_settings'];
324
	$context['sub_template'] = 'show_settings';
325
326
	// Are we saving them - are we??
327
	if (isset($_GET['save']))
328
	{
329
		checkSession();
330
		call_integration_hook('integrate_save_topic_settings');
331
332
		saveDBSettings($config_vars);
333
		$_SESSION['adm-save'] = true;
334
		redirectexit('action=admin;area=postsettings;sa=topics');
335
	}
336
337
	// Final settings...
338
	$context['post_url'] = $scripturl . '?action=admin;area=postsettings;save;sa=topics';
339
	$context['settings_title'] = $txt['manageposts_topic_settings'];
340
341
	// Prepare the settings...
342
	prepareDBSettingContext($config_vars);
343
}
344
345
/**
346
 * Modify any setting related to drafts.
347
 * Requires the admin_forum permission.
348
 * Accessed from ?action=admin;area=postsettings;sa=drafts
349
 *
350
 * @param bool $return_config Whether or not to return the config_vars array (used for admin search)
351
 * @return void|array Returns nothing or returns the $config_vars array if $return_config is true
352
 * @uses Admin template, edit_topic_settings sub-template.
353
 */
354
function ModifyDraftSettings($return_config = false)
355
{
356
	global $context, $txt, $sourcedir, $scripturl, $smcFunc;
357
358
	// Here are all the draft settings, a bit lite for now, but we can add more :P
359
	$config_vars = array(
360
		// Draft settings ...
361
		array('check', 'drafts_post_enabled'),
362
		array('check', 'drafts_pm_enabled'),
363
		array('check', 'drafts_show_saved_enabled', 'subtext' => $txt['drafts_show_saved_enabled_subnote']),
364
		array('int', 'drafts_keep_days', 'postinput' => $txt['days_word'], 'subtext' => $txt['drafts_keep_days_subnote']),
365
		'',
366
		array('check', 'drafts_autosave_enabled', 'subtext' => $txt['drafts_autosave_enabled_subnote']),
367
		array('int', 'drafts_autosave_frequency', 'postinput' => $txt['manageposts_seconds'], 'subtext' => $txt['drafts_autosave_frequency_subnote']),
368
	);
369
370
	if ($return_config)
371
		return $config_vars;
372
373
	// Get the settings template ready.
374
	require_once($sourcedir . '/ManageServer.php');
375
376
	// Setup the template.
377
	$context['page_title'] = $txt['managedrafts_settings'];
378
	$context['sub_template'] = 'show_settings';
379
380
	// Saving them ?
381
	if (isset($_GET['save']))
382
	{
383
		checkSession();
384
385
		// Protect them from themselves.
386
		$_POST['drafts_autosave_frequency'] = !isset($_POST['drafts_autosave_frequency']) || $_POST['drafts_autosave_frequency'] < 30 ? 30 : $_POST['drafts_autosave_frequency'];
387
388
		// Also disable the scheduled task if we're not using it.
389
		$smcFunc['db_query']('', '
390
			UPDATE {db_prefix}scheduled_tasks
391
			SET disabled = {int:disabled}
392
			WHERE task = {string:task}',
393
			array(
394
				'disabled' => !empty($_POST['drafts_keep_days']) ? 0 : 1,
395
				'task' => 'remove_old_drafts',
396
			)
397
		);
398
		require_once($sourcedir . '/ScheduledTasks.php');
399
		CalculateNextTrigger();
400
401
		// Save everything else and leave.
402
		saveDBSettings($config_vars);
403
		$_SESSION['adm-save'] = true;
404
		redirectexit('action=admin;area=postsettings;sa=drafts');
405
	}
406
407
	// some javascript to enable / disable the frequency input box
408
	$context['settings_post_javascript'] = '
409
		function toggle()
410
		{
411
			$("#drafts_autosave_frequency").prop("disabled", !($("#drafts_autosave_enabled").prop("checked")));
412
		};
413
		toggle();
414
415
		$("#drafts_autosave_enabled").click(function() { toggle(); });
416
	';
417
418
	// Final settings...
419
	$context['post_url'] = $scripturl . '?action=admin;area=postsettings;sa=drafts;save';
420
	$context['settings_title'] = $txt['managedrafts_settings'];
421
422
	// Prepare the settings...
423
	prepareDBSettingContext($config_vars);
424
}
425
426
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...