Issues (1014)

Themes/default/ManageNews.template.php (4 issues)

Labels
Severity
1
<?php
2
/**
3
 * Simple Machines Forum (SMF)
4
 *
5
 * @package SMF
6
 * @author Simple Machines https://www.simplemachines.org
7
 * @copyright 2022 Simple Machines and individual contributors
8
 * @license https://www.simplemachines.org/about/smf/license.php BSD
9
 *
10
 * @version 2.1.0
11
 */
12
13
/**
14
 * The template for sending newsletters
15
 */
16
function template_email_members()
17
{
18
	global $context, $txt, $scripturl;
19
20
	// Are we done sending the newsletter?
21
	if (!empty($context['newsletter_sent']))
22
		echo '
23
	<div class="infobox">', $txt['admin_news_newsletter_' . $context['newsletter_sent']], '</div>';
24
25
	echo '
26
		<form action="', $scripturl, '?action=admin;area=news;sa=mailingcompose" method="post" id="admin_newsletters" class="flow_hidden" accept-charset="', $context['character_set'], '">
27
			<div class="cat_bar">
28
				<h3 class="catbg">', $txt['admin_newsletters'], '</h3>
29
			</div>
30
			<div class="information noup">
31
				', $txt['admin_news_select_recipients'], '
32
			</div>
33
			<div class="windowbg noup">
34
				<dl class="settings">
35
					<dt>
36
						<strong>', $txt['admin_news_select_group'], ':</strong><br>
37
						<span class="smalltext">', $txt['admin_news_select_group_desc'], '</span>
38
					</dt>
39
					<dd>';
40
41
	foreach ($context['groups'] as $group)
42
		echo '
43
						<label for="groups_', $group['id'], '"><input type="checkbox" name="groups[', $group['id'], ']" id="groups_', $group['id'], '" value="', $group['id'], '" checked> ', $group['name'], '</label> <em>(', $group['member_count'], ')</em><br>';
44
45
	echo '
46
						<br>
47
						<label for="checkAllGroups"><input type="checkbox" id="checkAllGroups" checked onclick="invertAll(this, this.form, \'groups\');"> <em>', $txt['check_all'], '</em></label>
48
					</dd>
49
				</dl>
50
				<div id="advanced_panel_header" class="title_bar">
51
					<h3 class="titlebg">
52
						<span id="advanced_panel_toggle" class="toggle_down floatright" style="display: none;"></span>
53
						<a href="#" id="advanced_panel_link">', $txt['advanced'], '</a>
54
					</h3>
55
				</div>
56
				<div id="advanced_panel_div" class="padding">
57
					<dl class="settings">
58
						<dt>
59
							<strong>', $txt['admin_news_select_email'], ':</strong><br>
60
							<span class="smalltext">', $txt['admin_news_select_email_desc'], '</span>
61
						</dt>
62
						<dd>
63
							<textarea name="emails" rows="5" cols="30" style="width: 98%;"></textarea>
64
						</dd>
65
						<dt>
66
							<strong>', $txt['admin_news_select_members'], ':</strong><br>
67
							<span class="smalltext">', $txt['admin_news_select_members_desc'], '</span>
68
						</dt>
69
						<dd>
70
							<input type="text" name="members" id="members" value="" size="30">
71
							<span id="members_container"></span>
72
						</dd>
73
					</dl>
74
					<hr class="bordercolor">
75
					<dl class="settings">
76
						<dt>
77
							<strong>', $txt['admin_news_select_excluded_groups'], ':</strong><br>
78
							<span class="smalltext">', $txt['admin_news_select_excluded_groups_desc'], '</span>
79
						</dt>
80
						<dd>';
81
82
	foreach ($context['groups'] as $group)
83
		echo '
84
							<label for="exclude_groups_', $group['id'], '"><input type="checkbox" name="exclude_groups[', $group['id'], ']" id="exclude_groups_', $group['id'], '" value="', $group['id'], '"> ', $group['name'], '</label> <em>(', $group['member_count'], ')</em><br>';
85
86
	echo '
87
							<br>
88
							<label for="checkAllGroupsExclude"><input type="checkbox" id="checkAllGroupsExclude" onclick="invertAll(this, this.form, \'exclude_groups\');"> <em>', $txt['check_all'], '</em></label><br>
89
						</dd>
90
						<dt>
91
							<strong>', $txt['admin_news_select_excluded_members'], ':</strong><br>
92
							<span class="smalltext">', $txt['admin_news_select_excluded_members_desc'], '</span>
93
						</dt>
94
							<dd>
95
							<input type="text" name="exclude_members" id="exclude_members" value="" size="30">
96
							<span id="exclude_members_container"></span>
97
						</dd>
98
					</dl>
99
					<hr class="bordercolor">
100
					<dl class="settings">
101
						<dt>
102
							<label for="email_force"><strong>', $txt['admin_news_select_override_notify'], ':</strong></label><br>
103
							<span class="smalltext">', $txt['email_force'], '</span>
104
						</dt>
105
						<dd>
106
							<input type="checkbox" name="email_force" id="email_force" value="1">
107
						</dd>
108
					</dl>
109
				</div><!-- #advanced_panel_div -->
110
				<br>
111
				<input type="submit" value="', $txt['admin_next'], '" class="button">
112
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
113
			</div><!-- .windowbg -->
114
		</form>';
115
116
	// This is some javascript for the simple/advanced toggling and member suggest
117
	echo '
118
	<script>
119
		var oAdvancedPanelToggle = new smc_Toggle({
120
			bToggleEnabled: true,
121
			bCurrentlyCollapsed: true,
122
			aSwappableContainers: [
123
				\'advanced_panel_div\'
124
			],
125
			aSwapImages: [
126
				{
127
					sId: \'advanced_panel_toggle\',
128
					altExpanded: ', JavaScriptEscape($txt['hide']), ',
129
					altCollapsed: ', JavaScriptEscape($txt['show']), '
130
				}
131
			],
132
			aSwapLinks: [
133
				{
134
					sId: \'advanced_panel_link\',
135
					msgExpanded: ', JavaScriptEscape($txt['advanced']), ',
136
					msgCollapsed: ', JavaScriptEscape($txt['advanced']), '
137
				}
138
			]
139
		});
140
	</script>
141
	<script>
142
		var oMemberSuggest = new smc_AutoSuggest({
143
			sSelf: \'oMemberSuggest\',
144
			sSessionId: smf_session_id,
145
			sSessionVar: smf_session_var,
146
			sSuggestId: \'members\',
147
			sControlId: \'members\',
148
			sSearchType: \'member\',
149
			bItemList: true,
150
			sPostName: \'member_list\',
151
			sURLMask: \'action=profile;u=%item_id%\',
152
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
153
			sItemListContainerId: \'members_container\',
154
			aListItems: []
155
		});
156
		var oExcludeMemberSuggest = new smc_AutoSuggest({
157
			sSelf: \'oExcludeMemberSuggest\',
158
			sSessionId: \'', $context['session_id'], '\',
159
			sSessionVar: \'', $context['session_var'], '\',
160
			sSuggestId: \'exclude_members\',
161
			sControlId: \'exclude_members\',
162
			sSearchType: \'member\',
163
			bItemList: true,
164
			sPostName: \'exclude_member_list\',
165
			sURLMask: \'action=profile;u=%item_id%\',
166
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
167
			sItemListContainerId: \'exclude_members_container\',
168
			aListItems: []
169
		});
170
	</script>';
171
}
172
173
/**
174
 * The form for composing a newsletter
175
 */
