Issues (1014)

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

1
<?php
2
/**
3
 * Simple Machines Forum (SMF)
4
 *
5
 * @package SMF
6
 * @author Simple Machines https://www.simplemachines.org
7
 * @copyright 2022 Simple Machines and individual contributors
8
 * @license https://www.simplemachines.org/about/smf/license.php BSD
9
 *
10
 * @version 2.1.2
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;
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();
0 ignored issues
show
Are you sure the usage of template_error_message() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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;
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;
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
		{
109
			echo '
110
			<', !$details['show_links'] ? 'a href="' . $scripturl . '?action=profile;area=showalerts;alert=' . $id_alert . '" onclick="this.classList.add(\'alert_read\')"' : 'div', ' class="unread_notify">
111
				<div class="unread_notify_image">
112
					', empty($details['sender']['avatar']['image']) ? '' : $details['sender']['avatar']['image'] . '
113
					', $details['icon'], '
114
				</div>
115
				<div class="details">
116
					<span class="alert_text">', $details['text'], '</span> - <span class="alert_time">', $details['time'], '</span>
117
				</div>
118
			</', !$details['show_links'] ? 'a' : 'div', '>';
119
		}
120
	}
121
122
	echo '
123
		</div><!-- .alerts_unread -->
124
		<script>
125
			function markAlertsRead(obj) {
126
				ajax_indicator(true);
127
				$.get(
128
					obj.href,
129
					function(data) {
130
						ajax_indicator(false);
131
						$("#alerts_menu_top span.amt").remove();
132
						$("#alerts_menu div.alerts_unread").html(data);
133
						if (typeof localStorage != "undefined")
134
							localStorage.setItem("alertsCounter", 0);
135
					}
136
				);
137
				return false;
138
			}
139
		</script>';
140
}
141
142
/**
143
 * A simple template to say "You don't have any unread alerts".
144
 */
145
function template_alerts_all_read()
146
{
147
	global $txt;
148
149
	echo '<div class="no_unread">', $txt['alerts_no_unread'], '</div>';
150
}
151
152
/**
153
 * This template displays a user's details without any option to edit them.
154
 */
155
function template_summary()
156
{
157
	global $context, $settings, $scripturl, $modSettings, $txt;
158
159
	// Display the basic information about the user
160
	echo '
161
	<div id="profileview" class="roundframe flow_auto noup">
162
		<div id="basicinfo">';
163
164
	// Are there any custom profile fields for above the name?
165
	if (!empty($context['print_custom_fields']['above_member']))
166
	{
167
		$fields = '';
168
		foreach ($context['print_custom_fields']['above_member'] as $field)
169
			if (!empty($field['output_html']))
170
				$fields .= '
171
					<li>' . $field['output_html'] . '</li>';
172
173
		if (!empty($fields))
174
			echo '
175
			<div class="custom_fields_above_name">
176
				<ul>', $fields, '
177
				</ul>
178
			</div>';
179
	}
180
181
	echo '
182
			<div class="username clear">
183
				<h4>';
184
185
	if (!empty($context['print_custom_fields']['before_member']))
186
		foreach ($context['print_custom_fields']['before_member'] as $field)
187
			if (!empty($field['output_html']))
188
				echo '
189
					<span>', $field['output_html'], '</span>';
190
191
	echo '
192
					', $context['member']['name'];
193
194
	if (!empty($context['print_custom_fields']['after_member']))
195
		foreach ($context['print_custom_fields']['after_member'] as $field)
196
			if (!empty($field['output_html']))
197
				echo '
198
					<span>', $field['output_html'], '</span>';
199
200
	echo '
201
					<span class="position">', (!empty($context['member']['group']) ? $context['member']['group'] : $context['member']['post_group']), '</span>
202
				</h4>
203
			</div>
204
			', $context['member']['avatar']['image'];
205
206
	// Are there any custom profile fields for below the avatar?
207
	if (!empty($context['print_custom_fields']['below_avatar']))
208
	{
209
		$fields = '';
210
		foreach ($context['print_custom_fields']['below_avatar'] as $field)
211
			if (!empty($field['output_html']))
212
				$fields .= '
213
					<li>' . $field['output_html'] . '</li>';
214
215
		if (!empty($fields))
216
			echo '
217
			<div class="custom_fields_below_avatar">
218
				<ul>', $fields, '
219
				</ul>
220
			</div>';
221
	}
222
223
	echo '
224
			<ul class="icon_fields clear">';
225
226
	// Email is only visible if it's your profile or you have the moderate_forum permission
227
	if ($context['member']['show_email'])
228
		echo '
229
				<li><a href="mailto:', $context['member']['email'], '" title="', $context['member']['email'], '" rel="nofollow"><span class="main_icons mail" title="' . $txt['email'] . '"></span></a></li>';
230
231
	// Don't show an icon if they haven't specified a website.
232
	if ($context['member']['website']['url'] !== '' && !isset($context['disabled_fields']['website']))
233
		echo '
234
				<li><a href="', $context['member']['website']['url'], '" title="' . $context['member']['website']['title'] . '" target="_blank" rel="noopener">', ($settings['use_image_buttons'] ? '<span class="main_icons www" title="' . $context['member']['website']['title'] . '"></span>' : $txt['www']), '</a></li>';
235
236
	// Are there any custom profile fields as icons?
237
	if (!empty($context['print_custom_fields']['icons']))
238
	{
239
		foreach ($context['print_custom_fields']['icons'] as $field)
240
			if (!empty($field['output_html']))
241
				echo '
242
				<li class="custom_field">', $field['output_html'], '</li>';
243
	}
244
245
	echo '
246
			</ul>
247
			<span id="userstatus">
248
				', $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>' : '';
249
250
	// Can they add this member as a buddy?
251
	if (!empty($context['can_have_buddy']) && !$context['user']['is_owner'])
252
		echo '
253
				<br>
254
				<a href="', $scripturl, '?action=buddy;u=', $context['id_member'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['buddy_' . ($context['member']['is_buddy'] ? 'remove' : 'add')], '</a>';
255
256
	echo '
257
			</span>';
258
259
	if (!$context['user']['is_owner'] && $context['can_send_pm'])
260
		echo '
261
			<a href="', $scripturl, '?action=pm;sa=send;u=', $context['id_member'], '" class="infolinks">', $txt['profile_sendpm_short'], '</a>';
262
263
	echo '
264
			<a href="', $scripturl, '?action=profile;area=showposts;u=', $context['id_member'], '" class="infolinks">', $txt['showPosts'], '</a>';
265
266
	if ($context['user']['is_owner'] && !empty($modSettings['drafts_post_enabled']))
267
		echo '
268
			<a href="', $scripturl, '?action=profile;area=showdrafts;u=', $context['id_member'], '" class="infolinks">', $txt['drafts_show'], '</a>';
269
270
	echo '
271
			<a href="', $scripturl, '?action=profile;area=statistics;u=', $context['id_member'], '" class="infolinks">', $txt['statPanel'], '</a>';
272
273
	// Are there any custom profile fields for bottom?
274
	if (!empty($context['print_custom_fields']['bottom_poster']))
275
	{
276
		$fields = '';
277
		foreach ($context['print_custom_fields']['bottom_poster'] as $field)
278
			if (!empty($field['output_html']))
279
				$fields .= '
280
					<li>' . $field['output_html'] . '</li>';
281
282
		if (!empty($fields))
283
			echo '
284
			<div class="custom_fields_bottom">
285
				<ul class="nolist">', $fields, '
286
				</ul>
287
			</div>';
288
	}
289
290
	echo '
291
		</div><!-- #basicinfo -->
292
293
		<div id="detailedinfo">
294
			<dl class="settings">';
295
296
	if ($context['user']['is_owner'] || $context['user']['is_admin'])
297
		echo '
298
				<dt>', $txt['username'], ': </dt>
299
				<dd>', $context['member']['username'], '</dd>';
300
301
	if (!isset($context['disabled_fields']['posts']))
302
		echo '
303
				<dt>', $txt['profile_posts'], ': </dt>
304
				<dd>', $context['member']['posts'], ' (', $context['member']['posts_per_day'], ' ', $txt['posts_per_day'], ')</dd>';
305
306
	if ($context['member']['show_email'])
307
		echo '
308
				<dt>', $txt['email'], ': </dt>
309
				<dd><a href="mailto:', $context['member']['email'], '">', $context['member']['email'], '</a></dd>';
310
311
	if (!empty($modSettings['titlesEnable']) && !empty($context['member']['title']))
312
		echo '
313
				<dt>', $txt['custom_title'], ': </dt>
314
				<dd>', $context['member']['title'], '</dd>';
315
316
	if (!empty($context['member']['blurb']))
317
		echo '
318
				<dt>', $txt['personal_text'], ': </dt>
319
				<dd>', $context['member']['blurb'], '</dd>';
320
321
	echo '
322
				<dt>', $txt['age'], ':</dt>
323
				<dd>', $context['member']['age'] . ($context['member']['today_is_birthday'] ? ' &nbsp; <img src="' . $settings['images_url'] . '/cake.png" alt="">' : ''), '</dd>';
324
325
	echo '
326
			</dl>';
327
328
	// Any custom fields for standard placement?
329
	if (!empty($context['print_custom_fields']['standard']))
330
	{
331
		$fields = array();
332
333
		foreach ($context['print_custom_fields']['standard'] as $field)
334
			if (!empty($field['output_html']))
335
				$fields[] = $field;
336
337
		if (count($fields) > 0)
338
		{
339
			echo '
340
			<dl class="settings">';
341
342
			foreach ($fields as $field)
343
				echo '
344
				<dt>', $field['name'], ':</dt>
345
				<dd>', $field['output_html'], '</dd>';
346
347
			echo '
348
			</dl>';
349
		}
350
	}
351
352
	echo '
353
			<dl class="settings noborder">';
354
355
	// Can they view/issue a warning?
356
	if ($context['can_view_warning'] && $context['member']['warning'])
357
	{
358
		echo '
359
				<dt>', $txt['profile_warning_level'], ': </dt>
360
				<dd>
361
					<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=', ($context['can_issue_warning'] && !$context['user']['is_owner'] ? 'issuewarning' : 'viewwarning'), '">', $context['member']['warning'], '%</a>';
362
363
		// Can we provide information on what this means?
364
		if (!empty($context['warning_status']))
365
			echo '
366
					<span class="smalltext">(', $context['warning_status'], ')</span>';
367
368
		echo '
369
				</dd>';
370
	}
371
372
	// Is this member requiring activation and/or banned?
373
	if (!empty($context['activate_message']) || !empty($context['member']['bans']))
374
	{
375
		// If the person looking at the summary has permission, and the account isn't activated, give the viewer the ability to do it themselves.
376
		if (!empty($context['activate_message']))
377
			echo '
378
				<dt class="clear">
379
					<span class="alert">', $context['activate_message'], '</span> (<a href="', $context['activate_link'], '">', $context['activate_link_text'], '</a>)
380
				</dt>';
381
382
		// If the current member is banned, show a message and possibly a link to the ban.
383
		if (!empty($context['member']['bans']))
384
		{
385
			echo '
386
				<dt class="clear">
387
					<span class="alert">', $txt['user_is_banned'], '</span>&nbsp;[<a href="#" onclick="document.getElementById(\'ban_info\').classList.toggle(\'hidden\');return false;">' . $txt['view_ban'] . '</a>]
388
				</dt>
389
				<dt class="clear hidden" id="ban_info">
390
					<strong>', $txt['user_banned_by_following'], ':</strong>';
391
392
			foreach ($context['member']['bans'] as $ban)
393
				echo '
394
					<br>
395
					<span class="smalltext">', $ban['explanation'], '</span>';
396
397
			echo '
398
				</dt>';
399
		}
400
	}
401
402
	echo '
403
				<dt>', $txt['date_registered'], ': </dt>
404
				<dd>', $context['member']['registered'], '</dd>';
405
406
	// If the person looking is allowed, they can check the members IP address and hostname.
407
	if ($context['can_see_ip'])
408
	{
409
		if (!empty($context['member']['ip']))
410
			echo '
411
				<dt>', $txt['ip'], ': </dt>
412
				<dd><a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['member']['ip'], ';u=', $context['member']['id'], '">', $context['member']['ip'], '</a></dd>';
413
414
		if (empty($modSettings['disableHostnameLookup']) && !empty($context['member']['ip']))
415
			echo '
416
				<dt>', $txt['hostname'], ': </dt>
417
				<dd>', $context['member']['hostname'], '</dd>';
418
	}
419
420
	echo '
421
				<dt>', $txt['local_time'], ':</dt>
422
				<dd>', $context['member']['local_time'], '</dd>';
423
424
	if (!empty($modSettings['userLanguage']) && !empty($context['member']['language']))
425
		echo '
426
				<dt>', $txt['language'], ':</dt>
427
				<dd>', $context['member']['language'], '</dd>';
428
429
	if ($context['member']['show_last_login'])
430
		echo '
431
				<dt>', $txt['lastLoggedIn'], ': </dt>
432
				<dd>', $context['member']['last_login'], (!empty($context['member']['is_hidden']) ? ' (' . $txt['hidden'] . ')' : ''), '</dd>';
433
434
	echo '
435
			</dl>';
436
437
	// Are there any custom profile fields for above the signature?
438
	if (!empty($context['print_custom_fields']['above_signature']))
439
	{
440
		$fields = '';
441
		foreach ($context['print_custom_fields']['above_signature'] as $field)
442
			if (!empty($field['output_html']))
443
				$fields .= '
444
					<li>' . $field['output_html'] . '</li>';
445
446
		if (!empty($fields))
447
			echo '
448
			<div class="custom_fields_above_signature">
449
				<ul class="nolist">', $fields, '
450
				</ul>
451
			</div>';
452
	}
453
454
	// Show the users signature.
455
	if ($context['signature_enabled'] && !empty($context['member']['signature']))
456
		echo '
457
			<div class="signature">
458
				<h5>', $txt['signature'], ':</h5>
459
				', $context['member']['signature'], '
460
			</div>';
461
462
	// Are there any custom profile fields for below the signature?
463
	if (!empty($context['print_custom_fields']['below_signature']))
464
	{
465
		$fields = '';
466
		foreach ($context['print_custom_fields']['below_signature'] as $field)
467
			if (!empty($field['output_html']))
468
				$fields .= '
469
					<li>' . $field['output_html'] . '</li>';
470
471
		if (!empty($fields))
472
			echo '
473
			<div class="custom_fields_below_signature">
474
				<ul class="nolist">', $fields, '
475
				</ul>
476
			</div>';
477
	}
478
479
	echo '
480
		</div><!-- #detailedinfo -->
481
	</div><!-- #profileview -->';
482
}
483
484
/**
485
 * Template for showing all the posts of the user, in chronological order.
486
 */
