template_body_above()   B
last analyzed

Complexity

Conditions 7
Paths 1

Size

Total Lines 52
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 1
nop 0
dl 0
loc 52
ccs 0
cts 21
cp 0
crap 56
rs 8.6346
c 0
b 0
f 0

How to fix   Long Method   

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
/**
4
 * @package   ElkArte Forum
5
 * @copyright ElkArte Forum contributors
6
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
7
 *
8
 * This file contains code covered by:
9
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
10
 *
11
 * @version 2.0 dev
12
 *
13
 */
14
15
/**
16
 * This template is, perhaps, the most important template in the theme. It
17
 * contains the main template layer that displays the header and footer of
18
 * the forum, namely with body_above and body_below. It also contains the
19
 * menu sub template, which appropriately displays the menu; the init sub
20
 * template, which is there to set the theme up; (init can be missing.) and
21
 * the breadcrumb sub template, which sorts out the breadcrumbs.
22
 *
23
 * The init sub template should load any data and set any hardcoded options.
24
 *
25
 * The body_above sub template is what is shown above the main content, and
26
 * should contain anything that should be shown up there.
27
 *
28
 * The body_below sub template, conversely, is shown after the main content.
29
 * It should probably contain the copyright statement and some other things.
30
 *
31
 * The breadcrumb sub template should display the breadcrumbs, using the data
32
 * in the $context['breadcrumbs'] variable.
33
 *
34
 * The menu sub template should display all the relevant buttons the user
35
 * wants and or needs.
36
 */
37
38
/**
39
 * Start off the template by loading some helpers like
40
 * quick buttons, page index, etc
41
 */
42
function template_Index_init()
43
{
44
	theme()->getTemplates()->load('GenericHelpers');
45
}
46
47
/**
48
 * Simplify the use of callbacks in the templates.
49
 *
50
 * @param string $id - A prefix for the template functions the final name
51
 *                     should look like: template_{$id}_{$array[n]}
52
 * @param string[] $array - The array of function suffixes
53
 */
54
function call_template_callbacks($id, $array)
55
{
56
	if (empty($array))
57
	{
58
		return;
59
	}
60
61
	foreach ($array as $callback)
62
	{
63
		$func = 'template_' . $id . '_' . $callback;
64
		if (function_exists($func))
65
		{
66
			$func();
67
		}
68
	}
69
}
70
71
/**
72
 * The main sub template above the content.
73
 */
