Passed
Pull Request — release-2.1 (#6101)
by Jon
04:32 queued 16s
created

template_export_profile_data()   D

Complexity

Conditions 22
Paths 48

Size

Total Lines 184
Code Lines 84

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 22
eloc 84
c 1
b 0
f 0
nc 48
nop 0
dl 0
loc 184
rs 4.1666

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Simple Machines Forum (SMF)
4
 *
5
 * @package SMF
6
 * @author Simple Machines https://www.simplemachines.org
7
 * @copyright 2020 Simple Machines and individual contributors
8
 * @license https://www.simplemachines.org/about/smf/license.php BSD
9
 *
10
 * @version 2.1 RC2
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
Bug introduced by
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="' . $details['target_href'] . '" 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">
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_type'] == 4 ? ' class="you_sure" data-confirm="' . $txt['profileConfirm'] . '"' : ''), '>', $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">
493
			<h3 class="catbg">
494
				', (!isset($context['attachments']) && empty($context['is_topics']) ? $txt['showMessages'] : (!empty($context['is_topics']) ? $txt['showTopics'] : $txt['showAttachments'])), ' - ', $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="counter">', $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['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="floatleft">
623
					', $context['pagination'], '
624
				</div>
625
				<div class="floatright">';
626
627
		if ($context['showCheckboxes'])
628
			echo '
629
					', $txt['check_all'], ': <input type="checkbox" name="select_all" id="select_all">
630
					<select name="mark_as">
631
						<option value="read">', $txt['quick_mod_markread'], '</option>
632
						<option value="unread">', $txt['quick_mod_markunread'], '</option>
633
						<option value="remove">', $txt['quick_mod_remove'], '</option>
634
					</select>
635
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
636
					<input type="hidden" name="start" value="', $context['start'], '">
637
					<input type="submit" name="req" value="', $txt['quick_mod_go'], '" class="button you_sure">';
638
639
		echo '
640
					<a href="', $context['alert_purge_link'], '" class="button you_sure">', $txt['alert_purge'], '</a>
641
				</div>
642
			</div>';
643
644
		if ($context['showCheckboxes'])
645
			echo '
646
		</form>';
647
	}
648
}
649
650
/**
651
 * Template for showing all of a user's drafts
652
 */
653
function template_showDrafts()
654
{
655
	global $context, $scripturl, $txt;
656
657
	echo '
658
		<div class="cat_bar">
659
			<h3 class="catbg">
660
				', $txt['drafts'], ' - ', $context['member']['name'], '
661
			</h3>
662
		</div>', !empty($context['page_index']) ? '
663
		<div class="pagesection">
664
			<div class="pagelinks">' . $context['page_index'] . '</div>
665
		</div>' : '';
666
667
	// No drafts? Just show an informative message.
668
	if (empty($context['drafts']))
669
		echo '
670
		<div class="windowbg centertext">
671
			', $txt['draft_none'], '
672
		</div>';
673
	else
674
	{
675
		// For every draft to be displayed, give it its own div, and show the important details of the draft.
676
		foreach ($context['drafts'] as $draft)
677
		{
678
			echo '
679
		<div class="windowbg">
680
			<div class="counter">', $draft['counter'], '</div>
681
			<div class="topic_details">
682
				<h5>
683
					<strong><a href="', $scripturl, '?board=', $draft['board']['id'], '.0">', $draft['board']['name'], '</a> / ', $draft['topic']['link'], '</strong> &nbsp; &nbsp;';
684
685
			if (!empty($draft['sticky']))
686
				echo '
687
					<span class="main_icons sticky" title="', $txt['sticky_topic'], '"></span>';
688
689
			if (!empty($draft['locked']))
690
				echo '
691
					<span class="main_icons lock" title="', $txt['locked_topic'], '"></span>';
692
693
			echo '
694
				</h5>
695
				<span class="smalltext">&#171;&nbsp;<strong>', $txt['on'], ':</strong> ', $draft['time'], '&nbsp;&#187;</span>
696
			</div><!-- .topic_details -->
697
			<div class="list_posts">
698
				', $draft['body'], '
699
			</div>
700
			<div class="floatright">';
701
702
			// Draft buttons
703
			template_quickbuttons($draft['quickbuttons'], 'profile_drafts');
704
705
			echo '
706
			</div><!-- .floatright -->
707
		</div><!-- .windowbg -->';
708
		}
709
	}
710
711
	// Show page numbers.
712
	echo '
713
		<div class="pagesection">
714
			<div class="pagelinks">', $context['page_index'], '</div>
715
		</div>';
716
}
717
718
/**
719
 * Template for showing and managing the buddy list.
720
 */
721
function template_editBuddies()
722
{
723
	global $context, $scripturl, $txt;
724
725
	if (!empty($context['saved_successful']))
726
		echo '
727
	<div class="infobox">', $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $context['member']['name']), '</div>';
728
729
	elseif (!empty($context['saved_failed']))
730
		echo '
731
	<div class="errorbox">', $context['saved_failed'], '</div>';
732
733
	echo '
734
	<div id="edit_buddies">
735
		<div class="cat_bar">
736
			<h3 class="catbg">
737
				<span class="main_icons people icon"></span> ', $txt['editBuddies'], '
738
			</h3>
739
		</div>
740
		<table class="table_grid">
741
			<thead>
742
				<tr class="title_bar">
743
					<th scope="col" class="quarter_table buddy_link">', $txt['name'], '</th>
744
					<th scope="col" class="buddy_status">', $txt['status'], '</th>';
745
746
	if ($context['can_moderate_forum'])
747
		echo '
748
					<th scope="col" class="buddy_email">', $txt['email'], '</th>';
749
750
	if (!empty($context['custom_pf']))
751
		foreach ($context['custom_pf'] as $column)
752
			echo '
753
					<th scope="col" class="buddy_custom_fields">', $column['label'], '</th>';
754
755
	echo '
756
					<th scope="col" class="buddy_remove">', $txt['remove'], '</th>
757
				</tr>
758
			</thead>
759
			<tbody>';
760
761
	// If they don't have any buddies don't list them!
762
	if (empty($context['buddies']))
763
		echo '
764
				<tr class="windowbg">
765
					<td colspan="', $context['can_moderate_forum'] ? '10' : '9', '">
766
						<strong>', $txt['no_buddies'], '</strong>
767
					</td>
768
				</tr>';
769
770
	// Now loop through each buddy showing info on each.
771
	else
772
	{
773
		foreach ($context['buddies'] as $buddy)
774
		{
775
			echo '
776
				<tr class="windowbg">
777
					<td class="buddy_link">', $buddy['link'], '</td>
778
					<td class="centertext buddy_status">
779
						<a href="', $buddy['online']['href'], '"><span class="' . ($buddy['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $buddy['online']['text'] . '"></span></a>
780
					</td>';
781
782
			if ($buddy['show_email'])
783
				echo '
784
					<td class="buddy_email centertext">
785
						<a href="mailto:' . $buddy['email'] . '" rel="nofollow"><span class="main_icons mail icon" title="' . $txt['email'] . ' ' . $buddy['name'] . '"></span></a>
786
					</td>';
787
788
			// Show the custom profile fields for this user.
789
			if (!empty($context['custom_pf']))
790
				foreach ($context['custom_pf'] as $key => $column)
791
					echo '
792
					<td class="lefttext buddy_custom_fields">', $buddy['options'][$key], '</td>';
793
794
			echo '
795
					<td class="centertext buddy_remove">
796
						<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>
797
					</td>
798
				</tr>';
799
		}
800
	}
801
802
	echo '
803
			</tbody>
804
		</table>
805
	</div><!-- #edit_buddies -->';
806
807
	// Add a new buddy?
808
	echo '
809
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=buddies" method="post" accept-charset="', $context['character_set'], '">
810
		<div class="cat_bar">
811
			<h3 class="catbg">', $txt['buddy_add'], '</h3>
812
		</div>
813
		<div class="information">
814
			<dl class="settings">
815
				<dt>
816
					<label for="new_buddy"><strong>', $txt['who_member'], ':</strong></label>
817
				</dt>
818
				<dd>
819
					<input type="text" name="new_buddy" id="new_buddy" size="30">
820
					<input type="submit" value="', $txt['buddy_add_button'], '" class="button floatnone">
821
				</dd>
822
			</dl>
823
		</div>';
824
825
	if (!empty($context['token_check']))
826
		echo '
827
		<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
828
829
	echo '
830
		<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
831
	</form>
832
	<script>
833
		var oAddBuddySuggest = new smc_AutoSuggest({
834
			sSelf: \'oAddBuddySuggest\',
835
			sSessionId: smf_session_id,
836
			sSessionVar: smf_session_var,
837
			sSuggestId: \'new_buddy\',
838
			sControlId: \'new_buddy\',
839
			sSearchType: \'member\',
840
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
841
			bItemList: false
842
		});
843
	</script>';
844
}
845
846
/**
847
 * Template for showing the ignore list of the current user.
848
 */
849
function template_editIgnoreList()
850
{
851
	global $context, $scripturl, $txt;
852
853
	if (!empty($context['saved_successful']))
854
		echo '
855
	<div class="infobox">', $context['user']['is_owner'] ? $txt['profile_updated_own'] : sprintf($txt['profile_updated_else'], $context['member']['name']), '</div>';
856
857
	elseif (!empty($context['saved_failed']))
858
		echo '
859
	<div class="errorbox">', $context['saved_failed'], '</div>';
860
861
	echo '
862
	<div id="edit_buddies">
863
		<div class="cat_bar">
864
			<h3 class="catbg profile_hd">
865
				', $txt['editIgnoreList'], '
866
			</h3>
867
		</div>
868
		<table class="table_grid">
869
			<thead>
870
				<tr class="title_bar">
871
					<th scope="col" class="quarter_table buddy_link">', $txt['name'], '</th>
872
					<th scope="col" class="buddy_status">', $txt['status'], '</th>';
873
874
	if ($context['can_moderate_forum'])
875
		echo '
876
					<th scope="col" class="buddy_email">', $txt['email'], '</th>';
877
878
	echo '
879
					<th scope="col" class="buddy_remove">', $txt['ignore_remove'], '</th>
880
				</tr>
881
			</thead>
882
			<tbody>';
883
884
	// If they don't have anyone on their ignore list, don't list it!
885
	if (empty($context['ignore_list']))
886
		echo '
887
				<tr class="windowbg">
888
					<td colspan="', $context['can_moderate_forum'] ? '4' : '3', '">
889
						<strong>', $txt['no_ignore'], '</strong>
890
					</td>
891
				</tr>';
892
893
	// Now loop through each buddy showing info on each.
894
	foreach ($context['ignore_list'] as $member)
895
	{
896
		echo '
897
				<tr class="windowbg">
898
					<td class="buddy_link">', $member['link'], '</td>
899
					<td class="centertext buddy_status">
900
						<a href="', $member['online']['href'], '"><span class="' . ($member['online']['is_online'] == 1 ? 'on' : 'off') . '" title="' . $member['online']['text'] . '"></span></a>
901
					</td>';
902
903
		if ($context['can_moderate_forum'])
904
			echo '
905
					<td class="centertext buddy_email">
906
						<a href="mailto:' . $member['email'] . '" rel="nofollow"><span class="main_icons mail icon" title="' . $txt['email'] . ' ' . $member['name'] . '"></span></a>
907
					</td>';
908
		echo '
909
					<td class="centertext buddy_remove">
910
						<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>
911
					</td>
912
				</tr>';
913
	}
914
915
	echo '
916
			</tbody>
917
		</table>
918
	</div><!-- #edit_buddies -->';
919
920
	// Add to the ignore list?
921
	echo '
922
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=lists;sa=ignore" method="post" accept-charset="', $context['character_set'], '">
923
		<div class="cat_bar">
924
			<h3 class="catbg">', $txt['ignore_add'], '</h3>
925
		</div>
926
		<div class="information">
927
			<dl class="settings">
928
				<dt>
929
					<label for="new_buddy"><strong>', $txt['who_member'], ':</strong></label>
930
				</dt>
931
				<dd>
932
					<input type="text" name="new_ignore" id="new_ignore" size="30">
933
					<input type="submit" value="', $txt['ignore_add_button'], '" class="button">
934
				</dd>
935
			</dl>
936
		</div>';
937
938
	if (!empty($context['token_check']))
939
		echo '
940
		<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
941
942
	echo '
943
		<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
944
	</form>
945
	<script>
946
		var oAddIgnoreSuggest = new smc_AutoSuggest({
947
			sSelf: \'oAddIgnoreSuggest\',
948
			sSessionId: \'', $context['session_id'], '\',
949
			sSessionVar: \'', $context['session_var'], '\',
950
			sSuggestId: \'new_ignore\',
951
			sControlId: \'new_ignore\',
952
			sSearchType: \'member\',
953
			sTextDeleteItem: \'', $txt['autosuggest_delete_item'], '\',
954
			bItemList: false
955
		});
956
	</script>';
957
}
958
959
/**
960
 * This template shows an admin information on a users IP addresses used and errors attributed to them.
961
 */