487
function template_showPosts()
488
{
489
	global $context, $scripturl, $txt;
490
491
	echo '
492
		<div class="cat_bar', !isset($context['attachments']) ? ' cat_bar_round' : '', '">
493
			<h3 class="catbg">
494
				', (!isset($context['attachments']) && empty($context['is_topics']) ? $txt['showMessages'] : (!empty($context['is_topics']) ? $txt['showTopics'] : $txt['showAttachments'])), !$context['user']['is_owner'] ? ' - ' . $context['member']['name'] : '', '
495
			</h3>
496
		</div>', !empty($context['page_index']) ? '
497
		<div class="pagesection">
498
			<div class="pagelinks">' . $context['page_index'] . '</div>
499
		</div>' : '';
500
501
	// Are we displaying posts or attachments?
502
	if (!isset($context['attachments']))
503
	{
504
		// For every post to be displayed, give it its own div, and show the important details of the post.
505
		foreach ($context['posts'] as $post)
506
		{
507
			echo '
508
		<div class="', $post['css_class'], '">
509
			<div class="page_number floatright"> #', $post['counter'], '</div>
510
			<div class="topic_details">
511
				<h5>
512
					<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>
513
				</h5>
514
				<span class="smalltext">', $post['time'], '</span>
515
			</div>';
516
517
			if (!$post['approved'])
518
				echo '
519
			<div class="noticebox">
520
				', $txt['post_awaiting_approval'], '
521
			</div>';
522
523
			echo '
524
			<div class="post">
525
				<div class="inner">
526
					', $post['body'], '
527
				</div>
528
			</div><!-- .post -->';
529
530
			// Post options
531
			template_quickbuttons($post['quickbuttons'], 'profile_showposts');
532
533
			echo '
534
		</div><!-- .', $post['css_class'], ' -->';
535
		}
536
	}
537
	else
538
		template_show_list('attachments');
539
540
	// No posts? Just end with a informative message.
541
	if ((isset($context['attachments']) && empty($context['attachments'])) || (!isset($context['attachments']) && empty($context['posts'])))
542
		echo '
543
		<div class="windowbg">
544
			', isset($context['attachments']) ? $txt['show_attachments_none'] : ($context['is_topics'] ? $txt['show_topics_none'] : $txt['show_posts_none']), '
545
		</div>';
546
547
	// Show more page numbers.
548
	if (!empty($context['page_index']))
549
		echo '
550
		<div class="pagesection">
551
			<div class="pagelinks">', $context['page_index'], '</div>
552
		</div>';
553
}
554
555
/**
556
 * Template for showing all alerts
557
 */
558
function template_showAlerts()
559
{
560
	global $context, $txt, $scripturl;
561
562
	// Do we have an update message?
563
	if (!empty($context['update_message']))
564
		echo '
565
		<div class="infobox">
566
			', $context['update_message'], '
567
		</div>';
568
569
	echo '
570
		<div class="cat_bar">
571
			<h3 class="catbg">
572
			', $txt['alerts'], !$context['user']['is_owner'] ? ' - ' . $context['member']['name'] : '', '
573
			</h3>
574
		</div>';
575
576
	if (empty($context['alerts']))
577
		echo '
578
		<div class="information">
579
			', $txt['alerts_none'], '
580
		</div>';
581
582
	else
583
	{
584
		// Start the form if checkboxes are in use
585
		if ($context['showCheckboxes'])
586
			echo '
587
		<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=showalerts;save" method="post" accept-charset="', $context['character_set'], '" id="mark_all">';
588
589
		echo '
590
			<table id="alerts" class="table_grid">';
591
592
		foreach ($context['alerts'] as $id => $alert)
593
		{
594
			echo '
595
				<tr class="windowbg">
596
					<td class="alert_image">
597
						<div>
598
							', empty($alert['sender']['avatar']['image']) ? '' : $alert['sender']['avatar']['image'] . '
599
							', $alert['icon'], '
600
						</div>
601
					</td>
602
					<td class="alert_text">
603
						<div>', $alert['text'], '</div>
604
						<time class="alert_inline_time" datetime="', $alert['alert_time'], '">', $alert['time'], '</time>
605
					</td>
606
					<td class="alert_time">
607
						<time datetime="', $alert['alert_time'], '">', $alert['time'], '</time>
608
					</td>
609
					<td class="alert_buttons">';
610
611
			// Alert options
612
			template_quickbuttons($alert['quickbuttons'], 'profile_alerts');
613
614
			echo '
615
					</td>
616
				</tr>';
617
		}
618
619
		echo '
620
			</table>
621
			<div class="pagesection">
622
				<div class="pagelinks">', $context['pagination'], '</div>
623
				<div class="floatright">';
624
625
		if ($context['showCheckboxes'])
626
			echo '
627
					', $txt['check_all'], ': <input type="checkbox" name="select_all" id="select_all">
628
					<select name="mark_as">
629
						<option value="read">', $txt['quick_mod_markread'], '</option>
630
						<option value="unread">', $txt['quick_mod_markunread'], '</option>
631
						<option value="remove">', $txt['quick_mod_remove'], '</option>
632
					</select>
633
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
634
					<input type="hidden" name="start" value="', $context['start'], '">
635
					<input type="submit" name="req" value="', $txt['quick_mod_go'], '" class="button you_sure">';
636
637
		echo '
638
					<a href="', $context['alert_purge_link'], '" class="button you_sure">', $txt['alert_purge'], '</a>
639
				</div>
640
			</div>';
641
642
		if ($context['showCheckboxes'])
643
			echo '
644
		</form>';
645
	}
646
}
647
648
/**
649
 * Template for showing all of a user's drafts
650
 */
651
function template_showDrafts()
652
{
653
	global $context, $scripturl, $txt;
654
655
	echo '
656
		<div class="cat_bar cat_bar_round">
657
			<h3 class="catbg">
658
				', $txt['drafts'], !$context['user']['is_owner'] ? ' - ' . $context['member']['name'] : '', '
659
			</h3>
660
		</div>', !empty($context['page_index']) ? '
661
		<div class="pagesection">
662
			<div class="pagelinks">' . $context['page_index'] . '</div>
663
		</div>' : '';
664
665
	// No drafts? Just show an informative message.
666
	if (empty($context['drafts']))
667
		echo '
668
		<div class="windowbg centertext">
669
			', $txt['draft_none'], '
670
		</div>';
671
	else
672
	{
673
		// For every draft to be displayed, give it its own div, and show the important details of the draft.
674
		foreach ($context['drafts'] as $draft)
675
		{
676
			echo '
677
		<div class="windowbg">
678
			<div class="page_number floatright"> #', $draft['counter'], '</div>
679
			<div class="topic_details">
680
				<h5>
681
					<strong><a href="', $scripturl, '?board=', $draft['board']['id'], '.0">', $draft['board']['name'], '</a> / ', $draft['topic']['link'], '</strong> &nbsp; &nbsp;';
682
683
			if (!empty($draft['sticky']))
684
				echo '
685
					<span class="main_icons sticky" title="', $txt['sticky_topic'], '"></span>';
686
687
			if (!empty($draft['locked']))
688
				echo '
689
					<span class="main_icons lock" title="', $txt['locked_topic'], '"></span>';
690
691
			echo '
692
				</h5>
693
				<span class="smalltext"><strong>', $txt['draft_saved_on'], ':</strong> ', $draft['time'], '</span>
694
			</div><!-- .topic_details -->
695
			<div class="list_posts">
696
				', $draft['body'], '
697
			</div>
698
			<div class="floatright">';
699
700
			// Draft buttons
701
			template_quickbuttons($draft['quickbuttons'], 'profile_drafts');
702
703
			echo '
704
			</div><!-- .floatright -->
705
		</div><!-- .windowbg -->';
706
		}
707
	}
708
709
	// Show page numbers.
710
	echo '
711
		<div class="pagesection">
712
			<div class="pagelinks">', $context['page_index'], '</div>
713
		</div>';
714
}
715
716
/**
717
 * Template for showing and managing the buddy list.
718
 */
719
function template_editBuddies()
720
{
721
	global $context, $scripturl, $txt;
722
723
	if (!empty($context['saved_successful']))
724
		echo '
725
	<div class="infobox">', $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $context['member']['name']), '</div>';
726
727
	elseif (!empty($context['saved_failed']))
728
		echo '
729
	<div class="errorbox">', $context['saved_failed'], '</div>';
730
731
	echo '
732
	<div id="edit_buddies">
733
		<div class="cat_bar">
734
			<h3 class="catbg">
735
				<span class="main_icons people icon"></span> ', $txt['editBuddies'], '
736
			</h3>
737
		</div>
738
		<table class="table_grid">
739
			<thead>
740
				<tr class="title_bar">
741
					<th scope="col" class="quarter_table buddy_link">', $txt['name'], '</th>
742
					<th scope="col" class="buddy_status">', $txt['status'], '</th>';
743
744
	if ($context['can_moderate_forum'])
745
		echo '
746
					<th scope="col" class="buddy_email">', $txt['email'], '</th>';
747
748
	if (!empty($context['custom_pf']))
749
		foreach ($context['custom_pf'] as $column)
750
			echo '
751
					<th scope="col" class="buddy_custom_fields">', $column['label'], '</th>';
752
753
	echo '
754
					<th scope="col" class="buddy_remove">', $txt['remove'], '</th>
755
				</tr>
756
			</thead>
757
			<tbody>';
758
759
	// If they don't have any buddies don't list them!
760
	if (empty($context['buddies']))
761
		echo '
762
				<tr class="windowbg">
763
					<td colspan="', $context['can_moderate_forum'] ? '10' : '9', '">
764
						<strong>', $txt['no_buddies'], '</strong>
765
					</td>
766
				</tr>';
767
768
	// Now loop through each buddy showing info on each.
769
	else
770
	{
771
		foreach ($context['buddies'] as $buddy)
772
		{
773
			echo '
774
				<tr class="windowbg">
775
					<td class="buddy_link">', $buddy['link'], '</td>
776
					<td class="centertext buddy_status">
777
						<a href="', $buddy['online']['href'], '"><span class="' . ($buddy['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $buddy['online']['text'] . '"></span></a>
778
					</td>';
779
780
			if ($buddy['show_email'])
781
				echo '
782
					<td class="buddy_email centertext">
783
						<a href="mailto:' . $buddy['email'] . '" rel="nofollow"><span class="main_icons mail icon" title="' . $txt['email'] . ' ' . $buddy['name'] . '"></span></a>
784
					</td>';
785
786
			// Show the custom profile fields for this user.
787
			if (!empty($context['custom_pf']))
788
				foreach ($context['custom_pf'] as $key => $column)
789
					echo '
790
					<td class="centertext buddy_custom_fields">', $buddy['options'][$key], '</td>';
791
792
			echo '
793
					<td class="centertext buddy_remove">
794
						<a href="', $scripturl, '?action=profile;area=lists;sa=buddies;u=', $context['id_member'], ';remove=', $buddy['id'], ';', $context['session_var'], '=', $context['session_id'], '"><span class="main_icons delete" title="', $txt['buddy_remove'], '"></span></a>
795
					</td>
796
				</tr>';
797
		}
798
	}
799
800
	echo '
801
			</tbody>
802
		</table>
803
	</div><!-- #edit_buddies -->';
804
805
	// Add a new buddy?
806
	echo '
807
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=buddies" method="post" accept-charset="', $context['character_set'], '">
808
		<div class="cat_bar">
809
			<h3 class="catbg">', $txt['buddy_add'], '</h3>
810
		</div>
811
		<div class="information">
812
			<dl class="settings">
813
				<dt>
814
					<label for="new_buddy"><strong>', $txt['who_member'], ':</strong></label>
815
				</dt>
816
				<dd>
817
					<input type="text" name="new_buddy" id="new_buddy" size="30">
818
					<input type="submit" value="', $txt['buddy_add_button'], '" class="button floatnone">
819
				</dd>
820
			</dl>
821
		</div>';
822
823
	if (!empty($context['token_check']))
824
		echo '
825
		<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
826
827
	echo '
828
		<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
829
	</form>
830
	<script>
831
		var oAddBuddySuggest = new smc_AutoSuggest({
832
			sSelf: \'oAddBuddySuggest\',
833
			sSessionId: smf_session_id,
834
			sSessionVar: smf_session_var,
835
			sSuggestId: \'new_buddy\',
836
			sControlId: \'new_buddy\',
837
			sSearchType: \'member\',
838
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
839
			bItemList: false
840
		});
841
	</script>';
842
}
843
844
/**
845
 * Template for showing the ignore list of the current user.
846
 */
847
function template_editIgnoreList()
848
{
849
	global $context, $scripturl, $txt;
850
851
	if (!empty($context['saved_successful']))
852
		echo '
853
	<div class="infobox">', $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $context['member']['name']), '</div>';
854
855
	elseif (!empty($context['saved_failed']))
856
		echo '
857
	<div class="errorbox">', $context['saved_failed'], '</div>';
858
859
	echo '
860
	<div id="edit_buddies">
861
		<div class="cat_bar">
862
			<h3 class="catbg profile_hd">
863
				', $txt['editIgnoreList'], '
864
			</h3>
865
		</div>
866
		<table class="table_grid">
867
			<thead>
868
				<tr class="title_bar">
869
					<th scope="col" class="quarter_table buddy_link">', $txt['name'], '</th>
870
					<th scope="col" class="buddy_status">', $txt['status'], '</th>';
871
872
	if ($context['can_moderate_forum'])
873
		echo '
874
					<th scope="col" class="buddy_email">', $txt['email'], '</th>';
875
876
	echo '
877
					<th scope="col" class="buddy_remove">', $txt['ignore_remove'], '</th>
878
				</tr>
879
			</thead>
880
			<tbody>';
881
882
	// If they don't have anyone on their ignore list, don't list it!
883
	if (empty($context['ignore_list']))
884
		echo '
885
				<tr class="windowbg">
886
					<td colspan="', $context['can_moderate_forum'] ? '4' : '3', '">
887
						<strong>', $txt['no_ignore'], '</strong>
888
					</td>
889
				</tr>';
890
891
	// Now loop through each buddy showing info on each.
892
	foreach ($context['ignore_list'] as $member)
893
	{
894
		echo '
895
				<tr class="windowbg">
896
					<td class="buddy_link">', $member['link'], '</td>
897
					<td class="centertext buddy_status">
898
						<a href="', $member['online']['href'], '"><span class="' . ($member['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $member['online']['text'] . '"></span></a>
899
					</td>';
900
901
		if ($context['can_moderate_forum'])
902
			echo '
903
					<td class="centertext buddy_email">
904
						<a href="mailto:' . $member['email'] . '" rel="nofollow"><span class="main_icons mail icon" title="' . $txt['email'] . ' ' . $member['name'] . '"></span></a>
905
					</td>';
906
		echo '
907
					<td class="centertext buddy_remove">
908
						<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=ignore;remove=', $member['id'], ';', $context['session_var'], '=', $context['session_id'], '"><span class="main_icons delete" title="', $txt['ignore_remove'], '"></span></a>
909
					</td>
910
				</tr>';
911
	}
912
913
	echo '
914
			</tbody>
915
		</table>
916
	</div><!-- #edit_buddies -->';
917
918
	// Add to the ignore list?
919
	echo '
920
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=ignore" method="post" accept-charset="', $context['character_set'], '">
921
		<div class="cat_bar">
922
			<h3 class="catbg">', $txt['ignore_add'], '</h3>
923
		</div>
924
		<div class="information">
925
			<dl class="settings">
926
				<dt>
927
					<label for="new_buddy"><strong>', $txt['who_member'], ':</strong></label>
928
				</dt>
929
				<dd>
930
					<input type="text" name="new_ignore" id="new_ignore" size="30">
931
					<input type="submit" value="', $txt['ignore_add_button'], '" class="button">
932
				</dd>
933
			</dl>
934
		</div>';
935
936
	if (!empty($context['token_check']))
937
		echo '
938
		<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
939
940
	echo '
941
		<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
942
	</form>
943
	<script>
944
		var oAddIgnoreSuggest = new smc_AutoSuggest({
945
			sSelf: \'oAddIgnoreSuggest\',
946
			sSessionId: \'', $context['session_id'], '\',
947
			sSessionVar: \'', $context['session_var'], '\',
948
			sSuggestId: \'new_ignore\',
949
			sControlId: \'new_ignore\',
950
			sSearchType: \'member\',
951
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
952
			bItemList: false
953
		});
954
	</script>';
955
}
956
957
/**
958
 * This template shows an admin information on a users IP addresses used and errors attributed to them.
959
 */