74
function template_html_above()
75
{
76
	global $context, $scripturl, $txt;
77
78
	// Show right to left and the character set for ease of translating.
79
	echo '<!DOCTYPE html>
80
<html dir=', $context['right_to_left'] ? ' "RTL"' : 'LTR', ' lang="', str_replace('_', '-', $txt['lang_locale']), '">
81
<head>
82
	<title>', $context['page_title_html_safe'], '</title>
83
	<meta charset="utf-8" />';
84
85
	$description = $context['page_title_html_safe'];
86
	if (isset($context['page_description']))
87
	{
88
		$description .= ': ' . $context['page_description'];
89
	}
90
91
	echo '
92
	<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
93
	<meta name="mobile-web-app-capable" content="yes" />
94
	<meta name="description" content="', $description, '" />
95
	<meta name="theme-color" content="', $context['theme-color'], '" />';
96
97
	// Please don't index these Mr Robot.
98
	if (!empty($context['robot_no_index']))
99
	{
100
		echo '
101
	<meta name="robots" content="noindex" />';
102
	}
103
104
	// If we have any Open Graph data, here is where is inserted.
105
	if (!empty($context['open_graph']))
106
	{
107
		echo '
108
	' .implode("\n\t", $context['open_graph']);
109
	}
110
111
	// Present a canonical url for search engines to prevent duplicate content in their indices.
112
	if (!empty($context['canonical_url']))
113
	{
114
		echo '
115
	<link rel="canonical" href="', $context['canonical_url'], '" />';
116
	}
117
118
	// Various icons and optionally a PWA manifest
119
	echo '
120
	<link rel="icon" sizes="any" href="' . $context['favicon'] . '" />
121
	<link rel="apple-touch-icon" href="' . $context['apple_touch'] . '" />';
122
123
	// Personal Web Application Manifest
124
	if (!empty($context['pwa_manifest_enabled']))
125
	{
126
		echo '
127
	<link rel="manifest" href="./elkManifest.php">';
128
	}
129
130
	// Show all the relative links, such as help, search, contents, and the like.
131
	echo '
132
	<link rel="help" href="', getUrl('action', ['action' => 'help']), '" />
133
	<link rel="contents" href="', $scripturl, '" />', ($context['allow_search'] ? '
134
	<link rel="search" href="' . getUrl('action', ['action' => 'search']) . '" />' : '');
135
136
	// If RSS feeds are enabled, advertise the presence of one.
137
	if (!empty($context['newsfeed_urls']))
138
	{
139
		echo '
140
	<link rel="alternate" type="application/rss+xml" title="', $context['forum_name_html_safe'], ' - ', $txt['rss'], '" href="', $context['newsfeed_urls']['rss'], '" />
141
	<link rel="alternate" type="application/rss+xml" title="', $context['forum_name_html_safe'], ' - ', $txt['atom'], '" href="', $context['newsfeed_urls']['atom'], '" />';
142
	}
143
144
	// If we're viewing a topic, these should be the previous and next topics, respectively.
145
	if (!empty($context['links']['next']))
146
	{
147
		echo '
148
	<link rel="next" href="', $context['links']['next'], '" />';
149
	}
150
	elseif (!empty($context['current_topic']))
151
	{
152
		echo '
153
	<link rel="next" href="', $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=next" />';
154
	}
155
156
	if (!empty($context['links']['prev']))
157
	{
158
		echo '
159
	<link rel="prev" href="', $context['links']['prev'], '" />';
160
	}
161
	elseif (!empty($context['current_topic']))
162
	{
163
		echo '
164
	<link rel="prev" href="', $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=prev" />';
165
	}
166
167
	// If we're in a board, or a topic for that matter, the index will be the board's index.
168
	if (!empty($context['current_board']))
169
	{
170
		echo '
171
	<link rel="index" href="', $scripturl, '?board=', $context['current_board'], '.0" />';
172
	}
173
174
	// load in CSS from addons or themes, do it first so overrides are possible
175
	theme()->themeCss()->template_css();
176
177
	// load in any JavaScript files and inline from addons and themes
178
	theme()->themeJs()->template_javascript();
179
180
	// load in any inline CSS files from addons and themes
181
	theme()->themeCss()->template_inlinecss();
182
183
	// Output any remaining HTML headers. (from addons, maybe?)
184
	echo $context['html_headers'];
185
186
	echo '
187
	</head>';
188
189
	// Start defining the body class
190
	$bodyClass = 'action_';
191
192
	if (!empty($context['current_action']))
193
	{
194
		$bodyClass .= htmlspecialchars($context['current_action'], ENT_COMPAT, 'UTF-8');
195
	}
196
	elseif (!empty($context['current_board']))
197
	{
198
		$bodyClass .= 'messageindex';
199
	}
200
	elseif (!empty($context['current_topic']))
201
	{
202
		$bodyClass .= 'display';
203
	}
204
	else
205
	{
206
		$bodyClass .= 'home';
207
	}
208
209
	if (!empty($context['current_board']))
210
	{
211
		$bodyClass .= ' board_' . htmlspecialchars($context['current_board'], ENT_COMPAT, 'UTF-8');
212
	}
213
214
	echo '
215
	<body class="', $bodyClass .  '">';
216
}
217
218
/**
219
 * Section above the main contents of the page, after opening the body tag
220
 */