176
function template_email_members_compose()
177
{
178
	global $context, $txt, $scripturl;
179
180
	echo '
181
	<div id="preview_section"', isset($context['preview_message']) ? '' : ' class="hidden"', '>
182
		<div class="cat_bar">
183
			<h3 class="catbg">
184
				<span id="preview_subject">', empty($context['preview_subject']) ? '' : $context['preview_subject'], '</span>
185
			</h3>
186
		</div>
187
		<div class="windowbg">
188
			<div class="post" id="preview_body">
189
				', empty($context['preview_message']) ? '<br>' : $context['preview_message'], '
190
			</div>
191
		</div>
192
	</div>
193
	<br>';
194
195
	echo '
196
		<form name="newsmodify" action="', $scripturl, '?action=admin;area=news;sa=mailingsend" method="post" accept-charset="', $context['character_set'], '">
197
			<div class="cat_bar">
198
				<h3 class="catbg">
199
					<a href="', $scripturl, '?action=helpadmin;help=email_members" onclick="return reqOverlayDiv(this.href);" class="help"><span class="main_icons help" title="', $txt['help'], '"></span></a> ', $txt['admin_newsletters'], '
200
				</h3>
201
			</div>
202
			<div class="information noup">
203
				', sprintf($txt['email_variables'], $scripturl), '
204
			</div>
205
			<div class="windowbg noup">
206
				<div class="', empty($context['error_type']) || $context['error_type'] != 'serious' ? 'noticebox' : 'errorbox', '"', empty($context['post_error']['messages']) ? ' style="display: none"' : '', ' id="errors">
207
					<dl>
208
						<dt>
209
							<strong id="error_serious">', $txt['error_while_submitting'], '</strong>
210
						</dt>
211
						<dd class="error" id="error_list">
212
							', empty($context['post_error']['messages']) ? '' : implode('<br>', $context['post_error']['messages']), '
213
						</dd>
214
					</dl>
215
				</div>
216
				<dl id="post_header">
217
					<dt>
218
						<label', (isset($context['post_error']['no_subject']) ? ' class="error"' : ''), ' for="subject" id="caption_subject">', $txt['subject'], '</label>
219
					</dt>
220
					<dd id="pm_subject">
221
						<input type="text" id="subject" name="subject" value="', $context['subject'], '" tabindex="', $context['tabindex']++, '" size="80" maxlength="84"', isset($context['post_error']['no_subject']) ? ' class="error"' : '', '>
222
					</dd>
223
				</dl>
224
				<div id="bbcBox_message"></div>';
225
226
	// What about smileys?
227
	if (!empty($context['smileys']['postform']) || !empty($context['smileys']['popup']))
228
		echo '
229
				<div id="smileyBox_message"></div>';
230
231
	// Show BBC buttons, smileys and textbox.
232
	echo '
233
				', template_control_richedit($context['post_box_name'], 'smileyBox_message', 'bbcBox_message');
0 ignored issues
show
Are you sure the usage of template_control_richedi...age', 'bbcBox_message') 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...
'bbcBox_message' of type string is incompatible with the type boolean|null expected by parameter $bbcContainer of template_control_richedit(). ( Ignorable by Annotation )

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

233
				', template_control_richedit($context['post_box_name'], 'smileyBox_message', /** @scrutinizer ignore-type */ 'bbcBox_message');
Loading history...
'smileyBox_message' of type string is incompatible with the type boolean|null expected by parameter $smileyContainer of template_control_richedit(). ( Ignorable by Annotation )

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

233
				', template_control_richedit($context['post_box_name'], /** @scrutinizer ignore-type */ 'smileyBox_message', 'bbcBox_message');
Loading history...
234
235
	echo '
236
				<ul>
237
					<li><label for="send_pm"><input type="checkbox" name="send_pm" id="send_pm"', !empty($context['send_pm']) ? ' checked' : '', ' onclick="checkboxes_status(this);"> ', $txt['email_as_pms'], '</label></li>
238
					<li><label for="send_html"><input type="checkbox" name="send_html" id="send_html"', !empty($context['send_html']) ? ' checked' : '', ' onclick="checkboxes_status(this);"> ', $txt['email_as_html'], '</label></li>
239
					<li><label for="parse_html"><input type="checkbox" name="parse_html" id="parse_html" checked disabled> ', $txt['email_parsed_html'], '</label></li>
240
				</ul>
241
				<span id="post_confirm_buttons">
242
					', template_control_richedit_buttons($context['post_box_name']), '
0 ignored issues
show
Are you sure the usage of template_control_richedi...ntext['post_box_name']) 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...
243
				</span>