962
function template_trackActivity()
963
{
964
	global $context, $scripturl, $txt;
965
966
	// The first table shows IP information about the user.
967
	echo '
968
		<div class="cat_bar">
969
			<h3 class="catbg">', $txt['view_ips_by'], ' ', $context['member']['name'], '</h3>
970
		</div>';
971
972
	// The last IP the user used.
973
	echo '
974
		<div id="tracking" class="windowbg">
975
			<dl class="settings noborder">
976
				<dt>
977
					', $txt['most_recent_ip'], ':
978
					', (empty($context['last_ip2']) ? '' : '<br>
979
					<span class="smalltext">(<a href="' . $scripturl . '?action=helpadmin;help=whytwoip" onclick="return reqOverlayDiv(this.href);">' . $txt['why_two_ip_address'] . '</a>)</span>'), '
980
				</dt>
981
				<dd>
982
					<a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['last_ip'], ';u=', $context['member']['id'], '">', $context['last_ip'], '</a>';
983
984
	// Second address detected?
985
	if (!empty($context['last_ip2']))
986
		echo '
987
					, <a href="', $scripturl, '?action=profile;area=tracking;sa=ip;searchip=', $context['last_ip2'], ';u=', $context['member']['id'], '">', $context['last_ip2'], '</a>';
988
989
	echo '
990
				</dd>';
991
992
	// Lists of IP addresses used in messages / error messages.
993
	echo '
994
				<dt>', $txt['ips_in_messages'], ':</dt>
995
				<dd>
996
					', (count($context['ips']) > 0 ? implode(', ', $context['ips']) : '(' . $txt['none'] . ')'), '
997
				</dd>
998
				<dt>', $txt['ips_in_errors'], ':</dt>
999
				<dd>
1000
					', (count($context['error_ips']) > 0 ? implode(', ', $context['error_ips']) : '(' . $txt['none'] . ')'), '
1001
				</dd>';
1002
1003
	// List any members that have used the same IP addresses as the current member.
1004
	echo '
1005
				<dt>', $txt['members_in_range'], ':</dt>
1006
				<dd>
1007
					', (count($context['members_in_range']) > 0 ? implode(', ', $context['members_in_range']) : '(' . $txt['none'] . ')'), '
1008
				</dd>
1009
			</dl>
1010
		</div><!-- #tracking -->';
1011
1012
	// Show the track user list.
1013
	template_show_list('track_user_list');
1014
}
1015
1016
/**
1017
 * The template for trackIP, allowing the admin to see where/who a certain IP has been used.
1018
 */
1019
function template_trackIP()
1020
{
1021
	global $context, $txt;
1022
1023
	// This function always defaults to the last IP used by a member but can be set to track any IP.
1024
	// The first table in the template gives an input box to allow the admin to enter another IP to track.
1025
	echo '
1026
		<div class="cat_bar">
1027
			<h3 class="catbg">', $txt['trackIP'], '</h3>
1028
		</div>
1029
		<div class="windowbg">
1030
			<form action="', $context['base_url'], '" method="post" accept-charset="', $context['character_set'], '">
1031
				<dl class="settings">
1032
					<dt>
1033
						<label for="searchip"><strong>', $txt['enter_ip'], ':</strong></label>
1034
					</dt>
1035
					<dd>
1036
						<input type="text" name="searchip" value="', $context['ip'], '">
1037
					</dd>
1038
				</dl>
1039
				<input type="submit" value="', $txt['trackIP'], '" class="button">
1040
			</form>
1041
		</div>
1042
		<br>';
1043
1044
	// The table inbetween the first and second table shows links to the whois server for every region.
1045
	if ($context['single_ip'])
1046
	{
1047
		echo '
1048
		<div class="cat_bar">
1049
			<h3 class="catbg">', $txt['whois_title'], ' ', $context['ip'], '</h3>
1050
		</div>
1051
		<div class="windowbg">';
1052
1053
		foreach ($context['whois_servers'] as $server)
1054
			echo '
1055
			<a href="', $server['url'], '" target="_blank" rel="noopener"', '>', $server['name'], '</a><br>';
1056
		echo '
1057
		</div>
1058
		<br>';
1059
	}
1060
1061
	// The second table lists all the members who have been logged as using this IP address.
1062
	echo '
1063
		<div class="cat_bar">
1064
			<h3 class="catbg">', $txt['members_from_ip'], ' ', $context['ip'], '</h3>
1065
		</div>';
1066
1067
	if (empty($context['ips']))
1068
		echo '
1069
		<p class="windowbg description">
1070
			<em>', $txt['no_members_from_ip'], '</em>
1071
		</p>';
1072
1073
	else
1074
	{
1075
		echo '
1076
		<table class="table_grid">
1077
			<thead>
1078
				<tr class="title_bar">
1079
					<th scope="col">', $txt['ip_address'], '</th>
1080
					<th scope="col">', $txt['display_name'], '</th>
1081
				</tr>
1082
			</thead>
1083
			<tbody>';
1084
1085
		// Loop through each of the members and display them.
1086
		foreach ($context['ips'] as $ip => $memberlist)
1087
			echo '
1088
				<tr class="windowbg">
1089
					<td><a href="', $context['base_url'], ';searchip=', $ip, '">', $ip, '</a></td>
1090
					<td>', implode(', ', $memberlist), '</td>
1091
				</tr>';
1092
1093
		echo '
1094
			</tbody>
1095
		</table>';
1096
	}
1097
1098
	echo '
1099
		<br>';
1100
1101
	template_show_list('track_message_list');
1102
1103
	echo '<br>';
1104
1105
	template_show_list('track_user_list');
1106
1107
	// 3rd party integrations may have added additional tracking.
1108
	if (!empty($context['additional_track_lists']))
1109
	{
1110
		foreach ($context['additional_track_lists'] as $list)
1111
		{
1112
			echo '<br>';
1113
1114
			template_show_list($list);
1115
		}
1116
	}
1117
}
1118
1119
/**
1120
 * This template shows an admin which permissions a user have and which group(s) give them each permission.
1121
 */
1122
function template_showPermissions()
1123
{
1124
	global $context, $scripturl, $txt;
1125
1126
	echo '
1127
		<div class="cat_bar">
1128
			<h3 class="catbg profile_hd">
1129
				', $txt['showPermissions'], '
1130
			</h3>
1131
		</div>';
1132
1133
	if ($context['member']['has_all_permissions'])
1134
		echo '
1135
		<div class="information">', $txt['showPermissions_all'], '</div>';
1136
1137
	else
1138
	{
1139
		echo '
1140
		<div class="information">', $txt['showPermissions_help'], '</div>
1141
		<div id="permissions" class="flow_hidden">';
1142
1143
		if (!empty($context['no_access_boards']))
1144
		{
1145
			echo '
1146
			<div class="cat_bar">
1147
				<h3 class="catbg">', $txt['showPermissions_restricted_boards'], '</h3>
1148
			</div>
1149
			<div class="windowbg smalltext">
1150
				', $txt['showPermissions_restricted_boards_desc'], ':<br>';
1151
1152
			foreach ($context['no_access_boards'] as $no_access_board)
1153
				echo '
1154
				<a href="', $scripturl, '?board=', $no_access_board['id'], '.0">', $no_access_board['name'], '</a>', $no_access_board['is_last'] ? '' : ', ';
1155
			echo '
1156
			</div>';
1157
		}
1158
1159
		// General Permissions section.
1160
		echo '
1161
			<div class="tborder">
1162
				<div class="cat_bar">
1163
					<h3 class="catbg">', $txt['showPermissions_general'], '</h3>
1164
				</div>';
1165
		if (!empty($context['member']['permissions']['general']))
1166
		{
1167
			echo '
1168
				<table class="table_grid">
1169
					<thead>
1170
						<tr class="title_bar">
1171
							<th class="lefttext half_table">', $txt['showPermissions_permission'], '</th>
1172
							<th class="lefttext half_table">', $txt['showPermissions_status'], '</th>
1173
						</tr>
1174
					</thead>
1175
					<tbody>';
1176
1177
			foreach ($context['member']['permissions']['general'] as $permission)
1178
			{
1179
				echo '
1180
						<tr class="windowbg">
1181
							<td title="', $permission['id'], '">
1182
								', $permission['is_denied'] ? '<del>' . $permission['name'] . '</del>' : $permission['name'], '
1183
							</td>
1184
							<td class="smalltext">';
1185
1186
				if ($permission['is_denied'])
1187
					echo '
1188
								<span class="alert">', $txt['showPermissions_denied'], ': ', implode(', ', $permission['groups']['denied']), '</span>';
1189
				else
1190
					echo '
1191
								', $txt['showPermissions_given'], ': ', implode(', ', $permission['groups']['allowed']);
1192
1193
				echo '
1194
							</td>
1195
						</tr>';
1196
			}
1197
			echo '
1198
					</tbody>
1199
				</table>
1200
			</div><!-- .tborder -->
1201
			<br>';
1202
		}
1203
		else
1204
			echo '
1205
			<p class="windowbg">', $txt['showPermissions_none_general'], '</p>';
1206
1207
		// Board permission section.
1208
		echo '
1209
			<form action="' . $scripturl . '?action=profile;u=', $context['id_member'], ';area=permissions#board_permissions" method="post" accept-charset="', $context['character_set'], '">
1210
				<div class="cat_bar">
1211
					<h3 class="catbg">
1212
						<a id="board_permissions"></a>', $txt['showPermissions_select'], ':
1213
						<select name="board" onchange="if (this.options[this.selectedIndex].value) this.form.submit();">
1214
							<option value="0"', $context['board'] == 0 ? ' selected' : '', '>', $txt['showPermissions_global'], '</option>';
1215
1216
		if (!empty($context['boards']))
1217
			echo '
1218
							<option value="" disabled>---------------------------</option>';
1219
1220
		// Fill the box with any local permission boards.
1221
		foreach ($context['boards'] as $board)
1222
			echo '
1223
							<option value="', $board['id'], '"', $board['selected'] ? ' selected' : '', '>', $board['name'], ' (', $board['profile_name'], ')</option>';
1224
1225
		echo '
1226
						</select>
1227
					</h3>
1228
				</div><!-- .cat_bar -->
1229
			</form>';
1230
1231
		if (!empty($context['member']['permissions']['board']))
1232
		{
1233
			echo '
1234
			<table class="table_grid">
1235
				<thead>
1236
					<tr class="title_bar">
1237
						<th class="lefttext half_table">', $txt['showPermissions_permission'], '</th>
1238
						<th class="lefttext half_table">', $txt['showPermissions_status'], '</th>
1239
					</tr>
1240
				</thead>
1241
				<tbody>';
1242
1243
			foreach ($context['member']['permissions']['board'] as $permission)
1244
			{
1245
				echo '
1246
					<tr class="windowbg">
1247
						<td title="', $permission['id'], '">
1248
							', $permission['is_denied'] ? '<del>' . $permission['name'] . '</del>' : $permission['name'], '
1249
						</td>
1250
						<td class="smalltext">';
1251
1252
				if ($permission['is_denied'])
1253
					echo '
1254
							<span class="alert">', $txt['showPermissions_denied'], ': ', implode(', ', $permission['groups']['denied']), '</span>';
1255
1256
				else
1257
					echo '
1258
							', $txt['showPermissions_given'], ': ', implode(', ', $permission['groups']['allowed']);
1259
1260
				echo '
1261
						</td>
1262
					</tr>';
1263
			}
1264
			echo '
1265
				</tbody>
1266
			</table>';
1267
		}
1268
		else
1269
			echo '
1270
			<p class="windowbg">', $txt['showPermissions_none_board'], '</p>';
1271
		echo '
1272
		</div><!-- #permissions -->';
1273
	}
1274
}
1275
1276
/**
1277
 * Template for user statistics, showing graphs and the like.
1278
 */