960
function template_trackActivity()
961
{
962
	global $context, $scripturl, $txt;
963
964
	// The first table shows IP information about the user.
965
	echo '
966
		<div class="cat_bar">
967
			<h3 class="catbg">', $txt['view_ips_by'], ' ', $context['member']['name'], '</h3>
968
		</div>';
969
970
	// The last IP the user used.
971
	echo '
972
		<div id="tracking" class="windowbg">
973
			<dl class="settings noborder">
974
				<dt>
975
					', $txt['most_recent_ip'], ':
976
					', (empty($context['last_ip2']) ? '' : '<br>
977
					<span class="smalltext">(<a href="' . $scripturl . '?action=helpadmin;help=whytwoip" onclick="return reqOverlayDiv(this.href);">' . $txt['why_two_ip_address'] . '</a>)</span>'), '
978
				</dt>
979
				<dd>
980
					<a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['last_ip'], ';u=', $context['member']['id'], '">', $context['last_ip'], '</a>';
981
982
	// Second address detected?
983
	if (!empty($context['last_ip2']))
984
		echo '
985
					, <a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['last_ip2'], ';u=', $context['member']['id'], '">', $context['last_ip2'], '</a>';
986
987
	echo '
988
				</dd>';
989
990
	// Lists of IP addresses used in messages / error messages.
991
	echo '
992
				<dt>', $txt['ips_in_messages'], ':</dt>
993
				<dd>
994
					', (count($context['ips']) > 0 ? implode(', ', $context['ips']) : '(' . $txt['none'] . ')'), '
995
				</dd>
996
				<dt>', $txt['ips_in_errors'], ':</dt>
997
				<dd>
998
					', (count($context['error_ips']) > 0 ? implode(', ', $context['error_ips']) : '(' . $txt['none'] . ')'), '
999
				</dd>';
1000
1001
	// List any members that have used the same IP addresses as the current member.
1002
	echo '
1003
				<dt>', $txt['members_in_range'], ':</dt>
1004
				<dd>
1005
					', (count($context['members_in_range']) > 0 ? implode(', ', $context['members_in_range']) : '(' . $txt['none'] . ')'), '
1006
				</dd>
1007
			</dl>
1008
		</div><!-- #tracking -->';
1009
1010
	// Show the track user list.
1011
	template_show_list('track_user_list');
1012
}
1013
1014
/**
1015
 * The template for trackIP, allowing the admin to see where/who a certain IP has been used.
1016
 */
1017
function template_trackIP()
1018
{
1019
	global $context, $txt;
1020
1021
	// This function always defaults to the last IP used by a member but can be set to track any IP.
1022
	// The first table in the template gives an input box to allow the admin to enter another IP to track.
1023
	echo '
1024
		<div class="cat_bar">
1025
			<h3 class="catbg">', $txt['trackIP'], '</h3>
1026
		</div>
1027
		<div class="windowbg">
1028
			<form action="', $context['base_url'], '" method="post" accept-charset="', $context['character_set'], '">
1029
				<dl class="settings">
1030
					<dt>
1031
						<label for="searchip"><strong>', $txt['enter_ip'], ':</strong></label>
1032
					</dt>
1033
					<dd>
1034
						<input type="text" name="searchip" value="', $context['ip'], '">
1035
					</dd>
1036
				</dl>
1037
				<input type="submit" value="', $txt['trackIP'], '" class="button">
1038
			</form>
1039
		</div>
1040
		<br>';
1041
1042
	// The table inbetween the first and second table shows links to the whois server for every region.
1043
	if ($context['single_ip'])
1044
	{
1045
		echo '
1046
		<div class="cat_bar">
1047
			<h3 class="catbg">', $txt['whois_title'], ' ', $context['ip'], '</h3>
1048
		</div>
1049
		<div class="windowbg">';
1050
1051
		foreach ($context['whois_servers'] as $server)
1052
			echo '
1053
			<a href="', $server['url'], '" target="_blank" rel="noopener"', '>', $server['name'], '</a><br>';
1054
		echo '
1055
		</div>
1056
		<br>';
1057
	}
1058
1059
	// The second table lists all the members who have been logged as using this IP address.
1060
	echo '
1061
		<div class="cat_bar">
1062
			<h3 class="catbg">', $txt['members_from_ip'], ' ', $context['ip'], '</h3>
1063
		</div>';
1064
1065
	if (empty($context['ips']))
1066
		echo '
1067
		<p class="windowbg description">
1068
			<em>', $txt['no_members_from_ip'], '</em>
1069
		</p>';
1070
1071
	else
1072
	{
1073
		echo '
1074
		<table class="table_grid">
1075
			<thead>
1076
				<tr class="title_bar">
1077
					<th scope="col">', $txt['ip_address'], '</th>
1078
					<th scope="col">', $txt['display_name'], '</th>
1079
				</tr>
1080
			</thead>
1081
			<tbody>';
1082
1083
		// Loop through each of the members and display them.
1084
		foreach ($context['ips'] as $ip => $memberlist)
1085
			echo '
1086
				<tr class="windowbg">
1087
					<td><a href="', $context['base_url'], ';searchip=', $ip, '">', $ip, '</a></td>
1088
					<td>', implode(', ', $memberlist), '</td>
1089
				</tr>';
1090
1091
		echo '
1092
			</tbody>
1093
		</table>';
1094
	}
1095
1096
	echo '
1097
		<br>';
1098
1099
	template_show_list('track_message_list');
1100
1101
	echo '<br>';
1102
1103
	template_show_list('track_user_list');
1104
1105
	// 3rd party integrations may have added additional tracking.
1106
	if (!empty($context['additional_track_lists']))
1107
	{
1108
		foreach ($context['additional_track_lists'] as $list)
1109
		{
1110
			echo '<br>';
1111
1112
			template_show_list($list);
1113
		}
1114
	}
1115
}
1116
1117
/**
1118
 * This template shows an admin which permissions a user have and which group(s) give them each permission.
1119
 */
1120
function template_showPermissions()
1121
{
1122
	global $context, $scripturl, $txt;
1123
1124
	echo '
1125
		<div class="cat_bar">
1126
			<h3 class="catbg profile_hd">
1127
				', $txt['showPermissions'], '
1128
			</h3>
1129
		</div>';
1130
1131
	if ($context['member']['has_all_permissions'])
1132
		echo '
1133
		<div class="information">', $txt['showPermissions_all'], '</div>';
1134
1135
	else
1136
	{
1137
		echo '
1138
		<div class="information">', $txt['showPermissions_help'], '</div>
1139
		<div id="permissions" class="flow_hidden">';
1140
1141
		if (!empty($context['no_access_boards']))
1142
		{
1143
			echo '
1144
			<div class="cat_bar">
1145
				<h3 class="catbg">', $txt['showPermissions_restricted_boards'], '</h3>
1146
			</div>
1147
			<div class="windowbg smalltext">
1148
				', $txt['showPermissions_restricted_boards_desc'], ':<br>';
1149
1150
			foreach ($context['no_access_boards'] as $no_access_board)
1151
				echo '
1152
				<a href="', $scripturl, '?board=', $no_access_board['id'], '.0">', $no_access_board['name'], '</a>', $no_access_board['is_last'] ? '' : ', ';
1153
			echo '
1154
			</div>';
1155
		}
1156
1157
		// General Permissions section.
1158
		echo '
1159
			<div class="tborder">
1160
				<div class="cat_bar">
1161
					<h3 class="catbg">', $txt['showPermissions_general'], '</h3>
1162
				</div>';
1163
		if (!empty($context['member']['permissions']['general']))
1164
		{
1165
			echo '
1166
				<table class="table_grid">
1167
					<thead>
1168
						<tr class="title_bar">
1169
							<th class="lefttext half_table">', $txt['showPermissions_permission'], '</th>
1170
							<th class="lefttext half_table">', $txt['showPermissions_status'], '</th>
1171
						</tr>
1172
					</thead>
1173
					<tbody>';
1174
1175
			foreach ($context['member']['permissions']['general'] as $permission)
1176
			{
1177
				echo '
1178
						<tr class="windowbg">
1179
							<td title="', $permission['id'], '">
1180
								', $permission['is_denied'] ? '<del>' . $permission['name'] . '</del>' : $permission['name'], '
1181
							</td>
1182
							<td class="smalltext">';
1183
1184
				if ($permission['is_denied'])
1185
					echo '
1186
								<span class="alert">', $txt['showPermissions_denied'], ': ', implode(', ', $permission['groups']['denied']), '</span>';
1187
				else
1188
					echo '
1189
								', $txt['showPermissions_given'], ': ', implode(', ', $permission['groups']['allowed']);
1190
1191
				echo '
1192
							</td>
1193
						</tr>';
1194
			}
1195
			echo '
1196
					</tbody>
1197
				</table>
1198
			</div><!-- .tborder -->
1199
			<br>';
1200
		}
1201
		else
1202
			echo '
1203
			<p class="windowbg">', $txt['showPermissions_none_general'], '</p>';
1204
1205
		// Board permission section.
1206
		echo '
1207
			<form action="' . $scripturl . '?action=profile;u=', $context['id_member'], ';area=permissions#board_permissions" method="post" accept-charset="', $context['character_set'], '">
1208
				<div class="cat_bar">
1209
					<h3 class="catbg">
1210
						<a id="board_permissions"></a>', $txt['showPermissions_select'], ':
1211
						<select name="board" onchange="if (this.options[this.selectedIndex].value) this.form.submit();">
1212
							<option value="0"', $context['board'] == 0 ? ' selected' : '', '>', $txt['showPermissions_global'], '</option>';
1213
1214
		if (!empty($context['boards']))
1215
			echo '
1216
							<option value="" disabled>---------------------------</option>';
1217
1218
		// Fill the box with any local permission boards.
1219
		foreach ($context['boards'] as $board)
1220
			echo '
1221
							<option value="', $board['id'], '"', $board['selected'] ? ' selected' : '', '>', $board['name'], ' (', $board['profile_name'], ')</option>';
1222
1223
		echo '
1224
						</select>
1225
					</h3>
1226
				</div><!-- .cat_bar -->
1227
			</form>';
1228
1229
		if (!empty($context['member']['permissions']['board']))
1230
		{
1231
			echo '
1232
			<table class="table_grid">
1233
				<thead>
1234
					<tr class="title_bar">
1235
						<th class="lefttext half_table">', $txt['showPermissions_permission'], '</th>
1236
						<th class="lefttext half_table">', $txt['showPermissions_status'], '</th>
1237
					</tr>
1238
				</thead>
1239
				<tbody>';
1240
1241
			foreach ($context['member']['permissions']['board'] as $permission)
1242
			{
1243
				echo '
1244
					<tr class="windowbg">
1245
						<td title="', $permission['id'], '">
1246
							', $permission['is_denied'] ? '<del>' . $permission['name'] . '</del>' : $permission['name'], '
1247
						</td>
1248
						<td class="smalltext">';
1249
1250
				if ($permission['is_denied'])
1251
					echo '
1252
							<span class="alert">', $txt['showPermissions_denied'], ': ', implode(', ', $permission['groups']['denied']), '</span>';
1253
1254
				else
1255
					echo '
1256
							', $txt['showPermissions_given'], ': ', implode(', ', $permission['groups']['allowed']);
1257
1258
				echo '
1259
						</td>
1260
					</tr>';
1261
			}
1262
			echo '
1263
				</tbody>
1264
			</table>';
1265
		}
1266
		else
1267
			echo '
1268
			<p class="windowbg">', $txt['showPermissions_none_board'], '</p>';
1269
		echo '
1270
		</div><!-- #permissions -->';
1271
	}
1272
}
1273
1274
/**
1275
 * Template for user statistics, showing graphs and the like.
1276
 */
1277
function template_statPanel()
1278
{
1279
	global $context, $txt;
1280
1281
	// First, show a few text statistics such as post/topic count.
1282
	echo '
1283
	<div id="profileview" class="roundframe noup">
1284
		<div id="generalstats">
1285
			<dl class="stats">';
1286
1287
	foreach ($context['text_stats'] as $key => $stat)
1288
	{
1289
		echo '
1290
				<dt>', $txt['statPanel_' . $key], '</dt>';
1291
1292
		if (!empty($stat['url']))
1293
			echo '
1294
				<dd><a href="', $stat['url'], '">', $stat['text'], '</a></dd>';
1295
		else
1296
			echo '
1297
				<dd>', $stat['text'], '</dd>';
1298
	}
1299
1300
	echo '
1301
			</dl>
1302
		</div>';
1303
1304
	// This next section draws a graph showing what times of day they post the most.
1305
	echo '
1306
		<div id="activitytime" class="flow_hidden">
1307
			<div class="title_bar">
1308
				<h3 class="titlebg">
1309
					<span class="main_icons history"></span> ', $txt['statPanel_activityTime'], '
1310
				</h3>
1311
			</div>';
1312
1313
	// If they haven't post at all, don't draw the graph.
1314
	if (empty($context['posts_by_time']))
1315
		echo '
1316
			<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1317
1318
	// Otherwise do!
1319
	else
1320
	{
1321
		echo '
1322
			<ul class="activity_stats flow_hidden">';
1323
1324
		// The labels.
1325
		foreach ($context['posts_by_time'] as $time_of_day)
1326
			echo '
1327
				<li>
1328
					<div class="generic_bar vertical">
1329
						<div class="bar" style="height: ', (int) $time_of_day['relative_percent'], '%;">
1330
							<span>', sprintf($txt['statPanel_activityTime_posts'], $time_of_day['posts'], $time_of_day['posts_percent']), '</span>
1331
						</div>
1332
					</div>
1333
					<span class="stats_hour">', $time_of_day['hour_format'], '</span>
1334
				</li>';
1335
1336
		echo '
1337
			</ul>';
1338
	}
1339
1340
	echo '
1341
		</div><!-- #activitytime -->';
1342
1343
	// Two columns with the most popular boards by posts and activity (activity = users posts / total posts).
1344
	echo '
1345
		<div class="flow_hidden">
1346
			<div class="half_content">
1347
				<div class="title_bar">
1348
					<h3 class="titlebg">
1349
						<span class="main_icons replies"></span> ', $txt['statPanel_topBoards'], '
1350
					</h3>
1351
				</div>';
1352
1353
	if (empty($context['popular_boards']))
1354
		echo '
1355
				<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1356
1357
	else
1358
	{
1359
		echo '
1360
				<dl class="stats">';
1361
1362
		// Draw a bar for every board.
1363
		foreach ($context['popular_boards'] as $board)
1364
		{
1365
			echo '
1366
					<dt>', $board['link'], '</dt>
1367
					<dd>
1368
						<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']), '">
1369
							', sprintf($txt['statPanel_topBoards_memberposts'], $board['posts'], $board['total_posts_member'], $board['posts_percent']), '
1370
						</div>
1371
						', empty($context['hide_num_posts']) ? $board['posts'] : '', '
1372
					</dd>';
1373
		}
1374
1375
		echo '
1376
				</dl>';
1377
	}
1378
	echo '
1379
			</div><!-- .half_content -->
1380
			<div class="half_content">
1381
				<div class="title_bar">
1382
					<h3 class="titlebg">
1383
						<span class="main_icons replies"></span> ', $txt['statPanel_topBoardsActivity'], '
1384
					</h3>
1385
				</div>';
1386
1387
	if (empty($context['board_activity']))
1388
		echo '
1389
				<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1390
	else
1391
	{
1392
		echo '
1393
				<dl class="stats">';
1394
1395
		// Draw a bar for every board.
1396
		foreach ($context['board_activity'] as $activity)
1397
		{
1398
			echo '
1399
					<dt>', $activity['link'], '</dt>
1400
					<dd>
1401
						<div class="profile_pie" style="background-position: -', ((int) ($activity['posts_percent'] / 5) * 20), 'px 0;" title="', sprintf($txt['statPanel_topBoards_posts'], $activity['posts'], $activity['total_posts'], $activity['posts_percent']), '">
1402
							', sprintf($txt['statPanel_topBoards_posts'], $activity['posts'], $activity['total_posts'], $activity['posts_percent']), '
1403
						</div>
1404
						', $activity['percent'], '%
1405
					</dd>';
1406
		}
1407
1408
		echo '
1409
				</dl>';
1410
	}
1411
	echo '
1412
			</div><!-- .half_content -->
1413
		</div><!-- .flow_hidden -->';
1414
1415
	echo '
1416
	</div><!-- #profileview -->';
1417
}
1418
1419
/**
1420
 * Template for editing profile options.
1421
 */
