Completed
Pull Request — release-2.1 (#4470)
by Fran
12:04
created

Profile.template.php ➔ template_error_message()   B

Complexity

Conditions 6
Paths 2

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 12
nc 2
nop 0
dl 0
loc 25
rs 8.439
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
 * Minor stuff shown above the main profile - mostly used for error messages and showing that the profile update was successful.
15
 */
16
function template_profile_above()
17
{
18
	global $context;
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
	// Prevent Chrome from auto completing fields when viewing/editing other members profiles
21
	if (isBrowser('is_chrome') && !$context['user']['is_owner'])
22
		echo '
23
			<script>
24
				disableAutoComplete();
25
			</script>';
26
27
	// If an error occurred while trying to save previously, give the user a clue!
28
	echo '
29
			', template_error_message();
30
31
	// If the profile was update successfully, let the user know this.
32
	if (!empty($context['profile_updated']))
33
		echo '
34
			<div class="infobox">
35
				', $context['profile_updated'], '
36
			</div>';
37
}
38
39
/**
40
 * Template for any HTML needed below the profile (closing off divs/tables, etc.)
41
 */
42
function template_profile_below()
43
{
44
}
45
46
/**
47
 * Template for showing off the spiffy popup of the menu
48
 */
49
function template_profile_popup()
50
{
51
	global $context, $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...
52
53
	// Unlike almost every other template, this is designed to be included into the HTML directly via $().load()
54
55
	echo '
56
		<div class="profile_user_avatar floatleft">
57
			<a href="', $scripturl, '?action=profile;u=', $context['user']['id'], '">', $context['member']['avatar']['image'], '</a>
58
		</div>
59
		<div class="profile_user_info floatleft">
60
			<span class="profile_username"><a href="', $scripturl, '?action=profile;u=', $context['user']['id'], '">', $context['user']['name'], '</a></span>
61
			<span class="profile_group">', $context['member']['group'], '</span>
62
		</div>
63
		<div class="profile_user_links">
64
			<ol>';
65
66
	$menu_context = &$context[$context['profile_menu_name']];
67
	foreach ($context['profile_items'] as $item)
68
	{
69
		$area = &$menu_context['sections'][$item['menu']]['areas'][$item['area']];
70
		$item_url = (isset($item['url']) ? $item['url'] : (isset($area['url']) ? $area['url'] : $menu_context['base_url'] . ';area=' . $item['area'])) . $menu_context['extra_parameters'];
71
		echo '
72
				<li>
73
					', $area['icon'], '<a href="', $item_url, '">', !empty($item['title']) ? $item['title'] : $area['label'], '</a>
74
				</li>';
75
	}
76
77
	echo '
78
			</ol>
79
		</div><!-- .profile_user_links -->';
80
}
81
82
/**
83
 * The "popup" showing the user's alerts
84
 */
85
function template_alerts_popup()
86
{
87
	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...
88
89
	// Unlike almost every other template, this is designed to be included into the HTML directly via $().load()
90
	echo '
91
		<div class="alert_bar">
92
			<div class="alerts_opts block">
93
				<a href="' . $scripturl . '?action=profile;area=notification;sa=markread;', $context['session_var'], '=', $context['session_id'], '" onclick="return markAlertsRead(this)">', $txt['mark_alerts_read'], '</a>
94
				<a href="', $scripturl, '?action=profile;area=notification;sa=alerts" class="floatright">', $txt['alert_settings'], '</a>
95
			</div>
96
			<div class="alerts_box centertext">
97
				<a href="', $scripturl, '?action=profile;area=showalerts" class="button">', $txt['all_alerts'], '</a>
98
			</div>
99
		</div>
100
		<div class="alerts_unread">';
101
102
	if (empty($context['unread_alerts']))
103
		template_alerts_all_read();
104
105
	else
106
	{
107
		foreach ($context['unread_alerts'] as $id_alert => $details)
108
			echo '
109
			<div class="unread">
110
				', !empty($details['sender']) ? $details['sender']['avatar']['image'] : '', '
111
				<div class="details">
112
					', !empty($details['icon']) ? $details['icon'] : '', '<span>', $details['text'], '</span> - ', $details['time'], '
113
				</div>
114
			</div>';
115
	}
116
117
	echo '
118
		</div><!-- .alerts_unread -->
119
		<script>
120
			function markAlertsRead(obj) {
121
				ajax_indicator(true);
122
				$.get(
123
					obj.href,
124
					function(data) {
125
						ajax_indicator(false);
126
						$("#alerts_menu_top span.amt").remove();
127
						$("#alerts_menu div.alerts_unread").html(data);
128
					}
129
				);
130
				return false;
131
			}
132
		</script>';
133
}
134
135
/**
136
 * A simple template to say "You don't have any unread alerts".
137
 */
138
function template_alerts_all_read()
139
{
140
	global $txt;
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...
141
142
	echo '<div class="no_unread">', $txt['alerts_no_unread'], '</div>';
143
}
144
145
/**
146
 * This template displays a user's details without any option to edit them.
147
 */
148
function template_summary()
149
{
150
	global $context, $settings, $scripturl, $modSettings, $txt;
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...
151
152
	// Display the basic information about the user
153
	echo '
154
	<div id="profileview" class="roundframe flow_auto noup">
155
		<div id="basicinfo">';
156
157
	// Are there any custom profile fields for above the name?
158 View Code Duplication
	if (!empty($context['print_custom_fields']['above_member']))
159
	{
160
		echo '
161
			<div class="custom_fields_above_name">
162
				<ul>';
163
164
		foreach ($context['print_custom_fields']['above_member'] as $field)
165
			if (!empty($field['output_html']))
166
				echo '
167
					<li>', $field['output_html'], '</li>';
168
169
		echo '
170
				</ul>
171
			</div>
172
			<br>';
173
	}
174
175
	echo '
176
			<div class="username clear">
177
				<h4>';
178
179 View Code Duplication
	if (!empty($context['print_custom_fields']['before_member']))
180
		foreach ($context['print_custom_fields']['before_member'] as $field)
181
			if (!empty($field['output_html']))
182
				echo '
183
					<span>', $field['output_html'], '</span>';
184
185
	echo '
186
					', $context['member']['name'];
187
188 View Code Duplication
	if (!empty($context['print_custom_fields']['after_member']))
189
		foreach ($context['print_custom_fields']['after_member'] as $field)
190
			if (!empty($field['output_html']))
191
				echo '
192
					<span>', $field['output_html'], '</span>';
193
194
195
	echo '
196
					<span class="position">', (!empty($context['member']['group']) ? $context['member']['group'] : $context['member']['post_group']), '</span>
197
				</h4>
198
			</div>
199
			', $context['member']['avatar']['image'];
200
201
	// Are there any custom profile fields for below the avatar?
202 View Code Duplication
	if (!empty($context['print_custom_fields']['below_avatar']))
203
	{
204
		echo '
205
			<div class="custom_fields_below_avatar">
206
				<ul>';
207
208
		foreach ($context['print_custom_fields']['below_avatar'] as $field)
209
			if (!empty($field['output_html']))
210
				echo '
211
					<li>', $field['output_html'], '</li>';
212
213
		echo '
214
				</ul>
215
			</div>
216
			<br>';
217
	}
218
219
	echo '
220
			<ul class="clear">';
221
222
	// Email is only visible if it's your profile or you have the moderate_forum permission
223 View Code Duplication
	if ($context['member']['show_email'])
224
		echo '
225
				<li><a href="mailto:', $context['member']['email'], '" title="', $context['member']['email'], '" rel="nofollow"><span class="generic_icons mail" title="' . $txt['email'] . '"></span></a></li>';
226
227
	// Don't show an icon if they haven't specified a website.
228 View Code Duplication
	if ($context['member']['website']['url'] !== '' && !isset($context['disabled_fields']['website']))
229
		echo '
230
				<li><a href="', $context['member']['website']['url'], '" title="' . $context['member']['website']['title'] . '" target="_blank" rel="noopener">', ($settings['use_image_buttons'] ? '<span class="generic_icons www" title="' . $context['member']['website']['title'] . '"></span>' : $txt['www']), '</a></li>';
231
232
	// Are there any custom profile fields as icons?
233
	if (!empty($context['print_custom_fields']['icons']))
234
	{
235
		foreach ($context['print_custom_fields']['icons'] as $field)
236
			if (!empty($field['output_html']))
237
				echo '
238
				<li class="custom_field">', $field['output_html'], '</li>';
239
	}
240
241
	echo '
242
			</ul>
243
			<span id="userstatus">
244
				', $context['can_send_pm'] ? '<a href="' . $context['member']['online']['href'] . '" title="' . $context['member']['online']['text'] . '" rel="nofollow">' : '', $settings['use_image_buttons'] ? '<span class="' . ($context['member']['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $context['member']['online']['text'] . '"></span>' : $context['member']['online']['label'], $context['can_send_pm'] ? '</a>' : '', $settings['use_image_buttons'] ? '<span class="smalltext"> ' . $context['member']['online']['label'] . '</span>' : '';
245
246
	// Can they add this member as a buddy?
247
	if (!empty($context['can_have_buddy']) && !$context['user']['is_owner'])
248
		echo '
249
				<br>
250
				<a href="', $scripturl, '?action=buddy;u=', $context['id_member'], ';', $context['session_var'], '=', $context['session_id'], '">[', $txt['buddy_' . ($context['member']['is_buddy'] ? 'remove' : 'add')], ']</a>';
251
252
	echo '
253
			</span>';
254
255
	if (!$context['user']['is_owner'] && $context['can_send_pm'])
256
		echo '
257
			<a href="', $scripturl, '?action=pm;sa=send;u=', $context['id_member'], '" class="infolinks">', $txt['profile_sendpm_short'], '</a>';
258
259
	echo '
260
			<a href="', $scripturl, '?action=profile;area=showposts;u=', $context['id_member'], '" class="infolinks">', $txt['showPosts'], '</a>';
261
262
	if ($context['user']['is_owner'] && !empty($modSettings['drafts_post_enabled']))
263
		echo '
264
			<a href="', $scripturl, '?action=profile;area=showdrafts;u=', $context['id_member'], '" class="infolinks">', $txt['drafts_show'], '</a>';
265
266
	echo '
267
			<a href="', $scripturl, '?action=profile;area=statistics;u=', $context['id_member'], '" class="infolinks">', $txt['statPanel'], '</a>';
268
269
	// Are there any custom profile fields for bottom?
270 View Code Duplication
	if (!empty($context['print_custom_fields']['bottom_poster']))
271
	{
272
		echo '
273
			<div class="custom_fields_bottom">
274
				<ul class="nolist">';
275
276
		foreach ($context['print_custom_fields']['bottom_poster'] as $field)
277
			if (!empty($field['output_html']))
278
				echo '
279
					<li>', $field['output_html'], '</li>';
280
281
		echo '
282
				</ul>
283
			</div>';
284
	}
285
286
	echo '
287
		</div><!-- #basicinfo -->
288
289
		<div id="detailedinfo">
290
			<dl class="settings">';
291
292
	if ($context['user']['is_owner'] || $context['user']['is_admin'])
293
		echo '
294
				<dt>', $txt['username'], ': </dt>
295
				<dd>', $context['member']['username'], '</dd>';
296
297
	if (!isset($context['disabled_fields']['posts']))
298
		echo '
299
				<dt>', $txt['profile_posts'], ': </dt>
300
				<dd>', $context['member']['posts'], ' (', $context['member']['posts_per_day'], ' ', $txt['posts_per_day'], ')</dd>';
301
302 View Code Duplication
	if ($context['member']['show_email'])
303
		echo '
304
				<dt>', $txt['email'], ': </dt>
305
				<dd><a href="mailto:', $context['member']['email'], '">', $context['member']['email'], '</a></dd>';
306
307
	if (!empty($modSettings['titlesEnable']) && !empty($context['member']['title']))
308
		echo '
309
				<dt>', $txt['custom_title'], ': </dt>
310
				<dd>', $context['member']['title'], '</dd>';
311
312
	if (!empty($context['member']['blurb']))
313
		echo '
314
				<dt>', $txt['personal_text'], ': </dt>
315
				<dd>', $context['member']['blurb'], '</dd>';
316
317
	echo '
318
				<dt>', $txt['age'], ':</dt>
319
				<dd>', $context['member']['age'] . ($context['member']['today_is_birthday'] ? ' &nbsp; <img src="' . $settings['images_url'] . '/cake.png" alt="">' : ''), '</dd>';
320
321
	echo '
322
			</dl>';
323
324
	// Any custom fields for standard placement?
325
	if (!empty($context['print_custom_fields']['standard']))
326
	{
327
		$fields = array();
328
329
		foreach ($context['print_custom_fields']['standard'] as $field)
330
			if (!empty($field['output_html']))
331
				$fields[] = $field;
332
333
		if (count($fields) > 0)
334
		{
335
			echo '
336
			<dl class="settings">';
337
338
			foreach ($fields as $field)
339
				echo '
340
				<dt>', $field['name'], ':</dt>
341
				<dd>', $field['output_html'], '</dd>';
342
343
			echo '
344
			</dl>';
345
		}
346
347
	}
348
349
	echo '
350
			<dl class="settings noborder">';
351
352
	// Can they view/issue a warning?
353
	if ($context['can_view_warning'] && $context['member']['warning'])
354
	{
355
		echo '
356
				<dt>', $txt['profile_warning_level'], ': </dt>
357
				<dd>
358
					<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=', ($context['can_issue_warning'] && !$context['user']['is_owner'] ? 'issuewarning' : 'viewwarning'), '">', $context['member']['warning'], '%</a>';
359
360
		// Can we provide information on what this means?
361
		if (!empty($context['warning_status']))
362
			echo '
363
					<span class="smalltext">(', $context['warning_status'], ')</span>';
364
365
		echo '
366
				</dd>';
367
	}
368
369
	// Is this member requiring activation and/or banned?
370
	if (!empty($context['activate_message']) || !empty($context['member']['bans']))
371
	{
372
373
		// If the person looking at the summary has permission, and the account isn't activated, give the viewer the ability to do it themselves.
374
		if (!empty($context['activate_message']))
375
			echo '
376
				<dt class="clear">
377
					<span class="alert">', $context['activate_message'], '</span> (<a href="', $context['activate_link'], '"', ($context['activate_type'] == 4 ? ' class="you_sure" data-confirm="' . $txt['profileConfirm'] . '"' : ''), '>', $context['activate_link_text'], '</a>)
378
				</dt>';
379
380
		// If the current member is banned, show a message and possibly a link to the ban.
381
		if (!empty($context['member']['bans']))
382
		{
383
			echo '
384
				<dt class="clear">
385
					<span class="alert">', $txt['user_is_banned'], '</span>&nbsp;[<a href="#" onclick="document.getElementById(\'ban_info\').style.display = document.getElementById(\'ban_info\').style.display == \'none\' ? \'\' : \'none\';return false;">' . $txt['view_ban'] . '</a>]
386
				</dt>
387
				<dt class="clear" id="ban_info" style="display: none;">
388
					<strong>', $txt['user_banned_by_following'], ':</strong>';
389
390
			foreach ($context['member']['bans'] as $ban)
391
				echo '
392
					<br>
393
					<span class="smalltext">', $ban['explanation'], '</span>';
394
395
			echo '
396
				</dt>';
397
		}
398
	}
399
400
	echo '
401
				<dt>', $txt['date_registered'], ': </dt>
402
				<dd>', $context['member']['registered'], '</dd>';
403
404
	// If the person looking is allowed, they can check the members IP address and hostname.
405
	if ($context['can_see_ip'])
406
	{
407
		if (!empty($context['member']['ip']))
408
		echo '
409
				<dt>', $txt['ip'], ': </dt>
410
				<dd><a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['member']['ip'], ';u=', $context['member']['id'], '">', $context['member']['ip'], '</a></dd>';
411
412
		if (empty($modSettings['disableHostnameLookup']) && !empty($context['member']['ip']))
413
			echo '
414
				<dt>', $txt['hostname'], ': </dt>
415
				<dd>', $context['member']['hostname'], '</dd>';
416
	}
417
418
	echo '
419
				<dt>', $txt['local_time'], ':</dt>
420
				<dd>', $context['member']['local_time'], '</dd>';
421
422
	if (!empty($modSettings['userLanguage']) && !empty($context['member']['language']))
423
		echo '
424
				<dt>', $txt['language'], ':</dt>
425
				<dd>', $context['member']['language'], '</dd>';
426
427
	if ($context['member']['show_last_login'])
428
		echo '
429
				<dt>', $txt['lastLoggedIn'], ': </dt>
430
				<dd>', $context['member']['last_login'], (!empty($context['member']['is_hidden']) ? ' (' . $txt['hidden'] . ')' : ''), '</dd>';
431
432
	echo '
433
			</dl>';
434
435
	// Are there any custom profile fields for above the signature?
436 View Code Duplication
	if (!empty($context['print_custom_fields']['above_signature']))
437
	{
438
		echo '
439
			<div class="custom_fields_above_signature">
440
				<ul class="nolist">';
441
442
		foreach ($context['print_custom_fields']['above_signature'] as $field)
443
			if (!empty($field['output_html']))
444
				echo '
445
					<li>', $field['output_html'], '</li>';
446
447
		echo '
448
				</ul>
449
			</div>';
450
	}
451
452
	// Show the users signature.
453 View Code Duplication
	if ($context['signature_enabled'] && !empty($context['member']['signature']))
454
		echo '
455
			<div class="signature">
456
				<h5>', $txt['signature'], ':</h5>
457
				', $context['member']['signature'], '
458
			</div>';
459
460
	// Are there any custom profile fields for below the signature?
461 View Code Duplication
	if (!empty($context['print_custom_fields']['below_signature']))
462
	{
463
		echo '
464
			<div class="custom_fields_below_signature">
465
				<ul class="nolist">';
466
467
		foreach ($context['print_custom_fields']['below_signature'] as $field)
468
			if (!empty($field['output_html']))
469
				echo '
470
					<li>', $field['output_html'], '</li>';
471
472
		echo '
473
				</ul>
474
			</div>';
475
	}
476
477
	echo '
478
		</div><!-- #detailedinfo -->
479
	</div><!-- #profileview -->';
480
}
481
482
/**
483
 * Template for showing all the posts of the user, in chronological order.
484
 */
485
function template_showPosts()
486
{
487
	global $context, $scripturl, $txt;
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...
488
489
	echo '
490
		<div class="cat_bar">
491
			<h3 class="catbg">
492
				', (!isset($context['attachments']) && empty($context['is_topics']) ? $txt['showMessages'] : (!empty($context['is_topics']) ? $txt['showTopics'] : $txt['showAttachments'])), ' - ', $context['member']['name'], '
493
			</h3>
494
		</div>', !empty($context['page_index']) ? '
495
		<div class="pagesection">
496
			<div class="pagelinks">' . $context['page_index'] . '</div>
497
		</div>' : '';
498
499
	// Are we displaying posts or attachments?
500
	if (!isset($context['attachments']))
501
	{
502
		// For every post to be displayed, give it its own div, and show the important details of the post.
503
		foreach ($context['posts'] as $post)
504
		{
505
			echo '
506
		<div class="', $post['css_class'], '">
507
			<div class="counter">', $post['counter'], '</div>
508
			<div class="topic_details">
509
				<h5>
510
					<strong><a href="', $scripturl, '?board=', $post['board']['id'], '.0">', $post['board']['name'], '</a> / <a href="', $scripturl, '?topic=', $post['topic'], '.', $post['start'], '#msg', $post['id'], '">', $post['subject'], '</a></strong>
511
				</h5>
512
				<span class="smalltext">', $post['time'], '</span>
513
			</div>
514
			<div class="list_posts">';
515
516
			if (!$post['approved'])
517
				echo '
518
				<div class="approve_post">
519
					<em>', $txt['post_awaiting_approval'], '</em>
520
				</div>';
521
522
			echo '
523
				', $post['body'], '
524
			</div>';
525
526
			if ($post['can_reply'] || $post['can_quote'] || $post['can_delete'])
527
				echo '
528
			<div class="floatright">
529
				<ul class="quickbuttons">';
530
531
			// If they *can* reply?
532 View Code Duplication
			if ($post['can_reply'])
533
				echo '
534
					<li><a href="', $scripturl, '?action=post;topic=', $post['topic'], '.', $post['start'], '"><span class="generic_icons reply_button"></span>', $txt['reply'], '</a></li>';
535
536
			// If they *can* quote?
537 View Code Duplication
			if ($post['can_quote'])
538
				echo '
539
					<li><a href="', $scripturl . '?action=post;topic=', $post['topic'], '.', $post['start'], ';quote=', $post['id'], '"><span class="generic_icons quote"></span>', $txt['quote_action'], '</a></li>';
540
541
			// How about... even... remove it entirely?!
542 View Code Duplication
			if ($post['can_delete'])
543
				echo '
544
					<li><a href="', $scripturl, '?action=deletemsg;msg=', $post['id'], ';topic=', $post['topic'], ';profile;u=', $context['member']['id'], ';start=', $context['start'], ';', $context['session_var'], '=', $context['session_id'], '" data-confirm="', $txt['remove_message'], '" class="you_sure"><span class="generic_icons remove_button"></span>', $txt['remove'], '</a></li>';
545
546
			if ($post['can_reply'] || $post['can_quote'] || $post['can_delete'])
547
				echo '
548
				</ul>
549
			</div><!-- .floatright -->';
550
551
			echo '
552
		</div><!-- $post[css_class] -->';
553
		}
554
	}
555
	else
556
		template_show_list('attachments');
557
558
	// No posts? Just end with a informative message.
559
	if ((isset($context['attachments']) && empty($context['attachments'])) || (!isset($context['attachments']) && empty($context['posts'])))
560
		echo '
561
		<div class="windowbg2">
562
			', isset($context['attachments']) ? $txt['show_attachments_none'] : ($context['is_topics'] ? $txt['show_topics_none'] : $txt['show_posts_none']), '
563
		</div>';
564
565
	// Show more page numbers.
566
	if (!empty($context['page_index']))
567
		echo '
568
		<div class="pagesection">
569
			<div class="pagelinks">', $context['page_index'], '</div>
570
		</div>';
571
}
572
573
/**
574
 * Template for showing alerts within the alerts popup
575
 */
576
function template_showAlerts()
577
{
578
	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...
579
580
	// Do we have an update message?
581
	if (!empty($context['update_message']))
582
		echo '
583
		<div class="infobox">
584
			', $context['update_message'], '.
585
		</div>';
586
587
	echo '
588
		<div class="cat_bar">
589
			<h3 class="catbg">
590
			', $txt['alerts'], ' - ', $context['member']['name'], '
591
			</h3>
592
		</div>';
593
594
	if (empty($context['alerts']))
595
		echo '
596
		<div class="information">
597
			', $txt['alerts_none'], '
598
		</div>';
599
600
	else
601
	{
602
		// Start the form.
603
		echo '
604
		<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=showalerts;save" method="post" accept-charset="', $context['character_set'], '" id="mark_all">
605
			<table id="alerts" class="table_grid">';
606
607
		foreach ($context['alerts'] as $id => $alert)
608
		{
609
			echo '
610
				<tr class="windowbg">
611
					<td>', $alert['text'], '</td>
612
					<td>', $alert['time'], '</td>
613
					<td>
614
						<ul class="quickbuttons">
615
							<li><a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=showalerts;do=remove;aid=', $id, ';', $context['session_var'], '=', $context['session_id'], '" class="you_sure"><span class="generic_icons remove_button"></span>', $txt['delete'], '</a></li>
616
							<li><a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=showalerts;do=', ($alert['is_read'] != 0 ? 'unread' : 'read'), ';aid=', $id, ';', $context['session_var'], '=', $context['session_id'], '"><span class="generic_icons ', $alert['is_read'] != 0 ? 'unread_button' : 'read_button', '"></span>', ($alert['is_read'] != 0 ? $txt['mark_unread'] : $txt['mark_read_short']), '</a></li>
617
							<li><input type="checkbox" name="mark[', $id, ']" value="', $id, '"></li>
618
						</ul>
619
					</td>
620
				</tr>';
621
		}
622
623
		echo '
624
			</table>
625
			<div class="pagesection">
626
				<div class="floatleft">
627
					', $context['pagination'], '
628
				</div>
629
				<div class="floatright">
630
					', $txt['check_all'], ': <input type="checkbox" name="select_all" id="select_all">
631
					<select name="mark_as">
632
						<option value="read">', $txt['quick_mod_markread'], '</option>
633
						<option value="unread">', $txt['quick_mod_markunread'], '</option>
634
						<option value="remove">', $txt['quick_mod_remove'], '</option>
635
					</select>
636
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
637
					<input type="submit" name="req" value="', $txt['quick_mod_go'], '" class="button you_sure">
638
				</div>
639
			</div>
640
		</form>';
641
	}
642
}
643
644
/**
645
 * Template for showing all of a user's drafts
646
 */
647
function template_showDrafts()
648
{
649
	global $context, $scripturl, $txt;
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...
650
651
	echo '
652
		<div class="cat_bar">
653
			<h3 class="catbg">
654
				', $txt['drafts'], ' - ', $context['member']['name'], '
655
			</h3>
656
		</div>', !empty($context['page_index']) ? '
657
		<div class="pagesection">
658
			<div class="pagelinks">' . $context['page_index'] . '</div>
659
		</div>' : '';
660
661
	// No drafts? Just show an informative message.
662
	if (empty($context['drafts']))
663
		echo '
664
		<div class="windowbg2 centertext">
665
			', $txt['draft_none'], '
666
		</div>';
667
	else
668
	{
669
		// For every draft to be displayed, give it its own div, and show the important details of the draft.
670
		foreach ($context['drafts'] as $draft)
671
		{
672
			echo '
673
		<div class="windowbg">
674
			<div class="counter">', $draft['counter'], '</div>
675
			<div class="topic_details">
676
				<h5>
677
					<strong><a href="', $scripturl, '?board=', $draft['board']['id'], '.0">', $draft['board']['name'], '</a> / ', $draft['topic']['link'], '</strong> &nbsp; &nbsp;';
678
679
			if (!empty($draft['sticky']))
680
				echo '
681
					<span class="generic_icons sticky" title="', $txt['sticky_topic'], '"></span>';
682
683
			if (!empty($draft['locked']))
684
				echo '
685
					<span class="generic_icons lock" title="', $txt['locked_topic'], '"></span>';
686
687
			echo '
688
				</h5>
689
				<span class="smalltext">&#171;&nbsp;<strong>', $txt['on'], ':</strong> ', $draft['time'], '&nbsp;&#187;</span>
690
			</div><!-- .topic_details -->
691
			<div class="list_posts">
692
				', $draft['body'], '
693
			</div>
694
			<div class="floatright">
695
				<ul class="quickbuttons">
696
						<li><a href="', $scripturl, '?action=post;', (empty($draft['topic']['id']) ? 'board=' . $draft['board']['id'] : 'topic=' . $draft['topic']['id']), '.0;id_draft=', $draft['id_draft'], '"><span class="generic_icons reply_button"></span>', $txt['draft_edit'], '</a></li>
697
						<li><a href="', $scripturl, '?action=profile;u=', $context['member']['id'], ';area=showdrafts;delete=', $draft['id_draft'], ';', $context['session_var'], '=', $context['session_id'], '" data-confirm="', $txt['draft_remove'], '" class="you_sure"><span class="generic_icons remove_button"></span>', $txt['draft_delete'], '</a></li>
698
				</ul>
699
			</div><!-- .floatright -->
700
		</div><!-- .windowbg -->';
701
		}
702
	}
703
704
	// Show page numbers.
705
	echo '
706
		<div class="pagesection">
707
			<div class="pagelinks">', $context['page_index'], '</div>
708
		</div>';
709
}
710
711
/**
712
 * Template for showing and managing the buddy list.
713
 */
714
function template_editBuddies()
715
{
716
	global $context, $scripturl, $txt;
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...
717
718 View Code Duplication
	if (!empty($context['saved_successful']))
719
		echo '
720
	<div class="infobox">', $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $context['member']['name']), '</div>';
721
722
	elseif (!empty($context['saved_failed']))
723
		echo '
724
	<div class="errorbox">', $context['saved_failed'], '</div>';
725
726
	echo '
727
	<div id="edit_buddies">
728
		<div class="cat_bar">
729
			<h3 class="catbg">
730
				<span class="generic_icons people icon"></span> ', $txt['editBuddies'], '
731
			</h3>
732
		</div>
733
		<table class="table_grid">
734
			<thead>
735
				<tr class="title_bar">
736
					<th scope="col" class="quarter_table">', $txt['name'], '</th>
737
					<th scope="col">', $txt['status'], '</th>';
738
739
	if (allowedTo('moderate_forum'))
740
		echo '
741
					<th scope="col">', $txt['email'], '</th>';
742
743 View Code Duplication
	if (!empty($context['custom_pf']))
744
		foreach ($context['custom_pf'] as $column)
745
				echo '
746
					<th scope="col">', $column['label'], '</th>';
747
748
	echo '
749
					<th scope="col">', $txt['remove'], '</th>
750
				</tr>
751
			</thead>
752
			<tbody>';
753
754
	// If they don't have any buddies don't list them!
755
	if (empty($context['buddies']))
756
		echo '
757
				<tr class="windowbg">
758
					<td colspan="', allowedTo('moderate_forum') ? '10' : '9', '">
759
						<strong>', $txt['no_buddies'], '</strong>
760
					</td>
761
				</tr>';
762
763
		// Now loop through each buddy showing info on each.
764
	else
765
	{
766
		foreach ($context['buddies'] as $buddy)
767
		{
768
			echo '
769
				<tr class="windowbg">
770
					<td>', $buddy['link'], '</td>
771
					<td>
772
						<a href="', $buddy['online']['href'], '"><span class="' . ($buddy['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $buddy['online']['text'] . '"></span></a>
773
					</td>';
774
775 View Code Duplication
			if ($buddy['show_email'])
776
				echo '
777
					<td>
778
						<a href="mailto:' . $buddy['email'] . '" rel="nofollow"><span class="generic_icons mail icon" title="' . $txt['email'] . ' ' . $buddy['name'] . '"></span></a>
779
					</td>';
780
781
			// Show the custom profile fields for this user.
782 View Code Duplication
			if (!empty($context['custom_pf']))
783
				foreach ($context['custom_pf'] as $key => $column)
784
					echo '
785
					<td class="lefttext">', $buddy['options'][$key], '</td>';
786
787
			echo '
788
					<td>
789
						<a href="', $scripturl, '?action=profile;area=lists;sa=buddies;u=', $context['id_member'], ';remove=', $buddy['id'], ';', $context['session_var'], '=', $context['session_id'], '"><span class="generic_icons delete" title="', $txt['buddy_remove'], '"></span></a>
790
					</td>
791
				</tr>';
792
		}
793
	}
794
795
	echo '
796
			</tbody>
797
		</table>
798
	</div><!-- #edit_buddies -->';
799
800
	// Add a new buddy?
801
	echo '
802
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=buddies" method="post" accept-charset="', $context['character_set'], '">
803
		<div class="cat_bar">
804
			<h3 class="catbg">', $txt['buddy_add'], '</h3>
805
		</div>
806
		<div class="information">
807
			<dl class="settings">
808
				<dt>
809
					<label for="new_buddy"><strong>', $txt['who_member'], ':</strong></label>
810
				</dt>
811
				<dd>
812
					<input type="text" name="new_buddy" id="new_buddy" size="30">
813
					<input type="submit" value="', $txt['buddy_add_button'], '" class="button floatnone">
814
				</dd>
815
			</dl>
816
		</div>';
817
818 View Code Duplication
	if (!empty($context['token_check']))
819
		echo '
820
		<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
821
822
	echo '
823
		<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
824
	</form>
825
	<script>
826
		var oAddBuddySuggest = new smc_AutoSuggest({
827
			sSelf: \'oAddBuddySuggest\',
828
			sSessionId: smf_session_id,
829
			sSessionVar: smf_session_var,
830
			sSuggestId: \'new_buddy\',
831
			sControlId: \'new_buddy\',
832
			sSearchType: \'member\',
833
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
834
			bItemList: false
835
		});
836
	</script>';
837
}
838
839
/**
840
 * Template for showing the ignore list of the current user.
841
 */
842
function template_editIgnoreList()
843
{
844
	global $context, $scripturl, $txt;
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...
845
846 View Code Duplication
	if (!empty($context['saved_successful']))
847
		echo '
848
	<div class="infobox">', $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $context['member']['name']), '</div>';
849
850
	elseif (!empty($context['saved_failed']))
851
		echo '
852
	<div class="errorbox">', $context['saved_failed'], '</div>';
853
854
	echo '
855
	<div id="edit_buddies">
856
		<div class="cat_bar">
857
			<h3 class="catbg profile_hd">
858
				', $txt['editIgnoreList'], '
859
			</h3>
860
		</div>
861
		<table class="table_grid">
862
			<thead>
863
				<tr class="title_bar">
864
					<th scope="col" class="quarter_table">', $txt['name'], '</th>
865
					<th scope="col">', $txt['status'], '</th>';
866
867
	if (allowedTo('moderate_forum'))
868
		echo '
869
					<th scope="col">', $txt['email'], '</th>';
870
871
	echo '
872
					<th scope="col">', $txt['ignore_remove'], '</th>
873
				</tr>
874
			</thead>
875
			<tbody>';
876
877
	// If they don't have anyone on their ignore list, don't list it!
878
	if (empty($context['ignore_list']))
879
		echo '
880
				<tr class="windowbg">
881
					<td colspan="', allowedTo('moderate_forum') ? '4' : '3', '">
882
						<strong>', $txt['no_ignore'], '</strong>
883
					</td>
884
				</tr>';
885
886
	// Now loop through each buddy showing info on each.
887
	foreach ($context['ignore_list'] as $member)
888
	{
889
		echo '
890
				<tr class="windowbg">
891
					<td>', $member['link'], '</td>
892
					<td>
893
						<a href="', $member['online']['href'], '"><span class="' . ($member['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $member['online']['text'] . '"></span></a>
894
					</td>';
895
896 View Code Duplication
		if ($member['show_email'])
897
			echo '
898
					<td>
899
						<a href="mailto:' . $member['email'] . '" rel="nofollow"><span class="generic_icons mail icon" title="' . $txt['email'] . ' ' . $member['name'] . '"></span></a>
900
					</td>';
901
		echo '
902
					<td>
903
						<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=ignore;remove=', $member['id'], ';', $context['session_var'], '=', $context['session_id'], '"><span class="generic_icons delete" title="', $txt['ignore_remove'], '"></span></a>
904
					</td>
905
				</tr>';
906
	}
907
908
	echo '
909
			</tbody>
910
		</table>
911
	</div><!-- #edit_buddies -->';
912
913
	// Add to the ignore list?
914
	echo '
915
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=ignore" method="post" accept-charset="', $context['character_set'], '">
916
		<div class="cat_bar">
917
			<h3 class="catbg">', $txt['ignore_add'], '</h3>
918
		</div>
919
		<div class="information">
920
			<dl class="settings">
921
				<dt>
922
					<label for="new_buddy"><strong>', $txt['who_member'], ':</strong></label>
923
				</dt>
924
				<dd>
925
					<input type="text" name="new_ignore" id="new_ignore" size="25">
926
				</dd>
927
			</dl>
928
		</div>';
929
930 View Code Duplication
	if (!empty($context['token_check']))
931
		echo '
932
		<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
933
934
	echo '
935
		<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
936
		<input type="submit" value="', $txt['ignore_add_button'], '" class="button">
937
	</form>
938
	<script>
939
		var oAddIgnoreSuggest = new smc_AutoSuggest({
940
			sSelf: \'oAddIgnoreSuggest\',
941
			sSessionId: \'', $context['session_id'], '\',
942
			sSessionVar: \'', $context['session_var'], '\',
943
			sSuggestId: \'new_ignore\',
944
			sControlId: \'new_ignore\',
945
			sSearchType: \'member\',
946
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
947
			bItemList: false
948
		});
949
	</script>';
950
}
951
952
/**
953
 * This template shows an admin information on a users IP addresses used and errors attributed to them.
954
 */
955
function template_trackActivity()
956
{
957
	global $context, $scripturl, $txt;
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...
958
959
	// The first table shows IP information about the user.
960
	echo '
961
		<div class="cat_bar">
962
			<h3 class="catbg">', $txt['view_ips_by'], ' ', $context['member']['name'], '</h3>
963
		</div>';
964
965
	// The last IP the user used.
966
	echo '
967
		<div id="tracking" class="windowbg2 noup">
968
			<dl class="settings noborder">
969
				<dt>
970
					', $txt['most_recent_ip'], ':
971
					', (empty($context['last_ip2']) ? '' : '<br>
972
					<span class="smalltext">(<a href="' . $scripturl . '?action=helpadmin;help=whytwoip" onclick="return reqOverlayDiv(this.href);">' . $txt['why_two_ip_address'] . '</a>)</span>'), '
973
				</dt>
974
				<dd>
975
					<a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['last_ip'], ';u=', $context['member']['id'], '">', $context['last_ip'], '</a>';
976
977
	// Second address detected?
978 View Code Duplication
	if (!empty($context['last_ip2']))
979
		echo '
980
					, <a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['last_ip2'], ';u=', $context['member']['id'], '">', $context['last_ip2'], '</a>';
981
982
	echo '
983
				</dd>';
984
985
	// Lists of IP addresses used in messages / error messages.
986
	echo '
987
				<dt>', $txt['ips_in_messages'], ':</dt>
988
				<dd>
989
					', (count($context['ips']) > 0 ? implode(', ', $context['ips']) : '(' . $txt['none'] . ')'), '
990
				</dd>
991
				<dt>', $txt['ips_in_errors'], ':</dt>
992
				<dd>
993
					', (count($context['error_ips']) > 0 ? implode(', ', $context['error_ips']) : '(' . $txt['none'] . ')'), '
994
				</dd>';
995
996
	// List any members that have used the same IP addresses as the current member.
997
	echo '
998
				<dt>', $txt['members_in_range'], ':</dt>
999
				<dd>
1000
					', (count($context['members_in_range']) > 0 ? implode(', ', $context['members_in_range']) : '(' . $txt['none'] . ')'), '
1001
				</dd>
1002
			</dl>
1003
		</div><!-- #tracking -->';
1004
1005
	// Show the track user list.
1006
	template_show_list('track_user_list');
1007
}
1008
1009
/**
1010
 * The template for trackIP, allowing the admin to see where/who a certain IP has been used.
1011
 */
1012
function template_trackIP()
1013
{
1014
	global $context, $txt;
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...
1015
1016
	// This function always defaults to the last IP used by a member but can be set to track any IP.
1017
	// The first table in the template gives an input box to allow the admin to enter another IP to track.
1018
	echo '
1019
		<div class="cat_bar">
1020
			<h3 class="catbg">', $txt['trackIP'], '</h3>
1021
		</div>
1022
		<div class="windowbg2 noup">
1023
			<form action="', $context['base_url'], '" method="post" accept-charset="', $context['character_set'], '">
1024
				<dl class="settings">
1025
					<dt>
1026
						<label for="searchip"><strong>', $txt['enter_ip'], ':</strong></label>
1027
					</dt>
1028
					<dd>
1029
						<input type="text" name="searchip" value="', $context['ip'], '">
1030
					</dd>
1031
				</dl>
1032
				<input type="submit" value="', $txt['trackIP'], '" class="button">
1033
			</form>
1034
		</div>
1035
		<br>';
1036
1037
	// The table inbetween the first and second table shows links to the whois server for every region.
1038
	if ($context['single_ip'])
1039
	{
1040
		echo '
1041
		<div class="cat_bar">
1042
			<h3 class="catbg">', $txt['whois_title'], ' ', $context['ip'], '</h3>
1043
		</div>
1044
		<div class="windowbg2 noup">';
1045
1046
		foreach ($context['whois_servers'] as $server)
1047
			echo '
1048
			<a href="', $server['url'], '" target="_blank" rel="noopener"', isset($context['auto_whois_server']) && $context['auto_whois_server']['name'] == $server['name'] ? ' style="font-weight: bold;"' : '', '>', $server['name'], '</a><br>';
1049
		echo '
1050
		</div>
1051
		<br>';
1052
	}
1053
1054
	// The second table lists all the members who have been logged as using this IP address.
1055
	echo '
1056
		<div class="cat_bar">
1057
			<h3 class="catbg">', $txt['members_from_ip'], ' ', $context['ip'], '</h3>
1058
		</div>';
1059
1060
	if (empty($context['ips']))
1061
		echo '
1062
		<p class="windowbg2 description">
1063
			<em>', $txt['no_members_from_ip'], '</em>
1064
		</p>';
1065
1066
	else
1067
	{
1068
		echo '
1069
		<table class="table_grid">
1070
			<thead>
1071
				<tr class="title_bar">
1072
					<th scope="col">', $txt['ip_address'], '</th>
1073
					<th scope="col">', $txt['display_name'], '</th>
1074
				</tr>
1075
			</thead>
1076
			<tbody>';
1077
1078
		// Loop through each of the members and display them.
1079
		foreach ($context['ips'] as $ip => $memberlist)
1080
			echo '
1081
				<tr class="windowbg">
1082
					<td><a href="', $context['base_url'], ';searchip=', $ip, '">', $ip, '</a></td>
1083
					<td>', implode(', ', $memberlist), '</td>
1084
				</tr>';
1085
1086
		echo '
1087
			</tbody>
1088
		</table>';
1089
	}
1090
1091
	echo '
1092
		<br>';
1093
1094
	template_show_list('track_message_list');
1095
1096
	echo '<br>';
1097
1098
	template_show_list('track_user_list');
1099
1100
	// 3rd party integrations may have added additional tracking.
1101
	if (!empty($context['additional_track_lists']))
1102
	{
1103
		foreach ($context['additional_track_lists'] as $list)
1104
		{
1105
			echo '<br>';
1106
1107
			template_show_list($list);
1108
		}
1109
	}
1110
}
1111
1112
/**
1113
 * This template shows an admin which permissions a user have and which group(s) give them each permission.
1114
 */
1115
function template_showPermissions()
1116
{
1117
	global $context, $scripturl, $txt;
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...
1118
1119
	echo '
1120
		<div class="cat_bar">
1121
			<h3 class="catbg profile_hd">
1122
				', $txt['showPermissions'], '
1123
			</h3>
1124
		</div>';
1125
1126
	if ($context['member']['has_all_permissions'])
1127
		echo '
1128
		<div class="information">', $txt['showPermissions_all'], '</div>';
1129
1130
	else
1131
	{
1132
		echo '
1133
		<div class="information">',$txt['showPermissions_help'], '</div>
1134
		<div id="permissions" class="flow_hidden">';
1135
1136
		if (!empty($context['no_access_boards']))
1137
		{
1138
			echo '
1139
			<div class="cat_bar">
1140
				<h3 class="catbg">', $txt['showPermissions_restricted_boards'], '</h3>
1141
			</div>
1142
			<div class="windowbg smalltext">
1143
				', $txt['showPermissions_restricted_boards_desc'], ':<br>';
1144
1145
			foreach ($context['no_access_boards'] as $no_access_board)
1146
				echo '
1147
				<a href="', $scripturl, '?board=', $no_access_board['id'], '.0">', $no_access_board['name'], '</a>', $no_access_board['is_last'] ? '' : ', ';
1148
			echo '
1149
			</div>';
1150
		}
1151
1152
		// General Permissions section.
1153
		echo '
1154
			<div class="tborder">
1155
				<div class="cat_bar">
1156
					<h3 class="catbg">', $txt['showPermissions_general'], '</h3>
1157
				</div>';
1158 View Code Duplication
		if (!empty($context['member']['permissions']['general']))
1159
		{
1160
			echo '
1161
				<table class="table_grid">
1162
					<thead>
1163
						<tr class="title_bar">
1164
							<th class="lefttext half_table">', $txt['showPermissions_permission'], '</th>
1165
							<th class="lefttext half_table">', $txt['showPermissions_status'], '</th>
1166
						</tr>
1167
					</thead>
1168
					<tbody>';
1169
1170
			foreach ($context['member']['permissions']['general'] as $permission)
1171
			{
1172
				echo '
1173
						<tr class="windowbg">
1174
							<td title="', $permission['id'], '">
1175
								', $permission['is_denied'] ? '<del>' . $permission['name'] . '</del>' : $permission['name'], '
1176
							</td>
1177
							<td class="smalltext">';
1178
1179
				if ($permission['is_denied'])
1180
					echo '
1181
								<span class="alert">', $txt['showPermissions_denied'], ': ', implode(', ', $permission['groups']['denied']), '</span>';
1182
				else
1183
					echo '
1184
								', $txt['showPermissions_given'], ': ', implode(', ', $permission['groups']['allowed']);
1185
1186
				echo '
1187
							</td>
1188
						</tr>';
1189
			}
1190
			echo '
1191
					</tbody>
1192
				</table>
1193
			</div><!-- .tborder -->
1194
			<br>';
1195
		}
1196
		else
1197
			echo '
1198
			<p class="windowbg2">', $txt['showPermissions_none_general'], '</p>';
1199
1200
		// Board permission section.
1201
		echo '
1202
			<form action="' . $scripturl . '?action=profile;u=', $context['id_member'], ';area=permissions#board_permissions" method="post" accept-charset="', $context['character_set'], '">
1203
				<div class="cat_bar">
1204
					<h3 class="catbg">
1205
						<a id="board_permissions"></a>', $txt['showPermissions_select'], ':
1206
						<select name="board" onchange="if (this.options[this.selectedIndex].value) this.form.submit();">
1207
							<option value="0"', $context['board'] == 0 ? ' selected' : '', '>', $txt['showPermissions_global'], '</option>';
1208
1209
		if (!empty($context['boards']))
1210
			echo '
1211
							<option value="" disabled>---------------------------</option>';
1212
1213
		// Fill the box with any local permission boards.
1214
		foreach ($context['boards'] as $board)
1215
			echo '
1216
							<option value="', $board['id'], '"', $board['selected'] ? ' selected' : '', '>', $board['name'], ' (', $board['profile_name'], ')</option>';
1217
1218
		echo '
1219
						</select>
1220
					</h3>
1221
				</div><!-- .cat_bar -->
1222
			</form>';
1223
1224 View Code Duplication
		if (!empty($context['member']['permissions']['board']))
1225
		{
1226
			echo '
1227
			<table class="table_grid">
1228
				<thead>
1229
					<tr class="title_bar">
1230
						<th class="lefttext half_table">', $txt['showPermissions_permission'], '</th>
1231
						<th class="lefttext half_table">', $txt['showPermissions_status'], '</th>
1232
					</tr>
1233
				</thead>
1234
				<tbody>';
1235
1236
			foreach ($context['member']['permissions']['board'] as $permission)
1237
			{
1238
				echo '
1239
					<tr class="windowbg">
1240
						<td title="', $permission['id'], '">
1241
							', $permission['is_denied'] ? '<del>' . $permission['name'] . '</del>' : $permission['name'], '
1242
						</td>
1243
						<td class="smalltext">';
1244
1245
				if ($permission['is_denied'])
1246
					echo '
1247
							<span class="alert">', $txt['showPermissions_denied'], ': ', implode(', ', $permission['groups']['denied']), '</span>';
1248
1249
				else
1250
					echo '
1251
							', $txt['showPermissions_given'], ': ', implode(', ', $permission['groups']['allowed']);
1252
1253
				echo '
1254
						</td>
1255
					</tr>';
1256
			}
1257
			echo '
1258
				</tbody>
1259
			</table>';
1260
		}
1261
		else
1262
			echo '
1263
			<p class="windowbg2">', $txt['showPermissions_none_board'], '</p>';
1264
	echo '
1265
		</div><!-- #permissions -->';
1266
	}
1267
}
1268
1269
/**
1270
 * Template for user statistics, showing graphs and the like.
1271
 */
1272
function template_statPanel()
1273
{
1274
	global $context, $txt;
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...
1275
1276
	// First, show a few text statistics such as post/topic count.
1277
	echo '
1278
	<div id="profileview" class="roundframe">
1279
		<div id="generalstats">
1280
			<dl class="stats">
1281
				<dt>', $txt['statPanel_total_time_online'], ':</dt>
1282
				<dd>', $context['time_logged_in'], '</dd>
1283
				<dt>', $txt['statPanel_total_posts'], ':</dt>
1284
				<dd>', $context['num_posts'], ' ', $txt['statPanel_posts'], '</dd>
1285
				<dt>', $txt['statPanel_total_topics'], ':</dt>
1286
				<dd>', $context['num_topics'], ' ', $txt['statPanel_topics'], '</dd>
1287
				<dt>', $txt['statPanel_users_polls'], ':</dt>
1288
				<dd>', $context['num_polls'], ' ', $txt['statPanel_polls'], '</dd>
1289
				<dt>', $txt['statPanel_users_votes'], ':</dt>
1290
				<dd>', $context['num_votes'], ' ', $txt['statPanel_votes'], '</dd>
1291
			</dl>
1292
		</div>';
1293
1294
	// This next section draws a graph showing what times of day they post the most.
1295
	echo '
1296
		<div id="activitytime" class="flow_hidden">
1297
			<div class="title_bar">
1298
				<h3 class="titlebg">
1299
					<span class="generic_icons history"></span> ', $txt['statPanel_activityTime'], '
1300
				</h3>
1301
			</div>';
1302
1303
	// If they haven't post at all, don't draw the graph.
1304
	if (empty($context['posts_by_time']))
1305
		echo '
1306
			<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1307
1308
	// Otherwise do!
1309
	else
1310
	{
1311
		echo '
1312
			<ul class="activity_stats flow_hidden">';
1313
1314
		// The labels.
1315
		foreach ($context['posts_by_time'] as $time_of_day)
1316
			echo '
1317
				<li', $time_of_day['is_last'] ? ' class="last"' : '', '>
1318
					<div class="bar" style="padding-top: ', ((int) (100 - $time_of_day['relative_percent'])), 'px;" title="', sprintf($txt['statPanel_activityTime_posts'], $time_of_day['posts'], $time_of_day['posts_percent']), '">
1319
						<div style="height: ', (int) $time_of_day['relative_percent'], 'px;">
1320
							<span>', sprintf($txt['statPanel_activityTime_posts'], $time_of_day['posts'], $time_of_day['posts_percent']), '</span>
1321
						</div>
1322
					</div>
1323
					<span class="stats_hour">', $time_of_day['hour_format'], '</span>
1324
				</li>';
1325
1326
		echo '
1327
			</ul>';
1328
	}
1329
1330
	echo '
1331
		</div><!-- #activitytime -->';
1332
1333
	// Two columns with the most popular boards by posts and activity (activity = users posts / total posts).
1334
	echo '
1335
		<div class="flow_hidden">
1336
			<div class="half_content">
1337
				<div class="title_bar">
1338
					<h3 class="titlebg">
1339
						<span class="generic_icons replies"></span> ', $txt['statPanel_topBoards'], '
1340
					</h3>
1341
				</div>';
1342
1343 View Code Duplication
	if (empty($context['popular_boards']))
1344
		echo '
1345
				<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1346
1347
	else
1348
	{
1349
		echo '
1350
				<dl class="stats">';
1351
1352
		// Draw a bar for every board.
1353
		foreach ($context['popular_boards'] as $board)
1354
		{
1355
			echo '
1356
					<dt>', $board['link'], '</dt>
1357
					<dd>
1358
						<div class="profile_pie" style="background-position: -', ((int) ($board['posts_percent'] / 5) * 20), 'px 0;" title="', sprintf($txt['statPanel_topBoards_memberposts'], $board['posts'], $board['total_posts_member'], $board['posts_percent']), '">
1359
							', sprintf($txt['statPanel_topBoards_memberposts'], $board['posts'], $board['total_posts_member'], $board['posts_percent']), '
1360
						</div>
1361
						', empty($context['hide_num_posts']) ? $board['posts'] : '', '
1362
					</dd>';
1363
		}
1364
1365
		echo '
1366
				</dl>';
1367
	}
1368
	echo '
1369
			</div><!-- .half_content -->
1370
			<div class="half_content">
1371
				<div class="title_bar">
1372
					<h3 class="titlebg">
1373
						<span class="generic_icons replies"></span> ', $txt['statPanel_topBoardsActivity'], '
1374
					</h3>
1375
				</div>';
1376
1377 View Code Duplication
	if (empty($context['board_activity']))
1378
		echo '
1379
				<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1380
	else
1381
	{
1382
		echo '
1383
				<dl class="stats">';
1384
1385
		// Draw a bar for every board.
1386
		foreach ($context['board_activity'] as $activity)
1387
		{
1388
			echo '
1389
					<dt>', $activity['link'], '</dt>
1390
					<dd>
1391
						<div class="profile_pie" style="background-position: -', ((int) ($activity['percent'] / 5) * 20), 'px 0;" title="', sprintf($txt['statPanel_topBoards_posts'], $activity['posts'], $activity['total_posts'], $activity['posts_percent']), '">
1392
							', sprintf($txt['statPanel_topBoards_posts'], $activity['posts'], $activity['total_posts'], $activity['posts_percent']), '
1393
						</div>
1394
						', $activity['percent'], '%
1395
					</dd>';
1396
		}
1397
1398
		echo '
1399
				</dl>';
1400
	}
1401
	echo '
1402
			</div><!-- .half_content -->
1403
		</div><!-- .flow_hidden -->';
1404
1405
	echo '
1406
	</div><!-- #profileview -->';
1407
}
1408
1409
/**
1410
 * Template for editing profile options.
1411
 */
1412
function template_edit_options()
1413
{
1414
	global $context, $scripturl, $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...
1415
1416
	// The main header!
1417
	// because some browsers ignore autocomplete=off and fill username in display name and/ or email field, fake them out.
1418
	$url = !empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=' . $context['menu_item_selected'] . ';u=' . $context['id_member'];
1419
	$url = $context['require_password'] && !empty($modSettings['force_ssl']) && $modSettings['force_ssl'] < 2 ? strtr($url, array('http://' => 'https://')) : $url;
1420
1421
	echo '
1422
		<form action="', $url, '" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator" enctype="multipart/form-data"', ($context['menu_item_selected'] == 'account' ? ' autocomplete="off"' : ''), '>
1423
			<div style="position:absolute; left:-3000px;">
1424
				<input type="text" id="autocompleteFakeName">
1425
				<input type="password" id="autocompleteFakePassword">
1426
			</div>
1427
			<div class="cat_bar">
1428
				<h3 class="catbg profile_hd">';
1429
1430
		// Don't say "Profile" if this isn't the profile...
1431
		if (!empty($context['profile_header_text']))
1432
			echo '
1433
					', $context['profile_header_text'];
1434
		else
1435
			echo '
1436
					', $txt['profile'];
1437
1438
		echo '
1439
				</h3>
1440
			</div>';
1441
1442
	// Have we some description?
1443
	if ($context['page_desc'])
1444
		echo '
1445
			<p class="information">', $context['page_desc'], '</p>';
1446
1447
	echo '
1448
			<div class="roundframe">';
1449
1450
	// Any bits at the start?
1451
	if (!empty($context['profile_prehtml']))
1452
		echo '
1453
				<div>', $context['profile_prehtml'], '</div>';
1454
1455
	if (!empty($context['profile_fields']))
1456
		echo '
1457
				<dl class="settings">';
1458
1459
	// Start the big old loop 'of love.
1460
	$lastItem = 'hr';
1461
	foreach ($context['profile_fields'] as $key => $field)
1462
	{
1463
		// We add a little hack to be sure we never get more than one hr in a row!
1464
		if ($lastItem == 'hr' && $field['type'] == 'hr')
1465
			continue;
1466
1467
		$lastItem = $field['type'];
1468
		if ($field['type'] == 'hr')
1469
			echo '
1470
				</dl>
1471
				<hr>
1472
				<dl class="settings">';
1473
1474 View Code Duplication
		elseif ($field['type'] == 'callback')
1475
		{
1476
			if (isset($field['callback_func']) && function_exists('template_profile_' . $field['callback_func']))
1477
			{
1478
				$callback_func = 'template_profile_' . $field['callback_func'];
1479
				$callback_func();
1480
			}
1481
		}
1482
		else
1483
		{
1484
			echo '
1485
					<dt>
1486
						<strong', !empty($field['is_error']) ? ' class="error"' : '', '>', $field['type'] !== 'label' ? '<label for="' . $key . '">' : '', $field['label'], $field['type'] !== 'label' ? '</label>' : '', '</strong>';
1487
1488
			// Does it have any subtext to show?
1489
			if (!empty($field['subtext']))
1490
				echo '
1491
						<br>
1492
						<span class="smalltext">', $field['subtext'], '</span>';
1493
1494
			echo '
1495
					</dt>
1496
					<dd>';
1497
1498
			// Want to put something infront of the box?
1499
			if (!empty($field['preinput']))
1500
				echo '
1501
						', $field['preinput'];
1502
1503
			// What type of data are we showing?
1504
			if ($field['type'] == 'label')
1505
				echo '
1506
						', $field['value'];
1507
1508
			// Maybe it's a text box - very likely!
1509
			elseif (in_array($field['type'], array('int', 'float', 'text', 'password', 'color', 'date', 'datetime', 'datetime-local', 'email', 'month', 'number', 'time', 'url')))
1510
			{
1511
				if ($field['type'] == 'int' || $field['type'] == 'float')
1512
					$type = 'number';
1513
				else
1514
					$type = $field['type'];
1515
				$step = $field['type'] == 'float' ? ' step="0.1"' : '';
1516
1517
1518
				echo '
1519
						<input type="', $type, '" name="', $key, '" id="', $key, '" size="', empty($field['size']) ? 30 : $field['size'], '" value="', $field['value'], '" ', $field['input_attr'], ' ', $step, '>';
1520
			}
1521
			// You "checking" me out? ;)
1522 View Code Duplication
			elseif ($field['type'] == 'check')
1523
				echo '
1524
						<input type="hidden" name="', $key, '" value="0">
1525
						<input type="checkbox" name="', $key, '" id="', $key, '"', !empty($field['value']) ? ' checked' : '', ' value="1" ', $field['input_attr'], '>';
1526
1527
			// Always fun - select boxes!
1528 View Code Duplication
			elseif ($field['type'] == 'select')
1529
			{
1530
				echo '
1531
						<select name="', $key, '" id="', $key, '">';
1532
1533
				if (isset($field['options']))
1534
				{
1535
					// Is this some code to generate the options?
1536
					if (!is_array($field['options']))
1537
						$field['options'] = $field['options']();
1538
1539
					// Assuming we now have some!
1540
					if (is_array($field['options']))
1541
						foreach ($field['options'] as $value => $name)
1542
							echo '
1543
							<option value="', $value, '"', $value == $field['value'] ? ' selected' : '', '>', $name, '</option>';
1544
				}
1545
1546
				echo '
1547
						</select>';
1548
			}
1549
1550
			// Something to end with?
1551
			if (!empty($field['postinput']))
1552
				echo '
1553
						', $field['postinput'];
1554
1555
			echo '
1556
					</dd>';
1557
		}
1558
	}
1559
1560
	if (!empty($context['profile_fields']))
1561
		echo '
1562
				</dl>';
1563
1564
	// Are there any custom profile fields - if so print them!
1565
	if (!empty($context['custom_fields']))
1566
	{
1567
		if ($lastItem != 'hr')
1568
			echo '
1569
				<hr>';
1570
1571
		echo '
1572
				<dl class="settings">';
1573
1574
		foreach ($context['custom_fields'] as $field)
1575
			echo '
1576
					<dt>
1577
						<strong>', $field['name'], ': </strong><br>
1578
						<span class="smalltext">', $field['desc'], '</span>
1579
					</dt>
1580
					<dd>
1581
						', $field['input_html'], '
1582
					</dd>';
1583
1584
		echo '
1585
				</dl>';
1586
1587
	}
1588
1589
	// Any closing HTML?
1590
	if (!empty($context['profile_posthtml']))
1591
		echo '
1592
				<div>', $context['profile_posthtml'], '</div>';
1593
1594
	// Only show the password box if it's actually needed.
1595 View Code Duplication
	if ($context['require_password'])
1596
		echo '
1597
				<dl class="settings">
1598
					<dt>
1599
						<strong', isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : '', '><label for="oldpasswrd">', $txt['current_password'], ': </label></strong><br>
1600
						<span class="smalltext">', $txt['required_security_reasons'], '</span>
1601
					</dt>
1602
					<dd>
1603
						<input type="password" name="oldpasswrd" id="oldpasswrd" size="20">
1604
					</dd>
1605
				</dl>';
1606
1607
	// The button shouldn't say "Change profile" unless we're changing the profile...
1608
	if (!empty($context['submit_button_text']))
1609
		echo '
1610
				<input type="submit" name="save" value="', $context['submit_button_text'], '" class="button">';
1611
	else
1612
		echo '
1613
				<input type="submit" name="save" value="', $txt['change_profile'], '" class="button">';
1614
1615 View Code Duplication
	if (!empty($context['token_check']))
1616
		echo '
1617
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
1618
1619
	echo '
1620
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
1621
				<input type="hidden" name="u" value="', $context['id_member'], '">
1622
				<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
1623
			</div><!-- .roundframe -->
1624
		</form>';
1625
1626
	// Any final spellchecking stuff?
1627
	if (!empty($context['show_spellchecking']))
1628
		echo '
1629
		<form name="spell_form" id="spell_form" method="post" accept-charset="', $context['character_set'], '" target="spellWindow" action="', $scripturl, '?action=spellcheck"><input type="hidden" name="spellstring" value=""></form>';
1630
}
1631
1632
/**
1633
 * Personal Message settings.
1634
 */
1635
function template_profile_pm_settings()
1636
{
1637
	global $context, $modSettings, $txt;
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...
1638
1639
	echo '
1640
					<dt>
1641
						<label for="pm_prefs">', $txt['pm_display_mode'], ':</label>
1642
					</dt>
1643
					<dd>
1644
						<select name="pm_prefs" id="pm_prefs">
1645
							<option value="0"', $context['display_mode'] == 0 ? ' selected' : '', '>', $txt['pm_display_mode_all'], '</option>
1646
							<option value="1"', $context['display_mode'] == 1 ? ' selected' : '', '>', $txt['pm_display_mode_one'], '</option>
1647
							<option value="2"', $context['display_mode'] == 2 ? ' selected' : '', '>', $txt['pm_display_mode_linked'], '</option>
1648
						</select>
1649
					</dd>
1650
					<dt>
1651
						<label for="view_newest_pm_first">', $txt['recent_pms_at_top'], '</label>
1652
					</dt>
1653
					<dd>
1654
						<input type="hidden" name="default_options[view_newest_pm_first]" value="0">
1655
						<input type="checkbox" name="default_options[view_newest_pm_first]" id="view_newest_pm_first" value="1"', !empty($context['member']['options']['view_newest_pm_first']) ? ' checked' : '', '>
1656
					</dd>
1657
				</dl>
1658
				<hr>
1659
				<dl class="settings">
1660
					<dt>
1661
						<label for="pm_receive_from">', $txt['pm_receive_from'], '</label>
1662
					</dt>
1663
					<dd>
1664
						<select name="pm_receive_from" id="pm_receive_from">
1665
							<option value="0"', empty($context['receive_from']) || (empty($modSettings['enable_buddylist']) && $context['receive_from'] < 3) ? ' selected' : '', '>', $txt['pm_receive_from_everyone'], '</option>';
1666
1667
	if (!empty($modSettings['enable_buddylist']))
1668
		echo '
1669
							<option value="1"', !empty($context['receive_from']) && $context['receive_from'] == 1 ? ' selected' : '', '>', $txt['pm_receive_from_ignore'], '</option>
1670
							<option value="2"', !empty($context['receive_from']) && $context['receive_from'] == 2 ? ' selected' : '', '>', $txt['pm_receive_from_buddies'], '</option>';
1671
1672
	echo '
1673
							<option value="3"', !empty($context['receive_from']) && $context['receive_from'] > 2 ? ' selected' : '', '>', $txt['pm_receive_from_admins'], '</option>
1674
						</select>
1675
					</dd>
1676
					<dt>
1677
						<label for="popup_messages">', $txt['popup_messages'], '</label>
1678
					</dt>
1679
					<dd>
1680
						<input type="hidden" name="default_options[popup_messages]" value="0">
1681
						<input type="checkbox" name="default_options[popup_messages]" id="popup_messages" value="1"', !empty($context['member']['options']['popup_messages']) ? ' checked' : '', '>
1682
					</dd>
1683
				</dl>
1684
				<hr>
1685
				<dl class="settings">
1686
					<dt>
1687
						<label for="pm_remove_inbox_label">', $txt['pm_remove_inbox_label'], '</label>
1688
					</dt>
1689
					<dd>
1690
						<input type="hidden" name="default_options[pm_remove_inbox_label]" value="0">
1691
						<input type="checkbox" name="default_options[pm_remove_inbox_label]" id="pm_remove_inbox_label" value="1"', !empty($context['member']['options']['pm_remove_inbox_label']) ? ' checked' : '', '>
1692
					</dd>';
1693
1694
}
1695
1696
/**
1697
 * Template for showing theme settings. Note: template_options() actually adds the theme specific options.
1698
 */
1699
function template_profile_theme_settings()
1700
{
1701
	global $context, $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...
1702
1703
	$skeys = array_keys($context['theme_options']);
1704
	$first_option_key = array_shift($skeys);
1705
	$titled_section = false;
1706
1707
	foreach ($context['theme_options'] as $i => $setting)
1708
	{
1709
		// Just spit out separators and move on
1710 View Code Duplication
		if (empty($setting) || !is_array($setting))
1711
		{
1712
			// Insert a separator (unless this is the first item in the list)
1713
			if ($i !== $first_option_key)
1714
				echo '
1715
				</dl>
1716
				<hr>
1717
				<dl class="settings">';
1718
1719
			// Should we give a name to this section?
1720
			if (is_string($setting) && !empty($setting))
1721
			{
1722
				$titled_section = true;
1723
				echo '
1724
					<dt><strong>' . $setting . '</strong></dt>
1725
					<dd></dd>';
1726
			}
1727
			else
1728
				$titled_section = false;
1729
1730
			continue;
1731
		}
1732
1733
		// Is this disabled?
1734
		if ($setting['id'] == 'calendar_start_day' && empty($modSettings['cal_enabled']))
1735
			continue;
1736
1737
		elseif (($setting['id'] == 'topics_per_page' || $setting['id'] == 'messages_per_page') && !empty($modSettings['disableCustomPerPage']))
1738
			continue;
1739
1740
		elseif ($setting['id'] == 'show_no_censored' && empty($modSettings['allow_no_censored']))
1741
			continue;
1742
1743
		elseif ($setting['id'] == 'posts_apply_ignore_list' && empty($modSettings['enable_buddylist']))
1744
			continue;
1745
1746
		elseif ($setting['id'] == 'wysiwyg_default' && !empty($modSettings['disable_wysiwyg']))
1747
			continue;
1748
1749 View Code Duplication
		elseif ($setting['id'] == 'drafts_autosave_enabled' && (empty($modSettings['drafts_autosave_enabled']) || (empty($modSettings['drafts_post_enabled']) && empty($modSettings['drafts_pm_enabled']))))
1750
			continue;
1751
1752 View Code Duplication
		elseif ($setting['id'] == 'drafts_show_saved_enabled' && (empty($modSettings['drafts_show_saved_enabled']) || (empty($modSettings['drafts_post_enabled']) && empty($modSettings['drafts_pm_enabled']))))
1753
			continue;
1754
1755
		// Some of these may not be set...  Set to defaults here
1756
		$opts = array('topics_per_page', 'messages_per_page', 'display_quick_mod');
1757
		if (in_array($setting['id'], $opts) && !isset($context['member']['options'][$setting['id']]))
1758
			$context['member']['options'][$setting['id']] = 0;
1759
1760
		if (!isset($setting['type']) || $setting['type'] == 'bool')
1761
			$setting['type'] = 'checkbox';
1762
1763
		elseif ($setting['type'] == 'int' || $setting['type'] == 'integer')
1764
			$setting['type'] = 'number';
1765
1766
		elseif ($setting['type'] == 'string')
1767
			$setting['type'] = 'text';
1768
1769
		if (isset($setting['options']))
1770
			$setting['type'] = 'list';
1771
1772
		echo '
1773
					<dt>
1774
						<label for="', $setting['id'], '">', !$titled_section ? '<strong>' : '', $setting['label'], !$titled_section ? '</strong>' : '', '</label>';
1775
1776
		if (isset($setting['description']))
1777
			echo '
1778
						<br>
1779
						<span class="smalltext">', $setting['description'], '</span>';
1780
		echo '
1781
					</dt>
1782
					<dd>';
1783
1784
		// Display checkbox options
1785
		if ($setting['type'] == 'checkbox')
1786
			echo '
1787
						<input type="hidden" name="default_options[' . $setting['id'] . ']" value="0">
1788
						<input type="checkbox" name="default_options[', $setting['id'], ']" id="', $setting['id'], '"', !empty($context['member']['options'][$setting['id']]) ? ' checked' : '', ' value="1">';
1789
1790
		// How about selection lists, we all love them
1791 View Code Duplication
		elseif ($setting['type'] == 'list')
1792
		{
1793
			echo '
1794
						<select name="default_options[', $setting['id'], ']" id="', $setting['id'], '"', '>';
1795
1796
			foreach ($setting['options'] as $value => $label)
1797
				echo '
1798
							<option value="', $value, '"', $value == $context['member']['options'][$setting['id']] ? ' selected' : '', '>', $label, '</option>';
1799
1800
			echo '
1801
						</select>';
1802
		}
1803
		// A textbox it is then
1804
		else
1805
		{
1806
			if (isset($setting['type']) && $setting['type'] == 'number')
1807
			{
1808
				$min = isset($setting['min']) ? ' min="' . $setting['min'] . '"' : ' min="0"';
1809
				$max = isset($setting['max']) ? ' max="' . $setting['max'] . '"' : '';
1810
				$step = isset($setting['step']) ? ' step="' . $setting['step'] . '"' : '';
1811
1812
				echo '
1813
						<input type="number"', $min . $max . $step;
1814
			}
1815
			elseif (isset($setting['type']) && $setting['type'] == 'url')
1816
				echo'
1817
						<input type="url"';
1818
1819
			else
1820
				echo '
1821
						<input type="text"';
1822
1823
			echo ' name="default_options[', $setting['id'], ']" id="', $setting['id'], '" value="', isset($context['member']['options'][$setting['id']]) ? $context['member']['options'][$setting['id']] : $setting['value'], '"', $setting['type'] == 'number' ? ' size="5"' : '', '>';
1824
		}
1825
1826
		// end of this defintion
1827
		echo '
1828
					</dd>';
1829
	}
1830
}
1831
1832
/**
1833
 * The template for configuring alerts
1834
 */
1835
function template_alert_configuration()
1836
{
1837
	global $context, $txt, $scripturl, $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...
1838
1839
	echo '
1840
		<div class="cat_bar">
1841
			<h3 class="catbg">
1842
				', $txt['alert_prefs'], '
1843
			</h3>
1844
		</div>
1845
		<p class="information">
1846
			', (empty($context['description']) ? $txt['alert_prefs_desc'] : $context['description']), '
1847
		</p>
1848
		<form action="', $scripturl, '?', $context['action'], '" id="admin_form_wrapper" method="post" accept-charset="', $context['character_set'], '" id="notify_options" class="flow_hidden">
1849
			<div class="cat_bar">
1850
				<h3 class="catbg">
1851
					', $txt['notification_general'], '
1852
				</h3>
1853
			</div>
1854
			<div class="windowbg2 noup">
1855
				<dl class="settings">';
1856
1857
	// Allow notification on announcements to be disabled?
1858
	if (!empty($modSettings['allow_disableAnnounce']))
1859
		echo '
1860
					<dt>
1861
						<label for="notify_announcements">', $txt['notify_important_email'], '</label>
1862
					</dt>
1863
					<dd>
1864
						<input type="hidden" name="notify_announcements" value="0">
1865
						<input type="checkbox" id="notify_announcements" name="notify_announcements" value="1"', !empty($context['member']['notify_announcements']) ? ' checked' : '', '>
1866
					</dd>';
1867
1868
	if (!empty($modSettings['enable_ajax_alerts']))
1869
		echo '
1870
					<dt>
1871
						<label for="notify_send_body">', $txt['notify_alert_timeout'], '</label>
1872
					</dt>
1873
					<dd>
1874
						<input type="number" size="4" id="notify_alert_timeout" name="opt_alert_timeout" min="0" value="', $context['member']['alert_timeout'], '">
1875
					</dd>';
1876
1877
	echo '
1878
				</dl>
1879
			</div><!-- .windowbg2 -->
1880
			<div class="cat_bar">
1881
				<h3 class="catbg">
1882
					', $txt['notify_what_how'], '
1883
				</h3>
1884
			</div>
1885
			<table class="table_grid">';
1886
1887
	foreach ($context['alert_types'] as $alert_group => $alerts)
1888
	{
1889
		echo '
1890
				<tr class="title_bar">
1891
					<th>', $txt['alert_group_' . $alert_group], '</th>
1892
					<th>', $txt['receive_alert'], '</th>
1893
					<th>', $txt['receive_mail'], '</th>
1894
				</tr>
1895
				<tr class="windowbg">';
1896
1897
		if (isset($context['alert_group_options'][$alert_group]))
1898
		{
1899
			foreach ($context['alert_group_options'][$alert_group] as $opts)
1900
			{
1901
				echo '
1902
				<tr class="windowbg">
1903
					<td colspan="3">';
1904
1905
				$label = $txt['alert_opt_' . $opts[1]];
1906
				$label_pos = isset($opts['label']) ? $opts['label'] : '';
1907
				if ($label_pos == 'before')
1908
					echo '
1909
						<label for="opt_', $opts[1], '">', $label, '</label>';
1910
1911
				$this_value = isset($context['alert_prefs'][$opts[1]]) ? $context['alert_prefs'][$opts[1]] : 0;
1912
				switch ($opts[0])
1913
				{
1914
					case 'check':
1915
						echo '
1916
						<input type="checkbox" name="opt_', $opts[1], '" id="opt_', $opts[1], '"', $this_value ? ' checked' : '', '>';
1917
						break;
1918
1919
					case 'select':
1920
						echo '
1921
						<select name="opt_', $opts[1], '" id="opt_', $opts[1], '">';
1922
1923
						foreach ($opts['opts'] as $k => $v)
1924
							echo '
1925
							<option value="', $k, '"', $this_value == $k ? ' selected' : '', '>', $v, '</option>';
1926
						echo '
1927
						</select>';
1928
						break;
1929
				}
1930
1931
				if ($label_pos == 'after')
1932
					echo '
1933
						<label for="opt_', $opts[1], '">', $label, '</label>';
1934
1935
				echo '
1936
					</td>
1937
				</tr>';
1938
			}
1939
		}
1940
1941
		foreach ($alerts as $alert_id => $alert_details)
1942
		{
1943
			echo '
1944
				<tr class="windowbg">
1945
					<td>
1946
						', $txt['alert_' . $alert_id], isset($alert_details['help']) ? '<a href="' . $scripturl . '?action=helpadmin;help=' . $alert_details['help'] . '" onclick="return reqOverlayDiv(this.href);" class="help floatright"><span class="generic_icons help" title="' . $txt['help'] . '"></span></a>' : '', '
1947
					</td>';
1948
1949
			foreach ($context['alert_bits'] as $type => $bitmask)
1950
			{
1951
				echo '
1952
					<td class="centercol">';
1953
1954
				$this_value = isset($context['alert_prefs'][$alert_id]) ? $context['alert_prefs'][$alert_id] : 0;
1955
				switch ($alert_details[$type])
1956
				{
1957
					case 'always':
1958
						echo '
1959
						<input type="checkbox" checked disabled>';
1960
						break;
1961
					case 'yes':
1962
						echo '
1963
						<input type="checkbox" name="', $type, '_', $alert_id, '"', ($this_value & $bitmask) ? ' checked' : '', '>';
1964
						break;
1965
					case 'never':
1966
						echo '
1967
						<input type="checkbox" disabled>';
1968
						break;
1969
				}
1970
				echo '
1971
					</td>';
1972
			}
1973
1974
			echo '
1975
				</tr>';
1976
		}
1977
	}
1978
1979
	echo '
1980
			</table>
1981
			<br>
1982
			<div>
1983
				<input id="notify_submit" type="submit" name="notify_submit" value="', $txt['notify_save'], '" class="button">
1984
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">', !empty($context['token_check']) ? '
1985
				<input type="hidden" name="' . $context[$context['token_check'] . '_token_var'] . '" value="' . $context[$context['token_check'] . '_token'] . '">' : '', '
1986
				<input type="hidden" name="u" value="', $context['id_member'], '">
1987
				<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
1988
			</div>
1989
		</form>
1990
		<br>';
1991
}
1992
1993
/**
1994
 * Template for showing which topics you're subscribed to
1995
 */
1996
function template_alert_notifications_topics()
1997
{
1998
	global $txt;
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...
1999
2000
	// The main containing header.
2001
	echo '
2002
		<div class="cat_bar">
2003
			<h3 class="catbg">
2004
				', $txt['watched_topics'], '
2005
			</h3>
2006
		</div>
2007
		<p class="information">', $txt['watched_topics_desc'], '</p>
2008
		<br>';
2009
2010
	template_show_list('topic_notification_list');
2011
}
2012
2013
/**
2014
 * Template for showing which boards you're subscribed to
2015
 */
2016
function template_alert_notifications_boards()
2017
{
2018
	global $txt;
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...
2019
2020
	echo '
2021
		<div class="cat_bar">
2022
			<h3 class="catbg">
2023
				', $txt['watched_boards'], '
2024
			</h3>
2025
		</div>
2026
		<p class="information">', $txt['watched_boards_desc'], '</p>
2027
		<br>';
2028
2029
	template_show_list('board_notification_list');
2030
}
2031
2032
/**
2033
 * Template for choosing group membership.
2034
 */
2035
function template_groupMembership()
2036
{
2037
	global $context, $scripturl, $txt;
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...
2038
2039
	// The main containing header.
2040
	echo '
2041
		<form action="', $scripturl, '?action=profile;area=groupmembership;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2042
			<div class="cat_bar">
2043
				<h3 class="catbg profile_hd">
2044
					', $txt['profile'], '
2045
				</h3>
2046
			</div>
2047
			<p class="information">', $txt['groupMembership_info'], '</p>';
2048
2049
	// Do we have an update message?
2050
	if (!empty($context['update_message']))
2051
		echo '
2052
			<div class="infobox">
2053
				', $context['update_message'], '.
2054
			</div>';
2055
2056
	echo '
2057
			<div id="groups">';
2058
2059
	// Requesting membership to a group?
2060
	if (!empty($context['group_request']))
2061
	{
2062
		echo '
2063
			<div class="groupmembership">
2064
				<div class="cat_bar">
2065
					<h3 class="catbg">', $txt['request_group_membership'], '</h3>
2066
				</div>
2067
				<div class="roundframe">
2068
					', $txt['request_group_membership_desc'], ':
2069
					<textarea name="reason" rows="4"></textarea>
2070
					<div class="righttext">
2071
						<input type="hidden" name="gid" value="', $context['group_request']['id'], '">
2072
						<input type="submit" name="req" value="', $txt['submit_request'], '" class="button">
2073
						</div>
2074
					</div>
2075
				</div><!-- .groupmembership -->';
2076
	}
2077
	else
2078
	{
2079
		echo '
2080
				<div class="title_bar">
2081
					<h3 class="titlebg">', $txt['current_membergroups'], '</h3>
2082
				</div>';
2083
2084
		foreach ($context['groups']['member'] as $group)
2085
		{
2086
			echo '
2087
				<div class="windowbg" id="primdiv_', $group['id'], '">';
2088
2089
				if ($context['can_edit_primary'])
2090
					echo '
2091
					<input type="radio" name="primary" id="primary_', $group['id'], '" value="', $group['id'], '"', $group['is_primary'] ? ' checked' : '', ' onclick="highlightSelected(\'primdiv_' . $group['id'] . '\');"', $group['can_be_primary'] ? '' : ' disabled', '>';
2092
2093
				echo '
2094
					<label for="primary_', $group['id'], '"><strong>', (empty($group['color']) ? $group['name'] : '<span style="color: ' . $group['color'] . '">' . $group['name'] . '</span>'), '</strong>', (!empty($group['desc']) ? '<br><span class="smalltext">' . $group['desc'] . '</span>' : ''), '</label>';
2095
2096
				// Can they leave their group?
2097
				if ($group['can_leave'])
2098
					echo '
2099
					<a href="' . $scripturl . '?action=profile;save;u=' . $context['id_member'] . ';area=groupmembership;' . $context['session_var'] . '=' . $context['session_id'] . ';gid=' . $group['id'] . ';', $context[$context['token_check'] . '_token_var'], '=', $context[$context['token_check'] . '_token'], '">' . $txt['leave_group'] . '</a>';
2100
2101
				echo '
2102
				</div><!-- .windowbg -->';
2103
		}
2104
2105
		if ($context['can_edit_primary'])
2106
			echo '
2107
				<div class="padding righttext">
2108
					<input type="submit" value="', $txt['make_primary'], '" class="button">
2109
				</div>';
2110
2111
		// Any groups they can join?
2112
		if (!empty($context['groups']['available']))
2113
		{
2114
			echo '
2115
				<div class="title_bar">
2116
					<h3 class="titlebg">', $txt['available_groups'], '</h3>
2117
				</div>';
2118
2119
			foreach ($context['groups']['available'] as $group)
2120
			{
2121
				echo '
2122
				<div class="windowbg">
2123
					<strong>', (empty($group['color']) ? $group['name'] : '<span style="color: ' . $group['color'] . '">' . $group['name'] . '</span>'), '</strong>', (!empty($group['desc']) ? '<br><span class="smalltext">' . $group['desc'] . '</span>' : ''), '';
2124
2125
				if ($group['type'] == 3)
2126
					echo '
2127
					<a href="', $scripturl, '?action=profile;save;u=', $context['id_member'], ';area=groupmembership;', $context['session_var'], '=', $context['session_id'], ';gid=', $group['id'], ';', $context[$context['token_check'] . '_token_var'], '=', $context[$context['token_check'] . '_token'], '" class="button floatright">', $txt['join_group'], '</a>';
2128
2129
				elseif ($group['type'] == 2 && $group['pending'])
2130
					echo '
2131
					<span class="floatright">', $txt['approval_pending'], '</span>';
2132
2133
				elseif ($group['type'] == 2)
2134
					echo '
2135
					<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=groupmembership;request=', $group['id'], '" class="button floatright">', $txt['request_group'], '</a>';
2136
2137
				echo '
2138
				</div><!-- .windowbg -->';
2139
			}
2140
		}
2141
2142
		// Javascript for the selector stuff.
2143
		echo '
2144
				<script>
2145
					var prevClass = "";
2146
					var prevDiv = "";
2147
					function highlightSelected(box)
2148
					{
2149
						if (prevClass != "")
2150
						{
2151
							prevDiv.className = prevClass;
2152
						}
2153
						prevDiv = document.getElementById(box);
2154
						prevClass = prevDiv.className;
2155
2156
						prevDiv.className = "windowbg";
2157
					}';
2158
		if (isset($context['groups']['member'][$context['primary_group']]))
2159
			echo '
2160
					highlightSelected("primdiv_' . $context['primary_group'] . '");';
2161
2162
		echo '
2163
				</script>';
2164
	}
2165
2166
	echo '
2167
			</div><!-- #groups -->';
2168
2169 View Code Duplication
	if (!empty($context['token_check']))
2170
		echo '
2171
			<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2172
2173
	echo '
2174
			<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2175
			<input type="hidden" name="u" value="', $context['id_member'], '">
2176
		</form>';
2177
}
2178
2179
/**
2180
 * Template for managing ignored boards
2181
 */
2182
function template_ignoreboards()
2183
{
2184
	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...
2185
2186
	// The main containing header.
2187
	echo '
2188
	<form action="', $scripturl, '?action=profile;area=ignoreboards;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2189
		<div class="cat_bar">
2190
			<h3 class="catbg profile_hd">
2191
				', $txt['profile'], '
2192
			</h3>
2193
		</div>
2194
		<p class="information">', $txt['ignoreboards_info'], '</p>
2195
		<div class="windowbg2">
2196
			<div class="flow_hidden">
2197
				<ul class="ignoreboards floatleft">';
2198
2199
	$i = 0;
2200
	$limit = ceil($context['num_boards'] / 2);
2201
	foreach ($context['categories'] as $category)
2202
	{
2203
		if ($i == $limit)
2204
		{
2205
			echo '
2206
				</ul>
2207
				<ul class="ignoreboards floatright">';
2208
2209
			$i++;
2210
		}
2211
2212
		echo '
2213
					<li class="category">
2214
						<a href="javascript:void(0);" onclick="selectBoards([', implode(', ', $category['child_ids']), '], \'creator\'); return false;">', $category['name'], '</a>
2215
						<ul>';
2216
2217 View Code Duplication
		foreach ($category['boards'] as $board)
2218
		{
2219
			if ($i == $limit)
2220
				echo '
2221
						</ul>
2222
					</li>
2223
				</ul>
2224
				<ul class="ignoreboards floatright">
2225
					<li class="category">
2226
						<ul>';
2227
2228
			echo '
2229
							<li class="board" style="margin-', $context['right_to_left'] ? 'right' : 'left', ': ', $board['child_level'], 'em;">
2230
								<label for="ignore_brd', $board['id'], '"><input type="checkbox" id="brd', $board['id'], '" name="ignore_brd[', $board['id'], ']" value="', $board['id'], '"', $board['selected'] ? ' checked' : '', '> ', $board['name'], '</label>
2231
							</li>';
2232
2233
			$i++;
2234
		}
2235
2236
		echo '
2237
						</ul>
2238
					</li>';
2239
	}
2240
2241
	echo '
2242
				</ul>';
2243
2244
	// Show the standard "Save Settings" profile button.
2245
	template_profile_save();
2246
2247
	echo '
2248
			</div><!-- .flow_hidden -->
2249
		</div><!-- .windowbg2 -->
2250
	</form>
2251
	<br>';
2252
}
2253
2254
/**
2255
 * Simply loads some theme variables common to several warning templates.
2256
 */
2257
function template_load_warning_variables()
2258
{
2259
	global $modSettings, $context;
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...
2260
2261
	$context['warningBarWidth'] = 200;
2262
	// Setup the colors - this is a little messy for theming.
2263
	$context['colors'] = array(
2264
		0 => 'green',
2265
		$modSettings['warning_watch'] => 'darkgreen',
2266
		$modSettings['warning_moderate'] => 'orange',
2267
		$modSettings['warning_mute'] => 'red',
2268
	);
2269
2270
	// Work out the starting color.
2271
	$context['current_color'] = $context['colors'][0];
2272
	foreach ($context['colors'] as $limit => $color)
2273
		if ($context['member']['warning'] >= $limit)
2274
			$context['current_color'] = $color;
2275
}
2276
2277
// Show all warnings of a user?
2278
function template_viewWarning()
2279
{
2280
	global $context, $txt;
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...
2281
2282
	template_load_warning_variables();
2283
2284
	echo '
2285
		<div class="cat_bar">
2286
			<h3 class="catbg profile_hd">
2287
				', sprintf($txt['profile_viewwarning_for_user'], $context['member']['name']), '
2288
			</h3>
2289
		</div>
2290
		<p class="information">', $txt['viewWarning_help'], '</p>
2291
		<div class="windowbg">
2292
			<dl class="settings">
2293
				<dt>
2294
					<strong>', $txt['profile_warning_name'], ':</strong>
2295
				</dt>
2296
				<dd>
2297
					', $context['member']['name'], '
2298
				</dd>
2299
				<dt>
2300
					<strong>', $txt['profile_warning_level'], ':</strong>
2301
				</dt>
2302
				<dd>
2303
					<div>
2304
						<div>
2305
							<div style="font-size: 8pt; height: 12pt; width: ', $context['warningBarWidth'], 'px; border: 1px solid black; background-color: white; padding: 1px; position: relative;">
2306
								<div id="warning_text" style="padding-top: 1pt; width: 100%; z-index: 2; color: black; position: absolute; text-align: center; font-weight: bold;">', $context['member']['warning'], '%</div>
2307
								<div id="warning_progress" style="width: ', $context['member']['warning'], '%; height: 12pt; z-index: 1; background-color: ', $context['current_color'], ';">&nbsp;</div>
2308
							</div>
2309
						</div>
2310
					</div>
2311
				</dd>';
2312
2313
	// There's some impact of this?
2314
	if (!empty($context['level_effects'][$context['current_level']]))
2315
		echo '
2316
				<dt>
2317
					<strong>', $txt['profile_viewwarning_impact'], ':</strong>
2318
				</dt>
2319
				<dd>
2320
					', $context['level_effects'][$context['current_level']], '
2321
				</dd>';
2322
2323
	echo '
2324
			</dl>
2325
		</div><!-- .windowbg -->';
2326
2327
	template_show_list('view_warnings');
2328
}
2329
2330
// Show a lovely interface for issuing warnings.
2331
function template_issueWarning()
2332
{
2333
	global $context, $scripturl, $txt;
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...
2334
2335
	template_load_warning_variables();
2336
2337
	echo '
2338
	<script>
2339
		// Disable notification boxes as required.
2340
		function modifyWarnNotify()
2341
		{
2342
			disable = !document.getElementById(\'warn_notify\').checked;
2343
			document.getElementById(\'warn_sub\').disabled = disable;
2344
			document.getElementById(\'warn_body\').disabled = disable;
2345
			document.getElementById(\'warn_temp\').disabled = disable;
2346
			document.getElementById(\'new_template_link\').style.display = disable ? \'none\' : \'\';
2347
			document.getElementById(\'preview_button\').style.display = disable ? \'none\' : \'\';
2348
		}
2349
2350
		// Warn template.
2351
		function populateNotifyTemplate()
2352
		{
2353
			index = document.getElementById(\'warn_temp\').value;
2354
			if (index == -1)
2355
				return false;
2356
2357
			// Otherwise see what we can do...';
2358
2359
	foreach ($context['notification_templates'] as $k => $type)
2360
		echo '
2361
			if (index == ', $k, ')
2362
				document.getElementById(\'warn_body\').value = "', strtr($type['body'], array('"' => "'", "\n" => '\\n', "\r" => '')), '";';
2363
2364
	echo '
2365
		}
2366
2367
		function updateSlider(slideAmount)
2368
		{
2369
			// Also set the right effect.
2370
			effectText = "";';
2371
2372
	foreach ($context['level_effects'] as $limit => $text)
2373
		echo '
2374
			if (slideAmount >= ', $limit, ')
2375
				effectText = "', $text, '";';
2376
2377
	echo '
2378
			setInnerHTML(document.getElementById(\'cur_level_div\'), slideAmount + \'% (\' + effectText + \')\');
2379
		}
2380
	</script>';
2381
2382
	echo '
2383
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=issuewarning" method="post" class="flow_hidden" accept-charset="', $context['character_set'], '">
2384
		<div class="cat_bar">
2385
			<h3 class="catbg profile_hd">
2386
				', $context['user']['is_owner'] ? $txt['profile_warning_level'] : $txt['profile_issue_warning'], '
2387
			</h3>
2388
		</div>';
2389
2390
	if (!$context['user']['is_owner'])
2391
		echo '
2392
		<p class="information">', $txt['profile_warning_desc'], '</p>';
2393
2394
	echo '
2395
		<div class="windowbg">
2396
			<dl class="settings">';
2397
2398
	if (!$context['user']['is_owner'])
2399
		echo '
2400
				<dt>
2401
					<strong>', $txt['profile_warning_name'], ':</strong>
2402
				</dt>
2403
				<dd>
2404
					<strong>', $context['member']['name'], '</strong>
2405
				</dd>';
2406
2407
	echo '
2408
				<dt>
2409
					<strong>', $txt['profile_warning_level'], ':</strong>';
2410
2411
	// Is there only so much they can apply?
2412
	if ($context['warning_limit'])
2413
		echo '
2414
					<br>
2415
					<span class="smalltext">', sprintf($txt['profile_warning_limit_attribute'], $context['warning_limit']), '</span>';
2416
2417
	echo '
2418
				</dt>
2419
				<dd>
2420
					0% <input name="warning_level" id="warning_level" type="range" min="0" max="100" step="5" value="', $context['member']['warning'], '" onchange="updateSlider(this.value)"> 100%
2421
					<div class="clear_left">
2422
						', $txt['profile_warning_impact'], ': <span id="cur_level_div">', $context['member']['warning'], '% (', $context['level_effects'][$context['current_level']], ')</span>
2423
					</div>
2424
				</dd>';
2425
2426
	if (!$context['user']['is_owner'])
2427
	{
2428
		echo '
2429
				<dt>
2430
					<strong>', $txt['profile_warning_reason'], ':</strong><br>
2431
					<span class="smalltext">', $txt['profile_warning_reason_desc'], '</span>
2432
				</dt>
2433
				<dd>
2434
					<input type="text" name="warn_reason" id="warn_reason" value="', $context['warning_data']['reason'], '" size="50">
2435
				</dd>
2436
			</dl>
2437
			<hr>
2438
			<div id="box_preview"', !empty($context['warning_data']['body_preview']) ? '' : ' style="display:none"', '>
2439
				<dl class="settings">
2440
					<dt>
2441
						<strong>', $txt['preview'], '</strong>
2442
					</dt>
2443
					<dd id="body_preview">
2444
						', !empty($context['warning_data']['body_preview']) ? $context['warning_data']['body_preview'] : '', '
2445
					</dd>
2446
				</dl>
2447
				<hr>
2448
			</div>
2449
			<dl class="settings">
2450
				<dt>
2451
					<strong><label for="warn_notify">', $txt['profile_warning_notify'], ':</label></strong>
2452
				</dt>
2453
				<dd>
2454
					<input type="checkbox" name="warn_notify" id="warn_notify" onclick="modifyWarnNotify();"', $context['warning_data']['notify'] ? ' checked' : '', '>
2455
				</dd>
2456
				<dt>
2457
					<strong><label for="warn_sub">', $txt['profile_warning_notify_subject'], ':</label></strong>
2458
				</dt>
2459
				<dd>
2460
					<input type="text" name="warn_sub" id="warn_sub" value="', empty($context['warning_data']['notify_subject']) ? $txt['profile_warning_notify_template_subject'] : $context['warning_data']['notify_subject'], '" size="50">
2461
				</dd>
2462
				<dt>
2463
					<strong><label for="warn_temp">', $txt['profile_warning_notify_body'], ':</label></strong>
2464
				</dt>
2465
				<dd>
2466
					<select name="warn_temp" id="warn_temp" disabled onchange="populateNotifyTemplate();">
2467
						<option value="-1">', $txt['profile_warning_notify_template'], '</option>
2468
						<option value="-1" disabled>------------------------------</option>';
2469
2470
		foreach ($context['notification_templates'] as $id_template => $template)
2471
			echo '
2472
						<option value="', $id_template, '">', $template['title'], '</option>';
2473
2474
		echo '
2475
					</select>
2476
					<span class="smalltext" id="new_template_link" style="display: none;">[<a href="', $scripturl, '?action=moderate;area=warnings;sa=templateedit;tid=0" target="_blank" rel="noopener">', $txt['profile_warning_new_template'], '</a>]</span>
2477
					<br>
2478
					<textarea name="warn_body" id="warn_body" cols="40" rows="8">', $context['warning_data']['notify_body'], '</textarea>
2479
				</dd>';
2480
	}
2481
	echo '
2482
			</dl>
2483
			<div class="righttext">';
2484
2485 View Code Duplication
	if (!empty($context['token_check']))
2486
		echo '
2487
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2488
2489
	echo '
2490
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2491
				<input type="button" name="preview" id="preview_button" value="', $txt['preview'], '" class="button">
2492
				<input type="submit" name="save" value="', $context['user']['is_owner'] ? $txt['change_profile'] : $txt['profile_warning_issue'], '" class="button">
2493
			</div><!-- .righttext -->
2494
		</div><!-- .windowbg -->
2495
	</form>';
2496
2497
	// Previous warnings?
2498
	template_show_list('view_warnings');
2499
2500
	echo '
2501
	<script>';
2502
2503
	if (!$context['user']['is_owner'])
2504
		echo '
2505
		modifyWarnNotify();
2506
		$(document).ready(function() {
2507
			$("#preview_button").click(function() {
2508
				return ajax_getTemplatePreview();
2509
			});
2510
		});
2511
2512
		function ajax_getTemplatePreview ()
2513
		{
2514
			$.ajax({
2515
				type: "POST",
2516
				url: "' . $scripturl . '?action=xmlhttp;sa=previews;xml",
2517
				data: {item: "warning_preview", title: $("#warn_sub").val(), body: $("#warn_body").val(), issuing: true},
2518
				context: document.body,
2519
				success: function(request){
2520
					$("#box_preview").css({display:""});
2521
					$("#body_preview").html($(request).find(\'body\').text());
2522
					if ($(request).find("error").text() != \'\')
2523
					{
2524
						$("#profile_error").css({display:""});
2525
						var errors_html = \'<ul class="list_errors">\';
2526
						var errors = $(request).find(\'error\').each(function() {
2527
							errors_html += \'<li>\' + $(this).text() + \'</li>\';
2528
						});
2529
						errors_html += \'</ul>\';
2530
2531
						$("#profile_error").html(errors_html);
2532
					}
2533
					else
2534
					{
2535
						$("#profile_error").css({display:"none"});
2536
						$("#error_list").html(\'\');
2537
					}
2538
				return false;
2539
				},
2540
			});
2541
			return false;
2542
		}';
2543
2544
	echo '
2545
	</script>';
2546
}
2547
2548
/**
2549
 * Template to show for deleting a user's account - now with added delete post capability!
2550
 */
2551
function template_deleteAccount()
2552
{
2553
	global $context, $scripturl, $txt;
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...
2554
2555
	// The main containing header.
2556
	echo '
2557
		<form action="', $scripturl, '?action=profile;area=deleteaccount;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2558
			<div class="cat_bar">
2559
				<h3 class="catbg profile_hd">
2560
					', $txt['deleteAccount'], '
2561
				</h3>
2562
			</div>';
2563
2564
	// If deleting another account give them a lovely info box.
2565
	if (!$context['user']['is_owner'])
2566
		echo '
2567
			<p class="information">', $txt['deleteAccount_desc'], '</p>';
2568
2569
	echo '
2570
			<div class="windowbg2">';
2571
2572
	// If they are deleting their account AND the admin needs to approve it - give them another piece of info ;)
2573
	if ($context['needs_approval'])
2574
		echo '
2575
				<div class="errorbox">', $txt['deleteAccount_approval'], '</div>';
2576
2577
	// If the user is deleting their own account warn them first - and require a password!
2578
	if ($context['user']['is_owner'])
2579
	{
2580
		echo '
2581
				<div class="alert">', $txt['own_profile_confirm'], '</div>
2582
				<div>
2583
					<strong', (isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : ''), '>', $txt['current_password'], ': </strong>
2584
					<input type="password" name="oldpasswrd" size="20">
2585
					<input type="submit" value="', $txt['yes'], '" class="button">';
2586
2587 View Code Duplication
		if (!empty($context['token_check']))
2588
			echo '
2589
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2590
2591
		echo '
2592
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2593
					<input type="hidden" name="u" value="', $context['id_member'], '">
2594
					<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2595
				</div>';
2596
	}
2597
	// Otherwise an admin doesn't need to enter a password - but they still get a warning - plus the option to delete lovely posts!
2598
	else
2599
	{
2600
		echo '
2601
				<div class="alert">', $txt['deleteAccount_warning'], '</div>';
2602
2603
		// Only actually give these options if they are kind of important.
2604
		if ($context['can_delete_posts'])
2605
		{
2606
			echo '
2607
				<div>
2608
					<label for="deleteVotes">
2609
						<input type="checkbox" name="deleteVotes" id="deleteVotes" value="1"> ', $txt['deleteAccount_votes'], ':
2610
					</label><br>
2611
					<label for="deletePosts">
2612
						<input type="checkbox" name="deletePosts" id="deletePosts" value="1"> ', $txt['deleteAccount_posts'], ':
2613
					</label>
2614
					<select name="remove_type">
2615
						<option value="posts">', $txt['deleteAccount_all_posts'], '</option>
2616
						<option value="topics">', $txt['deleteAccount_topics'], '</option>
2617
					</select>';
2618
2619
			if ($context['show_perma_delete'])
2620
				echo '
2621
					<br>
2622
					<label for="perma_delete"><input type="checkbox" name="perma_delete" id="perma_delete" value="1">', $txt['deleteAccount_permanent'], ':</label>';
2623
2624
			echo '
2625
				</div>';
2626
		}
2627
2628
		echo '
2629
				<div>
2630
					<label for="deleteAccount"><input type="checkbox" name="deleteAccount" id="deleteAccount" value="1" onclick="if (this.checked) return confirm(\'', $txt['deleteAccount_confirm'], '\');"> ', $txt['deleteAccount_member'], '.</label>
2631
				</div>
2632
				<div>
2633
					<input type="submit" value="', $txt['delete'], '" class="button">';
2634
2635 View Code Duplication
		if (!empty($context['token_check']))
2636
			echo '
2637
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2638
2639
		echo '
2640
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2641
					<input type="hidden" name="u" value="', $context['id_member'], '">
2642
					<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2643
				</div>';
2644
	}
2645
	echo '
2646
			</div><!-- .windowbg2 -->
2647
			<br>
2648
		</form>';
2649
}
2650
2651
/**
2652
 * Template for the password box/save button stuck at the bottom of every profile page.
2653
 */
2654
function template_profile_save()
2655
{
2656
	global $context, $txt;
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...
2657
2658
	echo '
2659
2660
					<hr>';
2661
2662
	// Only show the password box if it's actually needed.
2663 View Code Duplication
	if ($context['require_password'])
2664
		echo '
2665
					<dl class="settings">
2666
						<dt>
2667
							<strong', isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : '', '>', $txt['current_password'], ': </strong><br>
2668
							<span class="smalltext">', $txt['required_security_reasons'], '</span>
2669
						</dt>
2670
						<dd>
2671
							<input type="password" name="oldpasswrd" size="20">
2672
						</dd>
2673
					</dl>';
2674
2675
	echo '
2676
					<div class="righttext">';
2677
2678 View Code Duplication
	if (!empty($context['token_check']))
2679
		echo '
2680
						<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2681
2682
	echo '
2683
						<input type="submit" value="', $txt['change_profile'], '" class="button">
2684
						<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2685
						<input type="hidden" name="u" value="', $context['id_member'], '">
2686
						<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2687
					</div>';
2688
}
2689
2690
/**
2691
 * Small template for showing an error message upon a save problem in the profile.
2692
 */
2693
function template_error_message()
2694
{
2695
	global $context, $txt;
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...
2696
2697
	echo '
2698
		<div class="errorbox" ', empty($context['post_errors']) ? 'style="display:none" ' : '', 'id="profile_error">';
2699
2700
	if (!empty($context['post_errors']))
2701
	{
2702
		echo '
2703
			<span>', !empty($context['custom_error_title']) ? $context['custom_error_title'] : $txt['profile_errors_occurred'], ':</span>
2704
			<ul id="list_errors">';
2705
2706
		// Cycle through each error and display an error message.
2707
		foreach ($context['post_errors'] as $error)
2708
			echo '
2709
				<li>', isset($txt['profile_error_' . $error]) ? $txt['profile_error_' . $error] : $error, '</li>';
2710
2711
		echo '
2712
			</ul>';
2713
	}
2714
2715
	echo '
2716
		</div><!-- #profile_error -->';
2717
}
2718
2719
/**
2720
 * Display a load of drop down selectors for allowing the user to change group.
2721
 */
2722
function template_profile_group_manage()
2723
{
2724
	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...
2725
2726
	echo '
2727
							<dt>
2728
								<strong>', $txt['primary_membergroup'], ': </strong><br>
2729
								<span class="smalltext"><a href="', $scripturl, '?action=helpadmin;help=moderator_why_missing" onclick="return reqOverlayDiv(this.href);"><span class="generic_icons help"></span> ', $txt['moderator_why_missing'], '</a></span>
2730
							</dt>
2731
							<dd>
2732
								<select name="id_group" ', ($context['user']['is_owner'] && $context['member']['group_id'] == 1 ? 'onchange="if (this.value != 1 &amp;&amp; !confirm(\'' . $txt['deadmin_confirm'] . '\')) this.value = 1;"' : ''), '>';
2733
2734
	// Fill the select box with all primary member groups that can be assigned to a member.
2735
	foreach ($context['member_groups'] as $member_group)
2736
		if (!empty($member_group['can_be_primary']))
2737
			echo '
2738
									<option value="', $member_group['id'], '"', $member_group['is_primary'] ? ' selected' : '', '>
2739
										', $member_group['name'], '
2740
									</option>';
2741
2742
	echo '
2743
								</select>
2744
							</dd>
2745
							<dt>
2746
								<strong>', $txt['additional_membergroups'], ':</strong>
2747
							</dt>
2748
							<dd>
2749
								<span id="additional_groupsList">
2750
									<input type="hidden" name="additional_groups[]" value="0">';
2751
2752
	// For each membergroup show a checkbox so members can be assigned to more than one group.
2753
	foreach ($context['member_groups'] as $member_group)
2754
		if ($member_group['can_be_additional'])
2755
			echo '
2756
									<label for="additional_groups-', $member_group['id'], '"><input type="checkbox" name="additional_groups[]" value="', $member_group['id'], '" id="additional_groups-', $member_group['id'], '"', $member_group['is_additional'] ? ' checked' : '', '> ', $member_group['name'], '</label><br>';
2757
2758
	echo '
2759
								</span>
2760
								<a href="javascript:void(0);" onclick="document.getElementById(\'additional_groupsList\').style.display = \'block\'; document.getElementById(\'additional_groupsLink\').style.display = \'none\'; return false;" id="additional_groupsLink" style="display: none;" class="toggle_down">', $txt['additional_membergroups_show'], '</a>
2761
								<script>
2762
									document.getElementById("additional_groupsList").style.display = "none";
2763
									document.getElementById("additional_groupsLink").style.display = "";
2764
								</script>
2765
							</dd>';
2766
2767
}
2768
2769
/**
2770
 * Callback function for entering a birthdate!
2771
 */
2772
function template_profile_birthdate()
2773
{
2774
	global $txt, $context;
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...
2775
2776
	// Just show the pretty box!
2777
	echo '
2778
							<dt>
2779
								<strong>', $txt['dob'], ':</strong><br>
2780
								<span class="smalltext">', $txt['dob_year'], ' - ', $txt['dob_month'], ' - ', $txt['dob_day'], '</span>
2781
							</dt>
2782
							<dd>
2783
								<input type="text" name="bday3" size="4" maxlength="4" value="', $context['member']['birth_date']['year'], '"> -
2784
								<input type="text" name="bday1" size="2" maxlength="2" value="', $context['member']['birth_date']['month'], '"> -
2785
								<input type="text" name="bday2" size="2" maxlength="2" value="', $context['member']['birth_date']['day'], '">
2786
							</dd>';
2787
}
2788
2789
/**
2790
 * Show the signature editing box?
2791
 */
2792
function template_profile_signature_modify()
2793
{
2794
	global $txt, $context;
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...
2795
2796
	echo '
2797
							<dt id="current_signature" style="display:none">
2798
								<strong>', $txt['current_signature'], ':</strong>
2799
							</dt>
2800
							<dd id="current_signature_display" style="display:none">
2801
								<hr>
2802
							</dd>
2803
2804
							<dt id="preview_signature" style="display:none">
2805
								<strong>', $txt['signature_preview'], ':</strong>
2806
							</dt>
2807
							<dd id="preview_signature_display" style="display:none">
2808
								<hr>
2809
							</dd>
2810
2811
							<dt>
2812
								<strong>', $txt['signature'], ':</strong><br>
2813
								<span class="smalltext">', $txt['sig_info'], '</span><br>
2814
								<br>';
2815
2816
	if ($context['show_spellchecking'])
2817
		echo '
2818
								<input type="button" value="', $txt['spell_check'], '" onclick="spellCheck(\'creator\', \'signature\');" class="button">';
2819
2820
	echo '
2821
							</dt>
2822
							<dd>
2823
								<textarea class="editor" onkeyup="calcCharLeft();" id="signature" name="signature" rows="5" cols="50">', $context['member']['signature'], '</textarea><br>';
2824
2825
	// If there is a limit at all!
2826
	if (!empty($context['signature_limits']['max_length']))
2827
		echo '
2828
								<span class="smalltext">', sprintf($txt['max_sig_characters'], $context['signature_limits']['max_length']), ' <span id="signatureLeft">', $context['signature_limits']['max_length'], '</span></span><br>';
2829
2830
	if (!empty($context['show_preview_button']))
2831
		echo '
2832
								<input type="button" name="preview_signature" id="preview_button" value="', $txt['preview_signature'], '" class="button">';
2833
2834
	if ($context['signature_warning'])
2835
		echo '
2836
								<span class="smalltext">', $context['signature_warning'], '</span>';
2837
2838
	// Some javascript used to count how many characters have been used so far in the signature.
2839
	echo '
2840
								<script>
2841
									var maxLength = ', $context['signature_limits']['max_length'], ';
2842
2843
									$(document).ready(function() {
2844
										calcCharLeft();
2845
										$("#preview_button").click(function() {
2846
											return ajax_getSignaturePreview(true);
2847
										});
2848
									});
2849
								</script>
2850
							</dd>';
2851
}
2852
2853
/**
2854
 * Template for selecting an avatar
2855
 */
2856
function template_profile_avatar_select()
2857
{
2858
	global $context, $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...
2859
2860
	// Start with the upper menu
2861
	echo '
2862
							<dt>
2863
								<strong id="personal_picture"><label for="avatar_upload_box">', $txt['personal_picture'], '</label></strong>
2864
								', empty($modSettings['gravatarOverride']) ? '<input type="radio" onclick="swap_avatar(this); return true;" name="avatar_choice" id="avatar_choice_none" value="none"' . ($context['member']['avatar']['choice'] == 'none' ? ' checked="checked"' : '') . '><label for="avatar_choice_none"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['no_avatar'] . '</label><br>' : '', '
2865
								', !empty($context['member']['avatar']['allow_server_stored']) ? '<input type="radio" onclick="swap_avatar(this); return true;" name="avatar_choice" id="avatar_choice_server_stored" value="server_stored"' . ($context['member']['avatar']['choice'] == 'server_stored' ? ' checked="checked"' : '') . '><label for="avatar_choice_server_stored"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['choose_avatar_gallery'] . '</label><br>' : '', '
2866
								', !empty($context['member']['avatar']['allow_external']) ? '<input type="radio" onclick="swap_avatar(this); return true;" name="avatar_choice" id="avatar_choice_external" value="external"' . ($context['member']['avatar']['choice'] == 'external' ? ' checked="checked"' : '') . '><label for="avatar_choice_external"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['my_own_pic'] . '</label><br>' : '', '
2867
								', !empty($context['member']['avatar']['allow_upload']) ? '<input type="radio" onclick="swap_avatar(this); return true;" name="avatar_choice" id="avatar_choice_upload" value="upload"' . ($context['member']['avatar']['choice'] == 'upload' ? ' checked="checked"' : '') . '><label for="avatar_choice_upload"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['avatar_will_upload'] . '</label><br>' : '', '
2868
								', !empty($context['member']['avatar']['allow_gravatar']) ? '<input type="radio" onclick="swap_avatar(this); return true;" name="avatar_choice" id="avatar_choice_gravatar" value="gravatar"' . ($context['member']['avatar']['choice'] == 'gravatar' ? ' checked="checked"' : '') . '><label for="avatar_choice_gravatar"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['use_gravatar'] . '</label>' : '', '
2869
							</dt>
2870
							<dd>';
2871
2872
	// If users are allowed to choose avatars stored on the server show selection boxes to choice them from.
2873
	if (!empty($context['member']['avatar']['allow_server_stored']))
2874
	{
2875
		echo '
2876
								<div id="avatar_server_stored">
2877
									<div>
2878
										<select name="cat" id="cat" size="10" onchange="changeSel(\'\');" onfocus="selectRadioByName(document.forms.creator.avatar_choice, \'server_stored\');">';
2879
2880
		// This lists all the file categories.
2881
		foreach ($context['avatars'] as $avatar)
2882
			echo '
2883
											<option value="', $avatar['filename'] . ($avatar['is_dir'] ? '/' : ''), '"', ($avatar['checked'] ? ' selected' : ''), '>', $avatar['name'], '</option>';
2884
2885
		echo '
2886
										</select>
2887
									</div>
2888
									<div>
2889
										<select name="file" id="file" size="10" style="display: none;" onchange="showAvatar()" onfocus="selectRadioByName(document.forms.creator.avatar_choice, \'server_stored\');" disabled><option></option></select>
2890
									</div>
2891
									<div>
2892
										<img id="avatar" src="', !empty($context['member']['avatar']['allow_external']) && $context['member']['avatar']['choice'] == 'external' ? $context['member']['avatar']['external'] : $modSettings['avatar_url'] . '/blank.png', '" alt="Do Nothing">
2893
									</div>
2894
									<script>
2895
										var files = ["' . implode('", "', $context['avatar_list']) . '"];
2896
										var avatar = document.getElementById("avatar");
2897
										var cat = document.getElementById("cat");
2898
										var selavatar = "' . $context['avatar_selected'] . '";
2899
										var avatardir = "' . $modSettings['avatar_url'] . '/";
2900
										var size = avatar.alt.substr(3, 2) + " " + avatar.alt.substr(0, 2) + String.fromCharCode(117, 98, 116);
2901
										var file = document.getElementById("file");
2902
										var maxHeight = ', !empty($modSettings['avatar_max_height_external']) ? $modSettings['avatar_max_height_external'] : 0, ';
2903
										var maxWidth = ', !empty($modSettings['avatar_max_width_external']) ? $modSettings['avatar_max_width_external'] : 0, ';
2904
2905
										if (avatar.src.indexOf("blank.png") > -1)
2906
											changeSel(selavatar);
2907
										else
2908
											previewExternalAvatar(avatar.src)
2909
2910
									</script>
2911
								</div><!-- #avatar_server_stored -->';
2912
	}
2913
2914
	// If the user can link to an off server avatar, show them a box to input the address.
2915
	if (!empty($context['member']['avatar']['allow_external']))
2916
		echo '
2917
								<div id="avatar_external">
2918
									<div class="smalltext">', $txt['avatar_by_url'], '</div>', !empty($modSettings['avatar_action_too_large']) && $modSettings['avatar_action_too_large'] == 'option_download_and_resize' ? template_max_size('external') : '', '
2919
									<input type="text" name="userpicpersonal" size="45" value="', ((stristr($context['member']['avatar']['external'], 'http://') || stristr($context['member']['avatar']['external'], 'https://')) ? $context['member']['avatar']['external'] : 'http://'), '" onfocus="selectRadioByName(document.forms.creator.avatar_choice, \'external\');" onchange="if (typeof(previewExternalAvatar) != \'undefined\') previewExternalAvatar(this.value);">
2920
								</div>';
2921
2922
	// If the user is able to upload avatars to the server show them an upload box.
2923
	if (!empty($context['member']['avatar']['allow_upload']))
2924
		echo '
2925
								<div id="avatar_upload">
2926
									<input type="file" size="44" name="attachment" id="avatar_upload_box" value="" onchange="readfromUpload(this)"  onfocus="selectRadioByName(document.forms.creator.avatar_choice, \'upload\');" accept="image/gif, image/jpeg, image/jpg, image/png">', template_max_size('upload'), '
2927
									', (!empty($context['member']['avatar']['id_attach']) ? '<br><img src="' . $context['member']['avatar']['href'] . (strpos($context['member']['avatar']['href'], '?') === false ? '?' : '&amp;') . 'time=' . time() . '" alt="" id="attached_image"><input type="hidden" name="id_attach" value="' . $context['member']['avatar']['id_attach'] . '">' : ''), '
2928
								</div>';
2929
2930
	// if the user is able to use Gravatar avatars show then the image preview
2931
	if (!empty($context['member']['avatar']['allow_gravatar']))
2932
	{
2933
		echo '
2934
								<div id="avatar_gravatar">
2935
									<img src="' . $context['member']['avatar']['href'] . '" alt="">';
2936
2937
		if (empty($modSettings['gravatarAllowExtraEmail']))
2938
			echo '
2939
									<div class="smalltext">', $txt['gravatar_noAlternateEmail'], '</div>';
2940
		else
2941
		{
2942
			// Depending on other stuff, the stored value here might have some odd things in it from other areas.
2943
			if ($context['member']['avatar']['external'] == $context['member']['email'])
2944
				$textbox_value = '';
2945
			else
2946
				$textbox_value = $context['member']['avatar']['external'];
2947
2948
			echo '
2949
									<div class="smalltext">', $txt['gravatar_alternateEmail'], '</div>
2950
									<input type="text" name="gravatarEmail" id="gravatarEmail" size="45" value="', $textbox_value, '">';
2951
		}
2952
		echo '
2953
								</div><!-- #avatar_gravatar -->';
2954
	}
2955
2956
	echo '
2957
								<script>
2958
									', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "' . ($context['member']['avatar']['choice'] == 'server_stored' ? '' : 'none') . '";' : '', '
2959
									', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "' . ($context['member']['avatar']['choice'] == 'external' ? '' : 'none') . '";' : '', '
2960
									', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "' . ($context['member']['avatar']['choice'] == 'upload' ? '' : 'none') . '";' : '', '
2961
									', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "' . ($context['member']['avatar']['choice'] == 'gravatar' ? '' : 'none') . '";' : '', '
2962
2963
									function swap_avatar(type)
2964
									{
2965
										switch(type.id)
2966
										{
2967
											case "avatar_choice_server_stored":
2968
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "";' : '', '
2969
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
2970
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
2971
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
2972
												break;
2973
											case "avatar_choice_external":
2974
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
2975
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "";' : '', '
2976
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
2977
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
2978
												break;
2979
											case "avatar_choice_upload":
2980
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
2981
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
2982
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "";' : '', '
2983
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
2984
												break;
2985
											case "avatar_choice_none":
2986
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
2987
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
2988
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
2989
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
2990
												break;
2991
											case "avatar_choice_gravatar":
2992
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
2993
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
2994
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
2995
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "";' : '', '
2996
												', ($context['member']['avatar']['external'] == $context['member']['email'] || strstr($context['member']['avatar']['external'], 'http://')) ?
2997
												'document.getElementById("gravatarEmail").value = "";' : '', '
2998
												break;
2999
										}
3000
									}
3001
								</script>
3002
							</dd>';
3003
}
3004
3005
/**
3006
 * This is just a really little helper to avoid duplicating code unnecessarily
3007
 *
3008
 * @param string $type The type of avatar
3009
 */
3010
function template_max_size($type)
3011
{
3012
	global $modSettings, $txt;
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...
3013
3014
	$w = !empty($modSettings['avatar_max_width_' . $type]) ? comma_format($modSettings['avatar_max_width_' . $type]) : 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $w. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
3015
	$h = !empty($modSettings['avatar_max_height_' . $type]) ? comma_format($modSettings['avatar_max_height_' . $type]) : 0;
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $h. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
3016
3017
	$suffix = (!empty($w) ? 'w' : '') . (!empty($h) ? 'h' : '');
3018
	if (empty($suffix))
3019
		return;
3020
3021
	echo '
3022
								<div class="smalltext">', sprintf($txt['avatar_max_size_' . $suffix], $w, $h), '</div>';
3023
}
3024
3025
/**
3026
 * Select the time format!
3027
 */
3028
function template_profile_timeformat_modify()
3029
{
3030
	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...
3031
3032
	echo '
3033
							<dt>
3034
								<strong><label for="easyformat">', $txt['time_format'], ':</label></strong><br>
3035
								<a href="', $scripturl, '?action=helpadmin;help=time_format" onclick="return reqOverlayDiv(this.href);" class="help"><span class="generic_icons help" title="', $txt['help'], '"></span></a>
3036
								<span class="smalltext">
3037
									<label for="time_format">', $txt['date_format'], '</label>
3038
								</span>
3039
							</dt>
3040
							<dd>
3041
								<select name="easyformat" id="easyformat" onchange="document.forms.creator.time_format.value = this.options[this.selectedIndex].value;">';
3042
3043
	// Help the user by showing a list of common time formats.
3044
	foreach ($context['easy_timeformats'] as $time_format)
3045
		echo '
3046
									<option value="', $time_format['format'], '"', $time_format['format'] == $context['member']['time_format'] ? ' selected' : '', '>', $time_format['title'], '</option>';
3047
3048
	echo '
3049
								</select><br>
3050
								<input type="text" name="time_format" id="time_format" value="', $context['member']['time_format'], '" size="30">
3051
							</dd>';
3052
}
3053
3054
/**
3055
 * Template for picking a theme
3056
 */
3057
function template_profile_theme_pick()
3058
{
3059
	global $txt, $context, $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...
3060
3061
	echo '
3062
							<dt>
3063
								<strong>', $txt['current_theme'], ':</strong>
3064
							</dt>
3065
							<dd>
3066
								', $context['member']['theme']['name'], ' [<a href="', $scripturl, '?action=theme;sa=pick;u=', $context['id_member'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['change'], '</a>]
3067
							</dd>';
3068
}
3069
3070
/**
3071
 * Smiley set picker.
3072
 */
3073
function template_profile_smiley_pick()
3074
{
3075
	global $txt, $context, $modSettings, $settings;
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...
3076
3077
	echo '
3078
							<dt>
3079
								<strong><label for="smiley_set">', $txt['smileys_current'], ':</label></strong>
3080
							</dt>
3081
							<dd>
3082
								<select name="smiley_set" id="smiley_set" onchange="document.getElementById(\'smileypr\').src = this.selectedIndex == 0 ? \'', $settings['images_url'], '/blank.png\' : \'', $modSettings['smileys_url'], '/\' + (this.selectedIndex != 1 ? this.options[this.selectedIndex].value : \'', !empty($settings['smiley_sets_default']) ? $settings['smiley_sets_default'] : $modSettings['smiley_sets_default'], '\') + \'/smiley.gif\';">';
3083
3084
	foreach ($context['smiley_sets'] as $set)
3085
		echo '
3086
									<option value="', $set['id'], '"', $set['selected'] ? ' selected' : '', '>', $set['name'], '</option>';
3087
3088
	echo '
3089
								</select>
3090
								<img id="smileypr" class="centericon" src="', $context['member']['smiley_set']['id'] != 'none' ? $modSettings['smileys_url'] . '/' . ($context['member']['smiley_set']['id'] != '' ? $context['member']['smiley_set']['id'] : (!empty($settings['smiley_sets_default']) ? $settings['smiley_sets_default'] : $modSettings['smiley_sets_default'])) . '/smiley.gif' : $settings['images_url'] . '/blank.png', '" alt=":)">
3091
							</dd>';
3092
}
3093
3094
/**
3095
 * Template for setting up and managing Two-Factor Authentication.
3096
 */
3097
function template_tfasetup()
3098
{
3099
	global $txt, $context, $scripturl, $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...
3100
3101
	echo '
3102
			<div class="cat_bar">
3103
				<h3 class="catbg">', $txt['tfa_title'], '</h3>
3104
			</div>
3105
			<div class="roundframe">
3106
				<div>
3107
		', !empty($context['tfa_backup']) ? '
3108
					<div class="smalltext error">' . $txt['tfa_backup_used_desc'] . '</div>' :
3109
			($modSettings['tfa_mode'] == 2 ? '
3110
									<div class="smalltext"><strong>' . $txt['tfa_forced_desc'] . '</strong></div>' : ''), '
3111
									<div class="smalltext">', $txt['tfa_desc'], '</div>
3112
									<div class="floatleft">
3113
										<form action="', $scripturl, '?action=profile;area=tfasetup" method="post">
3114
											<div class="title_top">
3115
												<strong>', $txt['tfa_step1'], '</strong><br>
3116
												', !empty($context['tfa_pass_error']) ? '<div class="error smalltext">' . $txt['tfa_pass_invalid'] . '</div>' : '', '
3117
												<input type="password" name="passwd" size="25"', !empty($context['tfa_pass_error']) ? ' class="error"' : '', !empty($context['tfa_pass_value']) ? ' value="' . $context['tfa_pass_value'] . '"' : '', '>
3118
											</div>
3119
											<div class="title_top">
3120
												<strong>', $txt['tfa_step2'], '</strong>
3121
												<div class="smalltext">', $txt['tfa_step2_desc'], '</div>
3122
												<div class="tfacode">', $context['tfa_secret'], '</div>
3123
											</div>
3124
											<div class="title_top">
3125
												<strong>', $txt['tfa_step3'], '</strong><br>
3126
												', !empty($context['tfa_error']) ? '<div class="error smalltext">' . $txt['tfa_code_invalid'] . '</div>' : '', '
3127
												<input type="text" name="tfa_code" size="25"', !empty($context['tfa_error']) ? ' class="error"' : '', !empty($context['tfa_value']) ? ' value="' . $context['tfa_value'] . '"' : '', '>
3128
												<input type="submit" name="save" value="', $txt['tfa_enable'], '" class="button">
3129
											</div>
3130
											<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3131
											<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3132
										</form>
3133
									</div>
3134
									<div class="floatright tfa_qrcode">
3135
										<img src="', $context['tfa_qr_url'], '" alt="">
3136
									</div>';
3137
3138
	if (!empty($context['from_ajax']))
3139
		echo '
3140
					<br>
3141
					<a href="javascript:self.close();"></a>';
3142
3143
	echo '
3144
				</div>
3145
			</div><!-- .roundframe -->';
3146
}
3147
3148
/**
3149
 * Template for setting up 2FA backup code
3150
 */
3151
function template_tfasetup_backup()
3152
{
3153
	global $context, $txt;
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...
3154
3155
	echo '
3156
			<div class="cat_bar">
3157
				<h3 class="catbg">', $txt['tfa_backup_title'], '</h3>
3158
			</div>
3159
			<div class="roundframe">
3160
				<div>
3161
					<div class="smalltext">', $txt['tfa_backup_desc'], '</div>
3162
					<div class="bbc_code" style="resize: none; border: none;">', $context['tfa_backup'], '</div>
3163
				</div>
3164
			</div>';
3165
}
3166
3167
/**
3168
 * Simple template for showing the 2FA area when editing a profile.
3169
 */
3170
function template_profile_tfa()
3171
{
3172
	global $context, $txt, $scripturl, $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...
3173
3174
	echo '
3175
							<dt>
3176
								<strong>', $txt['tfa_profile_label'], ':</strong><br>
3177
								<div class="smalltext">', $txt['tfa_profile_desc'], '</div>
3178
							</dt>
3179
							<dd>';
3180
3181
	if (!$context['tfa_enabled'] && $context['user']['is_owner'])
3182
		echo '
3183
								<a href="', !empty($modSettings['force_ssl']) && $modSettings['force_ssl'] < 2 ? strtr($scripturl, array('http://' => 'https://')) : $scripturl, '?action=profile;area=tfasetup" id="enable_tfa">', $txt['tfa_profile_enable'], '</a>';
3184
3185
	elseif (!$context['tfa_enabled'])
3186
		echo '
3187
								', $txt['tfa_profile_disabled'];
3188
3189
	else
3190
		echo '
3191
								', sprintf($txt['tfa_profile_enabled'], $scripturl . '?action=profile;u=' . $context['id_member'] . ';area=tfasetup;disable');
3192
3193
	echo '
3194
							</dd>';
3195
}
3196
3197
?>