1279
function template_statPanel()
1280
{
1281
	global $context, $txt;
1282
1283
	// First, show a few text statistics such as post/topic count.
1284
	echo '
1285
	<div id="profileview" class="roundframe noup">
1286
		<div id="generalstats">
1287
			<dl class="stats">';
1288
1289
	foreach ($context['text_stats'] as $key => $stat)
1290
	{
1291
		echo '
1292
				<dt>', $txt['statPanel_' . $key], '</dt>';
1293
1294
		if (!empty($stat['url']))
1295
			echo '
1296
				<dd><a href="', $stat['url'], '">', $stat['text'], '</a></dd>';
1297
		else
1298
			echo '
1299
				<dd>', $stat['text'], '</dd>';
1300
	}
1301
1302
	echo '
1303
			</dl>
1304
		</div>';
1305
1306
	// This next section draws a graph showing what times of day they post the most.
1307
	echo '
1308
		<div id="activitytime" class="flow_hidden">
1309
			<div class="title_bar">
1310
				<h3 class="titlebg">
1311
					<span class="main_icons history"></span> ', $txt['statPanel_activityTime'], '
1312
				</h3>
1313
			</div>';
1314
1315
	// If they haven't post at all, don't draw the graph.
1316
	if (empty($context['posts_by_time']))
1317
		echo '
1318
			<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1319
1320
	// Otherwise do!
1321
	else
1322
	{
1323
		echo '
1324
			<ul class="activity_stats flow_hidden">';
1325
1326
		// The labels.
1327
		foreach ($context['posts_by_time'] as $time_of_day)
1328
			echo '
1329
				<li>
1330
					<div class="generic_bar vertical">
1331
						<div class="bar" style="height: ', (int) $time_of_day['relative_percent'], '%;">
1332
							<span>', sprintf($txt['statPanel_activityTime_posts'], $time_of_day['posts'], $time_of_day['posts_percent']), '</span>
1333
						</div>
1334
					</div>
1335
					<span class="stats_hour">', $time_of_day['hour_format'], '</span>
1336
				</li>';
1337
1338
		echo '
1339
			</ul>';
1340
	}
1341
1342
	echo '
1343
		</div><!-- #activitytime -->';
1344
1345
	// Two columns with the most popular boards by posts and activity (activity = users posts / total posts).
1346
	echo '
1347
		<div class="flow_hidden">
1348
			<div class="half_content">
1349
				<div class="title_bar">
1350
					<h3 class="titlebg">
1351
						<span class="main_icons replies"></span> ', $txt['statPanel_topBoards'], '
1352
					</h3>
1353
				</div>';
1354
1355
	if (empty($context['popular_boards']))
1356
		echo '
1357
				<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1358
1359
	else
1360
	{
1361
		echo '
1362
				<dl class="stats">';
1363
1364
		// Draw a bar for every board.
1365
		foreach ($context['popular_boards'] as $board)
1366
		{
1367
			echo '
1368
					<dt>', $board['link'], '</dt>
1369
					<dd>
1370
						<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']), '">
1371
							', sprintf($txt['statPanel_topBoards_memberposts'], $board['posts'], $board['total_posts_member'], $board['posts_percent']), '
1372
						</div>
1373
						', empty($context['hide_num_posts']) ? $board['posts'] : '', '
1374
					</dd>';
1375
		}
1376
1377
		echo '
1378
				</dl>';
1379
	}
1380
	echo '
1381
			</div><!-- .half_content -->
1382
			<div class="half_content">
1383
				<div class="title_bar">
1384
					<h3 class="titlebg">
1385
						<span class="main_icons replies"></span> ', $txt['statPanel_topBoardsActivity'], '
1386
					</h3>
1387
				</div>';
1388
1389
	if (empty($context['board_activity']))
1390
		echo '
1391
				<p class="centertext padding">', $txt['statPanel_noPosts'], '</p>';
1392
	else
1393
	{
1394
		echo '
1395
				<dl class="stats">';
1396
1397
		// Draw a bar for every board.
1398
		foreach ($context['board_activity'] as $activity)
1399
		{
1400
			echo '
1401
					<dt>', $activity['link'], '</dt>
1402
					<dd>
1403
						<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']), '">
1404
							', sprintf($txt['statPanel_topBoards_posts'], $activity['posts'], $activity['total_posts'], $activity['posts_percent']), '
1405
						</div>
1406
						', $activity['percent'], '%
1407
					</dd>';
1408
		}
1409
1410
		echo '
1411
				</dl>';
1412
	}
1413
	echo '
1414
			</div><!-- .half_content -->
1415
		</div><!-- .flow_hidden -->';
1416
1417
	echo '
1418
	</div><!-- #profileview -->';
1419
}
1420
1421
/**
1422
 * Template for editing profile options.
1423
 */
1424
function template_edit_options()
1425
{
1426
	global $context, $scripturl, $txt, $modSettings;
1427
1428
	// The main header!
1429
	// because some browsers ignore autocomplete=off and fill username in display name and/ or email field, fake them out.
1430
	$url = !empty($context['profile_custom_submit_url']) ? $context['profile_custom_submit_url'] : $scripturl . '?action=profile;area=' . $context['menu_item_selected'] . ';u=' . $context['id_member'];
1431
	$url = $context['require_password'] && !empty($modSettings['force_ssl']) ? strtr($url, array('http://' => 'https://')) : $url;
1432
1433
	echo '
1434
		<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"' : ''), '>
1435
			<div style="height:0;overflow:hidden;">
1436
				<input type="text" id="autocompleteFakeName">
1437
				<input type="password" id="autocompleteFakePassword">
1438
			</div>
1439
			<div class="cat_bar">
1440
				<h3 class="catbg profile_hd">';
1441
1442
	// Don't say "Profile" if this isn't the profile...
1443
	if (!empty($context['profile_header_text']))
1444
		echo '
1445
					', $context['profile_header_text'];
1446
	else
1447
		echo '
1448
					', $txt['profile'];
1449
1450
	echo '
1451
				</h3>
1452
			</div>';
1453
1454
	// Have we some description?
1455
	if ($context['page_desc'])
1456
		echo '
1457
			<p class="information">', $context['page_desc'], '</p>';
1458
1459
	echo '
1460
			<div class="roundframe">';
1461
1462
	// Any bits at the start?
1463
	if (!empty($context['profile_prehtml']))
1464
		echo '
1465
				<div>', $context['profile_prehtml'], '</div>';
1466
1467
	if (!empty($context['profile_fields']))
1468
		echo '
1469
				<dl class="settings">';
1470
1471
	// Start the big old loop 'of love.
1472
	$lastItem = 'hr';
1473
	foreach ($context['profile_fields'] as $key => $field)
1474
	{
1475
		// We add a little hack to be sure we never get more than one hr in a row!
1476
		if ($lastItem == 'hr' && $field['type'] == 'hr')
1477
			continue;
1478
1479
		$lastItem = $field['type'];
1480
		if ($field['type'] == 'hr')
1481
			echo '
1482
				</dl>
1483
				<hr>
1484
				<dl class="settings">';
1485
1486
		elseif ($field['type'] == 'callback')
1487
		{
1488
			if (isset($field['callback_func']) && function_exists('template_profile_' . $field['callback_func']))
1489
			{
1490
				$callback_func = 'template_profile_' . $field['callback_func'];
1491
				$callback_func();
1492
			}
1493
		}
1494
		else
1495
		{
1496
			echo '
1497
					<dt>
1498
						<strong', !empty($field['is_error']) ? ' class="error"' : '', '>', $field['type'] !== 'label' ? '<label for="' . $key . '">' : '', $field['label'], $field['type'] !== 'label' ? '</label>' : '', '</strong>';
1499
1500
			// Does it have any subtext to show?
1501
			if (!empty($field['subtext']))
1502
				echo '
1503
						<br>
1504
						<span class="smalltext">', $field['subtext'], '</span>';
1505
1506
			echo '
1507
					</dt>
1508
					<dd>';
1509
1510
			// Want to put something infront of the box?
1511
			if (!empty($field['preinput']))
1512
				echo '
1513
						', $field['preinput'];
1514
1515
			// What type of data are we showing?
1516
			if ($field['type'] == 'label')
1517
				echo '
1518
						', $field['value'];
1519
1520
			// Maybe it's a text box - very likely!
1521
			elseif (in_array($field['type'], array('int', 'float', 'text', 'password', 'color', 'date', 'datetime', 'datetime-local', 'email', 'month', 'number', 'time', 'url')))
1522
			{
1523
				if ($field['type'] == 'int' || $field['type'] == 'float')
1524
					$type = 'number';
1525
				else
1526
					$type = $field['type'];
1527
				$step = $field['type'] == 'float' ? ' step="0.1"' : '';
1528
1529
				echo '
1530
						<input type="', $type, '" name="', $key, '" id="', $key, '" size="', empty($field['size']) ? 30 : $field['size'], '" value="', $field['value'], '" ', $field['input_attr'], ' ', $step, '>';
1531
			}
1532
			// You "checking" me out? ;)
1533
			elseif ($field['type'] == 'check')
1534
				echo '
1535
						<input type="hidden" name="', $key, '" value="0">
1536
						<input type="checkbox" name="', $key, '" id="', $key, '"', !empty($field['value']) ? ' checked' : '', ' value="1" ', $field['input_attr'], '>';
1537
1538
			// Always fun - select boxes!
1539
			elseif ($field['type'] == 'select')
1540
			{
1541
				echo '
1542
						<select name="', $key, '" id="', $key, '">';
1543
1544
				if (isset($field['options']))
1545
				{
1546
					// Is this some code to generate the options?
1547
					if (!is_array($field['options']))
1548
						$field['options'] = $field['options']();
1549
1550
					// Assuming we now have some!
1551
					if (is_array($field['options']))
1552
						foreach ($field['options'] as $value => $name)
1553
							echo '
1554
							<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>';
1555
				}
1556
1557
				echo '
1558
						</select>';
1559
			}
1560
1561
			// Something to end with?
1562
			if (!empty($field['postinput']))
1563
				echo '
1564
						', $field['postinput'];
1565
1566
			echo '
1567
					</dd>';
1568
		}
1569
	}
1570
1571
	if (!empty($context['profile_fields']))
1572
		echo '
1573
				</dl>';
1574
1575
	// Are there any custom profile fields - if so print them!
1576
	if (!empty($context['custom_fields']))
1577
	{
1578
		if ($lastItem != 'hr')
1579
			echo '
1580
				<hr>';
1581
1582
		echo '
1583
				<dl class="settings">';
1584
1585
		foreach ($context['custom_fields'] as $field)
1586
			echo '
1587
					<dt>
1588
						<strong>', $field['name'], ': </strong><br>
1589
						<span class="smalltext">', $field['desc'], '</span>
1590
					</dt>
1591
					<dd>
1592
						', $field['input_html'], '
1593
					</dd>';
1594
1595
		echo '
1596
				</dl>';
1597
	}
1598
1599
	// Any closing HTML?
1600
	if (!empty($context['profile_posthtml']))
1601
		echo '
1602
				<div>', $context['profile_posthtml'], '</div>';
1603
1604
	// Only show the password box if it's actually needed.
1605
	if ($context['require_password'])
1606
		echo '
1607
				<dl class="settings">
1608
					<dt>
1609
						<strong', isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : '', '><label for="oldpasswrd">', $txt['current_password'], ': </label></strong><br>
1610
						<span class="smalltext">', $txt['required_security_reasons'], '</span>
1611
					</dt>
1612
					<dd>
1613
						<input type="password" name="oldpasswrd" id="oldpasswrd" size="20">
1614
					</dd>
1615
				</dl>';
1616
1617
	// The button shouldn't say "Change profile" unless we're changing the profile...
1618
	if (!empty($context['submit_button_text']))
1619
		echo '
1620
				<input type="submit" name="save" value="', $context['submit_button_text'], '" class="button floatright">';
1621
	else
1622
		echo '
1623
				<input type="submit" name="save" value="', $txt['change_profile'], '" class="button floatright">';
1624
1625
	if (!empty($context['token_check']))
1626
		echo '
1627
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
1628
1629
	echo '
1630
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
1631
				<input type="hidden" name="u" value="', $context['id_member'], '">
1632
				<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
1633
			</div><!-- .roundframe -->
1634
		</form>';
1635
1636
	// Any final spellchecking stuff?
1637
	if (!empty($context['show_spellchecking']))
1638
		echo '
1639
		<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>';
1640
}
1641
1642
/**
1643
 * Personal Message settings.
1644
 */
1645
function template_profile_pm_settings()
1646
{
1647
	global $context, $modSettings, $txt;
1648
1649
	echo '
1650
					<dt>
1651
						<label for="pm_prefs">', $txt['pm_display_mode'], ':</label>
1652
					</dt>
1653
					<dd>
1654
						<select name="pm_prefs" id="pm_prefs">
1655
							<option value="0"', $context['display_mode'] == 0 ? ' selected' : '', '>', $txt['pm_display_mode_all'], '</option>
1656
							<option value="1"', $context['display_mode'] == 1 ? ' selected' : '', '>', $txt['pm_display_mode_one'], '</option>
1657
							<option value="2"', $context['display_mode'] == 2 ? ' selected' : '', '>', $txt['pm_display_mode_linked'], '</option>
1658
						</select>
1659
					</dd>
1660
					<dt>
1661
						<label for="view_newest_pm_first">', $txt['recent_pms_at_top'], '</label>
1662
					</dt>
1663
					<dd>
1664
						<input type="hidden" name="default_options[view_newest_pm_first]" value="0">
1665
						<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' : '', '>
1666
					</dd>
1667
				</dl>
1668
				<hr>
1669
				<dl class="settings">
1670
					<dt>
1671
						<label for="pm_receive_from">', $txt['pm_receive_from'], '</label>
1672
					</dt>
1673
					<dd>
1674
						<select name="pm_receive_from" id="pm_receive_from">
1675
							<option value="0"', empty($context['receive_from']) || (empty($modSettings['enable_buddylist']) && $context['receive_from'] < 3) ? ' selected' : '', '>', $txt['pm_receive_from_everyone'], '</option>';
1676
1677
	if (!empty($modSettings['enable_buddylist']))
1678
		echo '
1679
							<option value="1"', !empty($context['receive_from']) && $context['receive_from'] == 1 ? ' selected' : '', '>', $txt['pm_receive_from_ignore'], '</option>
1680
							<option value="2"', !empty($context['receive_from']) && $context['receive_from'] == 2 ? ' selected' : '', '>', $txt['pm_receive_from_buddies'], '</option>';
1681
1682
	echo '
1683
							<option value="3"', !empty($context['receive_from']) && $context['receive_from'] > 2 ? ' selected' : '', '>', $txt['pm_receive_from_admins'], '</option>
1684
						</select>
1685
					</dd>
1686
					<dt>
1687
						<label for="popup_messages">', $txt['popup_messages'], '</label>
1688
					</dt>
1689
					<dd>
1690
						<input type="hidden" name="default_options[popup_messages]" value="0">
1691
						<input type="checkbox" name="default_options[popup_messages]" id="popup_messages" value="1"', !empty($context['member']['options']['popup_messages']) ? ' checked' : '', '>
1692
					</dd>
1693
				</dl>
1694
				<hr>
1695
				<dl class="settings">
1696
					<dt>
1697
						<label for="pm_remove_inbox_label">', $txt['pm_remove_inbox_label'], '</label>
1698
					</dt>
1699
					<dd>
1700
						<input type="hidden" name="default_options[pm_remove_inbox_label]" value="0">
1701
						<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' : '', '>
1702
					</dd>';
1703
1704
}
1705
1706
/**
1707
 * Template for showing theme settings. Note: template_options() actually adds the theme specific options.
1708
 */