244
			</div><!-- .windowbg -->
245
			<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
246
			<input type="hidden" name="email_force" value="', $context['email_force'], '">
247
			<input type="hidden" name="total_emails" value="', $context['total_emails'], '">';
248
249
	foreach ($context['recipients'] as $key => $values)
250
		echo '
251
			<input type="hidden" name="', $key, '" value="', implode(($key == 'emails' ? ';' : ','), $values), '">';
252
253
	echo '
254
			<script>';
255
256
	// The functions used to preview a posts without loading a new page.
257
	echo '
258
				var txt_preview_title = "', $txt['preview_title'], '";
259
				var txt_preview_fetch = "', $txt['preview_fetch'], '";
260
				function previewPost()
261
				{
262
					if (window.XMLHttpRequest)
263
					{
264
						// Opera didn\'t support setRequestHeader() before 8.01.
265
						// @todo Remove support for old browsers
266
						if (\'opera\' in window)
267
						{
268
							// Handle the WYSIWYG editor.
269
							if (textFields[i] == ', JavaScriptEscape($context['post_box_name']), ' && ', JavaScriptEscape('oEditorHandle_' . $context['post_box_name']), ' in window && oEditorHandle_', $context['post_box_name'], '.bRichTextEnabled)
270
								x[x.length] = \'message_mode=1&\' + textFields[i] + \'=\' + oEditorHandle_', $context['post_box_name'], '.getText(false).php_to8bit().php_urlencode();
271
							else
272
								x[x.length] = textFields[i] + \'=\' + document.forms.newsmodify[textFields[i]].value.php_to8bit().php_urlencode();
273
						}
274
						// @todo Currently not sending poll options and option checkboxes.
275
						var x = new Array();
276
						var textFields = [\'subject\', ', JavaScriptEscape($context['post_box_name']), '];
277
						var checkboxFields = [\'send_html\', \'send_pm\'];
278
279
						for (var i = 0, n = textFields.length; i < n; i++)
280
							if (textFields[i] in document.forms.newsmodify)
281
							{
282
								// Handle the WYSIWYG editor.
283
								if (textFields[i] == ', JavaScriptEscape($context['post_box_name']), ' && ', JavaScriptEscape('oEditorHandle_' . $context['post_box_name']), ' in window && oEditorHandle_', $context['post_box_name'], '.bRichTextEnabled)
284
									x[x.length] = \'message_mode=1&\' + textFields[i] + \'=\' + oEditorHandle_', $context['post_box_name'], '.getText(false).replace(/&#/g, \'&#38;#\').php_to8bit().php_urlencode();
285
								else
286
									x[x.length] = textFields[i] + \'=\' + document.forms.newsmodify[textFields[i]].value.replace(/&#/g, \'&#38;#\').php_to8bit().php_urlencode();
287
							}
288
						for (var i = 0, n = checkboxFields.length; i < n; i++)
289
							if (checkboxFields[i] in document.forms.newsmodify && document.forms.newsmodify.elements[checkboxFields[i]].checked)
290
								x[x.length] = checkboxFields[i] + \'=\' + document.forms.newsmodify.elements[checkboxFields[i]].value;
291
292
						x[x.length] = \'item=newsletterpreview\';
293
294
						sendXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=xmlhttp;sa=previews;xml\', x.join(\'&\'), onDocSent);
295
296
						document.getElementById(\'preview_section\').style.display = \'\';
297
						setInnerHTML(document.getElementById(\'preview_subject\'), txt_preview_title);
298
						setInnerHTML(document.getElementById(\'preview_body\'), txt_preview_fetch);
299
300
						return false;
301
					}
302
					else
303
						return submitThisOnce(document.forms.newsmodify);
304
				}
305
				function onDocSent(XMLDoc)
306
				{
307
					if (!XMLDoc)
308
					{
309
						document.forms.newsmodify.preview.onclick = new function ()
310
						{
311
							return true;
312
						}
313
						document.forms.newsmodify.preview.click();
314
					}
315
316
					// Show the preview section.
317
					var preview = XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'preview\')[0];
318
					setInnerHTML(document.getElementById(\'preview_subject\'), preview.getElementsByTagName(\'subject\')[0].firstChild.nodeValue);
319
320
					var bodyText = \'\';
321
					for (var i = 0, n = preview.getElementsByTagName(\'body\')[0].childNodes.length; i < n; i++)
322
						bodyText += preview.getElementsByTagName(\'body\')[0].childNodes[i].nodeValue;
323
324
					setInnerHTML(document.getElementById(\'preview_body\'), bodyText);
325
					document.getElementById(\'preview_body\').className = \'post\';
326
327
					// Show a list of errors (if any).
328
					var errors = XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'errors\')[0];
329
					var errorList = new Array();
330
					for (var i = 0, numErrors = errors.getElementsByTagName(\'error\').length; i < numErrors; i++)
331
						errorList[errorList.length] = errors.getElementsByTagName(\'error\')[i].firstChild.nodeValue;
332
					document.getElementById(\'errors\').style.display = numErrors == 0 ? \'none\' : \'\';
333
					setInnerHTML(document.getElementById(\'error_list\'), numErrors == 0 ? \'\' : errorList.join(\'<br>\'));
334
335
					// Adjust the color of captions if the given data is erroneous.
336
					var captions = errors.getElementsByTagName(\'caption\');
337
					for (var i = 0, numCaptions = errors.getElementsByTagName(\'caption\').length; i < numCaptions; i++)
338
						if (document.getElementById(\'caption_\' + captions[i].getAttribute(\'name\')))
339
							document.getElementById(\'caption_\' + captions[i].getAttribute(\'name\')).className = captions[i].getAttribute(\'class\');
340
341
					if (errors.getElementsByTagName(\'post_error\').length == 1)
342
						document.forms.newsmodify.', $context['post_box_name'], '.style.border = \'1px solid red\';
343
					else if (document.forms.newsmodify.', $context['post_box_name'], '.style.borderColor == \'red\' || document.forms.newsmodify.', $context['post_box_name'], '.style.borderColor == \'red red red red\')
344
					{
345
						if (\'runtimeStyle\' in document.forms.newsmodify.', $context['post_box_name'], ')
346
							document.forms.newsmodify.', $context['post_box_name'], '.style.borderColor = \'\';
347
						else
348
							document.forms.newsmodify.', $context['post_box_name'], '.style.border = null;
349
					}
350
					location.hash = \'#\' + \'preview_section\';
351
				}
352
			</script>';
353
354
	echo '
355
			<script>
356
				function checkboxes_status (item)
357
				{
358
					if (item.id == \'send_html\')
359
						document.getElementById(\'parse_html\').disabled = !document.getElementById(\'parse_html\').disabled;
360
					if (item.id == \'send_pm\')
361
					{
362
						if (!document.getElementById(\'send_html\').checked)
363
							document.getElementById(\'parse_html\').disabled = true;
364
						else
365
							document.getElementById(\'parse_html\').disabled = false;
366
						document.getElementById(\'send_html\').disabled = !document.getElementById(\'send_html\').disabled;
367
					}
368
				}
369
			</script>
370
		</form>';
371
}
372
373
/**
374
 * The page shown while the newsletter is being sent
375
 */
376
function template_email_members_send()
377
{
378
	global $context, $txt, $scripturl;
379
380
	echo '
381
		<form action="', $scripturl, '?action=admin;area=news;sa=mailingsend" method="post" accept-charset="', $context['character_set'], '" name="autoSubmit" id="autoSubmit">
382
			<div class="cat_bar">
383
				<h3 class="catbg">
384
					<a href="', $scripturl, '?action=helpadmin;help=email_members" onclick="return reqOverlayDiv(this.href);" class="help"><span class="main_icons help" title="', $txt['help'], '"></span></a> ', $txt['admin_newsletters'], '
385
				</h3>
386
			</div>
387
			<div class="windowbg">
388
				<div class="progress_bar">
389
					<span>', $context['percentage_done'], '% ', $txt['email_done'], '</span>
390
					<div class="bar" style="width: ', $context['percentage_done'], '%;"></div>
391
				</div>
392
				<hr>
393
				<input type="submit" name="b" value="', $txt['email_continue'], '" class="button">
394
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
395
				<input type="hidden" name="subject" value="', $context['subject'], '">
396
				<input type="hidden" name="message" value="', $context['message'], '">
397
				<input type="hidden" name="start" value="', $context['start'], '">
398
				<input type="hidden" name="total_members" value="', $context['total_members'], '">
399
				<input type="hidden" name="total_emails" value="', $context['total_emails'], '">
400
				<input type="hidden" name="send_pm" value="', $context['send_pm'], '">
401
				<input type="hidden" name="send_html" value="', $context['send_html'], '">
402
				<input type="hidden" name="parse_html" value="', $context['parse_html'], '">';
403
404
	// All the things we must remember!
405
	foreach ($context['recipients'] as $key => $values)
406
		echo '
407
				<input type="hidden" name="', $key, '" value="', implode(($key == 'emails' ? ';' : ','), $values), '">';
408
409
	echo '
410
			</div><!-- .windowbg -->
411
		</form>
412
413
	<script>
414
		var countdown = 2;
415
		doAutoSubmit();
416
417
		function doAutoSubmit()
418
		{
419
			if (countdown == 0)
420
				document.forms.autoSubmit.submit();
421
			else if (countdown == -1)
422
				return;
423
424
			document.forms.autoSubmit.b.value = "', $txt['email_continue'], ' (" + countdown + ")";
425
			countdown--;
426
427
			setTimeout("doAutoSubmit();", 1000);
428
		}
429
	</script>';
430
}
431
432
/**
433
 * The settings page.
434
 */
435
function template_news_lists()
436
{
437
	global $context, $txt;
438
439
	if (!empty($context['saved_successful']))
440
		echo '
441
			<div class="infobox">', $txt['settings_saved'], '</div>';
442
443
	template_show_list('news_lists');
444
}
445
446
?>