Completed
Push — release-2.1 ( b61572...c939ca )
by Mathias
15s
created

Post.template.php ➔ template_announcement_send()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 48
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 0
dl 0
loc 48
rs 9.125
c 0
b 0
f 0
1
<?php
2
/**
3
 * Simple Machines Forum (SMF)
4
 *
5
 * @package SMF
6
 * @author Simple Machines http://www.simplemachines.org
7
 * @copyright 2017 Simple Machines and individual contributors
8
 * @license http://www.simplemachines.org/about/smf/license.php BSD
9
 *
10
 * @version 2.1 Beta 4
11
 */
12
13
/**
14
 * The main template for the post page.
15
 */
16
function template_main()
0 ignored issues
show
Best Practice introduced by
The function template_main() has been defined more than once; this definition is ignored, only the first definition in Themes/default/BoardIndex.template.php (L56-134) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
17
{
18
	global $context, $options, $txt, $scripturl, $modSettings, $counter;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
19
20
	// Start the javascript... and boy is there a lot.
21
	echo '
22
		<script>';
23
24
	// When using Go Back due to fatal_error, allow the form to be re-submitted with changes.
25
	if (isBrowser('is_firefox'))
26
		echo '
27
			window.addEventListener("pageshow", reActivate, false);';
28
29
	// Start with message icons - and any missing from this theme.
30
	echo '
31
			var icon_urls = {';
32
33 View Code Duplication
	foreach ($context['icons'] as $icon)
34
		echo '
35
				\'', $icon['value'], '\': \'', $icon['url'], '\'', $icon['is_last'] ? '' : ',';
36
	echo '
37
			};';
38
39
	// If this is a poll - use some javascript to ensure the user doesn't create a poll with illegal option combinations.
40
	if ($context['make_poll'])
41
		echo '
42
			var pollOptionNum = 0, pollTabIndex;
43
			var pollOptionId = ', $context['last_choice_id'], ';
44
			function addPollOption()
45
			{
46
				if (pollOptionNum == 0)
47
				{
48
					for (var i = 0, n = document.forms.postmodify.elements.length; i < n; i++)
49
						if (document.forms.postmodify.elements[i].id.substr(0, 8) == \'options-\')
50
						{
51
							pollOptionNum++;
52
							pollTabIndex = document.forms.postmodify.elements[i].tabIndex;
53
						}
54
				}
55
				pollOptionNum++
56
				pollOptionId++
57
58
				setOuterHTML(document.getElementById(\'pollMoreOptions\'), ', JavaScriptEscape('<dt><label for="options-'), ' + pollOptionId + ', JavaScriptEscape('">' . $txt['option'] . ' '), ' + pollOptionNum + ', JavaScriptEscape('</label>:</dt><dd><input type="text" name="options['), ' + pollOptionId + ', JavaScriptEscape(']" id="options-'), ' + pollOptionId + ', JavaScriptEscape('" value="" size="80" maxlength="255" tabindex="'), ' + pollTabIndex + ', JavaScriptEscape('"></dd><p id="pollMoreOptions"></p>'), ');
59
			}';
60
61
	// If we are making a calendar event we want to ensure we show the current days in a month etc... this is done here.
62
	if ($context['make_event'])
63
		echo '
64
			var monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];';
65
66
	// End of the javascript, start the form and display the link tree.
67
	echo '
68
		</script>
69
		<form action="', $scripturl, '?action=', $context['destination'], ';', empty($context['current_board']) ? '' : 'board=' . $context['current_board'], '" method="post" accept-charset="', $context['character_set'], '" name="postmodify" id="postmodify" class="flow_hidden" onsubmit="', ($context['becomes_approved'] ? '' : 'alert(\'' . $txt['js_post_will_require_approval'] . '\');'), 'submitonce(this);" enctype="multipart/form-data">';
70
71
	// If the user wants to see how their message looks - the preview section is where it's at!
72
	echo '
73
			<div id="preview_section"', isset($context['preview_message']) ? '' : ' style="display: none;"', '>
74
				<div class="cat_bar">
75
					<h3 class="catbg">
76
						<span id="preview_subject">', empty($context['preview_subject']) ? '&nbsp;' : $context['preview_subject'], '</span>
77
					</h3>
78
				</div>
79
				<div id="preview_body" class="windowbg noup">
80
					', empty($context['preview_message']) ? '<br>' : $context['preview_message'], '
81
				</div>
82
			</div>
83
			<br>';
84
85 View Code Duplication
	if ($context['make_event'] && (!$context['event']['new'] || !empty($context['current_board'])))
86
		echo '
87
			<input type="hidden" name="eventid" value="', $context['event']['id'], '">';
88
89
	// Start the main table.
90
	echo '
91
			<div class="cat_bar">
92
				<h3 class="catbg">', $context['page_title'], '</h3>
93
			</div>
94
			<div id="post_area">
95
				<div class="roundframe noup">', isset($context['current_topic']) ? '
96
					<input type="hidden" name="topic" value="' . $context['current_topic'] . '">' : '';
97
98
	// If an error occurred, explain what happened.
99
	echo '
100
					<div class="', empty($context['error_type']) || $context['error_type'] != 'serious' ? 'noticebox' : 'errorbox', '"', empty($context['post_error']) ? ' style="display: none"' : '', ' id="errors">
101
						<dl>
102
							<dt>
103
								<strong id="error_serious">', $txt['error_while_submitting'], '</strong>
104
							</dt>
105
							<dd class="error" id="error_list">
106
								', empty($context['post_error']) ? '' : implode('<br>', $context['post_error']), '
107
							</dd>
108
						</dl>
109
					</div>';
110
111
	// If this won't be approved let them know!
112
	if (!$context['becomes_approved'])
113
	{
114
		echo '
115
					<div class="noticebox">
116
						<em>', $txt['wait_for_approval'], '</em>
117
						<input type="hidden" name="not_approved" value="1">
118
					</div>';
119
	}
120
121
	// If it's locked, show a message to warn the replier.
122
	if (!empty($context['locked']))
123
	echo '
124
					<div class="errorbox">
125
						', $txt['topic_locked_no_reply'], '
126
					</div>';
127
128
	if (!empty($modSettings['drafts_post_enabled']))
129
		echo '
130
					<div id="draft_section" class="infobox"', isset($context['draft_saved']) ? '' : ' style="display: none;"', '>',
131
						sprintf($txt['draft_saved'], $scripturl . '?action=profile;u=' . $context['user']['id'] . ';area=showdrafts'), '
132
						', (!empty($modSettings['drafts_keep_days']) ? ' <strong>' . sprintf($txt['draft_save_warning'], $modSettings['drafts_keep_days']) . '</strong>' : ''), '
133
					</div>';
134
135
	// The post header... important stuff
136
	echo '
137
					<dl id="post_header">';
138
139
	// All the posting fields (subject, message icon, guest name & email, etc.)
140
	// Mod & theme authors can use the 'integrate_post_end' hook to modify or add to these (see Post.php)
141
	if (!empty($context['posting_fields']) && is_array($context['posting_fields']))
142
	{
143
		foreach ($context['posting_fields'] as $pfid => $pf)
144
		{
145
			echo '
146
						<dt class="clear', !is_numeric($pfid) ? ' pf_' . $pfid : '', '">
147
							', $pf['dt'], '
148
						</dt>
149
						<dd', !is_numeric($pfid) ? ' class="pf_' . $pfid . '"' : '', '>
150
							', preg_replace('~<(input|select|textarea|button|area|a|object)\b~', '<$1 tabindex="' . $context['tabindex']++ . '"', $pf['dd']), '
0 ignored issues
show
Coding Style introduced by
Increment and decrement operators must be bracketed when used in string concatenation
Loading history...
151
						</dd>';
152
		}
153
	}
154
155
	echo '
156
					</dl>';
157
158
	// Are you posting a calendar event?
159
	if ($context['make_event'])
160
	{
161
		echo '
162
					<hr class="clear">
163
					<div id="post_event">
164
						<fieldset id="event_main">
165
							<legend><span', isset($context['post_error']['no_event']) ? ' class="error"' : '', '>', $txt['calendar_event_title'], '</span></legend>
166
							<input type="hidden" name="calendar" value="1">
167
							<div class="event_options_left" id="event_title">
168
								<div>
169
									<input type="text" id="evtitle" name="evtitle" maxlength="255" size="55" value="', $context['event']['title'], '" tabindex="', $context['tabindex']++, '">
170
								</div>
171
							</div>';
172
173
		// If this is a new event let the user specify which board they want the linked post to be put into.
174
		if ($context['event']['new'] && $context['is_new_post'])
175
		{
176
			echo '
177
							<div class="event_options_right" id="event_board">
178
								<div>
179
									<span class="label">', $txt['calendar_post_in'], '</span>
180
								<select name="board">';
181 View Code Duplication
			foreach ($context['event']['categories'] as $category)
182
			{
183
				echo '
184
										<optgroup label="', $category['name'], '">';
185
186
				foreach ($category['boards'] as $board)
187
					echo '
188
											<option value="', $board['id'], '"', $board['selected'] ? ' selected' : '', '>', $board['child_level'] > 0 ? str_repeat('==', $board['child_level'] - 1) . '=&gt;' : '', ' ', $board['name'], '&nbsp;</option>';
189
				echo '
190
										</optgroup>';
191
			}
192
			echo '
193
									</select>
194
								</div>
195
							</div><!-- #event_board -->';
196
		}
197
198
		// Note to theme writers: The JavaScripts expect the input fields for the start and end dates & times to be contained in a wrapper element with the id "event_time_input"
199
		echo '
200
						</fieldset>
201
						<fieldset id="event_options">
202
							<legend>', $txt['calendar_event_options'], '</legend>
203
							<div class="event_options_left" id="event_time_input">
204
								<div>
205
									<span class="label">', $txt['start'], '</span>
206
									<input type="text" name="start_date" id="start_date" maxlength="10" value="', $context['event']['start_date'], '" tabindex="', $context['tabindex']++, '" class="date_input start" data-type="date">
207
									<input type="text" name="start_time" id="start_time" maxlength="11" value="', $context['event']['start_time'], '" tabindex="', $context['tabindex']++, '" class="time_input start" data-type="time"', !empty($context['event']['allday']) ? ' disabled' : '', '>
208
								</div>
209
								<div>
210
									<span class="label">', $txt['end'], '</span>
211
									<input type="text" name="end_date" id="end_date" maxlength="10" value="', $context['event']['end_date'], '" tabindex="', $context['tabindex']++, '" class="date_input end" data-type="date"', $modSettings['cal_maxspan'] == 1 ? ' disabled' : '', '>
212
									<input type="text" name="end_time" id="end_time" maxlength="11" value="', $context['event']['end_time'], '" tabindex="', $context['tabindex']++, '" class="time_input end" data-type="time"', !empty($context['event']['allday']) ? ' disabled' : '', '>
213
								</div>
214
							</div>
215
							<div class="event_options_right" id="event_time_options">
216
								<div id="event_allday">
217
									<label for="allday"><span class="label">', $txt['calendar_allday'], '</span></label>
218
									<input type="checkbox" name="allday" id="allday"', !empty($context['event']['allday']) ? ' checked' : '', ' tabindex="', $context['tabindex']++, '">
219
								</div>
220
								<div id="event_timezone">
221
									<span class="label">', $txt['calendar_timezone'], '</span>
222
									<select name="tz" id="tz"', !empty($context['event']['allday']) ? ' disabled' : '', '>';
223
224 View Code Duplication
		foreach ($context['all_timezones'] as $tz => $tzname)
225
			echo '
226
										<option value="', $tz, '"', $tz == $context['event']['tz'] ? ' selected' : '', '>', $tzname, '</option>';
227
228
		echo '
229
									</select>
230
								</div>
231
							</div><!-- #event_time_options -->
232
							<div>
233
								<span class="label">', $txt['location'], '</span>
234
								<input type="text" name="event_location" id="event_location" maxlength="255" value="', $context['event']['location'], '" tabindex="', $context['tabindex']++, '">
235
							</div>
236
						</fieldset>
237
					</div><!-- #post_event -->';
238
	}
239
240
	// If this is a poll then display all the poll options!
241
	if ($context['make_poll'])
242
	{
243
		echo '
244
					<hr class="clear">
245
					<div id="edit_poll">
246
						<fieldset id="poll_main">
247
							<legend><span ', (isset($context['poll_error']['no_question']) ? ' class="error"' : ''), '>', $txt['poll_question'], '</span></legend>
248
							<dl class="settings poll_options">
249
								<dt>', $txt['poll_question'], '</dt>
250
								<dd>
251
									<input type="text" name="question" value="', isset($context['question']) ? $context['question'] : '', '" tabindex="', $context['tabindex']++, '" size="80">
252
								</dd>';
253
254
		// Loop through all the choices and print them out.
255
		foreach ($context['choices'] as $choice)
256
		{
257
			echo '
258
								<dt>
259
									<label for="options-', $choice['id'], '">', $txt['option'], ' ', $choice['number'], '</label>:
260
								</dt>
261
								<dd>
262
									<input type="text" name="options[', $choice['id'], ']" id="options-', $choice['id'], '" value="', $choice['label'], '" tabindex="', $context['tabindex']++, '" size="80" maxlength="255">
263
								</dd>';
264
		}
265
266
		echo '
267
								<p id="pollMoreOptions"></p>
268
							</dl>
269
							<strong><a href="javascript:addPollOption(); void(0);">(', $txt['poll_add_option'], ')</a></strong>
270
						</fieldset>
271
						<fieldset id="poll_options">
272
							<legend>', $txt['poll_options'], '</legend>
273
							<dl class="settings poll_options">
274
								<dt>
275
									<label for="poll_max_votes">', $txt['poll_max_votes'], ':</label>
276
								</dt>
277
								<dd>
278
									<input type="text" name="poll_max_votes" id="poll_max_votes" size="2" value="', $context['poll_options']['max_votes'], '">
279
								</dd>
280
								<dt>
281
									<label for="poll_expire">', $txt['poll_run'], ':</label><br>
282
									<em class="smalltext">', $txt['poll_run_limit'], '</em>
283
								</dt>
284
								<dd>
285
									<input type="text" name="poll_expire" id="poll_expire" size="2" value="', $context['poll_options']['expire'], '" onchange="pollOptions();" maxlength="4"> ', $txt['days_word'], '
286
								</dd>
287
								<dt>
288
									<label for="poll_change_vote">', $txt['poll_do_change_vote'], ':</label>
289
								</dt>
290
								<dd>
291
									<input type="checkbox" id="poll_change_vote" name="poll_change_vote"', !empty($context['poll']['change_vote']) ? ' checked' : '', '>
292
								</dd>';
293
294 View Code Duplication
		if ($context['poll_options']['guest_vote_enabled'])
295
			echo '
296
								<dt>
297
									<label for="poll_guest_vote">', $txt['poll_guest_vote'], ':</label>
298
								</dt>
299
								<dd>
300
									<input type="checkbox" id="poll_guest_vote" name="poll_guest_vote"', !empty($context['poll_options']['guest_vote']) ? ' checked' : '', '>
301
								</dd>';
302
303
		echo '
304
								<dt>
305
									', $txt['poll_results_visibility'], ':
306
								</dt>
307
								<dd>
308
									<input type="radio" name="poll_hide" id="poll_results_anyone" value="0"', $context['poll_options']['hide'] == 0 ? ' checked' : '', '> <label for="poll_results_anyone">', $txt['poll_results_anyone'], '</label><br>
309
									<input type="radio" name="poll_hide" id="poll_results_voted" value="1"', $context['poll_options']['hide'] == 1 ? ' checked' : '', '> <label for="poll_results_voted">', $txt['poll_results_voted'], '</label><br>
310
									<input type="radio" name="poll_hide" id="poll_results_expire" value="2"', $context['poll_options']['hide'] == 2 ? ' checked' : '', empty($context['poll_options']['expire']) ? ' disabled' : '', '> <label for="poll_results_expire">', $txt['poll_results_after'], '</label>
311
								</dd>
312
							</dl>
313
						</fieldset>
314
					</div><!-- #edit_poll -->';
315
	}
316
317
	// Show the actual posting area...
318
	echo '
319
					', template_control_richedit($context['post_box_name'], 'smileyBox_message', 'bbcBox_message');
0 ignored issues
show
Documentation introduced by
'smileyBox_message' is of type string, but the function expects a null|boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
'bbcBox_message' is of type string, but the function expects a null|boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
320
321
	// If we're editing and displaying edit details, show a box where they can say why
322
	if (isset($context['editing']) && $modSettings['show_modify'])
323
		echo '
324
					<dl>
325
						<dt class="clear">
326
							<span id="caption_edit_reason">', $txt['reason_for_edit'], ':</span>
327
						</dt>
328
						<dd>
329
							<input type="text" name="modify_reason"', isset($context['last_modified_reason']) ? ' value="' . $context['last_modified_reason'] . '"' : '', ' tabindex="', $context['tabindex']++, '" size="80" maxlength="80">
330
						</dd>
331
					</dl>';
332
333
	// If this message has been edited in the past - display when it was.
334
	if (isset($context['last_modified']))
335
		echo '
336
					<div class="padding smalltext">
337
						', $context['last_modified_text'], '
338
					</div>';
339
340
	// If the admin has enabled the hiding of the additional options - show a link and image for it.
341
	if (!empty($modSettings['additional_options_collapsable']))
342
		echo '
343
					<div id="postAdditionalOptionsHeader">
344
						<strong><a href="#" id="postMoreExpandLink"> ', $context['can_post_attachment'] ? $txt['post_additionalopt_attach'] : $txt['post_additionalopt'], '</a></strong>
345
					</div>';
346
347
	echo '
348
					<div id="postAdditionalOptions">';
349
350
	// Display the checkboxes for all the standard options - if they are available to the user!
351
	echo '
352
						<div id="postMoreOptions" class="smalltext">
353
							<ul class="post_options">
354
								', $context['can_notify'] ? '<li><input type="hidden" name="notify" value="0"><label for="check_notify"><input type="checkbox" name="notify" id="check_notify"' . ($context['notify'] || !empty($options['auto_notify']) || $context['auto_notify'] ? ' checked' : '') . ' value="1"> ' . $txt['notify_replies'] . '</label></li>' : '', '
355
								', $context['can_lock'] ? '<li><input type="hidden" name="already_locked" value="' . $context['already_locked'] . '"><input type="hidden" name="lock" value="0"><label for="check_lock"><input type="checkbox" name="lock" id="check_lock"' . ($context['locked'] ? ' checked' : '') . ' value="1"> ' . $txt['lock_topic'] . '</label></li>' : '', '
356
								<li><label for="check_back"><input type="checkbox" name="goback" id="check_back"' . ($context['back_to_topic'] || !empty($options['return_to_post']) ? ' checked' : '') . ' value="1"> ' . $txt['back_to_topic'] . '</label></li>
357
								', $context['can_sticky'] ? '<li><input type="hidden" name="already_sticky" value="' . $context['already_sticky'] . '"><input type="hidden" name="sticky" value="0"><label for="check_sticky"><input type="checkbox" name="sticky" id="check_sticky"' . ($context['sticky'] ? ' checked' : '') . ' value="1"> ' . $txt['sticky_after'] . '</label></li>' : '', '
358
								<li><label for="check_smileys"><input type="checkbox" name="ns" id="check_smileys"', $context['use_smileys'] ? '' : ' checked', ' value="NS"> ', $txt['dont_use_smileys'], '</label></li>', '
359
								', $context['can_move'] ? '<li><input type="hidden" name="move" value="0"><label for="check_move"><input type="checkbox" name="move" id="check_move" value="1"' . (!empty($context['move']) ? ' checked" ' : '') . '> ' . $txt['move_after2'] . '</label></li>' : '', '
360
								', $context['can_announce'] && $context['is_first_post'] ? '<li><label for="check_announce"><input type="checkbox" name="announce_topic" id="check_announce" value="1"' . (!empty($context['announce']) ? ' checked' : '') . '> ' . $txt['announce_topic'] . '</label></li>' : '', '
361
								', $context['show_approval'] ? '<li><label for="approve"><input type="checkbox" name="approve" id="approve" value="2"' . ($context['show_approval'] === 2 ? ' checked' : '') . '> ' . $txt['approve_this_post'] . '</label></li>' : '', '
362
							</ul>
363
						</div><!-- #postMoreOptions -->';
364
365
	// If this post already has attachments on it - give information about them.
366
	if (!empty($context['current_attachments']))
367
	{
368
		echo '
369
						<dl id="postAttachment">
370
							<dt>
371
								', $txt['attached'], ':
372
							</dt>
373
							<dd class="smalltext" style="width: 100%;">
374
								<input type="hidden" name="attach_del[]" value="0">
375
								', $txt['uncheck_unwatchd_attach'], ':
376
							</dd>';
377
378
		foreach ($context['current_attachments'] as $attachment)
379
			echo '
380
							<dd class="smalltext">
381
								<label for="attachment_', $attachment['attachID'], '"><input type="checkbox" id="attachment_', $attachment['attachID'], '" name="attach_del[]" value="', $attachment['attachID'], '"', empty($attachment['unchecked']) ? ' checked' : '', '> ', $attachment['name'], (empty($attachment['approved']) ? ' (' . $txt['awaiting_approval'] . ')' : ''),
382
								!empty($modSettings['attachmentPostLimit']) || !empty($modSettings['attachmentSizeLimit']) ? sprintf($txt['attach_kb'], comma_format(round(max($attachment['size'], 1024) / 1024), 0)) : '', '</label>
383
							</dd>';
384
385
		echo '
386
						</dl>';
387
388
		if (!empty($context['files_in_session_warning']))
389
			echo '
390
						<div class="smalltext">', $context['files_in_session_warning'], '</div>';
391
	}
392
393
	// Is the user allowed to post any additional ones? If so give them the boxes to do it!
394
	if ($context['can_post_attachment'])
395
	{
396
		// Print dropzone UI.
397
		echo '
398
						<div class="files" id="au-previews">
399
							<div id="au-template">
400
								<div class="attach-preview">
401
									<img data-dz-thumbnail />
402
								</div>
403
								<div class="attach-info">
404
									<div>
405
										<span class="name" data-dz-name></span>
406
										<span class="error" data-dz-errormessage></span>
407
										<span class="size" data-dz-size></span>
408
										<span class="message" data-dz-message></span>
409
									</div>
410
									<div class="attached_BBC">
411
										<input type="text" name="attachBBC" value="" readonly>
412
										<div class="attached_BBC_width_height">
413
											<div class="attached_BBC_width">
414
												<label for="attached_BBC_width">', $txt['attached_insertwidth'], '</label>
415
												<input type="number" name="attached_BBC_width" min="0" value="" placeholder="auto">
416
											</div>
417
											<div class="attached_BBC_height">
418
												<label for="attached_BBC_height">', $txt['attached_insertheight'], '</label>
419
												<input type="number" name="attached_BBC_height" min="0" value="" placeholder="auto">
420
											</div>
421
										</div>
422
									</div><!-- .attached_BBC -->
423
									<div class="progressBar" role="progressBar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><span></span></div>
424
									<div class="attach-ui">
425
										<a data-dz-remove class="button cancel">', $txt['modify_cancel'] ,'</a>
426
										<a class="button upload">', $txt['upload'] ,'</a>
427
									</div>
428
								</div><!-- .attach-info -->
429
							</div><!-- #au-template -->
430
						</div><!-- #au-previews -->
431
						<div id ="maxFiles_progress" class="maxFiles_progress progressBar"><span></span></div>
432
						<div id ="maxFiles_progress_text"></div>';
433
434
		echo '
435
						<dl id="postAttachment2">';
436
437
438
		echo '
439
							<dt>
440
								', $txt['attach'], ':
441
							</dt>
442
							<dd class="smalltext fallback">
443
								<div id="attachUpload" class="descbox">
444
									<h5>', $txt['attach_drop_zone'] ,'</h5>
445
									<a class="button" id="attach-cancelAll">', $txt['attached_cancelAll'] ,'</a>
446
									<a class="button" id="attach-uploadAll">', $txt['attached_uploadAll'] ,'</a>
447
									<a class="button fileinput-button">', $txt['attach_add'] ,'</a>
448
									<div id="total-progress" class="progressBar" role="progressBar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><span></span></div>
449
									<div class="fallback">
450
										<input type="file" multiple="multiple" name="attachment[]" id="attachment1" class="fallback"> (<a href="javascript:void(0);" onclick="cleanFileInput(\'attachment1\');">', $txt['clean_attach'], '</a>)
451
								', empty($modSettings['attachmentSizeLimit']) ? '' : ('<input type="hidden" name="MAX_FILE_SIZE" value="' . $modSettings['attachmentSizeLimit'] * 1024 . '">');
452
453
		// Show more boxes if they aren't approaching that limit.
454
		if ($context['num_allowed_attachments'] > 1)
455
			echo '
456
										<script>
457
											var allowed_attachments = ', $context['num_allowed_attachments'], ';
458
											var current_attachment = 1;
459
460
											function addAttachment()
461
											{
462
												allowed_attachments = allowed_attachments - 1;
463
												current_attachment = current_attachment + 1;
464
												if (allowed_attachments <= 0)
465
													return alert("', $txt['more_attachments_error'], '");
466
467
												setOuterHTML(document.getElementById("moreAttachments"), \'<dd class="smalltext"><input type="file" name="attachment[]" id="attachment\' + current_attachment + \'"> (<a href="javascript:void(0);" onclick="cleanFileInput(\\\'attachment\' + current_attachment + \'\\\');">', $txt['clean_attach'], '<\/a>)\' + \'<\/dd><dd class="smalltext" id="moreAttachments"><a href="#" onclick="addAttachment(); return false;">(', $txt['more_attachments'], ')<\' + \'/a><\' + \'/dd>\');
468
469
												return true;
470
											}
471
										</script>
472
										<a href="#" onclick="addAttachment(); return false;">(', $txt['more_attachments'], ')</a>
473
									</div><!-- .fallback -->
474
								</div><!-- #attachUpload -->
475
							</dd>';
476
		else
477
			echo '
478
							</dd>';
479
480
		// Add any template changes for an alternative upload system here.
481
		call_integration_hook('integrate_upload_template');
482
483
		echo '
484
							<dd class="smalltext">';
485
486
		// Show some useful information such as allowed extensions, maximum size and amount of attachments allowed.
487
		if (!empty($modSettings['attachmentCheckExtensions']))
488
			echo '
489
								', $txt['allowed_types'], ': ', $context['allowed_extensions'], '<br>';
490
491
		if (!empty($context['attachment_restrictions']))
492
			echo '
493
								', $txt['attach_restrictions'], ' ', implode(', ', $context['attachment_restrictions']), '<br>';
494
495
		if ($context['num_allowed_attachments'] == 0)
496
			echo '
497
								', $txt['attach_limit_nag'], '<br>';
498
499
		if (!$context['can_post_attachment_unapproved'])
500
			echo '
501
								<span class="alert">', $txt['attachment_requires_approval'], '</span>', '<br>';
502
503
		echo '
504
							</dd>
505
						</dl>';
506
	}
507
508
	echo '
509
					</div><!-- #postAdditionalOptions -->';
510
511
	// If the admin enabled the drafts feature, show a draft selection box
512 View Code Duplication
	if (!empty($modSettings['drafts_post_enabled']) && !empty($context['drafts']) && !empty($options['drafts_show_saved_enabled']))
513
	{
514
		echo '
515
					<div id="postDraftOptionsHeader" class="title_bar title_top">
516
						<h4 class="titlebg">
517
							<span id="postDraftExpand" class="toggle_up floatright" style="display: none;"></span> <strong><a href="#" id="postDraftExpandLink">', $txt['draft_load'], '</a></strong>
518
						</h4>
519
					</div>
520
					<div id="postDraftOptions">
521
						<dl class="settings">
522
							<dt><strong>', $txt['subject'], '</strong></dt>
523
							<dd><strong>', $txt['draft_saved_on'], '</strong></dd>';
524
525
		foreach ($context['drafts'] as $draft)
526
			echo '
527
							<dt>', $draft['link'], '</dt>
528
							<dd>', $draft['poster_time'], '</dd>';
529
		echo '
530
						</dl>
531
					</div>';
532
	}
533
534
	// Is visual verification enabled?
535
	if ($context['require_verification'])
536
	{
537
		echo '
538
					<div class="post_verification">
539
						<span', !empty($context['post_error']['need_qr_verification']) ? ' class="error"' : '', '>
540
							<strong>', $txt['verification'], ':</strong>
541
						</span>
542
						', template_control_verification($context['visual_verification_id'], 'all'), '
543
					</div>';
544
	}
545
546
	// Finally, the submit buttons.
547
	echo '
548
					<br class="clear_right">
549
					<span id="post_confirm_buttons" class="floatright">
550
						', template_control_richedit_buttons($context['post_box_name']);
551
552
	// Option to delete an event if user is editing one.
553
	if ($context['make_event'] && !$context['event']['new'])
554
		echo '
555
						<input type="submit" name="deleteevent" value="', $txt['event_delete'], '" data-confirm="', $txt['event_delete_confirm'] ,'" class="button you_sure">';
556
557
	echo '
558
					</span>
559
				</div><!-- .roundframe -->
560
			</div><!-- #post_area -->
561
			<br class="clear">';
562
563
	// Assuming this isn't a new topic pass across the last message id.
564
	if (isset($context['topic_last_message']))
565
		echo '
566
			<input type="hidden" name="last_msg" value="', $context['topic_last_message'], '">';
567
568
	echo '
569
			<input type="hidden" name="additional_options" id="additional_options" value="', $context['show_additional_options'] ? '1' : '0', '">
570
			<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
571
			<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '">
572
		</form>';
573
574
	echo '
575
		<script>';
576
577
	// The functions used to preview a posts without loading a new page.
578
	echo '
579
			var make_poll = ', $context['make_poll'] ? 'true' : 'false', ';
580
			var txt_preview_title = "', $txt['preview_title'], '";
581
			var txt_preview_fetch = "', $txt['preview_fetch'], '";
582
			var new_replies = new Array();
583
			var reply_counter = ', empty($counter) ? 0 : $counter, ';
584
			function previewPost()
585
			{
586
				if (window.XMLHttpRequest)
587
				{
588
					// Opera didn\'t support setRequestHeader() before 8.01.
589
					if (\'opera\' in window)
590
					{
591
						var test = new XMLHttpRequest();
592
						if (!(\'setRequestHeader\' in test))
593
							return submitThisOnce(document.forms.postmodify);
594
					}
595
					// @todo Currently not sending poll options and option checkboxes.
596
					var x = new Array();
597
					var textFields = [\'subject\', ', JavaScriptEscape($context['post_box_name']), ', ', JavaScriptEscape($context['session_var']), ', \'icon\', \'guestname\', \'email\', \'evtitle\', \'question\', \'topic\'];
598
					var numericFields = [
599
						\'board\', \'topic\', \'last_msg\',
600
						\'eventid\', \'calendar\', \'year\', \'month\', \'day\',
601
						\'poll_max_votes\', \'poll_expire\', \'poll_change_vote\', \'poll_hide\'
602
					];
603
					var checkboxFields = [
604
						\'ns\'
605
					];
606
607
					for (var i = 0, n = textFields.length; i < n; i++)
608
						if (textFields[i] in document.forms.postmodify)
609
						{
610
							// Handle the WYSIWYG editor.
611
							if (textFields[i] == ', JavaScriptEscape($context['post_box_name']), ' && $("#', $context['post_box_name'], '").data("sceditor") != undefined)
612
								x[x.length] = textFields[i] + \'=\' + $("#', $context['post_box_name'], '").data("sceditor").getText().html();
613
							else
614
								x[x.length] = textFields[i] + \'=\' + document.forms.postmodify[textFields[i]].value.html();
615
						}
616
					for (var i = 0, n = numericFields.length; i < n; i++)
617
						if (numericFields[i] in document.forms.postmodify && \'value\' in document.forms.postmodify[numericFields[i]])
618
							x[x.length] = numericFields[i] + \'=\' + parseInt(document.forms.postmodify.elements[numericFields[i]].value);
619
					for (var i = 0, n = checkboxFields.length; i < n; i++)
620
						if (checkboxFields[i] in document.forms.postmodify && document.forms.postmodify.elements[checkboxFields[i]].checked)
621
							x[x.length] = checkboxFields[i] + \'=\' + document.forms.postmodify.elements[checkboxFields[i]].value;
622
623
					sendXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=post2\' + (current_board ? \';board=\' + current_board : \'\') + (make_poll ? \';poll\' : \'\') + \';preview;xml\', x.join(\'&\'), onDocSent);
624
625
					document.getElementById(\'preview_section\').style.display = \'\';
626
					setInnerHTML(document.getElementById(\'preview_subject\'), txt_preview_title);
627
					setInnerHTML(document.getElementById(\'preview_body\'), txt_preview_fetch);
628
629
					return false;
630
				}
631
				else
632
					return submitThisOnce(document.forms.postmodify);
633
			}
634
			function onDocSent(XMLDoc)
635
			{
636
				if (!XMLDoc)
637
				{
638
					document.forms.postmodify.preview.onclick = new function ()
639
					{
640
						return true;
641
					}
642
					document.forms.postmodify.preview.click();
643
				}
644
645
				// Show the preview section.
646
				var preview = XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'preview\')[0];
647
				setInnerHTML(document.getElementById(\'preview_subject\'), preview.getElementsByTagName(\'subject\')[0].firstChild.nodeValue);
648
649
				var bodyText = \'\';
650
				for (var i = 0, n = preview.getElementsByTagName(\'body\')[0].childNodes.length; i < n; i++)
651
					if (preview.getElementsByTagName(\'body\')[0].childNodes[i].nodeValue != null)
652
						bodyText += preview.getElementsByTagName(\'body\')[0].childNodes[i].nodeValue;
653
654
				setInnerHTML(document.getElementById(\'preview_body\'), bodyText);
655
				document.getElementById(\'preview_body\').className = \'windowbg\';
656
657
				// Show a list of errors (if any).
658
				var errors = XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'errors\')[0];
659
				var errorList = new Array();
660
				for (var i = 0, numErrors = errors.getElementsByTagName(\'error\').length; i < numErrors; i++)
661
					errorList[errorList.length] = errors.getElementsByTagName(\'error\')[i].firstChild.nodeValue;
662
				document.getElementById(\'errors\').style.display = numErrors == 0 ? \'none\' : \'\';
663
				document.getElementById(\'errors\').className = errors.getAttribute(\'serious\') == 1 ? \'errorbox\' : \'noticebox\';
664
				document.getElementById(\'error_serious\').style.display = numErrors == 0 ? \'none\' : \'\';
665
				setInnerHTML(document.getElementById(\'error_list\'), numErrors == 0 ? \'\' : errorList.join(\'<br>\'));
666
667
				// Adjust the color of captions if the given data is erroneous.
668
				var captions = errors.getElementsByTagName(\'caption\');
669
				for (var i = 0, numCaptions = errors.getElementsByTagName(\'caption\').length; i < numCaptions; i++)
670
					if (document.getElementById(\'caption_\' + captions[i].getAttribute(\'name\')))
671
						document.getElementById(\'caption_\' + captions[i].getAttribute(\'name\')).className = captions[i].getAttribute(\'class\');
672
673
				if (errors.getElementsByTagName(\'post_error\').length == 1)
674
					document.forms.postmodify.', $context['post_box_name'], '.style.border = \'1px solid red\';
675
				else if (document.forms.postmodify.', $context['post_box_name'], '.style.borderColor == \'red\' || document.forms.postmodify.', $context['post_box_name'], '.style.borderColor == \'red red red red\')
676
				{
677
					if (\'runtimeStyle\' in document.forms.postmodify.', $context['post_box_name'], ')
678
						document.forms.postmodify.', $context['post_box_name'], '.style.borderColor = \'\';
679
					else
680
						document.forms.postmodify.', $context['post_box_name'], '.style.border = null;
681
				}
682
683
				// Set the new last message id.
684
				if (\'last_msg\' in document.forms.postmodify)
685
					document.forms.postmodify.last_msg.value = XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'last_msg\')[0].firstChild.nodeValue;
686
687
				// Remove the new image from old-new replies!
688
				for (i = 0; i < new_replies.length; i++)
689
					document.getElementById(\'image_new_\' + new_replies[i]).style.display = \'none\';
690
				new_replies = new Array();
691
692
				var ignored_replies = new Array(), ignoring;
693
				var newPosts = XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'new_posts\')[0] ? XMLDoc.getElementsByTagName(\'smf\')[0].getElementsByTagName(\'new_posts\')[0].getElementsByTagName(\'post\') : {length: 0};
694
				var numNewPosts = newPosts.length;
695
				if (numNewPosts != 0)
696
				{
697
					var newPostsHTML = \'<span id="new_replies"><\' + \'/span>\';
698
					for (var i = 0; i < numNewPosts; i++)
699
					{
700
						new_replies[new_replies.length] = newPosts[i].getAttribute("id");
701
702
						ignoring = false;
703
						if (newPosts[i].getElementsByTagName("is_ignored")[0].firstChild.nodeValue != 0)
704
							ignored_replies[ignored_replies.length] = ignoring = newPosts[i].getAttribute("id");
705
706
						newPostsHTML += \'<div class="windowbg\' + (++reply_counter % 2 == 0 ? \'2\' : \'\') + \'"><div id="msg\' + newPosts[i].getAttribute("id") + \'"><div class="floatleft"><h5>', $txt['posted_by'], ': \' + newPosts[i].getElementsByTagName("poster")[0].firstChild.nodeValue + \'</h5><span class="smalltext">&#171;&nbsp;<strong>', $txt['on'], ':</strong> \' + newPosts[i].getElementsByTagName("time")[0].firstChild.nodeValue + \'&nbsp;&#187;</span> <span class="new_posts" id="image_new_\' + newPosts[i].getAttribute("id") + \'">', $txt['new'], '</span></div>\';';
707
708
	if ($context['can_quote'])
709
		echo '
710
						newPostsHTML += \'<ul class="quickbuttons" id="msg_\' + newPosts[i].getAttribute("id") + \'_quote"><li><a href="#postmodify" onclick="return insertQuoteFast(\\\'\' + newPosts[i].getAttribute("id") + \'\\\');" class="quote_button"><span>', $txt['quote'], '</span><\' + \'/a></li></ul>\';';
711
712
	echo '
713
						newPostsHTML += \'<br class="clear">\';
714
715
						if (ignoring)
716
							newPostsHTML += \'<div id="msg_\' + newPosts[i].getAttribute("id") + \'_ignored_prompt" class="smalltext">', $txt['ignoring_user'], '<a href="#" id="msg_\' + newPosts[i].getAttribute("id") + \'_ignored_link" style="display: none;">', $txt['show_ignore_user_post'], '</a></div>\';
717
718
						newPostsHTML += \'<div class="list_posts smalltext" id="msg_\' + newPosts[i].getAttribute("id") + \'_body">\' + newPosts[i].getElementsByTagName("message")[0].firstChild.nodeValue + \'<\' + \'/div></div></div>\';
719
					}
720
					setOuterHTML(document.getElementById(\'new_replies\'), newPostsHTML);
721
				}
722
723
				var numIgnoredReplies = ignored_replies.length;
724
				if (numIgnoredReplies != 0)
725
				{
726
					for (var i = 0; i < numIgnoredReplies; i++)
727
					{
728
						aIgnoreToggles[ignored_replies[i]] = new smc_Toggle({
729
							bToggleEnabled: true,
730
							bCurrentlyCollapsed: true,
731
							aSwappableContainers: [
732
								\'msg_\' + ignored_replies[i] + \'_body\',
733
								\'msg_\' + ignored_replies[i] + \'_quote\',
734
							],
735
							aSwapLinks: [
736
								{
737
									sId: \'msg_\' + ignored_replies[i] + \'_ignored_link\',
738
									msgExpanded: \'\',
739
									msgCollapsed: ', JavaScriptEscape($txt['show_ignore_user_post']), '
740
								}
741
							]
742
						});
743
					}
744
				}
745
746
				location.hash = \'#\' + \'preview_section\';
747
748
				if (typeof(smf_codeFix) != \'undefined\')
749
					smf_codeFix();
750
			}';
751
752
	// Code for showing and hiding additional options.
753
	if (!empty($modSettings['additional_options_collapsable']))
754
		echo '
755
			var oSwapAdditionalOptions = new smc_Toggle({
756
				bToggleEnabled: true,
757
				bCurrentlyCollapsed: ', $context['show_additional_options'] ? 'false' : 'true', ',
758
				funcOnBeforeCollapse: function () {
759
					document.getElementById(\'additional_options\').value = \'0\';
760
				},
761
				funcOnBeforeExpand: function () {
762
					document.getElementById(\'additional_options\').value = \'1\';
763
				},
764
				aSwappableContainers: [
765
					\'postAdditionalOptions\',
766
				],
767
				aSwapImages: [
768
					{
769
						sId: \'postMoreExpandLink\',
770
						altExpanded: \'-\',
771
						altCollapsed: \'+\'
772
					}
773
				],
774
				aSwapLinks: [
775
					{
776
						sId: \'postMoreExpandLink\',
777
						msgExpanded: ', JavaScriptEscape($context['can_post_attachment'] ? $txt['post_additionalopt_attach'] : $txt['post_additionalopt']), ',
778
						msgCollapsed: ', JavaScriptEscape($context['can_post_attachment'] ? $txt['post_additionalopt_attach'] : $txt['post_additionalopt']), '
779
					}
780
				]
781
			});';
782
783
	// Code for showing and hiding drafts
784 View Code Duplication
	if (!empty($context['drafts']))
785
		echo '
786
			var oSwapDraftOptions = new smc_Toggle({
787
				bToggleEnabled: true,
788
				bCurrentlyCollapsed: true,
789
				aSwappableContainers: [
790
					\'postDraftOptions\',
791
				],
792
				aSwapImages: [
793
					{
794
						sId: \'postDraftExpand\',
795
						altExpanded: \'-\',
796
						altCollapsed: \'+\'
797
					}
798
				],
799
				aSwapLinks: [
800
					{
801
						sId: \'postDraftExpandLink\',
802
						msgExpanded: ', JavaScriptEscape($txt['draft_hide']), ',
803
						msgCollapsed: ', JavaScriptEscape($txt['draft_load']), '
804
					}
805
				]
806
			});';
807
808
	echo '
809
			var oEditorID = "', $context['post_box_name'] ,'";
810
			var oEditorObject = oEditorHandle_', $context['post_box_name'], ';
811
		</script>';
812
813
	// If the user is replying to a topic show the previous posts.
814
	if (isset($context['previous_posts']) && count($context['previous_posts']) > 0)
815
	{
816
		echo '
817
		<div id="recent" class="flow_hidden main_section">
818
			<div class="cat_bar">
819
				<h3 class="catbg">', $txt['topic_summary'], '</h3>
820
			</div>
821
			<span id="new_replies"></span>';
822
823
		$ignored_posts = array();
824
		foreach ($context['previous_posts'] as $post)
825
		{
826
			$ignoring = false;
827
			if (!empty($post['is_ignored']))
828
				$ignored_posts[] = $ignoring = $post['id'];
829
830
			echo '
831
			<div class="windowbg">
832
				<div id="msg', $post['id'], '">
833
					<h5 class="floatleft">
834
						<span>', $txt['posted_by'], '</span>&nbsp;', $post['poster'], '
835
					</h5>&nbsp;-&nbsp;', $post['time'];
836
837
			if ($context['can_quote'])
838
			{
839
				echo '
840
					<ul class="quickbuttons" id="msg_', $post['id'], '_quote">
841
						<li style="display:none;" id="quoteSelected_', $post['id'], '" data-msgid="', $post['id'], '"><a href="javascript:void(0)"><span class="generic_icons quote_selected"></span>', $txt['quote_selected_action'] ,'</a></li>
842
						<li id="post_modify"><a href="#postmodify" onclick="return insertQuoteFast(', $post['id'], ');"><span class="generic_icons quote"></span>', $txt['quote'], '</a></li>
843
					</ul>';
844
			}
845
846
			echo '
847
					<br class="clear">';
848
849 View Code Duplication
			if ($ignoring)
850
			{
851
				echo '
852
					<div id="msg_', $post['id'], '_ignored_prompt" class="smalltext">
853
						', $txt['ignoring_user'], '
854
						<a href="#" id="msg_', $post['id'], '_ignored_link" style="display: none;">', $txt['show_ignore_user_post'], '</a>
855
					</div>';
856
			}
857
858
			echo '
859
					<div class="list_posts smalltext" id="msg_', $post['id'], '_body" data-msgid="', $post['id'], '">', $post['message'], '</div>
860
				</div><!-- #msg[id] -->
861
			</div><!-- .windowbg -->';
862
		}
863
864
		echo '
865
		</div><!-- #recent -->
866
		<script>
867
			var aIgnoreToggles = new Array();';
868
869
		foreach ($ignored_posts as $post_id)
870
		{
871
			echo '
872
			aIgnoreToggles[', $post_id, '] = new smc_Toggle({
873
				bToggleEnabled: true,
874
				bCurrentlyCollapsed: true,
875
				aSwappableContainers: [
876
					\'msg_', $post_id, '_body\',
877
					\'msg_', $post_id, '_quote\',
878
				],
879
				aSwapLinks: [
880
					{
881
						sId: \'msg_', $post_id, '_ignored_link\',
882
						msgExpanded: \'\',
883
						msgCollapsed: ', JavaScriptEscape($txt['show_ignore_user_post']), '
884
					}
885
				]
886
			});';
887
		}
888
889
		echo '
890
			function insertQuoteFast(messageid)
891
			{
892
				if (window.XMLHttpRequest)
893
					getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + \'action=quotefast;quote=\' + messageid + \';xml;pb=', $context['post_box_name'], ';mode=0\', onDocReceived);
894
				else
895
					reqWin(smf_prepareScriptUrl(smf_scripturl) + \'action=quotefast;quote=\' + messageid + \';pb=', $context['post_box_name'], ';mode=0\', 240, 90);
896
897
				return true;
898
			}
899
			function onDocReceived(XMLDoc)
900
			{
901
				var text = \'\';
902
903
				for (var i = 0, n = XMLDoc.getElementsByTagName(\'quote\')[0].childNodes.length; i < n; i++)
904
					text += XMLDoc.getElementsByTagName(\'quote\')[0].childNodes[i].nodeValue;
905
				$("#', $context['post_box_name'], '").data("sceditor").InsertText(text);
906
			}
907
			function onReceiveOpener(text)
908
			{
909
				$("#', $context['post_box_name'], '").data("sceditor").InsertText(text);
910
			}
911
		</script>';
912
	}
913
}
914
915
/**
916
 * The template for the spellchecker.
917
 */
918
function template_spellcheck()
919
{
920
	global $context, $settings, $txt, $modSettings;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
921
922
	// The style information that makes the spellchecker look... like the forum hopefully!
923
	echo '<!DOCTYPE html>
924
<html', $context['right_to_left'] ? ' dir="rtl"' : '', '>
925
	<head>
926
		<meta charset="', $context['character_set'], '">
927
		<title>', $txt['spell_check'], '</title>
928
		<link rel="stylesheet" href="', $settings['theme_url'], '/css/index', $context['theme_variant'], '.css', $modSettings['browser_cache'] ,'">
929
		<style>
930
			body, td {
931
				font-size: small;
932
				margin: 0;
933
				background: #f0f0f0;
934
				color: #000;
935
				padding: 10px;
936
			}
937
			.highlight {
938
				color: red;
939
				font-weight: bold;
940
			}
941
			#spellview {
942
				border-style: outset;
943
				border: 1px solid black;
944
				padding: 5px;
945
				width: 95%;
946
				height: 314px;
947
				overflow: auto;
948
				background: #ffffff;
949
			}';
950
951
	// As you may expect - we need a lot of javascript for this... load it form the separate files.
952
	echo '
953
		</style>
954
		<script>
955
			var spell_formname = window.opener.spell_formname;
956
			var spell_fieldname = window.opener.spell_fieldname;
957
		</script>
958
		<script src="', $settings['default_theme_url'], '/scripts/spellcheck.js', $modSettings['browser_cache'] ,'"></script>
959
		<script src="', $settings['default_theme_url'], '/scripts/script.js', $modSettings['browser_cache'] ,'"></script>
960
		<script>
961
			', $context['spell_js'], '
962
		</script>
963
	</head>
964
	<body onload="nextWord(false);">
965
		<form action="#" method="post" accept-charset="', $context['character_set'], '" name="spellingForm" id="spellingForm" onsubmit="return false;" style="margin: 0;">
966
			<div id="spellview">&nbsp;</div>
967
			<table width="100%">
968
				<tr class="windowbg">
969
					<td style="width: 50%; vertical-align: top">
970
						', $txt['spellcheck_change_to'], '<br>
971
						<input type="text" name="changeto" style="width: 98%;">
972
					</td>
973
					<td style="width: 50%">
974
						', $txt['spellcheck_suggest'], '<br>
975
						<select name="suggestions" style="width: 98%;" size="5" onclick="if (this.selectedIndex != -1) this.form.changeto.value = this.options[this.selectedIndex].text;" ondblclick="replaceWord();">
976
						</select>
977
					</td>
978
				</tr>
979
			</table>
980
			<div class="righttext" style="padding: 4px;">
981
				<input type="button" name="change" value="', $txt['spellcheck_change'], '" onclick="replaceWord();" class="button">
982
				<input type="button" name="changeall" value="', $txt['spellcheck_change_all'], '" onclick="replaceAll();" class="button">
983
				<input type="button" name="ignore" value="', $txt['spellcheck_ignore'], '" onclick="nextWord(false);" class="button">
984
				<input type="button" name="ignoreall" value="', $txt['spellcheck_ignore_all'], '" onclick="nextWord(true);" class="button">
985
			</div>
986
		</form>
987
	</body>
988
</html>';
989
}
990
991
/**
992
 * The template for the AJAX quote feature
993
 */
994
function template_quotefast()
995
{
996
	global $context, $settings, $txt, $modSettings;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
997
998
	echo '<!DOCTYPE html>
999
<html', $context['right_to_left'] ? ' dir="rtl"' : '', '>
1000
	<head>
1001
		<meta charset="', $context['character_set'], '">
1002
		<title>', $txt['retrieving_quote'], '</title>
1003
		<script src="', $settings['default_theme_url'], '/scripts/script.js', $modSettings['browser_cache'] ,'"></script>
1004
	</head>
1005
	<body>
1006
		', $txt['retrieving_quote'], '
1007
		<div id="temporary_posting_area" style="display: none;"></div>
1008
		<script>';
1009
1010
	if ($context['close_window'])
1011
		echo '
1012
			window.close();';
1013
	else
1014
	{
1015
		// Lucky for us, Internet Explorer has an "innerText" feature which basically converts entities <--> text. Use it if possible ;)
1016
		echo '
1017
			var quote = \'', $context['quote']['text'], '\';
1018
			var stage = \'createElement\' in document ? document.createElement("DIV") : document.getElementById("temporary_posting_area");
1019
1020
			if (\'DOMParser\' in window && !(\'opera\' in window))
1021
			{
1022
				var xmldoc = new DOMParser().parseFromString("<temp>" + \'', $context['quote']['mozilla'], '\'.replace(/\n/g, "_SMF-BREAK_").replace(/\t/g, "_SMF-TAB_") + "</temp>", "text/xml");
1023
				quote = xmldoc.childNodes[0].textContent.replace(/_SMF-BREAK_/g, "\n").replace(/_SMF-TAB_/g, "\t");
1024
			}
1025
			else if (\'innerText\' in stage)
1026
			{
1027
				setInnerHTML(stage, quote.replace(/\n/g, "_SMF-BREAK_").replace(/\t/g, "_SMF-TAB_").replace(/</g, "&lt;").replace(/>/g, "&gt;"));
1028
				quote = stage.innerText.replace(/_SMF-BREAK_/g, "\n").replace(/_SMF-TAB_/g, "\t");
1029
			}
1030
1031
			if (\'opera\' in window)
1032
				quote = quote.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, \'"\').replace(/&amp;/g, "&");
1033
1034
			window.opener.onReceiveOpener(quote);
1035
1036
			window.focus();
1037
			setTimeout("window.close();", 400);';
1038
	}
1039
	echo '
1040
		</script>
1041
	</body>
1042
</html>';
1043
}
1044
1045
/**
1046
 * The form for sending out an announcement
1047
 */
1048
function template_announce()
1049
{
1050
	global $context, $txt, $scripturl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1051
1052
	echo '
1053
	<div id="announcement">
1054
		<form action="', $scripturl, '?action=announce;sa=send" method="post" accept-charset="', $context['character_set'], '">
1055
			<div class="cat_bar">
1056
				<h3 class="catbg">', $txt['announce_title'], '</h3>
1057
			</div>
1058
			<div class="information">
1059
				', $txt['announce_desc'], '
1060
			</div>
1061
			<div class="windowbg2">
1062
				<p>
1063
					', $txt['announce_this_topic'], ' <a href="', $scripturl, '?topic=', $context['current_topic'], '.0">', $context['topic_subject'], '</a>
1064
				</p>
1065
				<ul>';
1066
1067 View Code Duplication
	foreach ($context['groups'] as $group)
1068
		echo '
1069
					<li>
1070
						<label for="who_', $group['id'], '"><input type="checkbox" name="who[', $group['id'], ']" id="who_', $group['id'], '" value="', $group['id'], '" checked> ', $group['name'], '</label> <em>(', $group['member_count'], ')</em>
1071
					</li>';
1072
1073
	echo '
1074
					<li>
1075
						<label for="checkall"><input type="checkbox" id="checkall" onclick="invertAll(this, this.form);" checked> <em>', $txt['check_all'], '</em></label>
1076
					</li>
1077
				</ul>
1078
				<hr>
1079
				<div id="confirm_buttons">
1080
					<input type="submit" value="', $txt['post'], '" class="button">
1081
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
1082
					<input type="hidden" name="topic" value="', $context['current_topic'], '">
1083
					<input type="hidden" name="move" value="', $context['move'], '">
1084
					<input type="hidden" name="goback" value="', $context['go_back'], '">
1085
				</div>
1086
				<br class="clear_right">
1087
			</div><!-- .windowbg2 -->
1088
		</form>
1089
	</div><!-- #announcement -->
1090
	<br>';
1091
}
1092
1093
/**
1094
 * The confirmation/progress page, displayed after the admin has clicked the button to send the announcement.
1095
 */
1096
function template_announcement_send()
1097
{
1098
	global $context, $txt, $scripturl;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1099
1100
	echo '
1101
	<div id="announcement">
1102
		<form action="' . $scripturl . '?action=announce;sa=send" method="post" accept-charset="', $context['character_set'], '" name="autoSubmit" id="autoSubmit">
1103
			<div class="windowbg2">
1104
				<p>
1105
					', $txt['announce_sending'], ' <a href="', $scripturl, '?topic=', $context['current_topic'], '.0" target="_blank">', $context['topic_subject'], '</a>
1106
				</p>
1107
				<div class="progress_bar">
1108
					<div class="full_bar">', $context['percentage_done'], '% ', $txt['announce_done'], '</div>
1109
					<div class="green_percent" style="width: ', $context['percentage_done'], '%;">&nbsp;</div>
1110
				</div>
1111
				<hr>
1112
				<div id="confirm_buttons">
1113
					<input type="submit" name="b" value="', $txt['announce_continue'], '" class="button">
1114
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
1115
					<input type="hidden" name="topic" value="', $context['current_topic'], '">
1116
					<input type="hidden" name="move" value="', $context['move'], '">
1117
					<input type="hidden" name="goback" value="', $context['go_back'], '">
1118
					<input type="hidden" name="start" value="', $context['start'], '">
1119
					<input type="hidden" name="membergroups" value="', $context['membergroups'], '">
1120
				</div>
1121
				<br class="clear_right">
1122
			</div><!-- .windowbg2 -->
1123
		</form>
1124
	</div><!-- #announcement -->
1125
	<br>
1126
	<script>
1127
		var countdown = 2;
1128
		doAutoSubmit();
1129
1130
		function doAutoSubmit()
1131
		{
1132
			if (countdown == 0)
1133
				document.forms.autoSubmit.submit();
1134
			else if (countdown == -1)
1135
				return;
1136
1137
			document.forms.autoSubmit.b.value = "', $txt['announce_continue'], ' (" + countdown + ")";
1138
			countdown--;
1139
1140
			setTimeout("doAutoSubmit();", 1000);
1141
		}
1142
	</script>';
1143
}
1144
1145
?>