1709
function template_profile_theme_settings()
1710
{
1711
	global $context, $modSettings;
1712
1713
	$skeys = array_keys($context['theme_options']);
1714
	$first_option_key = array_shift($skeys);
1715
	$titled_section = false;
1716
1717
	foreach ($context['theme_options'] as $i => $setting)
1718
	{
1719
		// Just spit out separators and move on
1720
		if (empty($setting) || !is_array($setting))
1721
		{
1722
			// Avoid double separators and empty titled sections
1723
			$empty_section = true;
1724
			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...
1725
			{
1726
				// Found another separator, so we're done
1727
				if (!is_array($context['theme_options'][$j]))
1728
					break;
1729
1730
				// Once we know there's something to show in this section, we can stop
1731
				if (!isset($context['theme_options'][$j]['enabled']) || !empty($context['theme_options'][$j]['enabled']))
1732
				{
1733
					$empty_section = false;
1734
					break;
1735
				}
1736
			}
1737
			if ($empty_section)
1738
			{
1739
				if ($i === $first_option_key)
1740
					$first_option_key = array_shift($skeys);
1741
1742
				continue;
1743
			}
1744
1745
			// Insert a separator (unless this is the first item in the list)
1746
			if ($i !== $first_option_key)
1747
				echo '
1748
				</dl>
1749
				<hr>
1750
				<dl class="settings">';
1751
1752
			// Should we give a name to this section?
1753
			if (is_string($setting) && !empty($setting))
1754
			{
1755
				$titled_section = true;
1756
				echo '
1757
					<dt><strong>' . $setting . '</strong></dt>
1758
					<dd></dd>';
1759
			}
1760
			else
1761
				$titled_section = false;
1762
1763
			continue;
1764
		}
1765
1766
		// Is this disabled?
1767
		if (isset($setting['enabled']) && $setting['enabled'] === false)
1768
		{
1769
			if ($i === $first_option_key)
1770
				$first_option_key = array_shift($skeys);
1771
1772
			continue;
1773
		}
1774
1775
		// Some of these may not be set...  Set to defaults here
1776
		$opts = array('calendar_start_day', 'topics_per_page', 'messages_per_page', 'display_quick_mod');
1777
		if (in_array($setting['id'], $opts) && !isset($context['member']['options'][$setting['id']]))
1778
			$context['member']['options'][$setting['id']] = 0;
1779
1780
		if (!isset($setting['type']) || $setting['type'] == 'bool')
1781
			$setting['type'] = 'checkbox';
1782
1783
		elseif ($setting['type'] == 'int' || $setting['type'] == 'integer')
1784
			$setting['type'] = 'number';
1785
1786
		elseif ($setting['type'] == 'string')
1787
			$setting['type'] = 'text';
1788
1789
		if (isset($setting['options']))
1790
			$setting['type'] = 'list';
1791
1792
		echo '
1793
					<dt>
1794
						<label for="', $setting['id'], '">', !$titled_section ? '<strong>' : '', $setting['label'], !$titled_section ? '</strong>' : '', '</label>';
1795
1796
		if (isset($setting['description']))
1797
			echo '
1798
						<br>
1799
						<span class="smalltext">', $setting['description'], '</span>';
1800
		echo '
1801
					</dt>
1802
					<dd>';
1803
1804
		// Display checkbox options
1805
		if ($setting['type'] == 'checkbox')
1806
			echo '
1807
						<input type="hidden" name="default_options[' . $setting['id'] . ']" value="0">
1808
						<input type="checkbox" name="default_options[', $setting['id'], ']" id="', $setting['id'], '"', !empty($context['member']['options'][$setting['id']]) ? ' checked' : '', ' value="1">';
1809
1810
		// How about selection lists, we all love them
1811
		elseif ($setting['type'] == 'list')
1812
		{
1813
			echo '
1814
						<select name="default_options[', $setting['id'], ']" id="', $setting['id'], '"', '>';
1815
1816
			foreach ($setting['options'] as $value => $label)
1817
				echo '
1818
							<option value="', $value, '"', isset($context['member']['options'][$setting['id']]) && $value == $context['member']['options'][$setting['id']] ? ' selected' : '', '>', $label, '</option>';
1819
1820
			echo '
1821
						</select>';
1822
		}
1823
		// A textbox it is then
1824
		else
1825
		{
1826
			if (isset($setting['type']) && $setting['type'] == 'number')
1827
			{
1828
				$min = isset($setting['min']) ? ' min="' . $setting['min'] . '"' : ' min="0"';
1829
				$max = isset($setting['max']) ? ' max="' . $setting['max'] . '"' : '';
1830
				$step = isset($setting['step']) ? ' step="' . $setting['step'] . '"' : '';
1831
1832
				echo '
1833
						<input type="number"', $min . $max . $step;
1834
			}
1835
			elseif (isset($setting['type']) && $setting['type'] == 'url')
1836
				echo '
1837
						<input type="url"';
1838
1839
			else
1840
				echo '
1841
						<input type="text"';
1842
1843
			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"' : '', '>';
1844
		}
1845
1846
		// end of this defintion
1847
		echo '
1848
					</dd>';
1849
	}
1850
}
1851
1852
/**
1853
 * The template for configuring alerts
1854
 */
1855
function template_alert_configuration()
1856
{
1857
	global $context, $txt, $scripturl, $modSettings;
1858
1859
	echo '
1860
		<div class="cat_bar">
1861
			<h3 class="catbg">
1862
				', $txt['alert_prefs'], '
1863
			</h3>
1864
		</div>
1865
		<p class="information">
1866
			', (empty($context['description']) ? $txt['alert_prefs_desc'] : $context['description']), '
1867
		</p>
1868
		<form action="', $scripturl, '?', $context['action'], '" method="post" accept-charset="', $context['character_set'], '" id="notify_options" class="flow_hidden">
1869
			<div class="cat_bar">
1870
				<h3 class="catbg">
1871
					', $txt['notification_general'], '
1872
				</h3>
1873
			</div>
1874
			<div class="windowbg">
1875
				<dl class="settings">
1876
					<dt>
1877
						<label for="notify_announcements">', $txt['notify_important_email'], '</label>
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
				echo '
1918
				<tr class="windowbg">
1919
					<td colspan="3">';
1920
1921
				$label = $txt['alert_opt_' . $opts[1]];
1922
				$label_pos = isset($opts['label']) ? $opts['label'] : '';
1923
				if ($label_pos == 'before')
1924
					echo '
1925
						<label for="opt_', $opts[1], '">', $label, '</label>';
1926
1927
				$this_value = isset($context['alert_prefs'][$opts[1]]) ? $context['alert_prefs'][$opts[1]] : 0;
1928
				switch ($opts[0])
1929
				{
1930
					case 'check':
1931
						echo '
1932
						<input type="checkbox" name="opt_', $opts[1], '" id="opt_', $opts[1], '"', $this_value ? ' checked' : '', '>';
1933
						break;
1934
1935
					case 'select':
1936
						echo '
1937
						<select name="opt_', $opts[1], '" id="opt_', $opts[1], '">';
1938
1939
						foreach ($opts['opts'] as $k => $v)
1940
							echo '
1941
							<option value="', $k, '"', $this_value == $k ? ' selected' : '', '>', $v, '</option>';
1942
						echo '
1943
						</select>';
1944
						break;
1945
				}
1946
1947
				if ($label_pos == 'after')
1948
					echo '
1949
						<label for="opt_', $opts[1], '">', $label, '</label>';
1950
1951
				echo '
1952
					</td>
1953
				</tr>';
1954
			}
1955
		}
1956
1957
		foreach ($alerts as $alert_id => $alert_details)
1958
		{
1959
			echo '
1960
				<tr class="windowbg">
1961
					<td>
1962
						', $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>' : '', '
1963
					</td>';
1964
1965
			foreach ($context['alert_bits'] as $type => $bitmask)
1966
			{
1967
				echo '
1968
					<td class="centercol">';
1969
1970
				$this_value = isset($context['alert_prefs'][$alert_id]) ? $context['alert_prefs'][$alert_id] : 0;
1971
				switch ($alert_details[$type])
1972
				{
1973
					case 'always':
1974
						echo '
1975
						<input type="checkbox" checked disabled>';
1976
						break;
1977
					case 'yes':
1978
						echo '
1979
						<input type="checkbox" name="', $type, '_', $alert_id, '"', ($this_value & $bitmask) ? ' checked' : '', '>';
1980
						break;
1981
					case 'never':
1982
						echo '
1983
						<input type="checkbox" disabled>';
1984
						break;
1985
				}
1986
				echo '
1987
					</td>';
1988
			}
1989
1990
			echo '
1991
				</tr>';
1992
		}
1993
	}
1994
1995
	echo '
1996
			</table>
1997
			<br>
1998
			<div>
1999
				<input id="notify_submit" type="submit" name="notify_submit" value="', $txt['notify_save'], '" class="button">
2000
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">', !empty($context['token_check']) ? '
2001
				<input type="hidden" name="' . $context[$context['token_check'] . '_token_var'] . '" value="' . $context[$context['token_check'] . '_token'] . '">' : '', '
2002
				<input type="hidden" name="u" value="', $context['id_member'], '">
2003
				<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2004
			</div>
2005
		</form>
2006
		<br>';
2007
}
2008
2009
/**
2010
 * Template for showing which topics you're subscribed to
2011
 */
2012
function template_alert_notifications_topics()
2013
{
2014
	global $txt;
2015
2016
	// The main containing header.
2017
	echo '
2018
		<div class="cat_bar">
2019
			<h3 class="catbg">
2020
				', $txt['watched_topics'], '
2021
			</h3>
2022
		</div>
2023
		<p class="information">', $txt['watched_topics_desc'], '</p>
2024
		<br>';
2025
2026
	template_show_list('topic_notification_list');
2027
}
2028
2029
/**
2030
 * Template for showing which boards you're subscribed to
2031
 */
2032
function template_alert_notifications_boards()
2033
{
2034
	global $txt;
2035
2036
	echo '
2037
		<div class="cat_bar">
2038
			<h3 class="catbg">
2039
				', $txt['watched_boards'], '
2040
			</h3>
2041
		</div>
2042
		<p class="information">', $txt['watched_boards_desc'], '</p>
2043
		<br>';
2044
2045
	template_show_list('board_notification_list');
2046
}
2047
2048
/**
2049
 * Template for choosing group membership.
2050
 */