1422
function template_edit_options()
1423
{
1424
	global $context, $scripturl, $txt, $modSettings;
1425
1426
	// The main header!
1427
	// because some browsers ignore autocomplete=off and fill username in display name and/ or email field, fake them out.
1428
	$url = !empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=' . $context['menu_item_selected'] . ';u=' . $context['id_member'];
1429
	$url = $context['require_password'] && !empty($modSettings['force_ssl']) ? strtr($url, array('http://' => 'https://')) : $url;
1430
1431
	echo '
1432
		<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"' : ''), '>
1433
			<div style="height:0;overflow:hidden;">
1434
				<input type="text" id="autocompleteFakeName">
1435
				<input type="password" id="autocompleteFakePassword">
1436
			</div>
1437
			<div class="cat_bar">
1438
				<h3 class="catbg profile_hd">';
1439
1440
	// Don't say "Profile" if this isn't the profile...
1441
	if (!empty($context['profile_header_text']))
1442
		echo '
1443
					', $context['profile_header_text'];
1444
	else
1445
		echo '
1446
					', $txt['profile'];
1447
1448
	echo '
1449
				</h3>
1450
			</div>';
1451
1452
	// Have we some description?
1453
	if ($context['page_desc'])
1454
		echo '
1455
			<p class="information">', $context['page_desc'], '</p>';
1456
1457
	echo '
1458
			<div class="roundframe">';
1459
1460
	// Any bits at the start?
1461
	if (!empty($context['profile_prehtml']))
1462
		echo '
1463
				<div>', $context['profile_prehtml'], '</div>';
1464
1465
	if (!empty($context['profile_fields']))
1466
		echo '
1467
				<dl class="settings">';
1468
1469
	// Start the big old loop 'of love.
1470
	$lastItem = 'hr';
1471
	foreach ($context['profile_fields'] as $key => $field)
1472
	{
1473
		// We add a little hack to be sure we never get more than one hr in a row!
1474
		if ($lastItem == 'hr' && $field['type'] == 'hr')
1475
			continue;
1476
1477
		$lastItem = $field['type'];
1478
		if ($field['type'] == 'hr')
1479
			echo '
1480
				</dl>
1481
				<hr>
1482
				<dl class="settings">';
1483
1484
		elseif ($field['type'] == 'callback')
1485
		{
1486
			if (isset($field['callback_func']) && function_exists('template_profile_' . $field['callback_func']))
1487
			{
1488
				$callback_func = 'template_profile_' . $field['callback_func'];
1489
				$callback_func();
1490
			}
1491
		}
1492
		else
1493
		{
1494
			echo '
1495
					<dt>
1496
						<strong', !empty($field['is_error']) ? ' class="error"' : '', '>', $field['type'] !== 'label' ? '<label for="' . $key . '">' : '', $field['label'], $field['type'] !== 'label' ? '</label>' : '', '</strong>';
1497
1498
			// Does it have any subtext to show?
1499
			if (!empty($field['subtext']))
1500
				echo '
1501
						<br>
1502
						<span class="smalltext">', $field['subtext'], '</span>';
1503
1504
			echo '
1505
					</dt>
1506
					<dd>';
1507
1508
			// Want to put something infront of the box?
1509
			if (!empty($field['preinput']))
1510
				echo '
1511
						', $field['preinput'];
1512
1513
			// What type of data are we showing?
1514
			if ($field['type'] == 'label')
1515
				echo '
1516
						', $field['value'];
1517
1518
			// Maybe it's a text box - very likely!
1519
			elseif (in_array($field['type'], array('int', 'float', 'text', 'password', 'color', 'date', 'datetime', 'datetime-local', 'email', 'month', 'number', 'time', 'url')))
1520
			{
1521
				if ($field['type'] == 'int' || $field['type'] == 'float')
1522
					$type = 'number';
1523
				else
1524
					$type = $field['type'];
1525
				$step = $field['type'] == 'float' ? ' step="0.1"' : '';
1526
1527
				echo '
1528
						<input type="', $type, '" name="', $key, '" id="', $key, '" size="', empty($field['size']) ? 30 : $field['size'], '"', isset($field['min']) ? ' min="' . $field['min'] . '"' : '', isset($field['max']) ? ' max="' . $field['max'] . '"' : '', ' value="', $field['value'], '" ', $field['input_attr'], ' ', $step, '>';
1529
			}
1530
			// You "checking" me out? ;)
1531
			elseif ($field['type'] == 'check')
1532
				echo '
1533
						<input type="hidden" name="', $key, '" value="0">
1534
						<input type="checkbox" name="', $key, '" id="', $key, '"', !empty($field['value']) ? ' checked' : '', ' value="1" ', $field['input_attr'], '>';
1535
1536
			// Always fun - select boxes!
1537
			elseif ($field['type'] == 'select')
1538
			{
1539
				echo '
1540
						<select name="', $key, '" id="', $key, '">';
1541
1542
				if (isset($field['options']))
1543
				{
1544
					// Is this some code to generate the options?
1545
					if (!is_array($field['options']))
1546
						$field['options'] = $field['options']();
1547
1548
					// Assuming we now have some!
1549
					if (is_array($field['options']))
1550
						foreach ($field['options'] as $value => $name)
1551
							echo '
1552
							<option value="' . $value . '"', (!empty($field['disabled_options']) && is_array($field['disabled_options']) && in_array($value, $field['disabled_options'], true) ? ' disabled' : ($value == $field['value'] ? ' selected' : '')), '>', $name, '</option>';
1553
				}
1554
1555
				echo '
1556
						</select>';
1557
			}
1558
1559
			// Something to end with?
1560
			if (!empty($field['postinput']))
1561
				echo '
1562
						', $field['postinput'];
1563
1564
			echo '
1565
					</dd>';
1566
		}
1567
	}
1568
1569
	if (!empty($context['profile_fields']))
1570
		echo '
1571
				</dl>';
1572
1573
	// Are there any custom profile fields - if so print them!
1574
	if (!empty($context['custom_fields']))
1575
	{
1576
		if ($lastItem != 'hr')
1577
			echo '
1578
				<hr>';
1579
1580
		echo '
1581
				<dl class="settings">';
1582
1583
		foreach ($context['custom_fields'] as $field)
1584
			echo '
1585
					<dt>
1586
						<strong>', $field['name'], '</strong><br>
1587
						<span class="smalltext">', $field['desc'], '</span>
1588
					</dt>
1589
					<dd>
1590
						', $field['input_html'], '
1591
					</dd>';
1592
1593
		echo '
1594
				</dl>';
1595
	}
1596
1597
	// Any closing HTML?
1598
	if (!empty($context['profile_posthtml']))
1599
		echo '
1600
				<div>', $context['profile_posthtml'], '</div>';
1601
1602
	// Only show the password box if it's actually needed.
1603
	if ($context['require_password'])
1604
		echo '
1605
				<dl class="settings">
1606
					<dt>
1607
						<strong', isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : '', '><label for="oldpasswrd">', $txt['current_password'], '</label></strong><br>
1608
						<span class="smalltext">', $txt['required_security_reasons'], '</span>
1609
					</dt>
1610
					<dd>
1611
						<input type="password" name="oldpasswrd" id="oldpasswrd" size="20">
1612
					</dd>
1613
				</dl>';
1614
1615
	// The button shouldn't say "Change profile" unless we're changing the profile...
1616
	if (!empty($context['submit_button_text']))
1617
		echo '
1618
				<input type="submit" name="save" value="', $context['submit_button_text'], '" class="button floatright">';
1619
	else
1620
		echo '
1621
				<input type="submit" name="save" value="', $txt['change_profile'], '" class="button floatright">';
1622
1623
	if (!empty($context['token_check']))
1624
		echo '
1625
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
1626
1627
	echo '
1628
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
1629
				<input type="hidden" name="u" value="', $context['id_member'], '">
1630
				<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
1631
			</div><!-- .roundframe -->
1632
		</form>';
1633
1634
	// Any final spellchecking stuff?
1635
	if (!empty($context['show_spellchecking']))
1636
		echo '
1637
		<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>';
1638
}
1639
1640
/**
1641
 * Personal Message settings.
1642
 */
1643
function template_profile_pm_settings()
1644
{
1645
	global $context, $modSettings, $txt;
1646
1647
	echo '
1648
					<dt>
1649
						<label for="pm_prefs">', $txt['pm_display_mode'], ':</label>
1650
					</dt>
1651
					<dd>
1652
						<select name="pm_prefs" id="pm_prefs">
1653
							<option value="0"', $context['display_mode'] == 0 ? ' selected' : '', '>', $txt['pm_display_mode_all'], '</option>
1654
							<option value="1"', $context['display_mode'] == 1 ? ' selected' : '', '>', $txt['pm_display_mode_one'], '</option>
1655
							<option value="2"', $context['display_mode'] == 2 ? ' selected' : '', '>', $txt['pm_display_mode_linked'], '</option>
1656
						</select>
1657
					</dd>
1658
					<dt>
1659
						<label for="view_newest_pm_first">', $txt['recent_pms_at_top'], '</label>
1660
					</dt>
1661
					<dd>
1662
						<input type="hidden" name="default_options[view_newest_pm_first]" value="0">
1663
						<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' : '', '>
1664
					</dd>
1665
				</dl>
1666
				<hr>
1667
				<dl class="settings">
1668
					<dt>
1669
						<label for="pm_receive_from">', $txt['pm_receive_from'], '</label>
1670
					</dt>
1671
					<dd>
1672
						<select name="pm_receive_from" id="pm_receive_from">
1673
							<option value="0"', empty($context['receive_from']) || (empty($modSettings['enable_buddylist']) && $context['receive_from'] < 3) ? ' selected' : '', '>', $txt['pm_receive_from_everyone'], '</option>';
1674
1675
	if (!empty($modSettings['enable_buddylist']))
1676
		echo '
1677
							<option value="1"', !empty($context['receive_from']) && $context['receive_from'] == 1 ? ' selected' : '', '>', $txt['pm_receive_from_ignore'], '</option>
1678
							<option value="2"', !empty($context['receive_from']) && $context['receive_from'] == 2 ? ' selected' : '', '>', $txt['pm_receive_from_buddies'], '</option>';
1679
1680
	echo '
1681
							<option value="3"', !empty($context['receive_from']) && $context['receive_from'] > 2 ? ' selected' : '', '>', $txt['pm_receive_from_admins'], '</option>
1682
						</select>
1683
					</dd>
1684
					<dt>
1685
						<label for="popup_messages">', $txt['popup_messages'], '</label>
1686
					</dt>
1687
					<dd>
1688
						<input type="hidden" name="default_options[popup_messages]" value="0">
1689
						<input type="checkbox" name="default_options[popup_messages]" id="popup_messages" value="1"', !empty($context['member']['options']['popup_messages']) ? ' checked' : '', '>
1690
					</dd>
1691
				</dl>
1692
				<hr>
1693
				<dl class="settings">
1694
					<dt>
1695
						<label for="pm_remove_inbox_label">', $txt['pm_remove_inbox_label'], '</label>
1696
					</dt>
1697
					<dd>
1698
						<input type="hidden" name="default_options[pm_remove_inbox_label]" value="0">
1699
						<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' : '', '>
1700
					</dd>';
1701
1702
}
1703
1704
/**
1705
 * Template for showing theme settings. Note: template_options() actually adds the theme specific options.
1706
 */
1707
function template_profile_theme_settings()
1708
{
1709
	global $context, $modSettings;
1710
1711
	$skeys = array_keys($context['theme_options']);
1712
	$first_option_key = array_shift($skeys);
1713
	$titled_section = false;
1714
1715
	foreach ($context['theme_options'] as $i => $setting)
1716
	{
1717
		// Just spit out separators and move on
1718
		if (empty($setting) || !is_array($setting))
1719
		{
1720
			// Avoid double separators and empty titled sections
1721
			$empty_section = true;
1722
			for ($j=$i+1; $j < count($context['theme_options']); $j++)
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1723
			{
1724
				// Found another separator, so we're done
1725
				if (!is_array($context['theme_options'][$j]))
1726
					break;
1727
1728
				// Once we know there's something to show in this section, we can stop
1729
				if (!isset($context['theme_options'][$j]['enabled']) || !empty($context['theme_options'][$j]['enabled']))
1730
				{
1731
					$empty_section = false;
1732
					break;
1733
				}
1734
			}
1735
			if ($empty_section)
1736
			{
1737
				if ($i === $first_option_key)
1738
					$first_option_key = array_shift($skeys);
1739
1740
				continue;
1741
			}
1742
1743
			// Insert a separator (unless this is the first item in the list)
1744
			if ($i !== $first_option_key)
1745
				echo '
1746
				</dl>
1747
				<hr>
1748
				<dl class="settings">';
1749
1750
			// Should we give a name to this section?
1751
			if (is_string($setting) && !empty($setting))
1752
			{
1753
				$titled_section = true;
1754
				echo '
1755
					<dt><strong>' . $setting . '</strong></dt>
1756
					<dd></dd>';
1757
			}
1758
			else
1759
				$titled_section = false;
1760
1761
			continue;
1762
		}
1763
1764
		// Is this disabled?
1765
		if (isset($setting['enabled']) && $setting['enabled'] === false)
1766
		{
1767
			if ($i === $first_option_key)
1768
				$first_option_key = array_shift($skeys);
1769
1770
			continue;
1771
		}
1772
1773
		// Some of these may not be set...  Set to defaults here
1774
		$opts = array('calendar_start_day', 'topics_per_page', 'messages_per_page', 'display_quick_mod');
1775
		if (in_array($setting['id'], $opts) && !isset($context['member']['options'][$setting['id']]))
1776
			$context['member']['options'][$setting['id']] = 0;
1777
1778
		if (!isset($setting['type']) || $setting['type'] == 'bool')
1779
			$setting['type'] = 'checkbox';
1780
1781
		elseif ($setting['type'] == 'int' || $setting['type'] == 'integer')
1782
			$setting['type'] = 'number';
1783
1784
		elseif ($setting['type'] == 'string')
1785
			$setting['type'] = 'text';
1786
1787
		if (isset($setting['options']))
1788
			$setting['type'] = 'list';
1789
1790
		echo '
1791
					<dt>
1792
						<label for="', $setting['id'], '">', !$titled_section ? '<strong>' : '', $setting['label'], !$titled_section ? '</strong>' : '', '</label>';
1793
1794
		if (isset($setting['description']))
1795
			echo '
1796
						<br>
1797
						<span class="smalltext">', $setting['description'], '</span>';
1798
		echo '
1799
					</dt>
1800
					<dd>';
1801
1802
		// Display checkbox options
1803
		if ($setting['type'] == 'checkbox')
1804
			echo '
1805
						<input type="hidden" name="default_options[' . $setting['id'] . ']" value="0">
1806
						<input type="checkbox" name="default_options[', $setting['id'], ']" id="', $setting['id'], '"', !empty($context['member']['options'][$setting['id']]) ? ' checked' : '', ' value="1">';
1807
1808
		// How about selection lists, we all love them
1809
		elseif ($setting['type'] == 'list')
1810
		{
1811
			echo '
1812
						<select name="default_options[', $setting['id'], ']" id="', $setting['id'], '"', '>';
1813
1814
			foreach ($setting['options'] as $value => $label)
1815
				echo '
1816
							<option value="', $value, '"', isset($context['member']['options'][$setting['id']]) && $value == $context['member']['options'][$setting['id']] ? ' selected' : '', '>', $label, '</option>';
1817
1818
			echo '
1819
						</select>';
1820
		}
1821
		// A textbox it is then
1822
		else
1823
		{
1824
			if (isset($setting['type']) && $setting['type'] == 'number')
1825
			{
1826
				$min = isset($setting['min']) ? ' min="' . $setting['min'] . '"' : ' min="0"';
1827
				$max = isset($setting['max']) ? ' max="' . $setting['max'] . '"' : '';
1828
				$step = isset($setting['step']) ? ' step="' . $setting['step'] . '"' : '';
1829
1830
				echo '
1831
						<input type="number"', $min . $max . $step;
1832
			}
1833
			elseif (isset($setting['type']) && $setting['type'] == 'url')
1834
				echo '
1835
						<input type="url"';
1836
1837
			else
1838
				echo '
1839
						<input type="text"';
1840
1841
			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"' : '', '>';
1842
		}
1843
1844
		// end of this defintion
1845
		echo '
1846
					</dd>';
1847
	}
1848
}
1849
1850
/**
1851
 * The template for configuring alerts
1852
 */
