Completed
Push — release-2.1 ( 5876a2...f30e04 )
by Mert
06:50
created

ManageNews.php ➔ ComposeMailing()   F

Complexity

Conditions 35
Paths 4096

Size

Total Lines 188
Code Lines 104

Duplication

Lines 19
Ratio 10.11 %
Metric Value
cc 35
eloc 104
nc 4096
nop 0
dl 19
loc 188
rs 2

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file manages... the news. :P
5
 *
6
 * Simple Machines Forum (SMF)
7
 *
8
 * @package SMF
9
 * @author Simple Machines http://www.simplemachines.org
10
 * @copyright 2016 Simple Machines and individual contributors
11
 * @license http://www.simplemachines.org/about/smf/license.php BSD
12
 *
13
 * @version 2.1 Beta 3
14
 */
15
16
if (!defined('SMF'))
17
	die('No direct access...');
18
19
/**
20
 * The news dispatcher; doesn't do anything, just delegates.
21
 * This is the entrance point for all News and Newsletter screens.
22
 * Called by ?action=admin;area=news.
23
 * It does the permission checks, and calls the appropriate function
24
 * based on the requested sub-action.
25
 */
26
function ManageNews()
27
{
28
	global $context, $txt;
29
30
	// First, let's do a quick permissions check for the best error message possible.
31
	isAllowedTo(array('edit_news', 'send_mail', 'admin_forum'));
32
33
	loadTemplate('ManageNews');
34
35
	// Format: 'sub-action' => array('function', 'permission')
36
	$subActions = array(
37
		'editnews' => array('EditNews', 'edit_news'),
38
		'mailingmembers' => array('SelectMailingMembers', 'send_mail'),
39
		'mailingcompose' => array('ComposeMailing', 'send_mail'),
40
		'mailingsend' => array('SendMailing', 'send_mail'),
41
		'settings' => array('ModifyNewsSettings', 'admin_forum'),
42
	);
43
44
	call_integration_hook('integrate_manage_news', array(&$subActions));
45
46
	// Default to sub action 'main' or 'settings' depending on permissions.
47
	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : (allowedTo('edit_news') ? 'editnews' : (allowedTo('send_mail') ? 'mailingmembers' : 'settings'));
48
49
	// Have you got the proper permissions?
50
	isAllowedTo($subActions[$_REQUEST['sa']][1]);
51
52
	// Create the tabs for the template.
53
	$context[$context['admin_menu_name']]['tab_data'] = array(
54
		'title' => $txt['news_title'],
55
		'help' => 'edit_news',
56
		'description' => $txt['admin_news_desc'],
57
		'tabs' => array(
58
			'editnews' => array(
59
			),
60
			'mailingmembers' => array(
61
				'description' => $txt['news_mailing_desc'],
62
			),
63
			'settings' => array(
64
				'description' => $txt['news_settings_desc'],
65
			),
66
		),
67
	);
68
69
	// Force the right area...
70
	if (substr($_REQUEST['sa'], 0, 7) == 'mailing')
71
		$context[$context['admin_menu_name']]['current_subsection'] = 'mailingmembers';
72
73
	call_helper($subActions[$_REQUEST['sa']][0]);
74
}
75
76
/**
77
 * Let the administrator(s) edit the news items for the forum.
78
 * It writes an entry into the moderation log.
79
 * This function uses the edit_news administration area.
80
 * Called by ?action=admin;area=news.
81
 * Requires the edit_news permission.
82
 * Can be accessed with ?action=admin;sa=editnews.
83
 *
84
 * @uses ManageNews template, edit_news sub template.
85
 */