2051
function template_groupMembership()
2052
{
2053
	global $context, $scripturl, $txt;
2054
2055
	// The main containing header.
2056
	echo '
2057
		<form action="', $scripturl, '?action=profile;area=groupmembership;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2058
			<div class="cat_bar">
2059
				<h3 class="catbg profile_hd">
2060
					', $txt['profile'], '
2061
				</h3>
2062
			</div>
2063
			<p class="information">', $txt['groupMembership_info'], '</p>';
2064
2065
	// Do we have an update message?
2066
	if (!empty($context['update_message']))
2067
		echo '
2068
			<div class="infobox">
2069
				', $context['update_message'], '.
2070
			</div>';
2071
2072
	echo '
2073
			<div id="groups">';
2074
2075
	// Requesting membership to a group?
2076
	if (!empty($context['group_request']))
2077
	{
2078
		echo '
2079
			<div class="groupmembership">
2080
				<div class="cat_bar">
2081
					<h3 class="catbg">', $txt['request_group_membership'], '</h3>
2082
				</div>
2083
				<div class="roundframe">
2084
					', $txt['request_group_membership_desc'], ':
2085
					<textarea name="reason" rows="4"></textarea>
2086
					<div class="righttext">
2087
						<input type="hidden" name="gid" value="', $context['group_request']['id'], '">
2088
						<input type="submit" name="req" value="', $txt['submit_request'], '" class="button">
2089
						</div>
2090
					</div>
2091
				</div><!-- .groupmembership -->';
2092
	}
2093
	else
2094
	{
2095
		echo '
2096
				<div class="title_bar">
2097
					<h3 class="titlebg">', $txt['current_membergroups'], '</h3>
2098
				</div>';
2099
2100
		foreach ($context['groups']['member'] as $group)
2101
		{
2102
			echo '
2103
				<div class="windowbg" id="primdiv_', $group['id'], '">';
2104
2105
			if ($context['can_edit_primary'])
2106
				echo '
2107
					<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', '>';
2108
2109
			echo '
2110
					<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>';
2111
2112
			// Can they leave their group?
2113
			if ($group['can_leave'])
2114
				echo '
2115
					<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>';
2116
2117
			echo '
2118
				</div><!-- .windowbg -->';
2119
		}
2120
2121
		if ($context['can_edit_primary'])
2122
			echo '
2123
				<div class="padding righttext">
2124
					<input type="submit" value="', $txt['make_primary'], '" class="button">
2125
				</div>';
2126
2127
		// Any groups they can join?
2128
		if (!empty($context['groups']['available']))
2129
		{
2130
			echo '
2131
				<div class="title_bar">
2132
					<h3 class="titlebg">', $txt['available_groups'], '</h3>
2133
				</div>';
2134
2135
			foreach ($context['groups']['available'] as $group)
2136
			{
2137
				echo '
2138
				<div class="windowbg">
2139
					<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>' : ''), '';
2140
2141
				if ($group['type'] == 3)
2142
					echo '
2143
					<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>';
2144
2145
				elseif ($group['type'] == 2 && $group['pending'])
2146
					echo '
2147
					<span class="floatright">', $txt['approval_pending'], '</span>';
2148
2149
				elseif ($group['type'] == 2)
2150
					echo '
2151
					<a href="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=groupmembership;request=', $group['id'], '" class="button floatright">', $txt['request_group'], '</a>';
2152
2153
				echo '
2154
				</div><!-- .windowbg -->';
2155
			}
2156
		}
2157
2158
		// Javascript for the selector stuff.
2159
		echo '
2160
				<script>
2161
					var prevClass = "";
2162
					var prevDiv = "";
2163
					function highlightSelected(box)
2164
					{
2165
						if (prevClass != "")
2166
						{
2167
							prevDiv.className = prevClass;
2168
						}
2169
						prevDiv = document.getElementById(box);
2170
						prevClass = prevDiv.className;
2171
2172
						prevDiv.className = "windowbg";
2173
					}';
2174
		if (isset($context['groups']['member'][$context['primary_group']]))
2175
			echo '
2176
					highlightSelected("primdiv_' . $context['primary_group'] . '");';
2177
2178
		echo '
2179
				</script>';
2180
	}
2181
2182
	echo '
2183
			</div><!-- #groups -->';
2184
2185
	if (!empty($context['token_check']))
2186
		echo '
2187
			<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2188
2189
	echo '
2190
			<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2191
			<input type="hidden" name="u" value="', $context['id_member'], '">
2192
		</form>';
2193
}
2194
2195
/**
2196
 * Template for managing ignored boards
2197
 */
2198
function template_ignoreboards()
2199
{
2200
	global $context, $txt, $scripturl;
2201
2202
	// The main containing header.
2203
	echo '
2204
	<form action="', $scripturl, '?action=profile;area=ignoreboards;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2205
		<div class="cat_bar">
2206
			<h3 class="catbg profile_hd">
2207
				', $txt['profile'], '
2208
			</h3>
2209
		</div>
2210
		<p class="information">', $txt['ignoreboards_info'], '</p>
2211
		<div class="windowbg">
2212
			<div class="flow_hidden boardslist">
2213
				<ul>';
2214
2215
	foreach ($context['categories'] as $category)
2216
	{
2217
		echo '
2218
					<li>
2219
						<a href="javascript:void(0);" onclick="selectBoards([', implode(', ', $category['child_ids']), '], \'creator\'); return false;">', $category['name'], '</a>
2220
						<ul>';
2221
2222
		foreach ($category['boards'] as $board)
2223
		{
2224
			echo '
2225
							<li style="margin-', $context['right_to_left'] ? 'right' : 'left', ': ', $board['child_level'], 'em;">
2226
								<label for="ignore_brd', $board['id'], '"><input type="checkbox" id="brd', $board['id'], '" name="ignore_brd[', $board['id'], ']" value="', $board['id'], '"', $board['selected'] ? ' checked' : '', '> ', $board['name'], '</label>
2227
							</li>';
2228
		}
2229
2230
		echo '
2231
						</ul>
2232
					</li>';
2233
	}
2234
2235
	echo '
2236
				</ul>
2237
			</div><!-- .flow_hidden boardslist -->';
2238
2239
	// Show the standard "Save Settings" profile button.
2240
	template_profile_save();
2241
2242
	echo '
2243
		</div><!-- .windowbg -->
2244
	</form>
2245
	<br>';
2246
}
2247
2248
/**
2249
 * Simply loads some theme variables common to several warning templates.
2250
 */
2251
function template_load_warning_variables()
2252
{
2253
	global $modSettings, $context;
2254
2255
	// Setup the warning mode
2256
	$context['warning_mode'] = array(
2257
		0 => 'none',
2258
		$modSettings['warning_watch'] => 'watched',
2259
		$modSettings['warning_moderate'] => 'moderated',
2260
		$modSettings['warning_mute'] => 'muted',
2261
	);
2262
2263
	// Work out the starting warning.
2264
	$context['current_warning_mode'] = $context['warning_mode'][0];
2265
	foreach ($context['warning_mode'] as $limit => $warning)
2266
		if ($context['member']['warning'] >= $limit)
2267
			$context['current_warning_mode'] = $warning;
2268
}
2269
2270
/**
2271
 * Template for viewing a user's warnings
2272
 */
2273
function template_viewWarning()
2274
{
2275
	global $context, $txt;
2276
2277
	template_load_warning_variables();
2278
2279
	echo '
2280
		<div class="cat_bar">
2281
			<h3 class="catbg profile_hd">
2282
				', sprintf($txt['profile_viewwarning_for_user'], $context['member']['name']), '
2283
			</h3>
2284
		</div>
2285
		<p class="information">', $txt['viewWarning_help'], '</p>
2286
		<div class="windowbg">
2287
			<dl class="settings">
2288
				<dt>
2289
					<strong>', $txt['profile_warning_name'], ':</strong>
2290
				</dt>
2291
				<dd>
2292
					', $context['member']['name'], '
2293
				</dd>
2294
				<dt>
2295
					<strong>', $txt['profile_warning_level'], ':</strong>
2296
				</dt>
2297
				<dd>
2298
					<div class="generic_bar warning_level ', $context['current_warning_mode'], '">
2299
						<div class="bar" style="width: ', $context['member']['warning'], '%;"></div>
2300
						<span>', $context['member']['warning'], '%</span>
2301
					</div>
2302
				</dd>';
2303
2304
	// There's some impact of this?
2305
	if (!empty($context['level_effects'][$context['current_level']]))
2306
		echo '
2307
				<dt>
2308
					<strong>', $txt['profile_viewwarning_impact'], ':</strong>
2309
				</dt>
2310
				<dd>
2311
					', $context['level_effects'][$context['current_level']], '
2312
				</dd>';
2313
2314
	echo '
2315
			</dl>
2316
		</div><!-- .windowbg -->';
2317
2318
	template_show_list('view_warnings');
2319
}
2320
2321
/**
2322
 * Template for issuing warnings
2323
 */