1853
function template_alert_configuration()
1854
{
1855
	global $context, $txt, $scripturl, $modSettings;
1856
1857
	echo '
1858
		<div class="cat_bar">
1859
			<h3 class="catbg">
1860
				', $txt['alert_prefs'], '
1861
			</h3>
1862
		</div>
1863
		<p class="information">
1864
			', (empty($context['description']) ? $txt['alert_prefs_desc'] : $context['description']), '
1865
		</p>
1866
		<form action="', $scripturl, '?', $context['action'], '" method="post" accept-charset="', $context['character_set'], '" id="notify_options" class="flow_auto">
1867
			<div class="cat_bar">
1868
				<h3 class="catbg">
1869
					', $txt['notification_general'], '
1870
				</h3>
1871
			</div>
1872
			<div class="windowbg">
1873
				<dl class="settings">
1874
					<dt>
1875
						<label for="notify_announcements">', $txt['notify_important_email'], '</label>', $context['id_member'] == 0 ? '
1876
						<br>
1877
						<span class="smalltext alert">' . $txt['notify_announcements_desc'] . '</span>' : '', '
1878
					</dt>
1879
					<dd>
1880
						<input type="hidden" name="notify_announcements" value="0">
1881
						<input type="checkbox" id="notify_announcements" name="notify_announcements" value="1"', !empty($context['member']['notify_announcements']) ? ' checked' : '', '>
1882
					</dd>';
1883
1884
	if (!empty($modSettings['enable_ajax_alerts']))
1885
		echo '
1886
					<dt>
1887
						<label for="notify_send_body">', $txt['notify_alert_timeout'], '</label>
1888
					</dt>
1889
					<dd>
1890
						<input type="number" size="4" id="notify_alert_timeout" name="opt_alert_timeout" min="0" value="', $context['member']['alert_timeout'], '">
1891
					</dd>';
1892
1893
	echo '
1894
				</dl>
1895
			</div><!-- .windowbg -->
1896
			<div class="cat_bar">
1897
				<h3 class="catbg">
1898
					', $txt['notify_what_how'], '
1899
				</h3>
1900
			</div>
1901
			<table class="table_grid">';
1902
1903
	foreach ($context['alert_types'] as $alert_group => $alerts)
1904
	{
1905
		echo '
1906
				<tr class="title_bar">
1907
					<th>', $txt['alert_group_' . $alert_group], '</th>
1908
					<th>', $txt['receive_alert'], '</th>
1909
					<th>', $txt['receive_mail'], '</th>
1910
				</tr>
1911
				<tr class="windowbg">';
1912
1913
		if (isset($context['alert_group_options'][$alert_group]))
1914
		{
1915
			foreach ($context['alert_group_options'][$alert_group] as $opts)
1916
			{
1917
				if ($opts[0] == 'hide')
1918
					continue;
1919
1920
				echo '
1921
				<tr class="windowbg">
1922
					<td colspan="3">';
1923
1924
				$label = $txt['alert_opt_' . $opts[1]];
1925
				$label_pos = isset($opts['label']) ? $opts['label'] : '';
1926
				if ($label_pos == 'before')
1927
					echo '
1928
						<label for="opt_', $opts[1], '">', $label, '</label>';
1929
1930
				$this_value = isset($context['alert_prefs'][$opts[1]]) ? $context['alert_prefs'][$opts[1]] : 0;
1931
				switch ($opts[0])
1932
				{
1933
					case 'check':
1934
						echo '
1935
						<input type="checkbox" name="opt_', $opts[1], '" id="opt_', $opts[1], '"', $this_value ? ' checked' : '', '>';
1936
						break;
1937
1938
					case 'select':
1939
						echo '
1940
						<select name="opt_', $opts[1], '" id="opt_', $opts[1], '">';
1941
1942
						foreach ($opts['opts'] as $k => $v)
1943
							echo '
1944
							<option value="', $k, '"', $this_value == $k ? ' selected' : '', '>', $v, '</option>';
1945
						echo '
1946
						</select>';
1947
						break;
1948
				}
1949
1950
				if ($label_pos == 'after')
1951
					echo '
1952
						<label for="opt_', $opts[1], '">', $label, '</label>';
1953
1954
				echo '
1955
					</td>
1956
				</tr>';
1957
			}
1958
		}
1959
1960
		foreach ($alerts as $alert_id => $alert_details)
1961
		{
1962
			echo '
1963
				<tr class="windowbg">
1964
					<td>
1965
						', $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="main_icons help" title="' . $txt['help'] . '"></span></a>' : '', '
1966
					</td>';
1967
1968
			foreach ($context['alert_bits'] as $type => $bitmask)
1969
			{
1970
				echo '
1971
					<td class="centercol">';
1972
1973
				$this_value = isset($context['alert_prefs'][$alert_id]) ? $context['alert_prefs'][$alert_id] : 0;
1974
				switch ($alert_details[$type])
1975
				{
1976
					case 'always':
1977
						echo '
1978
						<input type="checkbox" checked disabled>';
1979
						break;
1980
					case 'yes':
1981
						echo '
1982
						<input type="checkbox" name="', $type, '_', $alert_id, '"', ($this_value & $bitmask) ? ' checked' : '', '>';
1983
						break;
1984
					case 'never':
1985
						echo '
1986
						<input type="checkbox" disabled>';
1987
						break;
1988
				}
1989
				echo '
1990
					</td>';
1991
			}
1992
1993
			echo '
1994
				</tr>';
1995
		}
1996
	}
1997
1998
	echo '
1999
			</table>
2000
			<br>
2001
			<div>
2002
				<input id="notify_submit" type="submit" name="notify_submit" value="', $txt['notify_save'], '" class="button">
2003
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">', !empty($context['token_check']) ? '
2004
				<input type="hidden" name="' . $context[$context['token_check'] . '_token_var'] . '" value="' . $context[$context['token_check'] . '_token'] . '">' : '', '
2005
				<input type="hidden" name="u" value="', $context['id_member'], '">
2006
				<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2007
			</div>
2008
		</form>
2009
		<br>';
2010
}
2011
2012
/**
2013
 * Template for showing which topics you're subscribed to
2014
 */
2015
function template_alert_notifications_topics()
2016
{
2017
	global $txt;
2018
2019
	// The main containing header.
2020
	echo '
2021
		<div class="cat_bar">
2022
			<h3 class="catbg">
2023
				', $txt['watched_topics'], '
2024
			</h3>
2025
		</div>
2026
		<p class="information">', $txt['watched_topics_desc'], '</p>
2027
		<br>';
2028
2029
	template_show_list('topic_notification_list');
2030
}
2031
2032
/**
2033
 * Template for showing which boards you're subscribed to
2034
 */
2035
function template_alert_notifications_boards()
2036
{
2037
	global $txt;
2038
2039
	echo '
2040
		<div class="cat_bar">
2041
			<h3 class="catbg">
2042
				', $txt['watched_boards'], '
2043
			</h3>
2044
		</div>
2045
		<p class="information">', $txt['watched_boards_desc'], '</p>
2046
		<br>';
2047
2048
	template_show_list('board_notification_list');
2049
}
2050
2051
/**
2052
 * Template for choosing group membership.
2053
 */
2054
function template_groupMembership()
2055
{
2056
	global $context, $scripturl, $txt;
2057
2058
	// The main containing header.
2059
	echo '
2060
		<form action="', $scripturl, '?action=profile;area=groupmembership;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2061
			<div class="cat_bar">
2062
				<h3 class="catbg profile_hd">
2063
					', $txt['profile'], '
2064
				</h3>
2065
			</div>
2066
			<p class="information">', $txt['groupMembership_info'], '</p>';
2067
2068
	// Do we have an update message?
2069
	if (!empty($context['update_message']))
2070
		echo '
2071
			<div class="infobox">
2072
				', $context['update_message'], '.
2073
			</div>';
2074
2075
	echo '
2076
			<div id="groups">';
2077
2078
	// Requesting membership to a group?
2079
	if (!empty($context['group_request']))
2080
	{
2081
		echo '
2082
			<div class="groupmembership">
2083
				<div class="cat_bar">
2084
					<h3 class="catbg">', $txt['request_group_membership'], '</h3>
2085
				</div>
2086
				<div class="roundframe">
2087
					', $txt['request_group_membership_desc'], ':
2088
					<textarea name="reason" rows="4"></textarea>
2089
					<div class="righttext">
2090
						<input type="hidden" name="gid" value="', $context['group_request']['id'], '">
2091
						<input type="submit" name="req" value="', $txt['submit_request'], '" class="button">
2092
						</div>
2093
					</div>
2094
				</div><!-- .groupmembership -->';
2095
	}
2096
	else
2097
	{
2098
		echo '
2099
				<div class="title_bar">
2100
					<h3 class="titlebg">', $txt['current_membergroups'], '</h3>
2101
				</div>';
2102
2103
		foreach ($context['groups']['member'] as $group)
2104
		{
2105
			echo '
2106
				<div class="windowbg" id="primdiv_', $group['id'], '">';
2107
2108
			if ($context['can_edit_primary'])
2109
				echo '
2110
					<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', '>';
2111
2112
			echo '
2113
					<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>';
2114
2115
			// Can they leave their group?
2116
			if ($group['can_leave'])
2117
				echo '
2118
					<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>';
2119
2120
			echo '
2121
				</div><!-- .windowbg -->';
2122
		}
2123
2124
		if ($context['can_edit_primary'])
2125
			echo '
2126
				<div class="padding righttext">
2127
					<input type="submit" value="', $txt['make_primary'], '" class="button">
2128
				</div>';
2129
2130
		// Any groups they can join?
2131
		if (!empty($context['groups']['available']))
2132
		{
2133
			echo '
2134
				<div class="title_bar">
2135
					<h3 class="titlebg">', $txt['available_groups'], '</h3>
2136
				</div>';
2137
2138
			foreach ($context['groups']['available'] as $group)
2139
			{
2140
				echo '
2141
				<div class="windowbg">
2142
					<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>' : ''), '';
2143
2144
				if ($group['type'] == 3)
2145
					echo '
2146
					<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>';
2147
2148
				elseif ($group['type'] == 2 && $group['pending'])
2149
					echo '
2150
					<span class="floatright">', $txt['approval_pending'], '</span>';
2151
2152
				elseif ($group['type'] == 2)
2153
					echo '
2154
					<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=groupmembership;request=', $group['id'], '" class="button floatright">', $txt['request_group'], '</a>';
2155
2156
				echo '
2157
				</div><!-- .windowbg -->';
2158
			}
2159
		}
2160
2161
		// Javascript for the selector stuff.
2162
		echo '
2163
				<script>
2164
					var prevClass = "";
2165
					var prevDiv = "";
2166
					function highlightSelected(box)
2167
					{
2168
						if (prevClass != "")
2169
						{
2170
							prevDiv.className = prevClass;
2171
						}
2172
						prevDiv = document.getElementById(box);
2173
						prevClass = prevDiv.className;
2174
2175
						prevDiv.className = "windowbg";
2176
					}';
2177
		if (isset($context['groups']['member'][$context['primary_group']]))
2178
			echo '
2179
					highlightSelected("primdiv_' . $context['primary_group'] . '");';
2180
2181
		echo '
2182
				</script>';
2183
	}
2184
2185
	echo '
2186
			</div><!-- #groups -->';
2187
2188
	if (!empty($context['token_check']))
2189
		echo '
2190
			<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2191
2192
	echo '
2193
			<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2194
			<input type="hidden" name="u" value="', $context['id_member'], '">
2195
		</form>';
2196
}
2197
2198
/**
2199
 * Template for managing ignored boards
2200
 */
2201
function template_ignoreboards()
2202
{
2203
	global $context, $txt, $scripturl;
2204
2205
	// The main containing header.
2206
	echo '
2207
	<form action="', $scripturl, '?action=profile;area=ignoreboards;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2208
		<div class="cat_bar">
2209
			<h3 class="catbg profile_hd">
2210
				', $txt['profile'], '
2211
			</h3>
2212
		</div>
2213
		<p class="information">', $txt['ignoreboards_info'], '</p>
2214
		<div class="windowbg">
2215
			<div class="flow_hidden boardslist">
2216
				<ul>';
2217
2218
	foreach ($context['categories'] as $category)
2219
	{
2220
		echo '
2221
					<li>
2222
						<a href="javascript:void(0);" onclick="selectBoards([', implode(', ', $category['child_ids']), '], \'creator\'); return false;">', $category['name'], '</a>
2223
						<ul>';
2224
2225
		$cat_boards = array_values($category['boards']);
2226
		foreach ($cat_boards as $key => $board)
2227
		{
2228
			echo '
2229
							<li>
2230
								<label for="brd', $board['id'], '">
2231
									<input type="checkbox" id="brd', $board['id'], '" name="brd[', $board['id'], ']" value="', $board['id'], '"', $board['selected'] ? ' checked' : '', '>
2232
									', $board['name'], '
2233
								</label>';
2234
2235
			// Nest child boards inside another list.
2236
			$curr_child_level = $board['child_level'];
2237
			$next_child_level = $cat_boards[$key + 1]['child_level'] ?? 0;
2238
2239
			if ($next_child_level > $curr_child_level)
2240
			{
2241
				echo '
2242
								<ul style="margin-', $context['right_to_left'] ? 'right' : 'left', ': 2.5ch;">';
2243
			}
2244
			else
2245
			{
2246
				// Close child board lists until we reach a common level
2247
				// with the next board.
2248
				while ($next_child_level < $curr_child_level--)
2249
				{
2250
					echo '
2251
									</li>
2252
								</ul>';
2253
				}
2254
2255
				echo '
2256
							</li>';
2257
			}
2258
		}
2259
2260
		echo '
2261
						</ul>
2262
					</li>';
2263
	}
2264
2265
	echo '
2266
				</ul>
2267
			</div><!-- .flow_hidden boardslist -->';
2268
2269
	// Show the standard "Save Settings" profile button.
2270
	template_profile_save();
2271
2272
	echo '
2273
		</div><!-- .windowbg -->
2274
	</form>
2275
	<br>';
2276
}
2277
2278
/**
2279
 * Simply loads some theme variables common to several warning templates.
2280
 */