221
function template_body_above()
222
{
223
	global $context, $settings, $txt;
224
225
	// Go to top/bottom of page links and skipnav link for a11y.
226
	echo '
227
	<a id="top" href="#skipnav" tabindex="0">', $txt['skip_nav'], '</a>
228
	<a id="gotop" href="#top_section"  title="', $txt['go_up'], '">&#8593;</a>
229
	<a id="gobottom" href="#footer_section" title="', $txt['go_down'], '">&#8595;</a>';
230
231
	echo '
232
	<header id="top_section" class="', (empty($context['minmax_preferences']['upshrink']) ? 'th_expand' : 'th_collapse'), '">
233
		<aside id="top_header" class="wrapper">';
234
235
	// Load in all register header templates
236
	call_template_callbacks('th', $context['theme_header_callbacks']);
237
238
	echo '
239
		</aside>
240
		<section id="header" class="wrapper', empty($settings['header_layout']) ? '' : ($settings['header_layout'] == 1 ? ' centerheader' : ' rightheader'), empty($context['minmax_preferences']['upshrink']) ? '"' : ' hide" aria-hidden="true"', '>
241
			<h1 id="forumtitle">
242
				<a class="forumlink" href="', getUrl('boardindex', []), '">', $context['forum_name'], '</a>';
243
244
	echo '
245
				<span id="logobox">
246
					<img id="logo" src="', $context['header_logo_url_html_safe'], '" alt="', $context['forum_name_html_safe'], '" title="', $context['forum_name_html_safe'], '" />', empty($settings['site_slogan']) ? '' : '
247
					<span id="siteslogan">' . $settings['site_slogan'] . '</span>', '
248
				</span>
249
			</h1>';
250
251
	// Show the menu here, according to the menu sub template.
252
	echo '
253
		</section>';
254
255
	template_menu();
256
257
	echo '
258
	</header>
259
	<div id="wrapper" class="wrapper">
260
		<aside id="upper_section"', empty($context['minmax_preferences']['upshrink']) ? '' : ' class="hide" aria-hidden="true"', '>';
261
262
	// Load in all registered upper content templates
263
	call_template_callbacks('uc', $context['upper_content_callbacks']);
264
265
	echo '
266
		</aside>';
267
268
	// Show the navigation tree.
269
	theme_breadcrumbs();
270
271
	// The main content should go here.
272
	echo '
273
		<div id="main_content_section">
274
			<a id="skipnav"></a>';
275
}
276
277
/**
278
 * More or less a place holder for now, sits at the very page top.
279
 * The maintenance mode warning for admins is an obvious one, but this could also be used for moderation notifications.
280
 * I also assumed this would be an obvious place for sites to put a string of icons to link to their FB, Twitter, etc.
281
 * This could still be done via conditional, so that administration and moderation notices were still active when
282
 * applicable.
283
 */
284
function template_th_header_bar()
285
{
286
	global $context, $txt, $scripturl;
287
288
	echo '
289
			<div id="top_section_notice" class="user', (empty($context['minmax_preferences']['upshrink']) ? '' : ' hide'), '">
290
			</div>';
291
}
292
293
/**
294
 * Search bar form, expands to input form when search icon is clicked
295
 */