2324
function template_issueWarning()
2325
{
2326
	global $context, $scripturl, $txt;
2327
2328
	template_load_warning_variables();
2329
2330
	echo '
2331
	<script>
2332
		// Disable notification boxes as required.
2333
		function modifyWarnNotify()
2334
		{
2335
			disable = !document.getElementById(\'warn_notify\').checked;
2336
			document.getElementById(\'warn_sub\').disabled = disable;
2337
			document.getElementById(\'warn_body\').disabled = disable;
2338
			document.getElementById(\'warn_temp\').disabled = disable;
2339
			document.getElementById(\'new_template_link\').style.display = disable ? \'none\' : \'\';
2340
			document.getElementById(\'preview_button\').style.display = disable ? \'none\' : \'\';
2341
		}
2342
2343
		// Warn template.
2344
		function populateNotifyTemplate()
2345
		{
2346
			index = document.getElementById(\'warn_temp\').value;
2347
			if (index == -1)
2348
				return false;
2349
2350
			// Otherwise see what we can do...';
2351
2352
	foreach ($context['notification_templates'] as $k => $type)
2353
		echo '
2354
			if (index == ', $k, ')
2355
				document.getElementById(\'warn_body\').value = "', strtr($type['body'], array('"' => "'", "\n" => '\\n', "\r" => '')), '";';
2356
2357
	echo '
2358
		}
2359
2360
		function updateSlider(slideAmount)
2361
		{
2362
			// Also set the right effect.
2363
			effectText = "";';
2364
2365
	foreach ($context['level_effects'] as $limit => $text)
2366
		echo '
2367
			if (slideAmount >= ', $limit, ')
2368
				effectText = "', $text, '";';
2369
2370
	echo '
2371
			setInnerHTML(document.getElementById(\'cur_level_div\'), slideAmount + \'% (\' + effectText + \')\');
2372
		}
2373
	</script>';
2374
2375
	echo '
2376
	<form action="', $scripturl, '?action=profile;u=', $context['id_member'], ';area=issuewarning" method="post" class="flow_hidden" accept-charset="', $context['character_set'], '">
2377
		<div class="cat_bar">
2378
			<h3 class="catbg profile_hd">
2379
				', $context['user']['is_owner'] ? $txt['profile_warning_level'] : $txt['profile_issue_warning'], '
2380
			</h3>
2381
		</div>';
2382
2383
	if (!$context['user']['is_owner'])
2384
		echo '
2385
		<p class="information">', $txt['profile_warning_desc'], '</p>';
2386
2387
	echo '
2388
		<div class="windowbg">
2389
			<dl class="settings">';
2390
2391
	if (!$context['user']['is_owner'])
2392
		echo '
2393
				<dt>
2394
					<strong>', $txt['profile_warning_name'], ':</strong>
2395
				</dt>
2396
				<dd>
2397
					<strong>', $context['member']['name'], '</strong>
2398
				</dd>';
2399
2400
	echo '
2401
				<dt>
2402
					<strong>', $txt['profile_warning_level'], ':</strong>';
2403
2404
	// Is there only so much they can apply?
2405
	if ($context['warning_limit'])
2406
		echo '
2407
					<br>
2408
					<span class="smalltext">', sprintf($txt['profile_warning_limit_attribute'], $context['warning_limit']), '</span>';
2409
2410
	echo '
2411
				</dt>
2412
				<dd>
2413
					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%
2414
					<div class="clear_left">
2415
						', $txt['profile_warning_impact'], ': <span id="cur_level_div">', $context['member']['warning'], '% (', $context['level_effects'][$context['current_level']], ')</span>
2416
					</div>
2417
				</dd>';
2418
2419
	if (!$context['user']['is_owner'])
2420
	{
2421
		echo '
2422
				<dt>
2423
					<strong>', $txt['profile_warning_reason'], ':</strong><br>
2424
					<span class="smalltext">', $txt['profile_warning_reason_desc'], '</span>
2425
				</dt>
2426
				<dd>
2427
					<input type="text" name="warn_reason" id="warn_reason" value="', $context['warning_data']['reason'], '" size="50">
2428
				</dd>
2429
			</dl>
2430
			<hr>
2431
			<div id="box_preview"', !empty($context['warning_data']['body_preview']) ? '' : ' style="display:none"', '>
2432
				<dl class="settings">
2433
					<dt>
2434
						<strong>', $txt['preview'], '</strong>
2435
					</dt>
2436
					<dd id="body_preview">
2437
						', !empty($context['warning_data']['body_preview']) ? $context['warning_data']['body_preview'] : '', '
2438
					</dd>
2439
				</dl>
2440
				<hr>
2441
			</div>
2442
			<dl class="settings">
2443
				<dt>
2444
					<strong><label for="warn_notify">', $txt['profile_warning_notify'], ':</label></strong>
2445
				</dt>
2446
				<dd>
2447
					<input type="checkbox" name="warn_notify" id="warn_notify" onclick="modifyWarnNotify();"', $context['warning_data']['notify'] ? ' checked' : '', '>
2448
				</dd>
2449
				<dt>
2450
					<strong><label for="warn_sub">', $txt['profile_warning_notify_subject'], ':</label></strong>
2451
				</dt>
2452
				<dd>
2453
					<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">
2454
				</dd>
2455
				<dt>
2456
					<strong><label for="warn_temp">', $txt['profile_warning_notify_body'], ':</label></strong>
2457
				</dt>
2458
				<dd>
2459
					<select name="warn_temp" id="warn_temp" disabled onchange="populateNotifyTemplate();">
2460
						<option value="-1">', $txt['profile_warning_notify_template'], '</option>
2461
						<option value="-1" disabled>------------------------------</option>';
2462
2463
		foreach ($context['notification_templates'] as $id_template => $template)
2464
			echo '
2465
						<option value="', $id_template, '">', $template['title'], '</option>';
2466
2467
		echo '
2468
					</select>
2469
					<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>
2470
					<br>
2471
					<textarea name="warn_body" id="warn_body" cols="40" rows="8">', $context['warning_data']['notify_body'], '</textarea>
2472
				</dd>';
2473
	}
2474
	echo '
2475
			</dl>
2476
			<div class="righttext">';
2477
2478
	if (!empty($context['token_check']))
2479
		echo '
2480
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2481
2482
	echo '
2483
				<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2484
				<input type="button" name="preview" id="preview_button" value="', $txt['preview'], '" class="button">
2485
				<input type="submit" name="save" value="', $context['user']['is_owner'] ? $txt['change_profile'] : $txt['profile_warning_issue'], '" class="button">
2486
			</div><!-- .righttext -->
2487
		</div><!-- .windowbg -->
2488
	</form>';
2489
2490
	// Previous warnings?
2491
	template_show_list('view_warnings');
2492
2493
	echo '
2494
	<script>';
2495
2496
	if (!$context['user']['is_owner'])
2497
		echo '
2498
		modifyWarnNotify();
2499
		$(document).ready(function() {
2500
			$("#preview_button").click(function() {
2501
				return ajax_getTemplatePreview();
2502
			});
2503
		});
2504
2505
		function ajax_getTemplatePreview ()
2506
		{
2507
			$.ajax({
2508
				type: "POST",
2509
				url: "' . $scripturl . '?action=xmlhttp;sa=previews;xml",
2510
				data: {item: "warning_preview", title: $("#warn_sub").val(), body: $("#warn_body").val(), issuing: true},
2511
				context: document.body,
2512
				success: function(request){
2513
					$("#box_preview").css({display:""});
2514
					$("#body_preview").html($(request).find(\'body\').text());
2515
					if ($(request).find("error").text() != \'\')
2516
					{
2517
						$("#profile_error").css({display:""});
2518
						var errors_html = \'<ul class="list_errors">\';
2519
						var errors = $(request).find(\'error\').each(function() {
2520
							errors_html += \'<li>\' + $(this).text() + \'</li>\';
2521
						});
2522
						errors_html += \'</ul>\';
2523
2524
						$("#profile_error").html(errors_html);
2525
					}
2526
					else
2527
					{
2528
						$("#profile_error").css({display:"none"});
2529
						$("#error_list").html(\'\');
2530
					}
2531
				return false;
2532
				},
2533
			});
2534
			return false;
2535
		}';
2536
2537
	echo '
2538
	</script>';
2539
}
2540
2541
/**
2542
 * Template to show for deleting a user's account - now with added delete post capability!
2543
 */
2544
function template_deleteAccount()
2545
{
2546
	global $context, $scripturl, $txt;
2547
2548
	// The main containing header.
2549
	echo '
2550
		<form action="', $scripturl, '?action=profile;area=deleteaccount;save" method="post" accept-charset="', $context['character_set'], '" name="creator" id="creator">
2551
			<div class="cat_bar">
2552
				<h3 class="catbg profile_hd">
2553
					', $txt['deleteAccount'], '
2554
				</h3>
2555
			</div>';
2556
2557
	// If deleting another account give them a lovely info box.
2558
	if (!$context['user']['is_owner'])
2559
		echo '
2560
			<p class="information">', $txt['deleteAccount_desc'], '</p>';
2561
2562
	echo '
2563
			<div class="windowbg">';
2564
2565
	// If they are deleting their account AND the admin needs to approve it - give them another piece of info ;)
2566
	if ($context['needs_approval'])
2567
		echo '
2568
				<div class="errorbox">', $txt['deleteAccount_approval'], '</div>';
2569
2570
	// If the user is deleting their own account warn them first - and require a password!
2571
	if ($context['user']['is_owner'])
2572
	{
2573
		echo '
2574
				<div class="alert">', $txt['own_profile_confirm'], '</div>
2575
				<div>
2576
					<strong', (isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : ''), '>', $txt['current_password'], ': </strong>
2577
					<input type="password" name="oldpasswrd" size="20">
2578
					<input type="submit" value="', $txt['yes'], '" class="button">';
2579
2580
		if (!empty($context['token_check']))
2581
			echo '
2582
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2583
2584
		echo '
2585
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2586
					<input type="hidden" name="u" value="', $context['id_member'], '">
2587
					<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2588
				</div>';
2589
	}
2590
	// Otherwise an admin doesn't need to enter a password - but they still get a warning - plus the option to delete lovely posts!
2591
	else
2592
	{
2593
		echo '
2594
				<div class="alert">', $txt['deleteAccount_warning'], '</div>';
2595
2596
		// Only actually give these options if they are kind of important.
2597
		if ($context['can_delete_posts'])
2598
		{
2599
			echo '
2600
				<div>
2601
					<label for="deleteVotes">
2602
						<input type="checkbox" name="deleteVotes" id="deleteVotes" value="1"> ', $txt['deleteAccount_votes'], ':
2603
					</label><br>
2604
					<label for="deletePosts">
2605
						<input type="checkbox" name="deletePosts" id="deletePosts" value="1"> ', $txt['deleteAccount_posts'], ':
2606
					</label>
2607
					<select name="remove_type">
2608
						<option value="posts">', $txt['deleteAccount_all_posts'], '</option>
2609
						<option value="topics">', $txt['deleteAccount_topics'], '</option>
2610
					</select>';
2611
2612
			if ($context['show_perma_delete'])
2613
				echo '
2614
					<br>
2615
					<label for="perma_delete"><input type="checkbox" name="perma_delete" id="perma_delete" value="1">', $txt['deleteAccount_permanent'], '</label>';
2616
2617
			echo '
2618
				</div>';
2619
		}
2620
2621
		echo '
2622
				<div>
2623
					<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>
2624
				</div>
2625
				<div>
2626
					<input type="submit" value="', $txt['delete'], '" class="button">';
2627
2628
		if (!empty($context['token_check']))
2629
			echo '
2630
				<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2631
2632
		echo '
2633
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2634
					<input type="hidden" name="u" value="', $context['id_member'], '">
2635
					<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2636
				</div>';
2637
	}
2638
	echo '
2639
			</div><!-- .windowbg -->
2640
			<br>
2641
		</form>';
2642
}
2643
2644
/**
2645
 * Template for the password box/save button stuck at the bottom of every profile page.
2646
 */
2647
function template_profile_save()
2648
{
2649
	global $context, $txt;
2650
2651
	echo '
2652
2653
					<hr>';
2654
2655
	// Only show the password box if it's actually needed.
2656
	if ($context['require_password'])
2657
		echo '
2658
					<dl class="settings">
2659
						<dt>
2660
							<strong', isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : '', '>', $txt['current_password'], ': </strong><br>
2661
							<span class="smalltext">', $txt['required_security_reasons'], '</span>
2662
						</dt>
2663
						<dd>
2664
							<input type="password" name="oldpasswrd" size="20">
2665
						</dd>
2666
					</dl>';
2667
2668
	echo '
2669
					<div class="righttext">';
2670
2671
	if (!empty($context['token_check']))
2672
		echo '
2673
						<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">';
2674
2675
	echo '
2676
						<input type="submit" value="', $txt['change_profile'], '" class="button">
2677
						<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
2678
						<input type="hidden" name="u" value="', $context['id_member'], '">
2679
						<input type="hidden" name="sa" value="', $context['menu_item_selected'], '">
2680
					</div>';
2681
}
2682
2683
/**
2684
 * Small template for showing an error message upon a save problem in the profile.
2685
 */
2686
function template_error_message()
2687
{
2688
	global $context, $txt;
2689
2690
	echo '
2691
		<div class="errorbox" ', empty($context['post_errors']) ? 'style="display:none" ' : '', 'id="profile_error">';
2692
2693
	if (!empty($context['post_errors']))
2694
	{
2695
		echo '
2696
			<span>', !empty($context['custom_error_title']) ? $context['custom_error_title'] : $txt['profile_errors_occurred'], ':</span>
2697
			<ul id="list_errors">';
2698
2699
		// Cycle through each error and display an error message.
2700
		foreach ($context['post_errors'] as $error)
2701
		{
2702
			$text_key_error = $error == 'password_short' ?
2703
				printf($txt['profile_error_' . $error], (empty($modSettings['password_strength']) ? 4 : 8)) :
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $modSettings seems to never exist and therefore empty should always be true.
Loading history...
2704
				$txt['profile_error_' . $error];
2705
2706
			echo '
2707
				<li>', isset($txt['profile_error_' . $error]) ? $text_key_error : $error, '</li>';
2708
		}
2709
2710
		echo '
2711
			</ul>';
2712
	}
2713
2714
	echo '
2715
		</div><!-- #profile_error -->';
2716
}
2717
2718
/**
2719
 * Display a load of drop down selectors for allowing the user to change group.
2720
 */
2721
function template_profile_group_manage()
2722
{
2723
	global $context, $txt, $scripturl;
2724
2725
	echo '
2726
							<dt>
2727
								<strong>', $txt['primary_membergroup'], ': </strong><br>
2728
								<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>
2729
							</dt>
2730
							<dd>
2731
								<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;"' : ''), '>';
2732
2733
	// Fill the select box with all primary member groups that can be assigned to a member.
2734
	foreach ($context['member_groups'] as $member_group)
2735
		if (!empty($member_group['can_be_primary']))
2736
			echo '
2737
									<option value="', $member_group['id'], '"', $member_group['is_primary'] ? ' selected' : '', '>
2738
										', $member_group['name'], '
2739
									</option>';
2740
2741
	echo '
2742
								</select>
2743
							</dd>
2744
							<dt>
2745
								<strong>', $txt['additional_membergroups'], ':</strong>
2746
							</dt>
2747
							<dd>
2748
								<span id="additional_groupsList">
2749
									<input type="hidden" name="additional_groups[]" value="0">';
2750
2751
	// For each membergroup show a checkbox so members can be assigned to more than one group.
2752
	foreach ($context['member_groups'] as $member_group)
2753
		if ($member_group['can_be_additional'])
2754
			echo '
2755
									<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>';
2756
2757
	echo '
2758
								</span>
2759
								<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>
2760
								<script>
2761
									document.getElementById("additional_groupsList").style.display = "none";
2762
									document.getElementById("additional_groupsLink").style.display = "";
2763
								</script>
2764
							</dd>';
2765
2766
}
2767
2768
/**
2769
 * Callback function for entering a birthdate!
2770
 */
2771
function template_profile_birthdate()
2772
{
2773
	global $txt, $context;
2774
2775
	// Just show the pretty box!
2776
	echo '
2777
							<dt>
2778
								<strong>', $txt['dob'], ':</strong><br>
2779
								<span class="smalltext">', $txt['dob_year'], ' - ', $txt['dob_month'], ' - ', $txt['dob_day'], '</span>
2780
							</dt>
2781
							<dd>
2782
								<input type="text" name="bday3" size="4" maxlength="4" value="', $context['member']['birth_date']['year'], '"> -
2783
								<input type="text" name="bday1" size="2" maxlength="2" value="', $context['member']['birth_date']['month'], '"> -
2784
								<input type="text" name="bday2" size="2" maxlength="2" value="', $context['member']['birth_date']['day'], '">
2785
							</dd>';
2786
}
2787
2788
/**
2789
 * Show the signature editing box?
2790
 */
2791
function template_profile_signature_modify()
2792
{
2793
	global $txt, $context;
2794
2795
	echo '
2796
							<dt id="current_signature" style="display:none">
2797
								<strong>', $txt['current_signature'], ':</strong>
2798
							</dt>
2799
							<dd id="current_signature_display" style="display:none">
2800
								<hr>
2801
							</dd>
2802
2803
							<dt id="preview_signature" style="display:none">
2804
								<strong>', $txt['signature_preview'], ':</strong>
2805
							</dt>
2806
							<dd id="preview_signature_display" style="display:none">
2807
								<hr>
2808
							</dd>
2809
2810
							<dt>
2811
								<strong>', $txt['signature'], ':</strong><br>
2812
								<span class="smalltext">', $txt['sig_info'], '</span><br>
2813
								<br>';
2814
2815
	if ($context['show_spellchecking'])
2816
		echo '
2817
								<input type="button" value="', $txt['spell_check'], '" onclick="spellCheck(\'creator\', \'signature\');" class="button">';
2818
2819
	echo '
2820
							</dt>
2821
							<dd>
2822
								<textarea class="editor" onkeyup="calcCharLeft();" id="signature" name="signature" rows="5" cols="50">', $context['member']['signature'], '</textarea><br>';
2823
2824
	// If there is a limit at all!
2825
	if (!empty($context['signature_limits']['max_length']))
2826
		echo '
2827
								<span class="smalltext">', sprintf($txt['max_sig_characters'], $context['signature_limits']['max_length']), ' <span id="signatureLeft">', $context['signature_limits']['max_length'], '</span></span><br>';
2828
2829
	if (!empty($context['show_preview_button']))
2830
		echo '
2831
								<input type="button" name="preview_signature" id="preview_button" value="', $txt['preview_signature'], '" class="button floatright">';
2832
2833
	if ($context['signature_warning'])
2834
		echo '
2835
								<span class="smalltext">', $context['signature_warning'], '</span>';
2836
2837
	// Some javascript used to count how many characters have been used so far in the signature.
2838
	echo '
2839
								<script>
2840
									var maxLength = ', $context['signature_limits']['max_length'], ';
2841
2842
									$(document).ready(function() {
2843
										calcCharLeft();
2844
										$("#preview_button").click(function() {
2845
											return ajax_getSignaturePreview(true);
2846
										});
2847
									});
2848
								</script>
2849
							</dd>';
2850
}
2851
2852
/**
2853
 * Template for selecting an avatar
2854
 */
2855
function template_profile_avatar_select()
2856
{
2857
	global $context, $txt, $modSettings;
2858
2859
	// Start with the upper menu
2860
	echo '
2861
							<dt>
2862
								<strong id="personal_picture">
2863
									<label for="avatar_upload_box">', $txt['personal_picture'], '</label>
2864
								</strong>';
2865
2866
	if (empty($modSettings['gravatarOverride']))
2867
		echo '
2868
								<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"' : '') . '>
2869
								<label for="avatar_choice_none"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2870
									' . $txt['no_avatar'] . '
2871
								</label><br>';
2872
2873
	if (!empty($context['member']['avatar']['allow_server_stored']))
2874
		echo '
2875
								<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"' : '') . '>
2876
								<label for="avatar_choice_server_stored"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2877
									', $txt['choose_avatar_gallery'], '
2878
								</label><br>';
2879
2880
	if (!empty($context['member']['avatar']['allow_external']))
2881
		echo '
2882
								<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"' : '') . '>
2883
								<label for="avatar_choice_external"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2884
									', $txt['my_own_pic'], '
2885
								</label><br>';
2886
2887
	if (!empty($context['member']['avatar']['allow_upload']))
2888
		echo '
2889
								<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"' : '') . '>
2890
								<label for="avatar_choice_upload"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>
2891
									', $txt['avatar_will_upload'], '
2892
								</label><br>';
2893
2894
	if (!empty($context['member']['avatar']['allow_gravatar']))
2895
		echo '
2896
								<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"' : '') . '>
2897
								<label for="avatar_choice_gravatar"' . (isset($context['modify_error']['bad_avatar']) ? ' class="error"' : '') . '>' . $txt['use_gravatar'] . '</label>';
2898
2899
	echo '
2900
							</dt>
2901
							<dd>';
2902
2903
	// If users are allowed to choose avatars stored on the server show selection boxes to choice them from.
2904
	if (!empty($context['member']['avatar']['allow_server_stored']))
2905
	{
2906
		echo '
2907
								<div id="avatar_server_stored">
2908
									<div>
2909
										<select name="cat" id="cat" size="10" onchange="changeSel(\'\');" onfocus="selectRadioByName(document.forms.creator.avatar_choice, \'server_stored\');">';
2910
2911
		// This lists all the file categories.
2912
		foreach ($context['avatars'] as $avatar)
2913
			echo '
2914
											<option value="', $avatar['filename'] . ($avatar['is_dir'] ? '/' : ''), '"', ($avatar['checked'] ? ' selected' : ''), '>', $avatar['name'], '</option>';
2915
2916
		echo '
2917
										</select>
2918
									</div>
2919
									<div>
2920
										<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>
2921
									</div>
2922
									<div class="edit_avatar_img">
2923
										<img id="avatar" src="', $context['member']['avatar']['choice'] == 'server_stored' ? $context['member']['avatar']['href'] : $modSettings['avatar_url'] . '/blank.png', '" alt="">
2924
									</div>
2925
									<script>
2926
										var files = ["' . implode('", "', $context['avatar_list']) . '"];
2927
										var avatar = document.getElementById("avatar");
2928
										var cat = document.getElementById("cat");
2929
										var selavatar = "' . $context['avatar_selected'] . '";
2930
										var avatardir = "' . $modSettings['avatar_url'] . '/";
2931
										var size = avatar.alt.substr(3, 2) + " " + avatar.alt.substr(0, 2) + String.fromCharCode(117, 98, 116);
2932
										var file = document.getElementById("file");
2933
										var maxHeight = ', !empty($modSettings['avatar_max_height_external']) ? $modSettings['avatar_max_height_external'] : 0, ';
2934
										var maxWidth = ', !empty($modSettings['avatar_max_width_external']) ? $modSettings['avatar_max_width_external'] : 0, ';
2935
2936
										if (avatar.src.indexOf("blank.png") > -1)
2937
											changeSel(selavatar);
2938
										else
2939
											previewExternalAvatar(avatar.src)
2940
2941
									</script>
2942
								</div><!-- #avatar_server_stored -->';
2943
	}
2944
2945
	// If the user can link to an off server avatar, show them a box to input the address.
2946
	if (!empty($context['member']['avatar']['allow_external']))
2947
		echo '
2948
								<div id="avatar_external">
2949
									', $context['member']['avatar']['choice'] == 'external' ? '<div class="edit_avatar_img"><img src="' . $context['member']['avatar']['href'] . '" alt=""></div>' : '', '
2950
									<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
Bug introduced by
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...
2951
									<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);">
2952
								</div>';
2953
2954
	// If the user is able to upload avatars to the server show them an upload box.
2955
	if (!empty($context['member']['avatar']['allow_upload']))
2956
		echo '
2957
								<div id="avatar_upload">
2958
									', $context['member']['avatar']['choice'] == 'upload' ? '<div class="edit_avatar_img"><img src="' . $context['member']['avatar']['href'] . '" alt=""></div>' : '', '
2959
									<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
Bug introduced by
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...
2960
									', (!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'] . '">' : ''), '
2961
								</div>';
2962
2963
	// if the user is able to use Gravatar avatars show then the image preview
2964
	if (!empty($context['member']['avatar']['allow_gravatar']))
2965
	{
2966
		echo '
2967
								<div id="avatar_gravatar">
2968
									', $context['member']['avatar']['choice'] == 'gravatar' ? '<div class="edit_avatar_img"><img src="' . $context['member']['avatar']['href'] . '" alt=""></div>' : '';
2969
2970
		if (empty($modSettings['gravatarAllowExtraEmail']))
2971
			echo '
2972
									<div class="smalltext">', $txt['gravatar_noAlternateEmail'], '</div>';
2973
		else
2974
		{
2975
			// Depending on other stuff, the stored value here might have some odd things in it from other areas.
2976
			if ($context['member']['avatar']['external'] == $context['member']['email'])
2977
				$textbox_value = '';
2978
			else
2979
				$textbox_value = $context['member']['avatar']['external'];
2980
2981
			echo '
2982
									<div class="smalltext">', $txt['gravatar_alternateEmail'], '</div>
2983
									<input type="text" name="gravatarEmail" id="gravatarEmail" size="45" value="', $textbox_value, '">';
2984
		}
2985
		echo '
2986
								</div><!-- #avatar_gravatar -->';
2987
	}
2988
2989
	echo '
2990
								<script>
2991
									', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "' . ($context['member']['avatar']['choice'] == 'server_stored' ? '' : 'none') . '";' : '', '
2992
									', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "' . ($context['member']['avatar']['choice'] == 'external' ? '' : 'none') . '";' : '', '
2993
									', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "' . ($context['member']['avatar']['choice'] == 'upload' ? '' : 'none') . '";' : '', '
2994
									', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "' . ($context['member']['avatar']['choice'] == 'gravatar' ? '' : 'none') . '";' : '', '
2995
2996
									function swap_avatar(type)
2997
									{
2998
										switch(type.id)
2999
										{
3000
											case "avatar_choice_server_stored":
3001
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "";' : '', '
3002
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3003
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3004
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3005
												break;
3006
											case "avatar_choice_external":
3007
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3008
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "";' : '', '
3009
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3010
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3011
												break;
3012
											case "avatar_choice_upload":
3013
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3014
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3015
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "";' : '', '
3016
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3017
												break;
3018
											case "avatar_choice_none":
3019
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3020
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3021
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3022
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "none";' : '', '
3023
												break;
3024
											case "avatar_choice_gravatar":
3025
												', !empty($context['member']['avatar']['allow_server_stored']) ? 'document.getElementById("avatar_server_stored").style.display = "none";' : '', '
3026
												', !empty($context['member']['avatar']['allow_external']) ? 'document.getElementById("avatar_external").style.display = "none";' : '', '
3027
												', !empty($context['member']['avatar']['allow_upload']) ? 'document.getElementById("avatar_upload").style.display = "none";' : '', '
3028
												', !empty($context['member']['avatar']['allow_gravatar']) ? 'document.getElementById("avatar_gravatar").style.display = "";' : '', '
3029
												', ($context['member']['avatar']['external'] == $context['member']['email'] || strstr($context['member']['avatar']['external'], 'http://')) ?
3030
												'document.getElementById("gravatarEmail").value = "";' : '', '
3031
												break;
3032
										}
3033
									}
3034
								</script>
3035
							</dd>';
3036
}
3037
3038
/**
3039
 * This is just a really little helper to avoid duplicating code unnecessarily
3040
 *
3041
 * @param string $type The type of avatar
3042
 */
3043
function template_max_size($type)
3044
{
3045
	global $modSettings, $txt;
3046
3047
	$w = !empty($modSettings['avatar_max_width_' . $type]) ? comma_format($modSettings['avatar_max_width_' . $type]) : 0;
3048
	$h = !empty($modSettings['avatar_max_height_' . $type]) ? comma_format($modSettings['avatar_max_height_' . $type]) : 0;
3049
3050
	$suffix = (!empty($w) ? 'w' : '') . (!empty($h) ? 'h' : '');
3051
	if (empty($suffix))
3052
		return;
3053
3054
	echo '
3055
								<div class="smalltext">', sprintf($txt['avatar_max_size_' . $suffix], $w, $h), '</div>';
3056
}
3057
3058
/**
3059
 * Select the time format!
3060
 */
3061
function template_profile_timeformat_modify()
3062
{
3063
	global $context, $txt, $scripturl;
3064
3065
	echo '
3066
							<dt>
3067
								<strong><label for="easyformat">', $txt['time_format'], ':</label></strong><br>
3068
								<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>
3069
								<span class="smalltext">
3070
									<label for="time_format">', $txt['date_format'], '</label>
3071
								</span>
3072
							</dt>
3073
							<dd>
3074
								<select name="easyformat" id="easyformat" onchange="document.forms.creator.time_format.value = this.options[this.selectedIndex].value;">';
3075
3076
	// Help the user by showing a list of common time formats.
3077
	foreach ($context['easy_timeformats'] as $time_format)
3078
		echo '
3079
									<option value="', $time_format['format'], '"', $time_format['format'] == $context['member']['time_format'] ? ' selected' : '', '>', $time_format['title'], '</option>';
3080
3081
	echo '
3082
								</select>
3083
								<input type="text" name="time_format" id="time_format" value="', $context['member']['time_format'], '" size="30">
3084
							</dd>';
3085
}
3086
3087
/**
3088
 * Template for picking a theme
3089
 */
3090
function template_profile_theme_pick()
3091
{
3092
	global $txt, $context, $scripturl;
3093
3094
	echo '
3095
							<dt>
3096
								<strong>', $txt['current_theme'], ':</strong>
3097
							</dt>
3098
							<dd>
3099
								', $context['member']['theme']['name'], ' <a class="button" href="', $scripturl, '?action=theme;sa=pick;u=', $context['id_member'], '">', $txt['change'], '</a>
3100
							</dd>';
3101
}
3102
3103
/**
3104
 * Smiley set picker.
3105
 */
3106
function template_profile_smiley_pick()
3107
{
3108
	global $txt, $context, $modSettings, $settings;
3109
3110
	echo '
3111
							<dt>
3112
								<strong><label for="smiley_set">', $txt['smileys_current'], ':</label></strong>
3113
							</dt>
3114
							<dd>
3115
								<select name="smiley_set" id="smiley_set">';
3116
3117
	foreach ($context['smiley_sets'] as $set)
3118
		echo '
3119
									<option data-preview="', $set['preview'], '" value="', $set['id'], '"', $set['selected'] ? ' selected' : '', '>', $set['name'], '</option>';
3120
3121
	echo '
3122
								</select>
3123
								<img id="smileypr" class="centericon" src="', $context['member']['smiley_set']['preview'], '" alt=":)">
3124
							</dd>';
3125
}
3126
3127
/**
3128
 * Template for setting up and managing Two-Factor Authentication.
3129
 */
3130
function template_tfasetup()
3131
{
3132
	global $txt, $context, $scripturl, $modSettings;
3133
3134
	echo '
3135
			<div class="cat_bar">
3136
				<h3 class="catbg">', $txt['tfa_title'], '</h3>
3137
			</div>
3138
			<div class="roundframe">
3139
				<div>';
3140
3141
	if (!empty($context['tfa_backup']))
3142
		echo '
3143
					<div class="smalltext error">
3144
						', $txt['tfa_backup_used_desc'], '
3145
					</div>';
3146
3147
	elseif ($modSettings['tfa_mode'] == 2)
3148
		echo '
3149
					<div class="smalltext">
3150
						<strong>', $txt['tfa_forced_desc'], '</strong>
3151
					</div>';
3152
3153
	echo '
3154
					<div class="smalltext">
3155
						', $txt['tfa_desc'], '
3156
					</div>
3157
					<div class="floatleft">
3158
						<form action="', $scripturl, '?action=profile;area=tfasetup" method="post">
3159
							<div class="block">
3160
								<strong>', $txt['tfa_step1'], '</strong><br>';
3161
3162
	if (!empty($context['tfa_pass_error']))
3163
		echo '
3164
								<div class="error smalltext">
3165
									', $txt['tfa_pass_invalid'], '
3166
								</div>';
3167
3168
	echo '
3169
								<input type="password" name="oldpasswrd" size="25"', !empty($context['password_auth_failed']) ? ' class="error"' : '', !empty($context['tfa_pass_value']) ? ' value="' . $context['tfa_pass_value'] . '"' : '', '>
3170
							</div>
3171
							<div class="block">
3172
								<strong>', $txt['tfa_step2'], '</strong>
3173
								<div class="smalltext">', $txt['tfa_step2_desc'], '</div>
3174
								<div class="tfacode">', $context['tfa_secret'], '</div>
3175
							</div>
3176
							<div class="block">
3177
								<strong>', $txt['tfa_step3'], '</strong><br>';
3178
3179
	if (!empty($context['tfa_error']))
3180
		echo '
3181
								<div class="error smalltext">
3182
									', $txt['tfa_code_invalid'], '
3183
								</div>';
3184
3185
	echo '
3186
								<input type="text" name="tfa_code" size="25"', !empty($context['tfa_error']) ? ' class="error"' : '', !empty($context['tfa_value']) ? ' value="' . $context['tfa_value'] . '"' : '', '>
3187
								<input type="submit" name="save" value="', $txt['tfa_enable'], '" class="button">
3188
							</div>
3189
							<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3190
							<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3191
						</form>
3192
					</div>
3193
					<div class="floatright tfa_qrcode">
3194
						<div id="qrcode"></div>
3195
						<script type="text/javascript">
3196
							new QRCode(document.getElementById("qrcode"), "', $context['tfa_qr_url'], '");
3197
						</script>
3198
					</div>';
3199
3200
	if (!empty($context['from_ajax']))
3201
		echo '
3202
					<br>
3203
					<a href="javascript:self.close();"></a>';
3204
3205
	echo '
3206
				</div>
3207
			</div><!-- .roundframe -->';
3208
}
3209
3210
/**
3211
 * Template for disabling two-factor authentication.
3212
 */
3213
function template_tfadisable()
3214
{
3215
	global $txt, $context, $scripturl;
3216
3217
	echo '
3218
			<div class="cat_bar">
3219
				<h3 class="catbg">', $txt['tfadisable'], '</h3>
3220
			</div>
3221
			<div class="roundframe">
3222
				<form action="', $scripturl, '?action=profile;area=tfadisable" method="post">';
3223
3224
	if ($context['user']['is_owner'])
3225
		echo '
3226
					<div class="block">
3227
						<strong', (isset($context['modify_error']['bad_password']) || isset($context['modify_error']['no_password']) ? ' class="error"' : ''), '>', $txt['current_password'], ': </strong><br>
3228
						<input type="password" name="oldpasswrd" size="20">
3229
					</div>';
3230
	else
3231
		echo '
3232
					<div class="smalltext">
3233
						', sprintf($txt['tfa_disable_for_user'], $context['user']['name']), '
3234
					</div>';
3235
3236
	echo '
3237
					<input type="submit" name="save" value="', $txt['tfa_disable'], '" class="button floatright">
3238
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3239
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3240
					<input type="hidden" name="u" value="', $context['id_member'], '">
3241
				</form>
3242
			</div><!-- .roundframe -->';
3243
}
3244
3245
/**
3246
 * Template for setting up 2FA backup code
3247
 */
3248
function template_tfasetup_backup()
3249
{
3250
	global $context, $txt;
3251
3252
	echo '
3253
			<div class="cat_bar">
3254
				<h3 class="catbg">', $txt['tfa_backup_title'], '</h3>
3255
			</div>
3256
			<div class="roundframe">
3257
				<div>
3258
					<div class="smalltext">', $txt['tfa_backup_desc'], '</div>
3259
					<div class="bbc_code" style="resize: none; border: none;">', $context['tfa_backup'], '</div>
3260
				</div>
3261
			</div>';
3262
}
3263
3264
/**
3265
 * Simple template for showing the 2FA area when editing a profile.
3266
 */
3267
function template_profile_tfa()
3268
{
3269
	global $context, $txt, $scripturl, $modSettings;
3270
3271
	echo '
3272
							<dt>
3273
								<strong>', $txt['tfa_profile_label'], ':</strong><br>
3274
								<div class="smalltext">', $txt['tfa_profile_desc'], '</div>
3275
							</dt>
3276
							<dd>';
3277
3278
	if (!$context['tfa_enabled'] && $context['user']['is_owner'])
3279
		echo '
3280
								<a href="', !empty($modSettings['force_ssl']) ? strtr($scripturl, array('http://' => 'https://')) : $scripturl, '?action=profile;area=tfasetup" id="enable_tfa">', $txt['tfa_profile_enable'], '</a>';
3281
3282
	elseif (!$context['tfa_enabled'])
3283
		echo '
3284
								', $txt['tfa_profile_disabled'];
3285
3286
	else
3287
		echo '
3288
								', sprintf($txt['tfa_profile_enabled'], (!empty($modSettings['force_ssl']) ? strtr($scripturl, array('http://' => 'https://')) : $scripturl) . '?action=profile;u=' . $context['id_member'] . ';area=tfadisable');
3289
3290
	echo '
3291
							</dd>';
3292
}
3293
3294
/**
3295
 * Template for initiating and retrieving profile data exports
3296
 */
3297
function template_export_profile_data()
3298
{
3299
	global $context, $scripturl, $txt;
3300
3301
	$default_settings = array('included' => array(), 'format' => '');
3302
	$dltoken = '';
3303
3304
	// The main containing header.
3305
	echo '
3306
		<div class="cat_bar">
3307
			<h3 class="catbg profile_hd">
3308
				', $txt['export_profile_data'], '
3309
			</h3>
3310
		</div>
3311
		<div class="information">', $context['export_profile_data_desc'], '</div>';
3312
3313
	if (!empty($context['completed_exports']))
3314
	{
3315
		echo '
3316
		<div class="title_bar">
3317
			<h3 class="titlebg">', $txt['completed_exports'], '</h3>
3318
		</div>
3319
		<div class="windowbg noup">';
3320
3321
		foreach ($context['completed_exports'] as $basehash_ext => $parts)
3322
		{
3323
			echo '
3324
			<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', '">';
3325
3326
			if (!empty($context['outdated_exports'][$basehash_ext]))
3327
			{
3328
				echo '
3329
				<div class="noticebox">
3330
					<p>', $txt['export_outdated_warning'], '</p>
3331
					<ul class="bbc_list">';
3332
3333
				foreach ($context['outdated_exports'][$basehash_ext] as $datatype)
3334
					echo '
3335
						<li>', $txt[$datatype], '</li>';
3336
3337
				echo '
3338
					</ul>
3339
				</div>';
3340
			}
3341
3342
			echo '
3343
				<p>', sprintf($txt['export_file_desc'], $parts[1]['included_desc'], $context['export_formats'][$parts[1]['format']]['description']), '</p>';
3344
3345
			if (count($parts) > 10)
3346
				echo '
3347
				<details>
3348
					<summary>', sprintf($txt['export_file_count'], count($parts)), '</summary>';
3349
3350
			echo '
3351
				<ul class="bbc_list" id="', $parts[1]['format'], '_export_files">';
3352
3353
			foreach ($parts as $part => $file)
3354
			{
3355
				$dltoken = $file['dltoken'];
3356
				if (empty($default_settings['included']))
3357
					$default_settings['included'] = $file['included'];
3358
				if (empty($default_settings['format']))
3359
					$default_settings['format'] = $file['format'];
3360
3361
				echo '
3362
					<li>
3363
						<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'], ')
3364
					</li>';
3365
			}
3366
3367
			echo '
3368
				</ul>';
3369
3370
			if (count($parts) > 10)
3371
				echo '
3372
				</details>';
3373
3374
			echo '
3375
				<div class="righttext">
3376
					<input type="submit" name="delete" value="', $txt['delete'], '" class="button you_sure">
3377
					<input type="hidden" name="format" value="', $parts[1]['format'], '">
3378
					<input type="hidden" name="t" value="', $dltoken, '">
3379
					<button type="button" class="button export_download_all" style="display:none" onclick="export_download_all(\'', $parts[1]['format'], '\');">', $txt['export_download_all'], '</button>
3380
				</div>
3381
			</form>';
3382
		}
3383
3384
		echo '
3385
		</div>';
3386
	}
3387
3388
	if (!empty($context['active_exports']))
3389
	{
3390
		echo '
3391
		<div class="title_bar">
3392
			<h3 class="titlebg">', $txt['active_exports'], '</h3>
3393
		</div>
3394
		<div class="windowbg noup">';
3395
3396
		foreach ($context['active_exports'] as $file)
3397
		{
3398
			$dltoken = $file['dltoken'];
3399
			if (empty($default_settings['included']))
3400
				$default_settings['included'] = $file['included'];
3401
			if (empty($default_settings['format']))
3402
				$default_settings['format'] = $file['format'];
3403
3404
			echo '
3405
			<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"' : '', '>
3406
				<p class="padding">', sprintf($txt['export_file_desc'], $file['included_desc'], $context['export_formats'][$file['format']]['description']), '</p>
3407
				<div class="righttext">
3408
					<input type="submit" name="delete" value="', $txt['export_cancel'], '" class="button you_sure">
3409
					<input type="hidden" name="format" value="', $file['format'], '">
3410
					<input type="hidden" name="t" value="', $dltoken, '">
3411
				</div>
3412
			</form>';
3413
		}
3414
3415
		echo '
3416
		</div>';
3417
	}
3418
3419
	echo '
3420
		<div class="title_bar">
3421
			<h3 class="titlebg">', $txt['export_settings'], '</h3>
3422
		</div>
3423
		<div class="windowbg noup">
3424
			<form action="', $scripturl, '?action=profile;area=getprofiledata;u=', $context['id_member'], '" method="post" accept-charset="', $context['character_set'], '">
3425
				<dl class="settings">';
3426
3427
	foreach ($context['export_datatypes'] as $datatype => $datatype_settings)
3428
	{
3429
		if (!empty($datatype_settings['label']))
3430
			echo '
3431
					<dt>
3432
						<strong><label for="', $datatype, '">', $datatype_settings['label'], '</label></strong>
3433
					</dt>
3434
					<dd>
3435
						<input type="checkbox" id="', $datatype, '" name="', $datatype, '"', in_array($datatype, $default_settings['included']) ? ' checked' : '', '>
3436
					</dd>';
3437
	}
3438
3439
	echo '
3440
				</dl>
3441
				<dl class="settings">
3442
					<dt>
3443
						<strong>', $txt['export_format'], '</strong>
3444
					</dt>
3445
					<dd>
3446
						<select id="export_format_select" name="format">';
3447
3448
	foreach ($context['export_formats'] as $format => $format_settings)
3449
		echo '
3450
							<option value="', $format, '"', $format == $default_settings['format'] ? ' selected' : '', '>', $format_settings['description'], '</option>';
3451
3452
	echo '
3453
						</select>
3454
					</dd>
3455
				</dl>
3456
				<div class="righttext">';
3457
3458
	// At least one active or completed export exists.
3459
	if (!empty($dltoken))
3460
	{
3461
		echo '
3462
					<div id="export_begin" style="display:none">
3463
						<input type="submit" name="export_begin" value="', $txt['export_begin'], '" class="button">
3464
					</div>
3465
					<div id="export_restart">
3466
						<input type="submit" name="export_begin" value="', $txt['export_restart'], '" class="button you_sure" data-confirm="', $txt['export_restart_confirm'], '">
3467
						<input type="hidden" name="delete">
3468
						<input type="hidden" name="t" value="', $dltoken, '">
3469
					</div>';
3470
	}
3471
	// No existing exports.
3472
	else
3473
	{
3474
		echo '
3475
					<input type="submit" name="export_begin" value="', $txt['export_begin'], '" class="button">';
3476
	}
3477
3478
	echo '
3479
					<input type="hidden" name="', $context[$context['token_check'] . '_token_var'], '" value="', $context[$context['token_check'] . '_token'], '">
3480
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
3481
				</div>
3482
			</form>
3483
		</div><!-- .windowbg -->';
3484
}
3485
3486
?>