2281
function template_load_warning_variables()
2282
{
2283
	global $modSettings, $context;
2284
2285
	// Setup the warning mode
2286
	$context['warning_mode'] = array(
2287
		0 => 'none',
2288
		$modSettings['warning_watch'] => 'watched',
2289
		$modSettings['warning_moderate'] => 'moderated',
2290
		$modSettings['warning_mute'] => 'muted',
2291
	);
2292
2293
	// Work out the starting warning.
2294
	$context['current_warning_mode'] = $context['warning_mode'][0];
2295
	foreach ($context['warning_mode'] as $limit => $warning)
2296
		if ($context['member']['warning'] >= $limit)
2297
			$context['current_warning_mode'] = $warning;
2298
}
2299
2300
/**
2301
 * Template for viewing a user's warnings
2302
 */
2303
function template_viewWarning()
2304
{
2305
	global $context, $txt;
2306
2307
	template_load_warning_variables();
2308
2309
	echo '
2310
		<div class="cat_bar">
2311
			<h3 class="catbg profile_hd">
2312
				', sprintf($txt['profile_viewwarning_for_user'], $context['member']['name']), '
2313
			</h3>
2314
		</div>
2315
		<p class="information">', $txt['viewWarning_help'], '</p>
2316
		<div class="windowbg">
2317
			<dl class="settings">
2318
				<dt>
2319
					<strong>', $txt['profile_warning_name'], ':</strong>
2320
				</dt>
2321
				<dd>
2322
					', $context['member']['name'], '
2323
				</dd>
2324
				<dt>
2325
					<strong>', $txt['profile_warning_level'], ':</strong>
2326
				</dt>
2327
				<dd>
2328
					<div class="generic_bar warning_level ', $context['current_warning_mode'], '">
2329
						<div class="bar" style="width: ', $context['member']['warning'], '%;"></div>
2330
						<span>', $context['member']['warning'], '%</span>
2331
					</div>
2332
				</dd>';
2333
2334
	// There's some impact of this?
2335
	if (!empty($context['level_effects'][$context['current_level']]))
2336
		echo '
2337
				<dt>
2338
					<strong>', $txt['profile_viewwarning_impact'], ':</strong>
2339
				</dt>
2340
				<dd>
2341
					', $context['level_effects'][$context['current_level']], '
2342
				</dd>';
2343
2344
	echo '
2345
			</dl>
2346
		</div><!-- .windowbg -->';
2347
2348
	template_show_list('view_warnings');
2349
}
2350
2351
/**
2352
 * Template for issuing warnings
2353
 */