296
function template_search_form()
297
{
298
	global $context, $modSettings, $txt;
299
300
	echo '
301
			<form id="search_form_menu" action="', getUrl('action', ['action' => 'search', 'sa' => 'results']), '" method="post" role="search" accept-charset="UTF-8">';
302
303
	// Using the quick search dropdown?
304
	if (!empty($modSettings['search_dropdown']))
305
	{
306
		$selected = empty($context['current_topic']) ? (!empty($context['current_board']) ? 'current_board' : 'all') : ('current_topic');
307
		echo '
308
				<label for="search_selection">
309
					<select name="search_selection" id="search_selection" class="linklevel1" aria-label="search selection">
310
						<option value="all"', ($selected === 'all' ? ' selected="selected"' : ''), '>', $txt['search_entireforum'], ' </option>';
311
312
		// Can't limit it to a specific topic if we are not in one
313
		if (!empty($context['current_topic']))
314
		{
315
			echo '
316
						<option value="topic"', ($selected === 'current_topic' ? ' selected="selected"' : ''), '>', $txt['search_thistopic'], '</option>';
317
		}
318
319
		// Can't limit it to a specific board if we are not in one
320
		if (!empty($context['current_board']))
321
		{
322
			echo '
323
						<option value="board"', ($selected === 'current_board' ? ' selected="selected"' : ''), '>', $txt['search_thisbrd'], '</option>';
324
		}
325
326
		if (!empty($context['additional_dropdown_search']))
327
		{
328
			foreach ($context['additional_dropdown_search'] as $name => $engine)
329
			{
330
				echo '
331
						<option value="', $name, '">', $engine['name'], '</option>';
332
			}
333
		}
334
335
		echo '
336
						<option value="members"', ($selected === 'members' ? ' selected="selected"' : ''), '>', $txt['search_members'], ' </option>
337
					</select>
338
				</label>';
339
	}
340
341
	// Search within current topic?
342
	if (!empty($context['current_topic']))
343
	{
344
		echo '
345
				<input type="hidden" name="', (empty($modSettings['search_dropdown']) ? 'topic' : 'sd_topic'), '" value="', $context['current_topic'], '" />';
346
	}
347
348
	// If we're on a certain board, limit it to this board ;).
349
	if (!empty($context['current_board']))
350
	{
351
		echo '
352
				<input type="hidden" name="', (empty($modSettings['search_dropdown']) ? 'brd[' : 'sd_brd['), $context['current_board'], ']"', ' value="', $context['current_board'], '" />';
353
	}
354
355
	echo '					
356
				<label for="quicksearch" class="hide">', $txt['search'], '</label>
357
				<input type="search" name="search" id="quicksearch" value="" class="linklevel1" placeholder="', $txt['search'], '" />
358
				<button type="submit" aria-label="' . $txt['search'] . '" name="search;sa=results" class="', (empty($modSettings['search_dropdown'])) ? '' : 'with_select', '">
359
					<i class="icon i-search"><s>', $txt['search'], '</s></i>
360
				</button>
361
				<button type="button" aria-label="' . $txt['find_close'] . '">
362
					<label for="search_form_check">
363
						<i class="icon i-close"><s>', $txt['find_close'], '</s></i>
364
					</label>
365
				</button>
366
				<input type="hidden" name="advanced" value="0" />
367
			</form>';
368
}
369
370
/**
371
 * Search bar main menu icon
372
 */
373
function template_mb_search_bar()
374
{
375
	global $txt;
376
377
	echo '
378
						<li id="search_form_button" class="listlevel1" role="none">
379
							<label for="search_form_check">
380
								<a class="linklevel1 panel_search" role="menuitem">
381
									<i class="main-menu-icon i-search colorize-white"><s>', $txt['search'], '</s></i>
382
								</a>
383
							</label>
384
						</li>';
385
}
386
387
/**
388
 * The news fader wrapped in a div and with "news" text
389
 */
390
function template_uc_news_fader()
391
{
392
	global $settings, $context, $txt;
393
394
	// Display either news fader and random news lines (not both). These now run most of the same mark up and CSS. Less complication = happier n00bz. :)
395
	if (!empty($settings['enable_news']) && !empty($context['random_news_line']))
396
	{
397
		echo '
398
			<div id="news">
399
				<h2>', $txt['news'], '</h2>';
400
401
		template_news_fader();
402
403
		echo '
404
			</div>';
405
	}
406
}
407
408
/**
409
 * Section down the page, before closing body
410
 */
411
function template_body_below()
412
{
413
	global $context, $txt;
414
415
	echo '
416
		</div>
417
	</div>';
418
419
	// Show RSS link, as well as the copyright.
420
	// Footer is full-width. Wrapper inside automatically matches admin width setting.
421
	echo '
422
	<footer id="footer_section">
423
		<div class="wrapper">
424
			<ul>
425
				<li class="copyright">',
426
					theme_copyright(), '
0 ignored issues
show
Bug introduced by
Are you sure the usage of theme_copyright() 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...
Bug introduced by
Are you sure theme_copyright() of type void can be used in echo? ( Ignorable by Annotation )

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

426
					/** @scrutinizer ignore-type */ theme_copyright(), '
Loading history...
427
				</li>',
428
				empty($context['newsfeed_urls']['rss']) ? '' : '
429
				<li>
430
					<a id="button_rss" href="' . $context['newsfeed_urls']['rss'] . '" class="rssfeeds new_win">
431
						<i class="icon icon-margin i-rss icon-big"><s>' . $txt['rss'] . '</s></i>
432
					</a>
433
				</li>', '
434
			</ul>';
435
436
	// Show the load time?
437
	if ($context['show_load_time'])
438
	{
439
		echo '
440
			<p>', sprintf($txt['page_created_full'], $context['load_time'], $context['load_queries']), '</p>';
441
	}
442
}
443
444
/**
445
 * Section down the page, at closing html tag
446
 */