86
function EditNews()
87
{
88
	global $txt, $modSettings, $context, $sourcedir, $scripturl;
89
	global $smcFunc;
90
91
	require_once($sourcedir . '/Subs-Post.php');
92
93
	// The 'remove selected' button was pressed.
94
	if (!empty($_POST['delete_selection']) && !empty($_POST['remove']))
95
	{
96
		checkSession();
97
98
		// Store the news temporarily in this array.
99
		$temp_news = explode("\n", $modSettings['news']);
100
101
		// Remove the items that were selected.
102
		foreach ($temp_news as $i => $news)
103
			if (in_array($i, $_POST['remove']))
104
				unset($temp_news[$i]);
105
106
		// Update the database.
107
		updateSettings(array('news' => implode("\n", $temp_news)));
108
109
		$context['saved_successful'] = true;
110
111
		logAction('news');
112
	}
113
	// The 'Save' button was pressed.
114
	elseif (!empty($_POST['save_items']))
115
	{
116
		checkSession();
117
118
		foreach ($_POST['news'] as $i => $news)
119
		{
120
			if (trim($news) == '')
121
				unset($_POST['news'][$i]);
122
			else
123
			{
124
				$_POST['news'][$i] = $smcFunc['htmlspecialchars']($_POST['news'][$i], ENT_QUOTES);
125
				preparsecode($_POST['news'][$i]);
126
			}
127
		}
128
129
		// Send the new news to the database.
130
		updateSettings(array('news' => implode("\n", $_POST['news'])));
131
132
		$context['saved_successful'] = true;
133
134
		// Log this into the moderation log.
135
		logAction('news');
136
	}
137
138
	// We're going to want this for making our list.
139
	require_once($sourcedir . '/Subs-List.php');
140
141
	$context['page_title'] = $txt['admin_edit_news'];
142
143
	// Use the standard templates for showing this.
144
	$listOptions = array(
145
		'id' => 'news_lists',
146
		'get_items' => array(
147
			'function' => 'list_getNews',
148
		),
149
		'columns' => array(
150
			'news' => array(
151
				'header' => array(
152
					'value' => $txt['admin_edit_news'],
153
				),
154
				'data' => array(
155
					'function' => function ($news)
156
					{
157
						if (is_numeric($news['id']))
158
							return '<textarea id="data_' . $news['id'] . '" rows="3" cols="50" name="news[]" class="padding block">' . $news['unparsed'] . '</textarea>
159
							<div class="floatleft" id="preview_' . $news['id'] . '"></div>';
160
						else
161
							return $news['unparsed'];
162
					},
163
					'style' => 'width: 50%;',
164
				),
165
			),
166
			'preview' => array(
167
				'header' => array(
168
					'value' => $txt['preview'],
169
				),
170
				'data' => array(
171
					'function' => function ($news)
172
					{
173
						return '<div id="box_preview_' . $news['id'] . '" style="overflow: auto; width: 100%; height: 10ex;">' . $news['parsed'] . '</div>';
174
					},
175
					'style' => 'width: 45%;',
176
				),
177
			),
178
			'check' => array(
179
				'header' => array(
180
					'value' => '<input type="checkbox" onclick="invertAll(this, this.form);" class="input_check">',
181
					'class' => 'centercol',
182
				),
183
				'data' => array(
184
					'function' => function ($news)
185
					{
186
						if (is_numeric($news['id']))
187
							return '<input type="checkbox" name="remove[]" value="' . $news['id'] . '" class="input_check">';
188
						else
189
							return '';
190
					},
191
					'class' => 'centercol',
192
				),
193
			),
194
		),
195
		'form' => array(
196
			'href' => $scripturl . '?action=admin;area=news;sa=editnews',
197
			'hidden_fields' => array(
198
				$context['session_var'] => $context['session_id'],
199
			),
200
		),
201
		'additional_rows' => array(
202
			array(
203
				'position' => 'bottom_of_list',
204
				'value' => '
205
				<span id="moreNewsItems_link" class="floatleft" style="display: none;">
206
					<a class="button_link" href="javascript:void(0);" onclick="addNewsItem(); return false;">' . $txt['editnews_clickadd'] . '</a>
207
				</span>
208
				<input type="submit" name="save_items" value="' . $txt['save'] . '" class="button_submit">
209
				<input type="submit" name="delete_selection" value="' . $txt['editnews_remove_selected'] . '" data-confirm="' . $txt['editnews_remove_confirm'] . '" class="button_submit you_sure">',
210
			),
211
		),
212
		'javascript' => '
213
					document.getElementById(\'list_news_lists_last\').style.display = "none";
214
					document.getElementById("moreNewsItems_link").style.display = "";
215
					var last_preview = 0;
216
217
					$(document).ready(function () {
218
						$("div[id ^= \'preview_\']").each(function () {
219
							var preview_id = $(this).attr(\'id\').split(\'_\')[1];
220
							if (last_preview < preview_id)
221
								last_preview = preview_id;
222
							make_preview_btn(preview_id);
223
						});
224
					});
225
226
					function make_preview_btn (preview_id)
227
					{
228
						$("#preview_" + preview_id).addClass("button_link");
229
						$("#preview_" + preview_id).text(\'' . $txt['preview'] . '\').click(function () {
230
							$.ajax({
231
								type: "POST",
232
								url: "' . $scripturl . '?action=xmlhttp;sa=previews;xml",
233
								data: {item: "newspreview", news: $("#data_" + preview_id).val()},
234
								context: document.body,
235
								success: function(request){
236
									if ($(request).find("error").text() == \'\')
237
										$(document).find("#box_preview_" + preview_id).html($(request).text());
238
									else
239
										$(document).find("#box_preview_" + preview_id).text(\'' . $txt['news_error_no_news'] . '\');
240
								},
241
							});
242
						});
243
					}
244
245
					function addNewsItem ()
246
					{
247
						last_preview++;
248
						$("#list_news_lists_last").before(' . javaScriptEscape('
249
						<tr class="windowbg') . ' + (last_preview % 2 == 0 ? \'\' : \'2\') + ' . javaScriptEscape('">
250
							<td style="width: 50%;">
251
									<textarea id="data_') . ' + last_preview + ' . javaScriptEscape('" rows="3" cols="65" name="news[]" style="width: 95%;"></textarea>
252
									<br>
253
									<div class="floatleft" id="preview_') . ' + last_preview + ' . javaScriptEscape('"></div>
254
							</td>
255
							<td style="width: 45%;">
256
								<div id="box_preview_') . ' + last_preview + ' . javaScriptEscape('" style="overflow: auto; width: 100%; height: 10ex;"></div>
257
							</td>
258
							<td></td>
259
						</tr>') . ');
260
						make_preview_btn(last_preview);
261
					}',
262
	);
263
264
	// Create the request list.
265
	createList($listOptions);
266
267
	// And go!
268
	loadTemplate('ManageNews');
269
	$context['sub_template'] = 'news_lists';
270
}
271
272
/**
273
 * Prepares an array of the forum news items for display in the template
274
 *
275
 * @return array An array of information about the news items
276
 */
277
function list_getNews()
278
{
279
	global $modSettings;
280
281
	$admin_current_news = array();
282
	// Ready the current news.
283
	foreach (explode("\n", $modSettings['news']) as $id => $line)
284
		$admin_current_news[$id] = array(
285
			'id' => $id,
286
			'unparsed' => un_preparsecode($line),
287
			'parsed' => preg_replace('~<([/]?)form[^>]*?[>]*>~i', '<em class="smalltext">&lt;$1form&gt;</em>', parse_bbc($line)),
288
		);
289
290
	$admin_current_news['last'] = array(
291
		'id' => 'last',
292
		'unparsed' => '<div id="moreNewsItems"></div>
293
		<noscript><textarea rows="3" cols="65" name="news[]" style="width: 85%;"></textarea></noscript>',
294
		'parsed' => '<div id="moreNewsItems_preview"></div>',
295
	);
296
297
	return $admin_current_news;
298
}
299
300
/**
301
 * This function allows a user to select the membergroups to send their
302
 * mailing to.
303
 * Called by ?action=admin;area=news;sa=mailingmembers.
304
 * Requires the send_mail permission.
305
 * Form is submitted to ?action=admin;area=news;mailingcompose.
306
 *
307
 * @uses the ManageNews template and email_members sub template.
308
 */
309
function SelectMailingMembers()
310
{
311
	global $txt, $context, $modSettings, $smcFunc;
312
313
	// Is there any confirm message?
314
	$context['newsletter_sent'] = isset($_SESSION['newsletter_sent']) ? $_SESSION['newsletter_sent'] : '';
315
316
	$context['page_title'] = $txt['admin_newsletters'];
317
318
	$context['sub_template'] = 'email_members';
319
320
	$context['groups'] = array();
321
	$postGroups = array();
322
	$normalGroups = array();
323
324
	// If we have post groups disabled then we need to give a "ungrouped members" option.
325
	if (empty($modSettings['permission_enable_postgroups']))
326
	{
327
		$context['groups'][0] = array(
328
			'id' => 0,
329
			'name' => $txt['membergroups_members'],
330
			'member_count' => 0,
331
		);
332
		$normalGroups[0] = 0;
333
	}
334
335
	// Get all the extra groups as well as Administrator and Global Moderator.
336
	$request = $smcFunc['db_query']('', '
337
		SELECT mg.id_group, mg.group_name, mg.min_posts
338
		FROM {db_prefix}membergroups AS mg' . (empty($modSettings['permission_enable_postgroups']) ? '
339
		WHERE mg.min_posts = {int:min_posts}' : '') . '
340
		GROUP BY mg.id_group, mg.min_posts, mg.group_name
341
		ORDER BY mg.min_posts, CASE WHEN mg.id_group < {int:newbie_group} THEN mg.id_group ELSE 4 END, mg.group_name',
342
		array(
343
			'min_posts' => -1,
344
			'newbie_group' => 4,
345
		)
346
	);
347
	while ($row = $smcFunc['db_fetch_assoc']($request))
348
	{
349
		$context['groups'][$row['id_group']] = array(
350
			'id' => $row['id_group'],
351
			'name' => $row['group_name'],
352
			'member_count' => 0,
353
		);
354
355 View Code Duplication
		if ($row['min_posts'] == -1)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
356
			$normalGroups[$row['id_group']] = $row['id_group'];
357
		else
358
			$postGroups[$row['id_group']] = $row['id_group'];
359
	}
360
	$smcFunc['db_free_result']($request);
361
362
	// If we have post groups, let's count the number of members...
363
	if (!empty($postGroups))
364
	{
365
		$query = $smcFunc['db_query']('', '
366
			SELECT mem.id_post_group AS id_group, COUNT(*) AS member_count
367
			FROM {db_prefix}members AS mem
368
			WHERE mem.id_post_group IN ({array_int:post_group_list})
369
			GROUP BY mem.id_post_group',
370
			array(
371
				'post_group_list' => $postGroups,
372
			)
373
		);
374
		while ($row = $smcFunc['db_fetch_assoc']($query))
375
			$context['groups'][$row['id_group']]['member_count'] += $row['member_count'];
376
		$smcFunc['db_free_result']($query);
377
	}
378
379 View Code Duplication
	if (!empty($normalGroups))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
380
	{
381
		// Find people who are members of this group...
382
		$query = $smcFunc['db_query']('', '
383
			SELECT id_group, COUNT(*) AS member_count
384
			FROM {db_prefix}members
385
			WHERE id_group IN ({array_int:normal_group_list})
386
			GROUP BY id_group',
387
			array(
388
				'normal_group_list' => $normalGroups,
389
			)
390
		);
391
		while ($row = $smcFunc['db_fetch_assoc']($query))
392
			$context['groups'][$row['id_group']]['member_count'] += $row['member_count'];
393
		$smcFunc['db_free_result']($query);
394
395
		// Also do those who have it as an additional membergroup - this ones more yucky...
396
		$query = $smcFunc['db_query']('', '
397
			SELECT mg.id_group, COUNT(*) AS member_count
398
			FROM {db_prefix}membergroups AS mg
399
				INNER JOIN {db_prefix}members AS mem ON (mem.additional_groups != {string:blank_string}
400
					AND mem.id_group != mg.id_group
401
					AND FIND_IN_SET(mg.id_group, mem.additional_groups) != 0)
402
			WHERE mg.id_group IN ({array_int:normal_group_list})
403
			GROUP BY mg.id_group',
404
			array(
405
				'normal_group_list' => $normalGroups,
406
				'blank_string' => '',
407
			)
408
		);
409
		while ($row = $smcFunc['db_fetch_assoc']($query))
410
			$context['groups'][$row['id_group']]['member_count'] += $row['member_count'];
411
		$smcFunc['db_free_result']($query);
412
	}
413
414
	// Any moderators?
415
	$request = $smcFunc['db_query']('', '
416
		SELECT COUNT(DISTINCT id_member) AS num_distinct_mods
417
		FROM {db_prefix}moderators
418
		LIMIT 1',
419
		array(
420
		)
421
	);
422
	list ($context['groups'][3]['member_count']) = $smcFunc['db_fetch_row']($request);
423
	$smcFunc['db_free_result']($request);
424
425
	$context['can_send_pm'] = allowedTo('pm_send');
426
427
	loadJavascriptFile('suggest.js', array('defer' => false), 'smf_suggest');
428
}
429
430
/**
431
 * Prepare subject and message of an email for the preview box
432
 * Used in ComposeMailing and RetrievePreview (Xml.php)
433
 */
434
function prepareMailingForPreview ()
435
{
436
	global $context, $modSettings, $scripturl, $user_info, $txt;
437
	loadLanguage('Errors');
438
439
	$processing = array('preview_subject' => 'subject', 'preview_message' => 'message');
440
441
	// Use the default time format.
442
	$user_info['time_format'] = $modSettings['time_format'];
443
444
	$variables = array(
445
		'{$board_url}',
446
		'{$current_time}',
447
		'{$latest_member.link}',
448
		'{$latest_member.id}',
449
		'{$latest_member.name}'
450
	);
451
452
	$html = $context['send_html'];
453
454
	// We might need this in a bit
455
	$cleanLatestMember = empty($context['send_html']) || $context['send_pm'] ? un_htmlspecialchars($modSettings['latestRealName']) : $modSettings['latestRealName'];
456
457
	foreach ($processing as $key => $post)
458
	{
459
		$context[$key] = !empty($_REQUEST[$post]) ? $_REQUEST[$post] : '';
460
461
		if (empty($context[$key]) && empty($_REQUEST['xml']))
462
			$context['post_error']['messages'][] = $txt['error_no_' . $post];
463
		elseif (!empty($_REQUEST['xml']))
464
			continue;
465
466
		preparsecode($context[$key]);
467
		if ($html)
468
		{
469
			$enablePostHTML = $modSettings['enablePostHTML'];
470
			$modSettings['enablePostHTML'] = $context['send_html'];
471
			$context[$key] = parse_bbc($context[$key]);
472
			$modSettings['enablePostHTML'] = $enablePostHTML;
473
		}
474
475
		// Replace in all the standard things.
476
		$context[$key] = str_replace($variables,
477
			array(
478
				!empty($context['send_html']) ? '<a href="' . $scripturl . '">' . $scripturl . '</a>' : $scripturl,
479
				timeformat(forum_time(), false),
480
				!empty($context['send_html']) ? '<a href="' . $scripturl . '?action=profile;u=' . $modSettings['latestMember'] . '">' . $cleanLatestMember . '</a>' : ($context['send_pm'] ? '[url=' . $scripturl . '?action=profile;u=' . $modSettings['latestMember'] . ']' . $cleanLatestMember . '[/url]' : $cleanLatestMember),
481
				$modSettings['latestMember'],
482
				$cleanLatestMember
483
			), $context[$key]);
484
	}
485
}
486
487
/**
488
 * Shows a form to edit a forum mailing and its recipients.
489
 * Called by ?action=admin;area=news;sa=mailingcompose.
490
 * Requires the send_mail permission.
491
 * Form is submitted to ?action=admin;area=news;sa=mailingsend.
492
 *
493
 * @uses ManageNews template, email_members_compose sub-template.
494
 */
495
function ComposeMailing()
496
{
497
	global $txt, $sourcedir, $context, $smcFunc;
498
499
	// Setup the template!
500
	$context['page_title'] = $txt['admin_newsletters'];
501
	$context['sub_template'] = 'email_members_compose';
502
503
	$context['subject'] = !empty($_POST['subject']) ? $_POST['subject'] : $smcFunc['htmlspecialchars']($context['forum_name'] . ': ' . $txt['subject']);
504
	$context['message'] = !empty($_POST['message']) ? $_POST['message'] : $smcFunc['htmlspecialchars']($txt['message'] . "\n\n" . $txt['regards_team'] . "\n\n" . '{$board_url}');
505
506
	// Needed for the WYSIWYG editor.
507
	require_once($sourcedir . '/Subs-Editor.php');
508
509
	// Now create the editor.
510
	$editorOptions = array(
511
		'id' => 'message',
512
		'value' => $context['message'],
513
		'height' => '175px',
514
		'width' => '100%',
515
		'labels' => array(
516
			'post_button' => $txt['sendtopic_send'],
517
		),
518
		'preview_type' => 2,
519
		'required' => true,
520
	);
521
	create_control_richedit($editorOptions);
522
	// Store the ID for old compatibility.
523
	$context['post_box_name'] = $editorOptions['id'];
524
525
	if (isset($context['preview']))
526
	{
527
		require_once($sourcedir . '/Subs-Post.php');
528
		$context['recipients']['members'] = !empty($_POST['members']) ? explode(',', $_POST['members']) : array();
529
		$context['recipients']['exclude_members'] = !empty($_POST['exclude_members']) ? explode(',', $_POST['exclude_members']) : array();
530
		$context['recipients']['groups'] = !empty($_POST['groups']) ? explode(',', $_POST['groups']) : array();
531
		$context['recipients']['exclude_groups'] = !empty($_POST['exclude_groups']) ? explode(',', $_POST['exclude_groups']) : array();
532
		$context['recipients']['emails'] = !empty($_POST['emails']) ? explode(';', $_POST['emails']) : array();
533
		$context['email_force'] = !empty($_POST['email_force']) ? 1 : 0;
534
		$context['total_emails'] = !empty($_POST['total_emails']) ? (int) $_POST['total_emails'] : 0;
535
		$context['send_pm'] = !empty($_POST['send_pm']) ? 1 : 0;
536
		$context['send_html'] = !empty($_POST['send_html']) ? '1' : '0';
537
538
		return prepareMailingForPreview();
539
	}
540
541
	// Start by finding any members!
542
	$toClean = array();
543
	if (!empty($_POST['members']))
544
		$toClean[] = 'members';
545
	if (!empty($_POST['exclude_members']))
546
		$toClean[] = 'exclude_members';
547
	if (!empty($toClean))
548
	{
549
		require_once($sourcedir . '/Subs-Auth.php');
550
		foreach ($toClean as $type)
551
		{
552
			// Remove the quotes.
553
			$_POST[$type] = strtr($_POST[$type], array('\\"' => '"'));
0 ignored issues
show
Bug introduced by
It seems like $_POST[$type] can also be of type array; however, strtr() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
554
555
			preg_match_all('~"([^"]+)"~', $_POST[$type], $matches);
556
			$_POST[$type] = array_unique(array_merge($matches[1], explode(',', preg_replace('~"[^"]+"~', '', $_POST[$type]))));
557
558 View Code Duplication
			foreach ($_POST[$type] as $index => $member)
0 ignored issues
show
Bug introduced by
The expression $_POST[$type] of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
559
				if (strlen(trim($member)) > 0)
560
					$_POST[$type][$index] = $smcFunc['htmlspecialchars']($smcFunc['strtolower'](trim($member)));
561
				else
562
					unset($_POST[$type][$index]);
563
564
			// Find the members
565
			$_POST[$type] = implode(',', array_keys(findMembers($_POST[$type])));
0 ignored issues
show
Bug introduced by
It seems like $_POST[$type] can also be of type string; however, findMembers() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
566
		}
567
	}
568
569 View Code Duplication
	if (isset($_POST['member_list']) && is_array($_POST['member_list']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
570
	{
571
		$members = array();
572
		foreach ($_POST['member_list'] as $member_id)
573
			$members[] = (int) $member_id;
574
		$_POST['members'] = implode(',', $members);
575
	}
576
577 View Code Duplication
	if (isset($_POST['exclude_member_list']) && is_array($_POST['exclude_member_list']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
578
	{
579
		$members = array();
580
		foreach ($_POST['exclude_member_list'] as $member_id)
581
			$members[] = (int) $member_id;
582
		$_POST['exclude_members'] = implode(',', $members);
583
	}
584
585
	// Clean the other vars.
586
	SendMailing(true);
587
588
	// We need a couple strings from the email template file
589
	loadLanguage('EmailTemplates');
590
591
	// Get a list of all full banned users.  Use their Username and email to find them.  Only get the ones that can't login to turn off notification.
592
	$request = $smcFunc['db_query']('', '
593
		SELECT DISTINCT mem.id_member
594
		FROM {db_prefix}ban_groups AS bg
595
			INNER JOIN {db_prefix}ban_items AS bi ON (bg.id_ban_group = bi.id_ban_group)
596
			INNER JOIN {db_prefix}members AS mem ON (bi.id_member = mem.id_member)
597
		WHERE (bg.cannot_access = {int:cannot_access} OR bg.cannot_login = {int:cannot_login})
598
			AND (bg.expire_time IS NULL OR bg.expire_time > {int:current_time})',
599
		array(
600
			'cannot_access' => 1,
601
			'cannot_login' => 1,
602
			'current_time' => time(),
603
		)
604
	);
605
	while ($row = $smcFunc['db_fetch_assoc']($request))
606
		$context['recipients']['exclude_members'][] = $row['id_member'];
607
	$smcFunc['db_free_result']($request);
608
609
	$request = $smcFunc['db_query']('', '
610
		SELECT DISTINCT bi.email_address
611
		FROM {db_prefix}ban_items AS bi
612
			INNER JOIN {db_prefix}ban_groups AS bg ON (bg.id_ban_group = bi.id_ban_group)
613
		WHERE (bg.cannot_access = {int:cannot_access} OR bg.cannot_login = {int:cannot_login})
614
			AND (bg.expire_time IS NULL OR bg.expire_time > {int:current_time})
615
			AND bi.email_address != {string:blank_string}',
616
		array(
617
			'cannot_access' => 1,
618
			'cannot_login' => 1,
619
			'current_time' => time(),
620
			'blank_string' => '',
621
		)
622
	);
623
	$condition_array = array();
624
	$condition_array_params = array();
625
	$count = 0;
626
	while ($row = $smcFunc['db_fetch_assoc']($request))
627
	{
628
		$condition_array[] = '{string:email_' . $count . '}';
629
		$condition_array_params['email_' . $count++] = $row['email_address'];
630
	}
631
	$smcFunc['db_free_result']($request);
632
633
	if (!empty($condition_array))
634
	{
635
		$request = $smcFunc['db_query']('', '
636
			SELECT id_member
637
			FROM {db_prefix}members
638
			WHERE email_address IN(' . implode(', ', $condition_array) .')',
639
			$condition_array_params
640
		);
641
		while ($row = $smcFunc['db_fetch_assoc']($request))
642
			$context['recipients']['exclude_members'][] = $row['id_member'];
643
		$smcFunc['db_free_result']($request);
644
	}
645
646
	// Did they select moderators - if so add them as specific members...
647
	if ((!empty($context['recipients']['groups']) && in_array(3, $context['recipients']['groups'])) || (!empty($context['recipients']['exclude_groups']) && in_array(3, $context['recipients']['exclude_groups'])))
648
	{
649
		$request = $smcFunc['db_query']('', '
650
			SELECT DISTINCT mem.id_member AS identifier
651
			FROM {db_prefix}members AS mem
652
				INNER JOIN {db_prefix}moderators AS mods ON (mods.id_member = mem.id_member)
653
			WHERE mem.is_activated = {int:is_activated}',
654
			array(
655
				'is_activated' => 1,
656
			)
657
		);
658
		while ($row = $smcFunc['db_fetch_assoc']($request))
659
		{
660
			if (in_array(3, $context['recipients']))
661
				$context['recipients']['exclude_members'][] = $row['identifier'];
662
			else
663
				$context['recipients']['members'][] = $row['identifier'];
664
		}
665
		$smcFunc['db_free_result']($request);
666
	}
667
668
	// For progress bar!
669
	$context['total_emails'] = count($context['recipients']['emails']);
670
	$request = $smcFunc['db_query']('', '
671
		SELECT COUNT(*)
672
		FROM {db_prefix}members',
673
		array(
674
		)
675
	);
676
	list ($context['total_members']) = $smcFunc['db_fetch_row']($request);
677
	$smcFunc['db_free_result']($request);
678
679
	// Clean up the arrays.
680
	$context['recipients']['members'] = array_unique($context['recipients']['members']);
681
	$context['recipients']['exclude_members'] = array_unique($context['recipients']['exclude_members']);
682
}
683
684
/**
685
 * Handles the sending of the forum mailing in batches.
686
 * Called by ?action=admin;area=news;sa=mailingsend
687
 * Requires the send_mail permission.
688
 * Redirects to itself when more batches need to be sent.
689
 * Redirects to ?action=admin;area=news;sa=mailingmembers after everything has been sent.
690
 *
691
 * @param bool $clean_only If set, it will only clean the variables, put them in context, then return.
692
 * @uses the ManageNews template and email_members_send sub template.
693
 */
694
function SendMailing($clean_only = false)
695
{
696
	global $txt, $sourcedir, $context, $smcFunc;
697
	global $scripturl, $modSettings, $user_info;
698
699
	if (isset($_POST['preview']))
700
	{
701
		$context['preview'] = true;
702
		return ComposeMailing();
703
	}
704
705
	// How many to send at once? Quantity depends on whether we are queueing or not.
706
	// @todo Might need an interface? (used in Post.php too with different limits)
707
	$num_at_once = 1000;
708
709
	// If by PM's I suggest we half the above number.
710
	if (!empty($_POST['send_pm']))
711
		$num_at_once /= 2;
712
713
	checkSession();
714
715
	// Where are we actually to?
716
	$context['start'] = isset($_REQUEST['start']) ? $_REQUEST['start'] : 0;
717
	$context['email_force'] = !empty($_POST['email_force']) ? 1 : 0;
718
	$context['send_pm'] = !empty($_POST['send_pm']) ? 1 : 0;
719
	$context['total_emails'] = !empty($_POST['total_emails']) ? (int) $_POST['total_emails'] : 0;
720
	$context['send_html'] = !empty($_POST['send_html']) ? '1' : '0';
721
	$context['parse_html'] = !empty($_POST['parse_html']) ? '1' : '0';
722
723
	//One can't simply nullify things around
724
	if (empty($_REQUEST['total_members']))
725
	{
726
		$request = $smcFunc['db_query']('', '
727
			SELECT COUNT(*)
728
			FROM {db_prefix}members',
729
			array(
730
			)
731
		);
732
		list ($context['total_members']) = $smcFunc['db_fetch_row']($request);
733
		$smcFunc['db_free_result']($request);
734
	}
735
	else
736
	{
737
		$context['total_members'] = (int) $_REQUEST['total_members'];
738
	}
739
740
	// Create our main context.
741
	$context['recipients'] = array(
742
		'groups' => array(),
743
		'exclude_groups' => array(),
744
		'members' => array(),
745
		'exclude_members' => array(),
746
		'emails' => array(),
747
	);
748
749
	// Have we any excluded members?
750 View Code Duplication
	if (!empty($_POST['exclude_members']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
751
	{
752
		$members = explode(',', $_POST['exclude_members']);
753
		foreach ($members as $member)
754
			if ($member >= $context['start'])
755
				$context['recipients']['exclude_members'][] = (int) $member;
756
	}
757
758
	// What about members we *must* do?
759 View Code Duplication
	if (!empty($_POST['members']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
760
	{
761
		$members = explode(',', $_POST['members']);
762
		foreach ($members as $member)
763
			if ($member >= $context['start'])
764
				$context['recipients']['members'][] = (int) $member;
765
	}
766
	// Cleaning groups is simple - although deal with both checkbox and commas.
767 View Code Duplication
	if (isset($_POST['groups']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
768
	{
769
		if (is_array($_POST['groups']))
770
		{
771
			foreach ($_POST['groups'] as $group => $dummy)
772
				$context['recipients']['groups'][] = (int) $group;
773
		}
774
		else
775
		{
776
			$groups = explode(',', $_POST['groups']);
777
			foreach ($groups as $group)
778
				$context['recipients']['groups'][] = (int) $group;
779
		}
780
	}
781
	// Same for excluded groups
782 View Code Duplication
	if (isset($_POST['exclude_groups']))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
783
	{
784
		if (is_array($_POST['exclude_groups']))
785
		{
786
			foreach ($_POST['exclude_groups'] as $group => $dummy)
787
				$context['recipients']['exclude_groups'][] = (int) $group;
788
		}
789
		else
790
		{
791
			$groups = explode(',', $_POST['exclude_groups']);
792
			foreach ($groups as $group)
793
				$context['recipients']['exclude_groups'][] = (int) $group;
794
		}
795
	}
796
	// Finally - emails!
797
	if (!empty($_POST['emails']))
798
	{
799
		$addressed = array_unique(explode(';', strtr($_POST['emails'], array("\n" => ';', "\r" => ';', ',' => ';'))));
800
		foreach ($addressed as $curmem)
801
		{
802
			$curmem = trim($curmem);
803
			if ($curmem != '' && filter_var($curmem, FILTER_VALIDATE_EMAIL))
804
				$context['recipients']['emails'][$curmem] = $curmem;
805
		}
806
	}
807
808
	// If we're only cleaning drop out here.
809
	if ($clean_only)
810
		return;
811
812
	require_once($sourcedir . '/Subs-Post.php');
813
814
	// We are relying too much on writing to superglobals...
815
	$_POST['subject'] = !empty($_POST['subject']) ? $_POST['subject'] : '';
816
	$_POST['message'] = !empty($_POST['message']) ? $_POST['message'] : '';
817
818
	// Save the message and its subject in $context
819
	$context['subject'] = $smcFunc['htmlspecialchars']($_POST['subject'], ENT_QUOTES);
820
	$context['message'] = $smcFunc['htmlspecialchars']($_POST['message'], ENT_QUOTES);
821
822
	// Prepare the message for sending it as HTML
823
	if (!$context['send_pm'] && !empty($_POST['send_html']))
824
	{
825
		// Prepare the message for HTML.
826
		if (!empty($_POST['parse_html']))
827
			$_POST['message'] = str_replace(array("\n", '  '), array('<br>' . "\n", '&nbsp; '), $_POST['message']);
828
829
		// This is here to prevent spam filters from tagging this as spam.
830
		if (preg_match('~\<html~i', $_POST['message']) == 0)
831
		{
832
			if (preg_match('~\<body~i', $_POST['message']) == 0)
833
				$_POST['message'] = '<html><head><title>' . $_POST['subject'] . '</title></head>' . "\n" . '<body>' . $_POST['message'] . '</body></html>';
834
			else
835
				$_POST['message'] = '<html>' . $_POST['message'] . '</html>';
836
		}
837
	}
838
839
	if (empty($_POST['message']) || empty($_POST['subject']))
840
	{
841
		$context['preview'] = true;
842
		return ComposeMailing();
843
	}
844
845
	// Use the default time format.
846
	$user_info['time_format'] = $modSettings['time_format'];
847
848
	$variables = array(
849
		'{$board_url}',
850
		'{$current_time}',
851
		'{$latest_member.link}',
852
		'{$latest_member.id}',
853
		'{$latest_member.name}'
854
	);
855
856
	// We might need this in a bit
857
	$cleanLatestMember = empty($_POST['send_html']) || $context['send_pm'] ? un_htmlspecialchars($modSettings['latestRealName']) : $modSettings['latestRealName'];
858
859
	// Replace in all the standard things.
860
	$_POST['message'] = str_replace($variables,
861
		array(
862
			!empty($_POST['send_html']) ? '<a href="' . $scripturl . '">' . $scripturl . '</a>' : $scripturl,
863
			timeformat(forum_time(), false),
864
			!empty($_POST['send_html']) ? '<a href="' . $scripturl . '?action=profile;u=' . $modSettings['latestMember'] . '">' . $cleanLatestMember . '</a>' : ($context['send_pm'] ? '[url=' . $scripturl . '?action=profile;u=' . $modSettings['latestMember'] . ']' . $cleanLatestMember . '[/url]' : $cleanLatestMember),
865
			$modSettings['latestMember'],
866
			$cleanLatestMember
867
		), $_POST['message']);
868
	$_POST['subject'] = str_replace($variables,
869
		array(
870
			$scripturl,
871
			timeformat(forum_time(), false),
872
			$modSettings['latestRealName'],
873
			$modSettings['latestMember'],
874
			$modSettings['latestRealName']
875
		), $_POST['subject']);
876
877
	$from_member = array(
878
		'{$member.email}',
879
		'{$member.link}',
880
		'{$member.id}',
881
		'{$member.name}'
882
	);
883
884
	// If we still have emails, do them first!
885
	$i = 0;
886
	foreach ($context['recipients']['emails'] as $k => $email)
887
	{
888
		// Done as many as we can?
889
		if ($i >= $num_at_once)
890
			break;
891
892
		// Don't sent it twice!
893
		unset($context['recipients']['emails'][$k]);
894
895
		// Dammit - can't PM emails!
896
		if ($context['send_pm'])
897
			continue;
898
899
		$to_member = array(
900
			$email,
901
			!empty($_POST['send_html']) ? '<a href="mailto:' . $email . '">' . $email . '</a>' : $email,
902
			'??',
903
			$email
904
		);
905
906
		sendmail($email, str_replace($from_member, $to_member, $_POST['subject']), str_replace($from_member, $to_member, $_POST['message']), null, 'news', !empty($_POST['send_html']), 5);
907
908
		// Done another...
909
		$i++;
910
	}
911
912
	if ($i < $num_at_once)
913
	{
914
		// Need to build quite a query!
915
		$sendQuery = '(';
916
		$sendParams = array();
917
		if (!empty($context['recipients']['groups']))
918
		{
919
			// Take the long route...
920
			$queryBuild = array();
921
			foreach ($context['recipients']['groups'] as $group)
922
			{
923
				$sendParams['group_' . $group] = $group;
924
				$queryBuild[] = 'mem.id_group = {int:group_' . $group . '}';
925
				if (!empty($group))
926
				{
927
					$queryBuild[] = 'FIND_IN_SET({int:group_' . $group . '}, mem.additional_groups) != 0';
928
					$queryBuild[] = 'mem.id_post_group = {int:group_' . $group . '}';
929
				}
930
			}
931
			if (!empty($queryBuild))
932
			$sendQuery .= implode(' OR ', $queryBuild);
933
		}
934
		if (!empty($context['recipients']['members']))
935
		{
936
			$sendQuery .= ($sendQuery == '(' ? '' : ' OR ') . 'mem.id_member IN ({array_int:members})';
937
			$sendParams['members'] = $context['recipients']['members'];
938
		}
939
940
		$sendQuery .= ')';
941
942
		// If we've not got a query then we must be done!
943
		if ($sendQuery == '()')
944
		{
945
			// Set a confirmation message.
946
			$_SESSION['newsletter_sent'] = 'queue_done';
947
			redirectexit('action=admin;area=news;sa=mailingmembers');
948
		}
949
950
		// Anything to exclude?
951
		if (!empty($context['recipients']['exclude_groups']) && in_array(0, $context['recipients']['exclude_groups']))
952
			$sendQuery .= ' AND mem.id_group != {int:regular_group}';
953
		if (!empty($context['recipients']['exclude_members']))
954
		{
955
			$sendQuery .= ' AND mem.id_member NOT IN ({array_int:exclude_members})';
956
			$sendParams['exclude_members'] = $context['recipients']['exclude_members'];
957
		}
958
959
		// Get the smelly people - note we respect the id_member range as it gives us a quicker query.
960
		$result = $smcFunc['db_query']('', '
961
			SELECT mem.id_member, mem.email_address, mem.real_name, mem.id_group, mem.additional_groups, mem.id_post_group
962
			FROM {db_prefix}members AS mem
963
			WHERE ' . $sendQuery . '
964
				AND mem.is_activated = {int:is_activated}
965
			ORDER BY mem.id_member ASC
966
			LIMIT {int:start}, {int:atonce}',
967
			array_merge($sendParams, array(
968
				'start' => $context['start'],
969
				'atonce' => $num_at_once,
970
				'regular_group' => 0,
971
				'is_activated' => 1,
972
			))
973
		);
974
		$rows = array();
975
		while ($row = $smcFunc['db_fetch_assoc']($result))
976
		{
977
			$rows[$row['id_member']] = $row;
978
		}
979
		$smcFunc['db_free_result']($result);
980
981
		// Load their alert preferences
982
		require_once($sourcedir . '/Subs-Notify.php');
983
		$prefs = getNotifyPrefs(array_keys($rows), 'announcements', true);
984
985
		foreach ($rows as $row)
986
		{
987
			// Force them to have it?
988
			if (empty($context['email_force']) || empty($prefs[$row['id_member']]['announcements']))
989
				continue;
990
991
			// What groups are we looking at here?
992
			if (empty($row['additional_groups']))
993
				$groups = array($row['id_group'], $row['id_post_group']);
994 View Code Duplication
			else
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
995
				$groups = array_merge(
996
					array($row['id_group'], $row['id_post_group']),
997
					explode(',', $row['additional_groups'])
998
				);
999
1000
			// Excluded groups?
1001
			if (array_intersect($groups, $context['recipients']['exclude_groups']))
1002
				continue;
1003
1004
			// We might need this
1005
			$cleanMemberName = empty($_POST['send_html']) || $context['send_pm'] ? un_htmlspecialchars($row['real_name']) : $row['real_name'];
1006
1007
			// Replace the member-dependant variables
1008
			$message = str_replace($from_member,
1009
				array(
1010
					$row['email_address'],
1011
					!empty($_POST['send_html']) ? '<a href="' . $scripturl . '?action=profile;u=' . $row['id_member'] . '">' . $cleanMemberName . '</a>' : ($context['send_pm'] ? '[url=' . $scripturl . '?action=profile;u=' . $row['id_member'] . ']' . $cleanMemberName . '[/url]' : $cleanMemberName),
1012
					$row['id_member'],
1013
					$cleanMemberName,
1014
				), $_POST['message']);
1015
1016
			$subject = str_replace($from_member,
1017
				array(
1018
					$row['email_address'],
1019
					$row['real_name'],
1020
					$row['id_member'],
1021
					$row['real_name'],
1022
				), $_POST['subject']);
1023
1024
			// Send the actual email - or a PM!
1025
			if (!$context['send_pm'])
1026
				sendmail($row['email_address'], $subject, $message, null, 'news', !empty($_POST['send_html']), 5);
1027
			else
1028
				sendpm(array('to' => array($row['id_member']), 'bcc' => array()), $subject, $message);
1029
		}
1030
	}
1031
1032
1033
	$context['start'] = $context['start'] + $num_at_once;
1034
	if (empty($context['recipients']['emails']) && ($context['start'] >= $context['total_members']))
1035
	{
1036
		// Log this into the admin log.
1037
		logAction('newsletter', array(), 'admin');
1038
		$_SESSION['newsletter_sent'] = 'queue_done';
1039
		redirectexit('action=admin;area=news;sa=mailingmembers');
1040
	}
1041
1042
	// Working out progress is a black art of sorts.
1043
	$percentEmails = $context['total_emails'] == 0 ? 0 : ((count($context['recipients']['emails']) / $context['total_emails']) * ($context['total_emails'] / ($context['total_emails'] + $context['total_members'])));
1044
	$percentMembers = ($context['start'] / $context['total_members']) * ($context['total_members'] / ($context['total_emails'] + $context['total_members']));
1045
	$context['percentage_done'] = round(($percentEmails + $percentMembers) * 100, 2);
1046
1047
	$context['page_title'] = $txt['admin_newsletters'];
1048
	$context['sub_template'] = 'email_members_send';
1049
}
1050
1051
/**
1052
 * Set general news and newsletter settings and permissions.
1053
 * Called by ?action=admin;area=news;sa=settings.
1054
 * Requires the forum_admin permission.
1055
 *
1056
 * @uses ManageNews template, news_settings sub-template.
1057
 * @param bool $return_config Whether or not to return the config_vars array (used for admin search)
1058
 * @return void|array Returns nothing or returns the config_vars array if $return_config is true
1059
 */
1060
function ModifyNewsSettings($return_config = false)
1061
{
1062
	global $context, $sourcedir, $txt, $scripturl;
1063
1064
	$config_vars = array(
1065
		array('title', 'settings'),
1066
			// Inline permissions.
1067
			array('permissions', 'edit_news', 'help' => ''),
1068
			array('permissions', 'send_mail'),
1069
		'',
1070
			// Just the remaining settings.
1071
			array('check', 'xmlnews_enable', 'onclick' => 'document.getElementById(\'xmlnews_maxlen\').disabled = !this.checked;'),
1072
			array('int', 'xmlnews_maxlen', 'subtext' => $txt['xmlnews_maxlen_note'], 10),
1073
	);
1074
1075
	call_integration_hook('integrate_modify_news_settings', array(&$config_vars));
1076
1077
	if ($return_config)
1078
		return $config_vars;
1079
1080
	$context['page_title'] = $txt['admin_edit_news'] . ' - ' . $txt['settings'];
1081
	$context['sub_template'] = 'show_settings';
1082
1083
	// Needed for the settings template.
1084
	require_once($sourcedir . '/ManageServer.php');
1085
1086
	// Wrap it all up nice and warm...
1087
	$context['post_url'] = $scripturl . '?action=admin;area=news;save;sa=settings';
1088
1089
	// Add some javascript at the bottom...
1090
	addInlineJavascript('
1091
	document.getElementById("xmlnews_maxlen").disabled = !document.getElementById("xmlnews_enable").checked;', true);
1092
1093
	// Saving the settings?
1094
	if (isset($_GET['save']))
1095
	{
1096
		checkSession();
1097
1098
		call_integration_hook('integrate_save_news_settings');
1099
1100
		saveDBSettings($config_vars);
1101
		$_SESSION['adm-save'] = true;
1102
		redirectexit('action=admin;area=news;sa=settings');
1103
	}
1104
1105
	// We need this for the in-line permissions
1106
	createToken('admin-mp');
1107
1108
	prepareDBSettingContext($config_vars);
1109
}
1110
1111
?>
0 ignored issues
show
Best Practice introduced by
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...
1112