2354
function template_issueWarning()
2355
{
2356
	global $context, $scripturl, $txt;
2357
2358
	template_load_warning_variables();
2359
2360
	echo '
2361
	<script>
2362
		// Disable notification boxes as required.
2363
		function modifyWarnNotify()
2364
		{
2365
			disable = !document.getElementById(\'warn_notify\').checked;
2366
			document.getElementById(\'warn_sub\').disabled = disable;
2367
			document.getElementById(\'warn_body\').disabled = disable;
2368
			document.getElementById(\'warn_temp\').disabled = disable;
2369
			document.getElementById(\'new_template_link\').style.display = disable ? \'none\' : \'\';
2370
			document.getElementById(\'preview_button\').style.display = disable ? \'none\' : \'\';
2371
		}
2372
2373
		// Warn template.
2374
		function populateNotifyTemplate()
2375
		{
2376
			index = document.getElementById(\'warn_temp\').value;
2377
			if (index == -1)
2378
				return false;
2379
2380
			// Otherwise see what we can do...';
2381
2382
	foreach ($context['notification_templates'] as $k => $type)
2383
		echo '
2384
			if (index == ', $k, ')
2385
				document.getElementById(\'warn_body\').value = "', strtr($type['body'], array('"' => "'", "\n" => '\\n', "\r" => '')), '";';
2386
2387
	echo '
2388
		}
2389
2390
		function updateSlider(slideAmount)
2391
		{
2392
			// Also set the right effect.
2393
			effectText = "";';
2394
2395
	foreach ($context['level_effects'] as $limit => $text)
2396
		echo '
2397
			if (slideAmount >= ', $limit, ')
2398
				effectText = "', $text, '";';
2399
2400
	echo '
2401
			setInnerHTML(document.getElementById(\'cur_level_div\'), slideAmount + \'% (\' + effectText + \')\');
2402
		}
2403
	</script>';
2404
2405
	echo '
2406
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=issuewarning" method="post" class="flow_hidden" accept-charset="', $context['character_set'], '">
2407
		<div class="cat_bar">
2408
			<h3 class="catbg profile_hd">
2409
				', $context['user']['is_owner'] ? $txt['profile_warning_level'] : $txt['profile_issue_warning'], '
2410
			</h3>
2411
		</div>';
2412
2413
	if (!$context['user']['is_owner'])
2414
		echo '
2415
		<p class="information">', $txt['profile_warning_desc'], '</p>';
2416
2417
	echo '
2418
		<div class="windowbg">
2419
			<dl class="settings">';
2420
2421
	if (!$context['user']['is_owner'])
2422
		echo '
2423
				<dt>
2424
					<strong>', $txt['profile_warning_name'], ':</strong>
2425
				</dt>
2426
				<dd>
2427
					<strong>', $context['member']['name'], '</strong>
2428
				</dd>';
2429
2430
	echo '
2431
				<dt>
2432
					<strong>', $txt['profile_warning_level'], ':</strong>';
2433
2434
	// Is there only so much they can apply?
2435
	if ($context['warning_limit'])
2436
		echo '
2437
					<br>
2438
					<span class="smalltext">', sprintf($txt['profile_warning_limit_attribute'], $context['warning_limit']), '</span>';
2439
2440
	echo '
2441
				</dt>
2442
				<dd>
2443
					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%
2444
					<div class="clear_left">
2445
						', $txt['profile_warning_impact'], ': <span id="cur_level_div">', $context['member']['warning'], '% (', $context['level_effects'][$context['current_level']], ')</span>
2446
					</div>
2447
				</dd>';
2448
2449
	if (!$context['user']['is_owner'])
2450
	{
2451
		echo '
2452
				<dt>
2453
					<strong>', $txt['profile_warning_reason'], ':</strong><br>
2454
					<span class="smalltext">', $txt['profile_warning_reason_desc'], '</span>
2455
				</dt>
2456
				<dd>
2457
					<input type="text" name="warn_reason" id="warn_reason" value="', $context['warning_data']['reason'], '" size="50">
2458
				</dd>
2459
			</dl>
2460
			<hr>
2461
			<div id="box_preview"', !empty($context['warning_data']['body_preview']) ? '' : ' style="display:none"', '>
2462
				<dl class="settings">
2463
					<dt>
2464
						<strong>', $txt['preview'], '</strong>
2465
					</dt>
2466
					<dd id="body_preview">
2467
						', !empty($context['warning_data']['body_preview']) ? $context['warning_data']['body_preview'] : '', '
2468
					</dd>
2469
				</dl>
2470
				<hr>
2471
			</div>
2472
			<dl class="settings">
2473
				<dt>
2474
					<strong><label for="warn_notify">', $txt['profile_warning_notify'], ':</label></strong>
2475
				</dt>
2476
				<dd>
2477
					<input type="checkbox" name="warn_notify" id="warn_notify" onclick="modifyWarnNotify();"', $context['warning_data']['notify'] ? ' checked' : '', '>
2478
				</dd>
2479
				<dt>
2480
					<strong><label for="warn_sub">', $txt['profile_warning_notify_subject'], ':</label></strong>
2481
				</dt>
2482
				<dd>
2483
					<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">
2484
				</dd>
2485
				<dt>
2486
					<strong><label for="warn_temp">', $txt['profile_warning_notify_body'], ':</label></strong>
2487
				</dt>
2488
				<dd>
2489
					<select name="warn_temp" id="warn_temp" disabled onchange="populateNotifyTemplate();">
2490
						<option value="-1">', $txt['profile_warning_notify_template'], '</option>
2491
						<option value="-1" disabled>------------------------------</option>';
2492
2493
		foreach ($context['notification_templates'] as $id_template => $template)
2494
			echo '
2495
						<option value="', $id_template, '">', $template['title'], '</option>';
2496
2497
		echo '
2498
					</select>
2499
					<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>
2500
					<br>
2501
					<textarea name="warn_body" id="warn_body" cols="40" rows="8">', $context['warning_data']['notify_body'], '</textarea>
2502
				</dd>';
2503
	}
2504
	echo '
2505
			</dl>
2506
			<div class="righttext">';
2507
2508
	if (!empty($context['token_check']))
2509
		echo '
2510
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2511
2512
	echo '
2513
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2514
				<input type="button" name="preview" id="preview_button" value="', $txt['preview'], '" class="button">
2515
				<input type="submit" name="save" value="', $context['user']['is_owner'] ? $txt['change_profile'] : $txt['profile_warning_issue'], '" class="button">
2516
			</div><!-- .righttext -->
2517
		</div><!-- .windowbg -->
2518
	</form>';
2519
2520
	// Previous warnings?
2521
	template_show_list('view_warnings');
2522
2523
	echo '
2524
	<script>';
2525
2526
	if (!$context['user']['is_owner'])
2527
		echo '
2528
		modifyWarnNotify();
2529
		$(document).ready(function() {
2530
			$("#preview_button").click(function() {
2531
				return ajax_getTemplatePreview();
2532
			});
2533
		});
2534
2535
		function ajax_getTemplatePreview ()
2536
		{
2537
			$.ajax({
2538
				type: "POST",
2539
				headers: {
2540
					"X-SMF-AJAX": 1
2541
				},
2542
				xhrFields: {
2543
					withCredentials: typeof allow_xhjr_credentials !== "undefined" ? allow_xhjr_credentials : false
2544
				},
2545
				url: "' . $scripturl . '?action=xmlhttp;sa=previews;xml",
2546
				data: {item: "warning_preview", title: $("#warn_sub").val(), body: $("#warn_body").val(), issuing: true},
2547
				context: document.body,
2548
				success: function(request){
2549
					$("#box_preview").css({display:""});
2550
					$("#body_preview").html($(request).find(\'body\').text());
2551
					if ($(request).find("error").text() != \'\')
2552
					{
2553
						$("#profile_error").css({display:""});
2554
						var errors_html = \'<ul class="list_errors">\';
2555
						var errors = $(request).find(\'error\').each(function() {
2556
							errors_html += \'<li>\' + $(this).text() + \'</li>\';
2557
						});
2558
						errors_html += \'</ul>\';
2559
2560
						$("#profile_error").html(errors_html);
2561
					}
2562
					else
2563
					{
2564
						$("#profile_error").css({display:"none"});
2565
						$("#error_list").html(\'\');
2566
					}
2567
				return false;
2568
				},
2569
			});
2570
			return false;
2571
		}';
2572
2573
	echo '
2574
	</script>';
2575
}
2576
2577
/**
2578
 * Template to show for deleting a user's account - now with added delete post capability!
2579
 */
2580
function template_deleteAccount()
2581
{
2582
	global $context, $scripturl, $txt;
2583
2584
	// The main containing header.
2585
	echo '
2586
		<form action="', $scripturl, '?action=profile;area=deleteaccount;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2587
			<div class="cat_bar">
2588
				<h3 class="catbg profile_hd">
2589
					', $txt['deleteAccount'], '
2590
				</h3>
2591
			</div>';
2592
2593
	// If deleting another account give them a lovely info box.
2594
	if (!$context['user']['is_owner'])
2595
		echo '
2596
			<p class="information">', $txt['deleteAccount_desc'], '</p>';
2597
2598
	echo '
2599
			<div class="windowbg">';
2600
2601
	// If they are deleting their account AND the admin needs to approve it - give them another piece of info ;)
2602
	if ($context['needs_approval'])
2603
		echo '
2604
				<div class="errorbox">', $txt['deleteAccount_approval'], '</div>';
2605
2606
	// If the user is deleting their own account warn them first - and require a password!
2607
	if ($context['user']['is_owner'])
2608
	{
2609
		echo '
2610
				<div class="alert">', $txt['own_profile_confirm'], '</div>
2611
				<div>
2612
					<strong', (isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : ''), '>', $txt['current_password'], ': </strong>
2613
					<input type="password" name="oldpasswrd" size="20">
2614
					<input type="submit" value="', $txt['yes'], '" class="button">';
2615
2616
		if (!empty($context['token_check']))
2617
			echo '
2618
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2619
2620
		echo '
2621
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2622
					<input type="hidden" name="u" value="', $context['id_member'], '">
2623
					<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2624
				</div>';
2625
	}
2626
	// Otherwise an admin doesn't need to enter a password - but they still get a warning - plus the option to delete lovely posts!
2627
	else
2628
	{
2629
		echo '
2630
				<div class="alert">', $txt['deleteAccount_warning'], '</div>';
2631
2632
		// Only actually give these options if they are kind of important.
2633
		if ($context['can_delete_posts'])
2634
		{
2635
			echo '
2636
				<div>
2637
					<label for="deleteVotes">
2638
						<input type="checkbox" name="deleteVotes" id="deleteVotes" value="1"> ', $txt['deleteAccount_votes'], ':
2639
					</label><br>
2640
					<label for="deletePosts">
2641
						<input type="checkbox" name="deletePosts" id="deletePosts" value="1"> ', $txt['deleteAccount_posts'], ':
2642
					</label>
2643
					<select name="remove_type">
2644
						<option value="posts">', $txt['deleteAccount_all_posts'], '</option>
2645
						<option value="topics">', $txt['deleteAccount_topics'], '</option>
2646
					</select>';
2647
2648
			if ($context['show_perma_delete'])
2649
				echo '
2650
					<br>
2651
					<label for="perma_delete"><input type="checkbox" name="perma_delete" id="perma_delete" value="1">', $txt['deleteAccount_permanent'], '</label>';
2652
2653
			echo '
2654
				</div>';
2655
		}
2656
2657
		echo '
2658
				<div>
2659
					<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>
2660
				</div>
2661
				<div>
2662
					<input type="submit" value="', $txt['delete'], '" class="button">';
2663
2664
		if (!empty($context['token_check']))
2665
			echo '
2666
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2667
2668
		echo '
2669
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2670
					<input type="hidden" name="u" value="', $context['id_member'], '">
2671
					<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2672
				</div>';
2673
	}
2674
	echo '
2675
			</div><!-- .windowbg -->
2676
			<br>
2677
		</form>';
2678
}
2679
2680
/**
2681
 * Template for the password box/save button stuck at the bottom of every profile page.
2682
 */
2683
function template_profile_save()
2684
{
2685
	global $context, $txt;
2686
2687
	echo '
2688
2689
					<hr>';
2690
2691
	// Only show the password box if it's actually needed.
2692
	if ($context['require_password'])
2693
		echo '
2694
					<dl class="settings">
2695
						<dt>
2696
							<strong', isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : '', '>', $txt['current_password'], ': </strong><br>
2697
							<span class="smalltext">', $txt['required_security_reasons'], '</span>
2698
						</dt>
2699
						<dd>
2700
							<input type="password" name="oldpasswrd" size="20">
2701
						</dd>
2702
					</dl>';
2703
2704
	echo '
2705
					<div class="righttext">';
2706
2707
	if (!empty($context['token_check']))
2708
		echo '
2709
						<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2710
2711
	echo '
2712
						<input type="submit" value="', $txt['change_profile'], '" class="button">
2713
						<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2714
						<input type="hidden" name="u" value="', $context['id_member'], '">
2715
						<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2716
					</div>';
2717
}
2718
2719
/**
2720
 * Small template for showing an error message upon a save problem in the profile.
2721
 */
2722
function template_error_message()
2723
{
2724
	global $context, $modSettings, $txt;
2725
2726
	echo '
2727
		<div class="errorbox" ', empty($context['post_errors']) ? 'style="display:none" ' : '', 'id="profile_error">';
2728
2729
	if (!empty($context['post_errors']))
2730
	{
2731
		echo '
2732
			<span>', !empty($context['custom_error_title']) ? $context['custom_error_title'] : $txt['profile_errors_occurred'], ':</span>
2733
			<ul id="list_errors">';
2734
2735
		// Cycle through each error and display an error message.
2736
		foreach ($context['post_errors'] as $error)
2737
		{
2738
			$text_key_error = $error == 'password_short' ?
2739
				sprintf($txt['profile_error_' . $error], (empty($modSettings['password_strength']) ? 4 : 8)) :
2740
				(isset($txt['profile_error_' . $error]) ? $txt['profile_error_' . $error] : '');
2741
2742
			echo '
2743
				<li>', isset($txt['profile_error_' . $error]) ? $text_key_error : $error, '</li>';
2744
		}
2745
2746
		echo '
2747
			</ul>';
2748
	}
2749
2750
	echo '
2751
		</div><!-- #profile_error -->';
2752
}
2753
2754
/**
2755
 * Display a load of drop down selectors for allowing the user to change group.
2756
 */
2757
function template_profile_group_manage()
2758
{
2759
	global $context, $txt, $scripturl;
2760
2761
	echo '
2762
							<dt>
2763
								<strong>', $txt['primary_membergroup'], '</strong><br>
2764
								<span class="smalltext"><a href="', $scripturl, '?action=helpadmin;help=moderator_why_missing" onclick="return reqOverlayDiv(this.href);"><span class="main_icons help"></span> ', $txt['moderator_why_missing'], '</a></span>
2765
							</dt>
2766
							<dd>
2767
								<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;"' : ''), '>';
2768
2769
	// Fill the select box with all primary member groups that can be assigned to a member.
2770
	foreach ($context['member_groups'] as $member_group)
2771
		if (!empty($member_group['can_be_primary']))
2772
			echo '
2773
									<option value="', $member_group['id'], '"', $member_group['is_primary'] ? ' selected' : '', '>
2774
										', $member_group['name'], '
2775
									</option>';
2776
2777
	echo '
2778
								</select>
2779
							</dd>
2780
							<dt>
2781
								<strong>', $txt['additional_membergroups'], '</strong>
2782
							</dt>
2783
							<dd>
2784
								<span id="additional_groupsList">
2785
									<input type="hidden" name="additional_groups[]" value="0">';
2786
2787
	// For each membergroup show a checkbox so members can be assigned to more than one group.
2788
	foreach ($context['member_groups'] as $member_group)
2789
		if ($member_group['can_be_additional'])
2790
			echo '
2791
									<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>';
2792
2793
	echo '
2794
								</span>
2795
								<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>
2796
								<script>
2797
									document.getElementById("additional_groupsList").style.display = "none";
2798
									document.getElementById("additional_groupsLink").style.display = "";
2799
								</script>
2800
							</dd>';
2801
2802
}
2803
2804
/**
2805
 * Callback function for entering a birthdate!
2806
 */
2807
function template_profile_birthdate()
2808
{
2809
	global $txt, $context;
2810
2811
	// Just show the pretty box!
2812
	echo '
2813
							<dt>
2814
								<strong>', $txt['dob'], '</strong><br>
2815
								<span class="smalltext">', $txt['dob_year'], ' - ', $txt['dob_month'], ' - ', $txt['dob_day'], '</span>
2816
							</dt>
2817
							<dd>
2818
								<input type="text" name="bday3" size="4" maxlength="4" value="', $context['member']['birth_date']['year'], '"> -
2819
								<input type="text" name="bday1" size="2" maxlength="2" value="', $context['member']['birth_date']['month'], '"> -
2820
								<input type="text" name="bday2" size="2" maxlength="2" value="', $context['member']['birth_date']['day'], '">
2821
							</dd>';
2822
}
2823
2824
/**
2825
 * Show the signature editing box?
2826
 */
2827
function template_profile_signature_modify()
2828
{
2829
	global $txt, $context;
2830
2831
	echo '
2832
							<dt id="current_signature" style="display:none">
2833
								<strong>', $txt['current_signature'], '</strong>
2834
							</dt>
2835
							<dd id="current_signature_display" style="display:none">
2836
								<hr>
2837
							</dd>
2838
2839
							<dt id="preview_signature" style="display:none">
2840
								<strong>', $txt['signature_preview'], '</strong>
2841
							</dt>
2842
							<dd id="preview_signature_display" style="display:none">
2843
								<hr>
2844
							</dd>
2845
2846
							<dt>
2847
								<strong>', $txt['signature'], '</strong><br>
2848
								<span class="smalltext">', $txt['sig_info'], '</span><br>
2849
								<br>';
2850
2851
	if ($context['show_spellchecking'])
2852
		echo '
2853
								<input type="button" value="', $txt['spell_check'], '" onclick="spellCheck(\'creator\', \'signature\');" class="button">';
2854
2855
	echo '
2856
							</dt>
2857
							<dd>
2858
								<textarea class="editor" onkeyup="calcCharLeft();" id="signature" name="signature" rows="5" cols="50">', $context['member']['signature'], '</textarea><br>';
2859
2860
	// If there is a limit at all!
2861
	if (!empty($context['signature_limits']['max_length']))
2862
		echo '
2863
								<span class="smalltext">', sprintf($txt['max_sig_characters'], $context['signature_limits']['max_length']), ' <span id="signatureLeft">', $context['signature_limits']['max_length'], '</span></span><br>';
2864
2865
	if (!empty($context['show_preview_button']))
2866
		echo '
2867
								<input type="button" name="preview_signature" id="preview_button" value="', $txt['preview_signature'], '" class="button floatright">';
2868
2869
	if ($context['signature_warning'])
2870
		echo '
2871
								<span class="smalltext">', $context['signature_warning'], '</span>';
2872
2873
	// Some javascript used to count how many characters have been used so far in the signature.
2874
	echo '
2875
								<script>
2876
									var maxLength = ', $context['signature_limits']['max_length'], ';
2877
2878
									$(document).ready(function() {
2879
										calcCharLeft();
2880
										$("#preview_button").click(function() {
2881
											return ajax_getSignaturePreview(true);
2882
										});
2883
									});
2884
								</script>
2885
							</dd>';
2886
}
2887
2888
/**
2889
 * Template for selecting an avatar
2890
 */
2891
function template_profile_avatar_select()
2892
{
2893
	global $context, $txt, $modSettings, $scripturl;
2894
2895
	// Start with the upper menu
2896
	echo '
2897
							<dt>
2898
								<strong id="personal_picture">
2899
									<label for="avatar_upload_box">', $txt['personal_picture'], '</label>
2900
								</strong>';
2901
2902
	if (empty($modSettings['gravatarEnabled']) || empty($modSettings['gravatarOverride']))
2903
		echo '
2904
								<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"' : '') . '>
2905
								<label for="avatar_choice_none"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2906
									' . $txt['no_avatar'] . '
2907
								</label><br>';
2908
2909
	if (!empty($context['member']['avatar']['allow_server_stored']))
2910
		echo '
2911
								<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"' : '') . '>
2912
								<label for="avatar_choice_server_stored"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2913
									', $txt['choose_avatar_gallery'], '
2914
								</label><br>';
2915
2916
	if (!empty($context['member']['avatar']['allow_external']))
2917
		echo '
2918
								<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"' : '') . '>
2919
								<label for="avatar_choice_external"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2920
									', $txt['my_own_pic'], '
2921
								</label><br>';
2922
2923
	if (!empty($context['member']['avatar']['allow_upload']))
2924
		echo '
2925
								<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"' : '') . '>
2926
								<label for="avatar_choice_upload"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2927
									', $txt['avatar_will_upload'], '
2928
								</label><br>';
2929
2930
	if (!empty($context['member']['avatar']['allow_gravatar']))
2931
		echo '
2932
								<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"' : '') . '>
2933
								<label for="avatar_choice_gravatar"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['use_gravatar'] . '</label>
2934
								<span class="smalltext"><a href="', $scripturl, '?action=helpadmin;help=gravatar" onclick="return reqOverlayDiv(this.href);"><span class="main_icons help"></span></a></span>';
2935
2936
	echo '
2937
							</dt>
2938
							<dd>';
2939
2940
	// If users are allowed to choose avatars stored on the server show selection boxes to choice them from.
2941
	if (!empty($context['member']['avatar']['allow_server_stored']))
2942
	{
2943
		echo '
2944
								<div id="avatar_server_stored">
2945
									<div>
2946
										<select name="cat" id="cat" size="10" onchange="changeSel(\'\');" onfocus="selectRadioByName(document.forms.creator.avatar_choice, \'server_stored\');">';
2947
2948
		// This lists all the file categories.
2949
		foreach ($context['avatars'] as $avatar)
2950
			echo '
2951
											<option value="', $avatar['filename'] . ($avatar['is_dir'] ? '/' : ''), '"', ($avatar['checked'] ? ' selected' : ''), '>', $avatar['name'], '</option>';
2952
2953
		echo '
2954
										</select>
2955
									</div>
2956
									<div>
2957
										<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>
2958
									</div>
2959
									<div class="edit_avatar_img">
2960
										<img id="avatar" src="', $context['member']['avatar']['choice'] == 'server_stored' ? $context['member']['avatar']['href'] : $modSettings['avatar_url'] . '/blank.png', '" alt="">
2961
									</div>
2962
									<script>
2963
										var files = ["' . implode('", "', $context['avatar_list']) . '"];
2964
										var avatar = document.getElementById("avatar");
2965
										var cat = document.getElementById("cat");
2966
										var selavatar = "' . $context['avatar_selected'] . '";
2967
										var avatardir = "' . $modSettings['avatar_url'] . '/";
2968
										var size = avatar.alt.substr(3, 2) + " " + avatar.alt.substr(0, 2) + String.fromCharCode(117, 98, 116);
2969
										var file = document.getElementById("file");
2970
2971
										if (avatar.src.indexOf("blank.png") > -1)
2972
											changeSel(selavatar);
2973
										else
2974
											previewExternalAvatar(avatar.src)
2975
2976
									</script>
2977
								</div><!-- #avatar_server_stored -->';
2978
	}
2979
2980
	// If the user can link to an off server avatar, show them a box to input the address.
2981
	if (!empty($context['member']['avatar']['allow_external']))
2982
		echo '
2983
								<div id="avatar_external">
2984
									', $context['member']['avatar']['choice'] == 'external' ? '<div class="edit_avatar_img"><img src="' . $context['member']['avatar']['href'] . '" alt="" class="avatar"></div>' : '', '
2985
									<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') : '', '
0 ignored issues
show
Are you sure the usage of template_max_size('external') is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2986
									<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);"><br>
2987
								</div>';
2988
2989
	// If the user is able to upload avatars to the server show them an upload box.
2990
	if (!empty($context['member']['avatar']['allow_upload']))
2991
		echo '
2992
								<div id="avatar_upload">
2993
									', $context['member']['avatar']['choice'] == 'upload' ? '<div class="edit_avatar_img"><img src="' . $context['member']['avatar']['href'] . '" alt=""></div>' : '', '
2994
									<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'), '
0 ignored issues
show
Are you sure the usage of template_max_size('upload') is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
2995
									', (!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'] . '">' : ''), '
2996
								</div>';
2997
2998
	// if the user is able to use Gravatar avatars show then the image preview
2999
	if (!empty($context['member']['avatar']['allow_gravatar']))
3000
	{
3001
		echo '
3002
								<div id="avatar_gravatar">
3003
									', $context['member']['avatar']['choice'] == 'gravatar' ? '<div class="edit_avatar_img"><img src="' . $context['member']['avatar']['href'] . '" alt=""></div>' : '';
3004
3005
		if (empty($modSettings['gravatarAllowExtraEmail']))
3006
			echo '
3007
									<div class="smalltext">', $txt['gravatar_noAlternateEmail'], '</div>';
3008
		else
3009
		{
3010
			// Depending on other stuff, the stored value here might have some odd things in it from other areas.
3011
			if ($context['member']['avatar']['external'] == $context['member']['email'])
3012
				$textbox_value = '';
3013
			else
3014
				$textbox_value = $context['member']['avatar']['external'];
3015
3016
			echo '
3017
									<div class="smalltext">', $txt['gravatar_alternateEmail'], '</div>
3018
									<input type="text" name="gravatarEmail" id="gravatarEmail" size="45" value="', $textbox_value, '">';
3019
		}
3020
		echo '
3021
								</div><!-- #avatar_gravatar -->';
3022
	}
3023
3024
	echo '
3025
								<script>
3026
									', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "' . ($context['member']['avatar']['choice'] == 'server_stored' ? '' : 'none') . '";' : '', '
3027
									', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "' . ($context['member']['avatar']['choice'] == 'external' ? '' : 'none') . '";' : '', '
3028
									', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "' . ($context['member']['avatar']['choice'] == 'upload' ? '' : 'none') . '";' : '', '
3029
									', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "' . ($context['member']['avatar']['choice'] == 'gravatar' ? '' : 'none') . '";' : '', '
3030
3031
									function swap_avatar(type)
3032
									{
3033
										switch(type.id)
3034
										{
3035
											case "avatar_choice_server_stored":
3036
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "";' : '', '
3037
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3038
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3039
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3040
												break;
3041
											case "avatar_choice_external":
3042
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3043
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "";' : '', '
3044
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3045
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3046
												break;
3047
											case "avatar_choice_upload":
3048
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3049
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3050
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "";' : '', '
3051
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3052
												break;
3053
											case "avatar_choice_none":
3054
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3055
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3056
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3057
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3058
												break;
3059
											case "avatar_choice_gravatar":
3060
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3061
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3062
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3063
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "";' : '', '
3064
												', !empty($modSettings['gravatarAllowExtraEmail']) && ($context['member']['avatar']['external'] == $context['member']['email'] || strstr($context['member']['avatar']['external'], 'http://') || strstr($context['member']['avatar']['external'], 'https://')) ?
3065
												'document.getElementById("gravatarEmail").value = "";' : '', '
3066
												break;
3067
										}
3068
									}
3069
								</script>
3070
							</dd>';
3071
}
3072
3073
/**
3074
 * This is just a really little helper to avoid duplicating code unnecessarily
3075
 *
3076
 * @param string $type The type of avatar
3077
 */
3078
function template_max_size($type)
3079
{
3080
	global $modSettings, $txt;
3081
3082
	$w = !empty($modSettings['avatar_max_width_' . $type]) ? comma_format($modSettings['avatar_max_width_' . $type]) : 0;
3083
	$h = !empty($modSettings['avatar_max_height_' . $type]) ? comma_format($modSettings['avatar_max_height_' . $type]) : 0;
3084
3085
	$suffix = (!empty($w) ? 'w' : '') . (!empty($h) ? 'h' : '');
3086
	if (empty($suffix))
3087
		return;
3088
3089
	echo '
3090
								<div class="smalltext">', sprintf($txt['avatar_max_size_' . $suffix], $w, $h), '</div>';
3091
}
3092
3093
/**
3094
 * Select the time format!
3095
 */
3096
function template_profile_timeformat_modify()
3097
{
3098
	global $context, $txt, $scripturl;
3099
3100
	echo '
3101
							<dt>
3102
								<strong><label for="easyformat">', $txt['time_format'], '</label></strong><br>
3103
								<a href="', $scripturl, '?action=helpadmin;help=time_format" onclick="return reqOverlayDiv(this.href);" class="help"><span class="main_icons help" title="', $txt['help'], '"></span></a>
3104
								<span class="smalltext">
3105
									<label for="time_format">', $txt['date_format'], '</label>
3106
								</span>
3107
							</dt>
3108
							<dd>
3109
								<select name="easyformat" id="easyformat" onchange="document.forms.creator.time_format.value = this.options[this.selectedIndex].value;">';
3110
3111
	// Help the user by showing a list of common time formats.
3112
	foreach ($context['easy_timeformats'] as $time_format)
3113
		echo '
3114
									<option value="', $time_format['format'], '"', $time_format['format'] == $context['member']['time_format'] ? ' selected' : '', '>', $time_format['title'], '</option>';
3115
3116
	echo '
3117
								</select>
3118
								<input type="text" name="time_format" id="time_format" value="', $context['member']['time_format'], '" size="30">
3119
							</dd>';
3120
}
3121
3122
/**
3123
 * Template for picking a theme
3124
 */
3125
function template_profile_theme_pick()
3126
{
3127
	global $txt, $context, $scripturl;
3128
3129
	echo '
3130
							<dt>
3131
								<strong>', $txt['current_theme'], '</strong>
3132
							</dt>
3133
							<dd>
3134
								', $context['member']['theme']['name'], ' <a class="button" href="', $scripturl, '?action=theme;sa=pick;u=', $context['id_member'], '">', $txt['change'], '</a>
3135
							</dd>';
3136
}
3137
3138
/**
3139
 * Smiley set picker.
3140
 */
3141
function template_profile_smiley_pick()
3142
{
3143
	global $txt, $context, $modSettings, $settings;
3144
3145
	echo '
3146
							<dt>
3147
								<strong><label for="smiley_set">', $txt['smileys_current'], '</label></strong>
3148
							</dt>
3149
							<dd>
3150
								<select name="smiley_set" id="smiley_set">';
3151
3152
	foreach ($context['smiley_sets'] as $set)
3153
		echo '
3154
									<option data-preview="', $set['preview'], '" value="', $set['id'], '"', $set['selected'] ? ' selected' : '', '>', $set['name'], '</option>';
3155
3156
	echo '
3157
								</select>
3158
								<img id="smileypr" class="centericon" src="', $context['member']['smiley_set']['preview'], '" alt=":)">
3159
							</dd>';
3160
}
3161
3162
/**
3163
 * Template for setting up and managing Two-Factor Authentication.
3164
 */
3165
function template_tfasetup()
3166
{
3167
	global $txt, $context, $scripturl, $modSettings;
3168
3169
	echo '
3170
			<div class="cat_bar">
3171
				<h3 class="catbg">', $txt['tfa_title'], '</h3>
3172
			</div>
3173
			<div class="roundframe">
3174
				<div>';
3175
3176
	if (!empty($context['tfa_backup']))
3177
		echo '
3178
					<div class="smalltext error">
3179
						', $txt['tfa_backup_used_desc'], '
3180
					</div>';
3181
3182
	elseif ($modSettings['tfa_mode'] == 2)
3183
		echo '
3184
					<div class="smalltext">
3185
						<strong>', $txt['tfa_forced_desc'], '</strong>
3186
					</div>';
3187
3188
	echo '
3189
					<div class="smalltext">
3190
						', $txt['tfa_desc'], '
3191
					</div>
3192
					<div class="floatleft">
3193
						<form action="', $scripturl, '?action=profile;area=tfasetup" method="post">
3194
							<div class="block">
3195
								<strong>', $txt['tfa_step1'], '</strong><br>';
3196
3197
	if (!empty($context['tfa_pass_error']))
3198
		echo '
3199
								<div class="error smalltext">
3200
									', $txt['tfa_pass_invalid'], '
3201
								</div>';
3202
3203
	echo '
3204
								<input type="password" name="oldpasswrd" size="25"', !empty($context['password_auth_failed']) ? ' class="error"' : '', !empty($context['tfa_pass_value']) ? ' value="' . $context['tfa_pass_value'] . '"' : '', '>
3205
							</div>
3206
							<div class="block">
3207
								<strong>', $txt['tfa_step2'], '</strong>
3208
								<div class="smalltext">', $txt['tfa_step2_desc'], '</div>
3209
								<div class="tfacode">', $context['tfa_secret'], '</div>
3210
							</div>
3211
							<div class="block">
3212
								<strong>', $txt['tfa_step3'], '</strong><br>';
3213
3214
	if (!empty($context['tfa_error']))
3215
		echo '
3216
								<div class="error smalltext">
3217
									', $txt['tfa_code_invalid'], '
3218
								</div>';
3219
3220
	echo '
3221
								<input type="text" name="tfa_code" size="25"', !empty($context['tfa_error']) ? ' class="error"' : '', !empty($context['tfa_value']) ? ' value="' . $context['tfa_value'] . '"' : '', '>
3222
								<input type="submit" name="save" value="', $txt['tfa_enable'], '" class="button">
3223
							</div>
3224
							<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3225
							<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3226
						</form>
3227
					</div>
3228
					<div class="floatright tfa_qrcode">
3229
						<div id="qrcode"></div>
3230
						<script type="text/javascript">
3231
							new QRCode(document.getElementById("qrcode"), "', $context['tfa_qr_url'], '");
3232
						</script>
3233
					</div>';
3234
3235
	if (!empty($context['from_ajax']))
3236
		echo '
3237
					<br>
3238
					<a href="javascript:self.close();"></a>';
3239
3240
	echo '
3241
				</div>
3242
			</div><!-- .roundframe -->';
3243
}
3244
3245
/**
3246
 * Template for disabling two-factor authentication.
3247
 */
3248
function template_tfadisable()
3249
{
3250
	global $txt, $context, $scripturl;
3251
3252
	echo '
3253
			<div class="cat_bar">
3254
				<h3 class="catbg">', $txt['tfadisable'], '</h3>
3255
			</div>
3256
			<div class="roundframe">
3257
				<form action="', $scripturl, '?action=profile;area=tfadisable" method="post">';
3258
3259
	if ($context['user']['is_owner'])
3260
		echo '
3261
					<div class="block">
3262
						<strong', (isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : ''), '>', $txt['current_password'], '</strong><br>
3263
						<input type="password" name="oldpasswrd" size="20">
3264
					</div>';
3265
	else
3266
		echo '
3267
					<div class="smalltext">
3268
						', sprintf($txt['tfa_disable_for_user'], $context['user']['name']), '
3269
					</div>';
3270
3271
	echo '
3272
					<input type="submit" name="save" value="', $txt['tfa_disable'], '" class="button floatright">
3273
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3274
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3275
					<input type="hidden" name="u" value="', $context['id_member'], '">
3276
				</form>
3277
			</div><!-- .roundframe -->';
3278
}
3279
3280
/**
3281
 * Template for setting up 2FA backup code
3282
 */
3283
function template_tfasetup_backup()
3284
{
3285
	global $context, $txt;
3286
3287
	echo '
3288
			<div class="cat_bar">
3289
				<h3 class="catbg">', $txt['tfa_backup_title'], '</h3>
3290
			</div>
3291
			<div class="roundframe">
3292
				<div>
3293
					<div class="smalltext">', $txt['tfa_backup_desc'], '</div>
3294
					<div class="bbc_code" style="resize: none; border: none;">', $context['tfa_backup'], '</div>
3295
				</div>
3296
			</div>';
3297
}
3298
3299
/**
3300
 * Simple template for showing the 2FA area when editing a profile.
3301
 */
3302
function template_profile_tfa()
3303
{
3304
	global $context, $txt, $scripturl, $modSettings;
3305
3306
	echo '
3307
							<dt>
3308
								<strong>', $txt['tfa_profile_label'], '</strong><br>
3309
								<div class="smalltext">', $txt['tfa_profile_desc'], '</div>
3310
							</dt>
3311
							<dd>';
3312
3313
	if (!$context['tfa_enabled'] && $context['user']['is_owner'])
3314
		echo '
3315
								<a href="', !empty($modSettings['force_ssl']) ? strtr($scripturl, array('http://' => 'https://')) : $scripturl, '?action=profile;area=tfasetup" id="enable_tfa">', $txt['tfa_profile_enable'], '</a>';
3316
3317
	elseif (!$context['tfa_enabled'])
3318
		echo '
3319
								', $txt['tfa_profile_disabled'];
3320
3321
	else
3322
		echo '
3323
								', sprintf($txt['tfa_profile_enabled'], (!empty($modSettings['force_ssl']) ? strtr($scripturl, array('http://' => 'https://')) : $scripturl) . '?action=profile;u=' . $context['id_member'] . ';area=tfadisable');
3324
3325
	echo '
3326
							</dd>';
3327
}
3328
3329
/**
3330
 * Template for initiating and retrieving profile data exports
3331
 */
3332
function template_export_profile_data()
3333
{
3334
	global $context, $scripturl, $txt;
3335
3336
	$default_settings = array('included' => array(), 'format' => '');
3337
	$dltoken = '';
3338
3339
	// The main containing header.
3340
	echo '
3341
		<div class="cat_bar">
3342
			<h3 class="catbg profile_hd">
3343
				', $txt['export_profile_data'], '
3344
			</h3>
3345
		</div>
3346
		<div class="information">', $context['export_profile_data_desc'], '</div>';
3347
3348
	if (!empty($context['completed_exports']))
3349
	{
3350
		echo '
3351
		<div class="title_bar">
3352
			<h3 class="titlebg">', $txt['completed_exports'], '</h3>
3353
		</div>
3354
		<div class="windowbg noup">';
3355
3356
		foreach ($context['completed_exports'] as $basehash_ext => $parts)
3357
		{
3358
			echo '
3359
			<form action="', $scripturl, '?action=profile;area=getprofiledata;u=', $context['id_member'], '" method="post" accept-charset="', $context['character_set'], '" class="', count($context['completed_exports']) > 1 ? 'descbox' : 'padding', '">';
3360
3361
			if (!empty($context['outdated_exports'][$basehash_ext]))
3362
			{
3363
				echo '
3364
				<div class="noticebox">
3365
					<p>', $txt['export_outdated_warning'], '</p>
3366
					<ul class="bbc_list">';
3367
3368
				foreach ($context['outdated_exports'][$basehash_ext] as $datatype)
3369
					echo '
3370
						<li>', $txt[$datatype], '</li>';
3371
3372
				echo '
3373
					</ul>
3374
				</div>';
3375
			}
3376
3377
			echo '
3378
				<p>', sprintf($txt['export_file_desc'], $parts[1]['included_desc'], $context['export_formats'][$parts[1]['format']]['description']), '</p>';
3379
3380
			if (count($parts) > 10)
3381
				echo '
3382
				<details>
3383
					<summary>', sprintf($txt['export_file_count'], count($parts)), '</summary>';
3384
3385
			echo '
3386
				<ul class="bbc_list" id="', $parts[1]['format'], '_export_files">';
3387
3388
			foreach ($parts as $part => $file)
3389
			{
3390
				$dltoken = $file['dltoken'];
3391
				if (empty($default_settings['included']))
3392
					$default_settings['included'] = $file['included'];
3393
				if (empty($default_settings['format']))
3394
					$default_settings['format'] = $file['format'];
3395
3396
				echo '
3397
					<li>
3398
						<a href="', $scripturl, '?action=profile;area=download;u=', $context['id_member'], ';format=', $file['format'], ';part=', $part, ';t=', $dltoken, '" class="bbc_link" download>', $file['dlbasename'], '</a> (', $file['size'], ', ', $file['mtime'], ')
3399
					</li>';
3400
			}
3401
3402
			echo '
3403
				</ul>';
3404
3405
			if (count($parts) > 10)
3406
				echo '
3407
				</details>';
3408
3409
			echo '
3410
				<div class="righttext">
3411
					<input type="submit" name="delete" value="', $txt['delete'], '" class="button you_sure">
3412
					<input type="hidden" name="format" value="', $parts[1]['format'], '">
3413
					<input type="hidden" name="t" value="', $dltoken, '">
3414
					<button type="button" class="button export_download_all" style="display:none" onclick="export_download_all(\'', $parts[1]['format'], '\');">', $txt['export_download_all'], '</button>
3415
				</div>
3416
			</form>';
3417
		}
3418
3419
		echo '
3420
		</div>';
3421
	}
3422
3423
	if (!empty($context['active_exports']))
3424
	{
3425
		echo '
3426
		<div class="title_bar">
3427
			<h3 class="titlebg">', $txt['active_exports'], '</h3>
3428
		</div>
3429
		<div class="windowbg noup">';
3430
3431
		foreach ($context['active_exports'] as $file)
3432
		{
3433
			$dltoken = $file['dltoken'];
3434
			if (empty($default_settings['included']))
3435
				$default_settings['included'] = $file['included'];
3436
			if (empty($default_settings['format']))
3437
				$default_settings['format'] = $file['format'];
3438
3439
			echo '
3440
			<form action="', $scripturl, '?action=profile;area=getprofiledata;u=', $context['id_member'], '" method="post" accept-charset="', $context['character_set'], '"', count($context['active_exports']) > 1 ? ' class="descbox"' : '', '>
3441
				<p class="padding">', sprintf($txt['export_file_desc'], $file['included_desc'], $context['export_formats'][$file['format']]['description']), '</p>
3442
				<div class="righttext">
3443
					<input type="submit" name="delete" value="', $txt['export_cancel'], '" class="button you_sure">
3444
					<input type="hidden" name="format" value="', $file['format'], '">
3445
					<input type="hidden" name="t" value="', $dltoken, '">
3446
				</div>
3447
			</form>';
3448
		}
3449
3450
		echo '
3451
		</div>';
3452
	}
3453
3454
	echo '
3455
		<div class="title_bar">
3456
			<h3 class="titlebg">', $txt['export_settings'], '</h3>
3457
		</div>
3458
		<div class="windowbg noup">
3459
			<form action="', $scripturl, '?action=profile;area=getprofiledata;u=', $context['id_member'], '" method="post" accept-charset="', $context['character_set'], '">
3460
				<dl class="settings">';
3461
3462
	foreach ($context['export_datatypes'] as $datatype => $datatype_settings)
3463
	{
3464
		if (!empty($datatype_settings['label']))
3465
			echo '
3466
					<dt>
3467
						<strong><label for="', $datatype, '">', $datatype_settings['label'], '</label></strong>
3468
					</dt>
3469
					<dd>
3470
						<input type="checkbox" id="', $datatype, '" name="', $datatype, '"', in_array($datatype, $default_settings['included']) ? ' checked' : '', '>
3471
					</dd>';
3472
	}
3473
3474
	echo '
3475
				</dl>
3476
				<dl class="settings">
3477
					<dt>
3478
						<strong>', $txt['export_format'], '</strong>
3479
					</dt>
3480
					<dd>
3481
						<select id="export_format_select" name="format">';
3482
3483
	foreach ($context['export_formats'] as $format => $format_settings)
3484
		echo '
3485
							<option value="', $format, '"', $format == $default_settings['format'] ? ' selected' : '', '>', $format_settings['description'], '</option>';
3486
3487
	echo '
3488
						</select>
3489
					</dd>
3490
				</dl>
3491
				<div class="righttext">';
3492
3493
	// At least one active or completed export exists.
3494
	if (!empty($dltoken))
3495
	{
3496
		echo '
3497
					<div id="export_begin" style="display:none">
3498
						<input type="submit" name="export_begin" value="', $txt['export_begin'], '" class="button">
3499
					</div>
3500
					<div id="export_restart">
3501
						<input type="submit" name="export_begin" value="', $txt['export_restart'], '" class="button you_sure" data-confirm="', $txt['export_restart_confirm'], '">
3502
						<input type="hidden" name="delete">
3503
						<input type="hidden" name="t" value="', $dltoken, '">
3504
					</div>';
3505
	}
3506
	// No existing exports.
3507
	else
3508
	{
3509
		echo '
3510
					<input type="submit" name="export_begin" value="', $txt['export_begin'], '" class="button">';
3511
	}
3512
3513
	echo '
3514
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3515
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3516
				</div>
3517
			</form>
3518
		</div><!-- .windowbg -->';
3519
}
3520
3521
?>