447
function template_html_below()
448
{
449
	global $context;
450
451
	echo '
452
		</div>
453
	</footer>';
454
455
	// This is here to catch any late loading of JS files via templates
456
	theme()->themeJs()->outputJavascriptFiles(theme()->themeJs()->getJSFiles());
457
458
	// load inline javascript that needed to be deferred to the end of the page
459
	theme()->themeJs()->template_inline_javascript(true);
460
461
	// Schema microdata about the organization?
462
	if (!empty($context['smd_site']))
463
	{
464
		echo '
465
	<script type="application/ld+json">
466
	', json_encode($context['smd_site'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), '
467
	</script>';
468
	}
469
470
	// Schema microdata about the post?
471
	if (!empty($context['smd_article']))
472
	{
473
		echo '
474
	<script type="application/ld+json">
475
	', json_encode($context['smd_article'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), '
476
	</script>';
477
	}
478
479
	// Anything special to put out?
480
	if (!empty($context['insert_after_template']))
481
	{
482
		echo $context['insert_after_template'];
483
	}
484
485
	echo '
486
</body>
487
</html>';
488
}
489
490
/**
491
 * Show breadcrumbs. This is that thing that shows
492
 * "My Community | General Category | General Discussion"..
493
 *
494
 * @param string $default a string representing the index in $context where
495
 *               the breadcrumbs are stored (default value is 'breadcrumbs')
496
 */
497
function theme_breadcrumbs($default = 'breadcrumbs')
498
{
499
	global $context, $settings, $txt;
500
501
	// If breadcrumbs is empty, just return - also allow an override.
502
	if (empty($context[$default]))
503
	{
504
		return;
505
	}
506
507
	echo '
508
		<nav class="breadcrumb" aria-label="breadcrumbs">';
509
510
	// Each tree item has a URL and name. Some may have extra_before and extra_after.
511
	// Added a crumb class to make targeting dividers easy.
512
	foreach ($context[$default] as $pos => $tree)
513
	{
514
		$tree['name'] = ($tree['extra_before'] ?? '') . $tree['name'] . ($tree['extra_after'] ?? '');
515
516
		// Show the link, including a URL if it should have one.
517
		echo isset($tree['url'])
518
			? '
519
			<span class="crumb">
520
				<a href="' . $tree['url'] . '">' .
521
					($pos === 0
522
						? '<i class="icon i-home"><s>' . $txt['home'] . '</s></i>'
523
						: $tree['name']) . '
524
				</a>
525
			</span>'
526
			: '
527
			<span class="crumb">
528
				' . $tree['name'] . '
529
			</span>';
530
	}
531
532
	echo '
533
		</nav>';
534
}
535
536
/**
537
 * Show the menu up top. Something like [home] [help] [profile] [logout]...
538
 */
539
function template_menu()
540
{
541
	global $context, $txt;
542
543
	// WAI-ARIA a11y tweaks have been applied here.
544
	echo '
545
				<nav id="menu_nav" aria-label="', $txt['main_menu'], '">
546
					<div class="wrapper no_js">
547
					<input type="checkbox" id="search_form_check" aria-hidden="true" />
548
					<ul id="main_menu" aria-label="', $txt['main_menu'], '" role="menubar">';
549
550
	// Add any additional menu buttons from addons
551
	call_template_callbacks('mb', $context['theme_header_callbacks']);
552
553
	// This defines the start of right-aligned buttons, set your button order > 10
554
	echo '
555
						<li id="button_none" class="listlevel1" role="none">
556
							<a role="none"></a>
557
						</li>';
558
559
	// The upshrink image.
560
	echo '
561
						<li id="collapse_button" class="listlevel1" role="none">
562
							<a class="linklevel1 panel_toggle" role="menuitem">
563
								<i id="upshrink" class="hide main-menu-icon i-chevron-up" title="', $txt['upshrink_description'], '"></i>
564
							</a>
565
						</li>';
566
567
	// Now all the buttons from menu.subs
568
	foreach ($context['menu_buttons'] as $act => $button)
569
	{
570
		// Top link details, easier to maintain broken out
571
		$class = 'class="linklevel1' . (empty($button['active_button']) ? '' : ' active') . (empty($button['indicator']) ? '' : ' indicator') . '"';
572
		$href = ' href="' . $button['href'] . '"';
573
		$target = isset($button['target']) ? ' target="' . $button['target'] . '"' : '';
574
		$onclick = isset($button['onclick']) ? ' onclick="' . $button['onclick'] . '"' : '';
575
		$altTitle = 'title="' . (empty($button['alttitle']) ? $button['title'] : $button['alttitle']) . '"';
576
		$ally = empty($button['active_button']) ? '' : ' aria-current="page"';
577
578
		echo '
579
						<li id="button_', $act, '" class="listlevel1', empty($button['sub_buttons']) ? '"' : ' subsections"', ' role="none">
580
							<a ', $class, $href, $target, $ally, $onclick, ' role="menuitem"', empty($button['sub_buttons']) ? '' : ' aria-haspopup="true"', '>',
581
								(empty($button['data-icon']) ? '' : '<i class="icon icon-menu icon-lg ' . $button['data-icon'] . (empty($button['active_button']) ? '' : ' enabled') . '" ' . $altTitle . '></i> '),
582
								'<span class="button_title" aria-hidden="', (empty($button['sub_buttons']) ? 'false' : 'true'), '">', $button['title'], '</span>
583
							</a>';
584
585
		// Any 2nd level menus?
586
		if (!empty($button['sub_buttons']))
587
		{
588
			echo '
589
							<ul class="menulevel2" role="menu">';
590
591
			foreach ($button['sub_buttons'] as $childact => $childbutton)
592
			{
593
				echo '
594
								<li id="button_', $childact, '" class="listlevel2', empty($childbutton['sub_buttons']) ? '"' : ' subsections"', ' role="none">
595
									<a class="linklevel2" href="', $childbutton['href'], '" ', isset($childbutton['target']) ? 'target="' . $childbutton['target'] . '"' : '', isset($childbutton['onclick']) ? ' onclick="' . $childbutton['onclick'] . '"' : '', empty($childbutton['sub_buttons']) ? '' : ' aria-haspopup="true"', ' role="menuitem">',
596
										$childbutton['title'], '
597
									</a>';
598
599
				// 3rd level menus :)
600
				if (!empty($childbutton['sub_buttons']))
601
				{
602
					echo '
603
									<ul class="menulevel3" role="menu">';
604
605
					foreach ($childbutton['sub_buttons'] as $grandchildact => $grandchildbutton)
606
					{
607
						echo '
608
										<li id="button_', $grandchildact, '" class="listlevel3" role="none">
609
											<a class="linklevel3" href="', $grandchildbutton['href'], '" ', isset($grandchildbutton['target']) ? 'target="' . $grandchildbutton['target'] . '"' : '', isset($grandchildbutton['onclick']) ? ' onclick="' . $grandchildbutton['onclick'] . '"' : '', ' role="menuitem">',
610
												$grandchildbutton['title'], '
611
											</a>
612
										</li>';
613
					}
614
615
					echo '
616
									</ul>';
617
				}
618
619
				echo '
620
								</li>';
621
			}
622
623
			echo '
624
							</ul>';
625
		}
626
627
		echo '
628
						</li>';
629
	}
630
631
	echo '
632
						
633
					</ul>';
634
635
	// If search is enabled, plop in the form
636
	if ($context['allow_search'])
637
	{
638
		template_search_form();
639
	}
640
641
	echo '	</div>
642
				</nav>';
643
644
	// Define the upper_section toggle in javascript.
645
	theme()->themeJs()->addInlineJavascript('
646
		var oMainHeaderToggle = new elk_Toggle({
647
			bToggleEnabled: true,
648
			bCurrentlyCollapsed: ' . (empty($context['minmax_preferences']['upshrink']) ? 'false' : 'true') . ',
649
			aSwappableContainers: [
650
				\'upper_section\',\'header\',\'top_header\'
651
			],
652
			aSwapClasses: [
653
				{
654
					sId: \'upshrink\',
655
					classExpanded: \'main-menu-icon i-chevron-up\',
656
					titleExpanded: ' . JavaScriptEscape($txt['upshrink_description']) . ',
657
					classCollapsed: \'main-menu-icon i-chevron-down\',
658
					titleCollapsed: ' . JavaScriptEscape($txt['upshrink_description']) . '
659
				},
660
			],
661
			oThemeOptions: {
662
				bUseThemeSettings: ' . ($context['user']['is_guest'] ? 'false' : 'true') . ',
663
				sOptionName: \'minmax_preferences\',
664
				sSessionId: elk_session_id,
665
				sSessionVar: elk_session_var,
666
				sAdditionalVars: \';minmax_key=upshrink\'
667
			},
668
			oCookieOptions: {
669
				bUseCookie: elk_member_id == 0 ? true : false,
670
				sCookieName: \'upshrink\'
671
			},
672
			funcOnBeforeCollapse: function () {
673
				let header = document.getElementById(\'top_section\');
674
				header.classList.add(\'th_collapse\');
675
				header.classList.remove(\'th_expand\');
676
			},
677
			funcOnBeforeExpand: function () {
678
				let header = document.getElementById(\'top_section\');
679
				header.classList.add(\'th_expand\');
680
				header.classList.remove(\'th_collapse\');
681
			},
682
		});
683
	', true);
684
}
685
686
/**
687
 * Very simple and basic template to display a legend explaining the meaning
688
 * of some icons used in the messages listing (locked, sticky, etc.)
689
 */
690
function template_basicicons_legend()
691
{
692
	global $context, $modSettings, $txt;
693
694
	echo '
695
		<p class="floatleft">', !empty($modSettings['enableParticipation']) && $context['user']['is_logged'] ? '
696
			<span class="topicicon i-profile"></span> ' . $txt['participation_caption'] : '<span class="topicicon img_normal"> </span>' . $txt['normal_topic'], '<br />
697
			' . (empty($modSettings['pollMode']) ? '' : '<span class="topicicon i-poll"> </span>' . $txt['poll']) . '
698
		</p>
699
		<p>
700
			<span class="topicicon i-locked"> </span>' . $txt['locked_topic'] . '<br />
701
			<span class="topicicon i-sticky"> </span>' . $txt['sticky_topic'] . '<br />
702
		</p>';
703
}
704
705
/**
706
 * Show a box with a message, mostly used to show errors, but can be used to show
707
 * success as well
708
 *
709
 * Looks for the display information in the $context[$error_id] array
710
 * Keys of array are 'type'
711
 *  - empty or success for successbox
712
 *  - serious for error box
713
 *  - warning for warning box
714
 * 'title' - optional value to place above list
715
 * 'errors' - array of text strings to display in the box
716
 *
717
 * @param string $error_id
718
 */
719
function template_show_error($error_id)
720
{
721
	global $context;
722
723
	if (empty($error_id))
724
	{
725
		return;
726
	}
727
728
	$error = $context[$error_id] ?? array();
729
730
	echo '
731
					<div id="', $error_id, '" class="', (isset($error['type']) ? ($error['type'] === 'serious' ? 'errorbox' : 'warningbox') : 'successbox'), empty($error['errors']) ? ' hide"' : '"', '>';
732
733
	// Optional title for our results
734
	if (!empty($error['title']))
735
	{
736
		echo '
737
						<dl>
738
							<dt>
739
								<strong id="', $error_id, '_title">', $error['title'], '</strong>
740
							</dt>
741
							<dd>';
742
	}
743
744
	// Everything that went wrong, or correctly :)
745
	if (!empty($error['errors']))
746
	{
747
		echo '
748
								<ul', (isset($error['type']) ? ' class="error"' : ''), ' id="', $error_id, '_list">';
749
750
		foreach ($error['errors'] as $key => $err)
751
		{
752
			echo '
753
									<li id="', $error_id, '_', $key, '">', $err, '</li>';
754
		}
755
756
		echo '
757
								</ul>';
758
	}
759
760
	// All done
761
	if (!empty($error['title']))
762
	{
763
		echo '
764
							</dd>
765
						</dl>';
766
	}
767
768
	echo '
769
					</div>';
770
}
771
772
/**
773
 * Is this used?
774
 */
775
function template_uc_generic_infobox()
776
{
777
	global $context;
778
779
	if (empty($context['generic_infobox']))
780
	{
781
		return;
782
	}
783
784
	foreach ($context['generic_infobox'] as $key)
785
	{
786
		template_show_error($key);
787
	}
788
}
789
790
/**
791
 * This is the news fader
792
 */
793
function template_news_fader()
794
{
795
	global $settings, $context;
796
797
	echo '
798
				<ul id="elkFadeScroller">
799
					<li>
800
						', $settings['enable_news'] == 2 ? implode('</li><li>', $context['news_lines']) : $context['random_news_line'], '
801
					</li>
802
				</ul>
803
				<script type="module">
804
					Elk_NewsFader("elkFadeScroller", {' .  (empty($settings['newsfader_time']) ? '' : 'iFadeDelay: ' . $settings['newsfader_time']) . '})
805
				</script>';
806
}
807
808
/**
809
 *
810
 * @TODO: These need to be moved somewhere appropriate >_>
811
 *
812
 * @param array $member
813
 * @param bool $link
814
 *
815
 * @return string
816
 */
817
function template_member_online($member, $link = true)
818
{
819
	global $context;
820
821
	return ((!empty($context['can_send_pm']) && $link) ? '<a href="' . $member['online']['href'] . '" title="' . $member['online']['text'] . '">' : '') .
822
		   '<i class="' . ($member['online']['is_online'] ? 'iconline' : 'icoffline') . '" title="' . $member['online']['text'] . '"></i>' .
823
		   ((!empty($context['can_send_pm']) && $link) ? '</a>' : '');
824
}
825
826
/**
827
 * Similar to the above. Wanted to centralize this to make it easier to pull out the emailuser action and replace with
828
 * a mailto: href, which many sane board admins would prefer.
829
 *
830
 * @param array $member
831
 * @param bool $text
832
 *
833
 * @return string
834
 */
835
function template_member_email($member, $text = false)
836
{
837
	global $context, $txt;
838
839
	if ($context['can_send_email'])
840
	{
841
		if ($text)
842
		{
843
			if ($member !== false && $member['show_email'])
844
			{
845
				return '<a class="linkbutton" href="mailto:' . $member['email'] . '" rel="nofollow">' . $txt['email'] . '</a>';
846
			}
847
848
			return $txt['hidden'];
849
		}
850
851
		if ($member !== false && $member['show_email'])
852
		{
853
			return '<a href="mailto:' . $member['email'] . '" rel="nofollow" class="icon i-envelope-o' . ($member['online']['is_online'] ? '' : '-blank') . '" title="' . $txt['email'] . ' ' . $member['name'] . '"><s>' . $txt['email'] . ' ' . $member['name'] . '</s></a>';
854
		}
855
856
		return '<i class="icon i-envelope-o" title="' . $txt['email'] . ' ' . $txt['hidden'] . '"><s>' . $txt['email'] . ' ' . $txt['hidden'] . '</s></i>';
857
	}
858
859
	return '';
860
}
861