Passed
Pull Request — release-2.1 (#6101)
by Jon
03:54
created

xslt_export_html_css_js()   C

Complexity

Conditions 17
Paths 64

Size

Total Lines 96
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 17
eloc 40
c 1
b 0
f 0
nc 64
nop 0
dl 0
loc 96
rs 5.2166

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
	This template file is unusual. Instead of echoing HTML to send to a user's
15
	browser, these functions return components for XSLT stylesheets that will be
16
	used to transform XML data.
17
18
	The format for function names is different from typical SMF template files.
19
	This is intentional. The format has two variants:
20
21
	1. xslt_generic_{descriptive name}
22
23
		For XSLT elements that can be used in any XSLT stylesheet. They must be
24
		completely agnostic about the data they handle.
25
26
	2. xslt_{source type}_{result type}_{descriptive name}
27
28
		For XSLT templates that transform a specific type of XML source document
29
		into a specific type of result document. For example, XSLT templates
30
		that transfrorm the XML of a SMF profile export document into HTML use
31
		'xslt_export_html_' as their function name prefix.
32
 */
33
34
35
/**
36
 * Returns the opening tag for the XSLT stylesheet element + optional preamble.
37
 *
38
 * Attributes are set using the following from $context['xslt_settings']:
39
 * - no_xml_declaration
40
 * - preamble
41
 * - version
42
 * - namespaces
43
 * - exclude-result-prefixes
44
 * - extension-element-prefixes
45
 * - id
46
 */
47
function xslt_generic_header()
48
{
49
	global $context;
50
51
	$header = '';
52
53
	// Include the XML declaration unless explicitly told not to.
54
	if (empty($context['xslt_settings']['no_xml_declaration']))
55
		$header .= '<' . '?xml version="1.0" encoding="' . $context['character_set'] . '"?' . '>' . "\n";
56
57
	// Is there a preamble (e.g. Document Type Definition, XML processing instructions, etc.) to include?
58
	if (!empty($context['xslt_settings']['preamble']))
59
	{
60
		$header .= implode("\n", (array) $context['xslt_settings']['preamble']);
61
62
		// Append line break only if preamble didn't specify its own trailing whitespace.
63
		if ($header === rtrim($header))
64
			$header .= "\n";
65
	}
66
67
	// The main thing...
68
	$header .= '<xsl:stylesheet version="' . (!empty($context['xslt_settings']['version']) ? $context['xslt_settings']['version'] : '1.0') . '"';
69
70
	// XSL's own namespace declaration is required no matter what.
71
	$context['xslt_settings']['namespaces']['xsl'] = 'htt'.'p:/'.'/ww'.'w.w3.o'.'rg/1999/XSL/Transform';
72
73
	foreach ($context['xslt_settings']['namespaces'] as $ns_prefix => $ns_uri)
74
	{
75
		if (empty($ns_prefix) || ctype_digit(substr($ns_prefix, 0, 1)))
76
			continue;
77
78
		$header .= ' xmlns:' . $ns_prefix . '="' . trim($ns_uri) . '"';
79
	}
80
81
	foreach (array('exclude-result-prefixes', 'extension-element-prefixes', 'id') as $attribute)
82
	{
83
		if (in_array(gettype(@$context['xslt_settings'][$attribute]), array('string', 'array')))
84
			$header .= ' ' . $attribute . '="' . trim(implode(' ', (array) $context['xslt_settings'][$attribute])) . '"';
85
	}
86
87
	$header .= '>';
88
89
	return $header;
90
}
91
92
/**
93
 * Returns the closing tag for the XSLT stylesheet element itself.
94
 */
95
function xslt_generic_footer()
96
{
97
	global $context;
98
99
	return (!empty($context['xslt_settings']['before_footer']) ? (string) $context['xslt_settings']['before_footer'] : "\n") . '</xsl:stylesheet>';
100
}
101
102
/**
103
 * Returns an XSLT output control element (<xsl:output>) based on the settings
104
 * defined in $context['xslt_settings']['output'].
105
 */
106
function xslt_generic_output_control()
107
{
108
	global $context;
109
110
	$output_control = '
111
		<xsl:output';
112
113
	foreach ($context['xslt_settings']['output'] as $attribute => $value)
114
	{
115
		if (!in_array($attribute, array('method', 'version', 'encoding', 'omit-xml-declaration', 'standalone', 'doctype-public', 'doctype-system', 'cdata-section-elements', 'indent', 'media-type')))
116
			continue;
117
118
		elseif (is_bool($value))
119
			$output_control .= ' ' . $attribute . '="' . (empty($value) ? 'no' : 'yes') . '"';
120
121
		elseif (!empty($value))
122
			$output_control .= ' ' . $attribute . '="' . trim(implode(' ', (array) $value)) . '"';
123
	}
124
125
	if (empty($context['xslt_settings']['output']['encoding']))
126
		$output_control .= ' encoding="' . $context['character_set'] . '"';
127
128
	$output_control .= '/>';
129
130
	return $output_control;
131
}
132
133
/**
134
 * Returns white space control elements (<xsl:strip-space>/<xsl:preserve-space>)
135
 * based on the settings defined in $context['xslt_settings']['whitespace'].
136
 */
137
function xslt_generic_whitespace_control()
138
{
139
	global $context;
140
141
	$whitespace_control = '';
142
143
	foreach ($context['xslt_settings']['whitespace'] as $strip_preserve => $elements)
144
	{
145
		if (!in_array($strip_preserve, array('strip', 'preserve')) || empty($elements))
146
			continue;
147
148
		$whitespace_control .= '
149
		<xsl:' . $strip_preserve . '-space elements="' . ($elements === true ? '*' : trim(implode(' ', (array) $elements))) . '"/>';
150
	}
151
152
	return $whitespace_control;
153
}
154
155
/**
156
 * Returns global variable and/or param elements (<xsl:variable>/<xsl:param>)
157
 * based on the values defined in $context['xslt_settings']['variables'].
158
 */
159
function xslt_generic_global_variables()
160
{
161
	global $context;
162
163
	$variables = '';
164
165
	foreach ($context['xslt_settings']['variables'] as $name => $var)
166
	{
167
		$element = !empty($var['param']) ? 'param' : 'variable';
168
169
		$variables .= '
170
		<xsl:' . $element . ' name="' . $name . '"';
171
172
		if (isset($var['xpath']))
173
			$variables .= ' select="' . $var['value'] . '"/>';
174
		else
175
			$variables .= '>' . (!empty($var['no_cdata_parse']) ? $var['value'] : cdata_parse($var['value'])) . '</xsl:' . $element . '>';
176
	}
177
178
	return $variables;
179
}
180
181
/**
182
 * Assembles and returns the content of $context['xslt_settings']['custom'].
183
 */
184
function xslt_generic_custom()
185
{
186
	global $context;
187
188
	$custom = '';
189
190
	if (!empty($context['xslt_settings']['custom']))
191
		$custom .= "\n\t\t" . implode("\n\t\t", (array) $context['xslt_settings']['custom']);
192
193
	return $custom;
194
}
195
196
/**
197
 * The root template for a profile export. Creates the shell of the HTML document.
198
 */
199
function xslt_export_html_root()
200
{
201
	return '
202
		<xsl:template match="/*">
203
			<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE html&gt;</xsl:text>
204
			<html>
205
				<head>
206
					<title>
207
						<xsl:value-of select="@title"/>
208
					</title>
209
					<xsl:call-template name="css_js"/>
210
				</head>
211
				<body>
212
					<div id="footerfix">
213
						<div id="header">
214
							<h1 class="forumtitle">
215
								<a id="top">
216
									<xsl:attribute name="href">
217
										<xsl:value-of select="$scripturl"/>
218
									</xsl:attribute>
219
									<xsl:value-of select="@forum-name"/>
220
								</a>
221
							</h1>
222
						</div>
223
						<div id="wrapper">
224
							<div id="upper_section">
225
								<div id="inner_section">
226
									<div id="inner_wrap">
227
										<div class="user">
228
											<time>
229
												<xsl:attribute name="datetime">
230
													<xsl:value-of select="@generated-date-UTC"/>
231
												</xsl:attribute>
232
												<xsl:value-of select="@generated-date-localized"/>
233
											</time>
234
										</div>
235
										<hr class="clear"/>
236
									</div>
237
								</div>
238
							</div>
239
240
							<xsl:call-template name="content_section"/>
241
242
						</div>
243
					</div>
244
					<div id="footer">
245
						<div class="inner_wrap">
246
							<ul>
247
								<li class="floatright">
248
									<a>
249
										<xsl:attribute name="href">
250
											<xsl:value-of select="concat($scripturl, \'?action=help\')"/>
251
										</xsl:attribute>
252
										<xsl:value-of select="$txt_help"/>
253
									</a>
254
									<xsl:text> | </xsl:text>
255
									<a>
256
										<xsl:attribute name="href">
257
											<xsl:value-of select="concat($scripturl, \'?action=help;sa=rules\')"/>
258
										</xsl:attribute>
259
										<xsl:value-of select="$txt_terms_rules"/>
260
									</a>
261
									<xsl:text> | </xsl:text>
262
									<a href="#top">
263
										<xsl:value-of select="$txt_go_up"/>
264
										<xsl:text> &#9650;</xsl:text>
265
									</a>
266
								</li>
267
								<li class="copyright">
268
									<xsl:value-of select="$forum_copyright" disable-output-escaping="yes"/>
269
								</li>
270
							</ul>
271
						</div>
272
					</div>
273
				</body>
274
			</html>
275
		</xsl:template>';
276
}
277
278
/**
279
 * Template to show the unique content of the export file.
280
 */
281
function xslt_export_html_content_section()
282
{
283
	return '
284
		<xsl:template name="content_section">
285
			<div id="content_section">
286
				<div id="main_content_section">
287
288
					<div class="cat_bar">
289
						<h3 class="catbg">
290
							<xsl:value-of select="@title"/>
291
						</h3>
292
					</div>
293
					<div class="information">
294
						<h2 class="display_title">
295
							<xsl:value-of select="@description"/>
296
						</h2>
297
					</div>
298
299
					<xsl:if test="username">
300
						<div class="cat_bar">
301
							<h3 class="catbg">
302
								<xsl:value-of select="$txt_summary_heading"/>
303
							</h3>
304
						</div>
305
						<div id="profileview" class="roundframe flow_auto noup">
306
							<xsl:call-template name="summary"/>
307
						</div>
308
					</xsl:if>
309
310
					<xsl:call-template name="page_index"/>
311
312
					<xsl:if test="member_post">
313
						<div class="cat_bar">
314
							<h3 class="catbg">
315
								<xsl:value-of select="$txt_posts_heading"/>
316
							</h3>
317
						</div>
318
						<div id="posts" class="roundframe flow_auto noup">
319
							<xsl:apply-templates select="member_post" mode="posts"/>
320
						</div>
321
					</xsl:if>
322
323
					<xsl:if test="personal_message">
324
						<div class="cat_bar">
325
							<h3 class="catbg">
326
								<xsl:value-of select="$txt_personal_messages_heading"/>
327
							</h3>
328
						</div>
329
						<div id="personal_messages" class="roundframe flow_auto noup">
330
							<xsl:apply-templates select="personal_message" mode="pms"/>
331
						</div>
332
					</xsl:if>
333
334
					<xsl:call-template name="page_index"/>
335
336
				</div>
337
			</div>
338
		</xsl:template>';
339
}
340
341
/**
342
 * Template for user profile summary in an export file.
343
 */
344
function xslt_export_html_summary()
345
{
346
	return '
347
		<xsl:template name="summary">
348
			<div id="basicinfo">
349
				<div class="username clear">
350
					<h4>
351
						<a>
352
							<xsl:attribute name="href">
353
								<xsl:value-of select="link"/>
354
							</xsl:attribute>
355
							<xsl:value-of select="name"/>
356
						</a>
357
						<xsl:text> </xsl:text>
358
						<span class="position">
359
							<xsl:choose>
360
								<xsl:when test="position">
361
									<xsl:value-of select="position"/>
362
								</xsl:when>
363
								<xsl:otherwise>
364
									<xsl:value-of select="post_group"/>
365
								</xsl:otherwise>
366
							</xsl:choose>
367
						</span>
368
					</h4>
369
				</div>
370
				<img class="avatar">
371
					<xsl:attribute name="src">
372
						<xsl:value-of select="avatar"/>
373
					</xsl:attribute>
374
				</img>
375
			</div>
376
377
			<div id="detailedinfo">
378
				<dl class="settings noborder">
379
					<xsl:apply-templates mode="detailedinfo"/>
380
				</dl>
381
			</div>
382
		</xsl:template>';
383
}
384
385
/**
386
 * Default helper template for listing details inside the profile summary.
387
 */
388
function xslt_export_html_detail_default()
389
{
390
	return '
391
		<xsl:template match="*" mode="detailedinfo">
392
			<xsl:apply-templates select="@label" mode="detailedinfo"/>
393
			<dd>
394
				<xsl:value-of select="." disable-output-escaping="yes"/>
395
			</dd>
396
		</xsl:template>';
397
}
398
399
/**
400
 * Helper template to skip things that shouldn't be included in the profile summary.
401
 */
402
function xslt_export_html_detail_not_included()
403
{
404
	return '
405
		<xsl:template match="name|link|avatar|online|member_post|personal_message" mode="detailedinfo"/>';
406
}
407
408
/**
409
 * Helper template to show the label for a given profile detail.
410
 */
411
function xslt_export_html_detail_label()
412
{
413
	return '
414
		<xsl:template match="@label" mode="detailedinfo">
415
			<dt>
416
				<xsl:value-of select="." disable-output-escaping="yes"/>
417
				<xsl:text>:</xsl:text>
418
			</dt>
419
		</xsl:template>';
420
}
421
422
/**
423
 * Helper template for listing an email address inside the profile summary.
424
 */
425
function xslt_export_html_detail_email()
426
{
427
	return '
428
		<xsl:template match="email" mode="detailedinfo">
429
			<xsl:apply-templates select="@label" mode="detailedinfo"/>
430
			<dd>
431
				<a>
432
					<xsl:attribute name="href">
433
						<xsl:text>mailto:</xsl:text>
434
						<xsl:value-of select="."/>
435
					</xsl:attribute>
436
					<xsl:value-of select="."/>
437
				</a>
438
			</dd>
439
		</xsl:template>';
440
}
441
442
/**
443
 * Helper template for listing a website inside the profile summary.
444
 */
445
function xslt_export_html_detail_website()
446
{
447
	return '
448
		<xsl:template match="website" mode="detailedinfo">
449
			<xsl:apply-templates select="@label" mode="detailedinfo"/>
450
			<dd>
451
				<a>
452
					<xsl:attribute name="href">
453
						<xsl:value-of select="link"/>
454
					</xsl:attribute>
455
					<xsl:value-of select="title"/>
456
				</a>
457
			</dd>
458
		</xsl:template>';
459
}
460
461
/**
462
 * Helper template for listing IP addresses inside the profile summary.
463
 */
464
function xslt_export_html_detail_ip()
465
{
466
	return '
467
		<xsl:template match="ip_addresses" mode="detailedinfo">
468
			<xsl:apply-templates select="@label" mode="detailedinfo"/>
469
			<dd>
470
				<ul class="nolist">
471
					<xsl:apply-templates mode="ip_address"/>
472
				</ul>
473
			</dd>
474
		</xsl:template>
475
		<xsl:template match="*" mode="ip_address">
476
			<li>
477
				<xsl:value-of select="."/>
478
				<xsl:if test="@label and following-sibling">
479
					<xsl:text> </xsl:text>
480
					<span>(<xsl:value-of select="@label"/>)</span>
481
				</xsl:if>
482
			</li>
483
		</xsl:template>';
484
}
485
486
/**
487
 * Template for displaying a single post in an export file.
488
 */
489
function xslt_export_html_member_post()
490
{
491
	return '
492
		<xsl:template match="member_post" mode="posts">
493
			<div>
494
				<xsl:attribute name="id">
495
					<xsl:value-of select="concat(\'member_post_\', id)"/>
496
				</xsl:attribute>
497
				<xsl:attribute name="class">
498
					<xsl:choose>
499
						<xsl:when test="approval_status = 1">
500
							<xsl:text>windowbg</xsl:text>
501
						</xsl:when>
502
						<xsl:otherwise>
503
							<xsl:text>approvebg</xsl:text>
504
						</xsl:otherwise>
505
					</xsl:choose>
506
				</xsl:attribute>
507
508
				<div class="post_wrapper">
509
					<div class="poster">
510
						<h4>
511
							<a>
512
								<xsl:attribute name="href">
513
									<xsl:value-of select="poster/link"/>
514
								</xsl:attribute>
515
								<xsl:value-of select="poster/name"/>
516
							</a>
517
						</h4>
518
						<ul class="user_info">
519
							<xsl:if test="poster/id = $member_id">
520
								<xsl:call-template name="own_user_info"/>
521
							</xsl:if>
522
							<li>
523
								<xsl:value-of select="poster/email"/>
524
							</li>
525
							<li class="poster_ip">
526
								<xsl:value-of select="concat(poster/ip/@label, \': \')"/>
527
								<xsl:value-of select="poster/ip"/>
528
							</li>
529
						</ul>
530
					</div>
531
532
					<div class="postarea">
533
						<div class="flow_hidden">
534
535
							<div class="keyinfo">
536
								<h5>
537
									<strong>
538
										<a>
539
											<xsl:attribute name="href">
540
												<xsl:value-of select="board/link"/>
541
											</xsl:attribute>
542
											<xsl:value-of select="board/name"/>
543
										</a>
544
										<xsl:text> / </xsl:text>
545
										<a>
546
											<xsl:attribute name="href">
547
												<xsl:value-of select="link"/>
548
											</xsl:attribute>
549
											<xsl:value-of select="subject"/>
550
										</a>
551
									</strong>
552
									<span class="page_number floatright">
553
										<a>
554
											<xsl:attribute name="href">
555
												<xsl:value-of select="link"/>
556
											</xsl:attribute>
557
											<xsl:value-of select="concat($txt_id, \': \', id)"/>
558
										</a>
559
									</span>
560
								</h5>
561
								<span class="smalltext"><xsl:value-of select="time"/></span>
562
								<xsl:if test="modified_time">
563
									<span class="smalltext modified floatright mvisible em">
564
										<xsl:attribute name="id">
565
											<xsl:value-of select="concat(\'modified_\', id)"/>
566
										</xsl:attribute>
567
										<span class="lastedit">
568
											<xsl:value-of select="modified_time/@label"/>
569
										</span>
570
										<xsl:text>: </xsl:text>
571
										<xsl:value-of select="modified_time"/>
572
										<xsl:text>. </xsl:text>
573
										<xsl:value-of select="modified_by/@label"/>
574
										<xsl:text>: </xsl:text>
575
										<xsl:value-of select="modified_by"/>
576
										<xsl:text>. </xsl:text>
577
									</span>
578
								</xsl:if>
579
							</div>
580
581
							<div class="post">
582
								<div class="inner">
583
									<xsl:value-of select="body_html" disable-output-escaping="yes"/>
584
								</div>
585
								<div class="inner monospace" style="display:none;">
586
									<xsl:choose>
587
										<xsl:when test="contains(body/text(), \'[html]\')">
588
											<xsl:call-template name="bbc_html_splitter">
589
												<xsl:with-param name="bbc_string" select="body/text()"/>
590
											</xsl:call-template>
591
										</xsl:when>
592
										<xsl:otherwise>
593
											<xsl:value-of select="body" disable-output-escaping="yes"/>
594
										</xsl:otherwise>
595
									</xsl:choose>
596
								</div>
597
							</div>
598
599
							<xsl:apply-templates select="attachments">
600
								<xsl:with-param name="post_id" select="id"/>
601
							</xsl:apply-templates>
602
603
							<div class="under_message">
604
								<ul class="floatleft">
605
									<xsl:if test="likes > 0">
606
										<li class="smflikebutton">
607
											<xsl:attribute name="id">
608
												<xsl:value-of select="concat(\'msg_\', id, \'_likes\')"/>
609
											</xsl:attribute>
610
											<span><span class="main_icons like"></span> <xsl:value-of select="likes"/></span>
611
										</li>
612
									</xsl:if>
613
								</ul>
614
								<xsl:call-template name="quickbuttons">
615
									<xsl:with-param name="toggle_target" select="concat(\'member_post_\', id)"/>
616
								</xsl:call-template>
617
							</div>
618
619
						</div>
620
					</div>
621
622
					<div class="moderatorbar">
623
						<xsl:if test="poster/id = $member_id">
624
							<xsl:call-template name="signature"/>
625
						</xsl:if>
626
					</div>
627
628
				</div>
629
			</div>
630
		</xsl:template>';
631
}
632
633
/**
634
 * Template for displaying a single PM in an export file.
635
 */
636
function xslt_export_html_personal_message()
637
{
638
	return '
639
		<xsl:template match="personal_message" mode="pms">
640
			<div class="windowbg">
641
				<xsl:attribute name="id">
642
					<xsl:value-of select="concat(\'personal_message_\', id)"/>
643
				</xsl:attribute>
644
645
				<div class="post_wrapper">
646
					<div class="poster">
647
						<h4>
648
							<a>
649
								<xsl:attribute name="href">
650
									<xsl:value-of select="sender/link"/>
651
								</xsl:attribute>
652
								<xsl:value-of select="sender/name"/>
653
							</a>
654
						</h4>
655
						<ul class="user_info">
656
							<xsl:if test="sender/id = $member_id">
657
								<xsl:call-template name="own_user_info"/>
658
							</xsl:if>
659
						</ul>
660
					</div>
661
662
					<div class="postarea">
663
						<div class="flow_hidden">
664
665
							<div class="keyinfo">
666
								<h5>
667
									<xsl:attribute name="id">
668
										<xsl:value-of select="concat(\'subject_\', id)"/>
669
									</xsl:attribute>
670
									<xsl:value-of select="subject"/>
671
									<span class="page_number floatright">
672
										<a>
673
											<xsl:attribute name="href">
674
												<xsl:value-of select="link"/>
675
											</xsl:attribute>
676
											<xsl:value-of select="concat($txt_id, \': \', id)"/>
677
										</a>
678
									</span>
679
								</h5>
680
								<span class="smalltext">
681
									<strong>
682
										<xsl:value-of select="concat(recipient[1]/@label, \': \')"/>
683
									</strong>
684
									<xsl:apply-templates select="recipient"/>
685
								</span>
686
								<br/>
687
								<span class="smalltext">
688
									<strong>
689
										<xsl:value-of select="concat(sent_date/@label, \': \')"/>
690
									</strong>
691
									<time>
692
										<xsl:attribute name="datetime">
693
											<xsl:value-of select="sent_date/@UTC"/>
694
										</xsl:attribute>
695
										<xsl:value-of select="normalize-space(sent_date)"/>
696
									</time>
697
								</span>
698
							</div>
699
700
							<div class="post">
701
								<div class="inner">
702
									<xsl:value-of select="body_html" disable-output-escaping="yes"/>
703
								</div>
704
								<div class="inner monospace" style="display:none;">
705
									<xsl:call-template name="bbc_html_splitter">
706
										<xsl:with-param name="bbc_string" select="body/text()"/>
707
									</xsl:call-template>
708
								</div>
709
							</div>
710
711
							<div class="under_message">
712
								<xsl:call-template name="quickbuttons">
713
									<xsl:with-param name="toggle_target" select="concat(\'personal_message_\', id)"/>
714
								</xsl:call-template>
715
							</div>
716
717
						</div>
718
					</div>
719
720
					<div class="moderatorbar">
721
						<xsl:if test="sender/id = $member_id">
722
							<xsl:call-template name="signature"/>
723
						</xsl:if>
724
					</div>
725
726
				</div>
727
			</div>
728
		</xsl:template>';
729
}
730
731
/**
732
 * A couple of templates to handle attachments in an export file.
733
 */
734
function xslt_export_html_attachments()
735
{
736
	return '
737
		<xsl:template match="attachments">
738
			<xsl:param name="post_id"/>
739
			<xsl:if test="attachment">
740
				<div class="attachments">
741
					<xsl:attribute name="id">
742
						<xsl:value-of select="concat(\'msg_\', $post_id, \'_footer\')"/>
743
					</xsl:attribute>
744
					<xsl:apply-templates/>
745
				</div>
746
			</xsl:if>
747
		</xsl:template>
748
		<xsl:template match="attachment">
749
			<div class="attached">
750
				<div class="attachments_bot">
751
					<a>
752
						<xsl:attribute name="href">
753
							<xsl:value-of select="concat(id, \' - \', name)"/>
754
						</xsl:attribute>
755
						<img class="centericon" alt="*">
756
							<xsl:attribute name="src">
757
								<xsl:value-of select="concat($themeurl, \'/images/icons/clip.png\')"/>
758
							</xsl:attribute>
759
						</img>
760
						<xsl:text> </xsl:text>
761
						<xsl:value-of select="name"/>
762
					</a>
763
					<br/>
764
					<xsl:text>(</xsl:text>
765
					<a class="bbc_link">
766
						<xsl:attribute name="href">
767
							<xsl:value-of select="concat($scripturl, \'?action=profile;area=dlattach;u=\', $member_id, \';attach=\', id, \';t=\', $dltoken)"/>
768
						</xsl:attribute>
769
						<xsl:value-of select="$txt_download_original"/>
770
					</a>
771
					<xsl:text>)</xsl:text>
772
					<br/>
773
					<xsl:value-of select="size/@label"/>
774
					<xsl:text>: </xsl:text>
775
					<xsl:value-of select="size"/>
776
					<br/>
777
					<xsl:value-of select="downloads/@label"/>
778
					<xsl:text>: </xsl:text>
779
					<xsl:value-of select="downloads"/>
780
				</div>
781
			</div>
782
		</xsl:template>';
783
}
784
785
/**
786
 * Helper template for printing the user's own info next to the post or personal message.
787
 */
788
function xslt_export_html_own_user_info()
789
{
790
	return '
791
		<xsl:template name="own_user_info">
792
			<xsl:if test="/*/avatar">
793
				<li class="avatar">
794
					<a>
795
						<xsl:attribute name="href">
796
							<xsl:value-of select="/*/link"/>
797
						</xsl:attribute>
798
						<img class="avatar">
799
							<xsl:attribute name="src">
800
								<xsl:value-of select="/*/avatar"/>
801
							</xsl:attribute>
802
						</img>
803
					</a>
804
				</li>
805
			</xsl:if>
806
			<li class="membergroup">
807
				<xsl:value-of select="/*/position"/>
808
			</li>
809
			<xsl:if test="/*/title">
810
				<li class="title">
811
					<xsl:value-of select="/*/title"/>
812
				</li>
813
			</xsl:if>
814
			<li class="postgroup">
815
				<xsl:value-of select="/*/post_group"/>
816
			</li>
817
			<li class="postcount">
818
				<xsl:value-of select="concat(/*/posts/@label, \': \')"/>
819
				<xsl:value-of select="/*/posts"/>
820
			</li>
821
			<xsl:if test="/*/blurb">
822
				<li class="blurb">
823
					<xsl:value-of select="/*/blurb"/>
824
				</li>
825
			</xsl:if>
826
		</xsl:template>';
827
}
828
829
/**
830
 * Helper template for printing the quickbuttons used in the export file
831
 */
832
function xslt_export_html_quickbuttons()
833
{
834
	return '
835
		<xsl:template name="quickbuttons">
836
			<xsl:param name="toggle_target"/>
837
			<ul class="quickbuttons quickbuttons_post sf-js-enabled sf-arrows" style="touch-action: pan-y;">
838
				<li>
839
					<a>
840
						<xsl:attribute name="onclick">
841
							<xsl:text>$(\'#</xsl:text>
842
							<xsl:value-of select="$toggle_target"/>
843
							<xsl:text> .inner\').toggle();</xsl:text>
844
						</xsl:attribute>
845
						<xsl:value-of select="$txt_view_source_button"/>
846
					</a>
847
				</li>
848
			</ul>
849
		</xsl:template>';
850
}
851
852
/**
853
 * Helper template for printing a signature
854
 */
855
function xslt_export_html_signature()
856
{
857
	return '
858
		<xsl:template name="signature">
859
			<xsl:if test="/*/signature">
860
				<div class="signature">
861
					<xsl:value-of select="/*/signature" disable-output-escaping="yes"/>
862
				</div>
863
			</xsl:if>
864
		</xsl:template>';
865
}
866
867
/**
868
 * Helper template for printing a list of PM recipients
869
 */
870
function xslt_export_html_recipient()
871
{
872
	return '
873
		<xsl:template match="recipient">
874
			<a>
875
				<xsl:attribute name="href">
876
					<xsl:value-of select="link"/>
877
				</xsl:attribute>
878
				<xsl:value-of select="name"/>
879
			</a>
880
			<xsl:choose>
881
				<xsl:when test="following-sibling::recipient">
882
					<xsl:text>, </xsl:text>
883
				</xsl:when>
884
				<xsl:otherwise>
885
					<xsl:text>. </xsl:text>
886
				</xsl:otherwise>
887
			</xsl:choose>
888
		</xsl:template>';
889
}
890
891
/**
892
 * Helper template for special handling of the contents of the [html] BBCode
893
 */
894
function xslt_export_html_bbc_html_splitter()
895
{
896
	return '
897
		<xsl:template name="bbc_html_splitter">
898
			<xsl:param name="bbc_string"/>
899
			<xsl:param name="inside_outside" select="outside"/>
900
			<xsl:choose>
901
				<xsl:when test="$inside_outside = \'outside\'">
902
					<xsl:choose>
903
						<xsl:when test="contains($bbc_string, \'[html]\')">
904
							<xsl:variable name="following_string">
905
								<xsl:value-of select="substring-after($bbc_string, \'[html]\')" disable-output-escaping="yes"/>
906
							</xsl:variable>
907
							<xsl:value-of select="substring-before($bbc_string, \'[html]\')" disable-output-escaping="yes"/>
908
							<xsl:text>[html]</xsl:text>
909
							<xsl:call-template name="bbc_html_splitter">
910
								<xsl:with-param name="bbc_string" select="$following_string"/>
911
								<xsl:with-param name="inside_outside" select="inside"/>
912
							</xsl:call-template>
913
						</xsl:when>
914
						<xsl:otherwise>
915
							<xsl:value-of select="$bbc_string" disable-output-escaping="yes"/>
916
						</xsl:otherwise>
917
					</xsl:choose>
918
				</xsl:when>
919
				<xsl:otherwise>
920
					<xsl:choose>
921
						<xsl:when test="contains($bbc_string, \'[/html]\')">
922
							<xsl:variable name="following_string">
923
								<xsl:value-of select="substring-after($bbc_string, \'[/html]\')" disable-output-escaping="yes"/>
924
							</xsl:variable>
925
							<xsl:value-of select="substring-before($bbc_string, \'[/html]\')" disable-output-escaping="no"/>
926
							<xsl:text>[/html]</xsl:text>
927
							<xsl:call-template name="bbc_html_splitter">
928
								<xsl:with-param name="bbc_string" select="$following_string"/>
929
								<xsl:with-param name="inside_outside" select="outside"/>
930
							</xsl:call-template>
931
						</xsl:when>
932
						<xsl:otherwise>
933
							<xsl:value-of select="$bbc_string" disable-output-escaping="no"/>
934
						</xsl:otherwise>
935
					</xsl:choose>
936
				</xsl:otherwise>
937
			</xsl:choose>
938
		</xsl:template>';
939
}
940
941
/**
942
 * Helper templates to build a page index in the export file
943
 */
944
function xslt_export_html_page_index()
945
{
946
	return '
947
		<xsl:template name="page_index">
948
			<xsl:variable name="current_page" select="/*/@page"/>
949
			<xsl:variable name="prev_page" select="/*/@page - 1"/>
950
			<xsl:variable name="next_page" select="/*/@page + 1"/>
951
952
			<div class="pagesection">
953
				<div class="pagelinks floatleft">
954
955
					<span class="pages">
956
						<xsl:value-of select="$txt_pages"/>
957
					</span>
958
959
					<xsl:if test="$current_page &gt; 1">
960
						<a class="nav_page">
961
							<xsl:attribute name="href">
962
								<xsl:value-of select="concat($dlfilename, \'_\', $prev_page, \'.\', $ext)"/>
963
							</xsl:attribute>
964
							<span class="main_icons previous_page"></span>
965
						</a>
966
					</xsl:if>
967
968
					<xsl:call-template name="page_links"/>
969
970
					<xsl:if test="$current_page &lt; $last_page">
971
						<a class="nav_page">
972
							<xsl:attribute name="href">
973
								<xsl:value-of select="concat($dlfilename, \'_\', $next_page, \'.\', $ext)"/>
974
							</xsl:attribute>
975
							<span class="main_icons next_page"></span>
976
						</a>
977
					</xsl:if>
978
				</div>
979
			</div>
980
		</xsl:template>
981
982
		<xsl:template name="page_links">
983
			<xsl:param name="page_num" select="1"/>
984
			<xsl:variable name="current_page" select="/*/@page"/>
985
			<xsl:variable name="prev_page" select="/*/@page - 1"/>
986
			<xsl:variable name="next_page" select="/*/@page + 1"/>
987
988
			<xsl:choose>
989
				<xsl:when test="$page_num = $current_page">
990
					<span class="current_page">
991
						<xsl:value-of select="$page_num"/>
992
					</span>
993
				</xsl:when>
994
				<xsl:when test="$page_num = 1 or $page_num = ($current_page - 1) or $page_num = ($current_page + 1) or $page_num = $last_page">
995
					<a class="nav_page">
996
						<xsl:attribute name="href">
997
							<xsl:value-of select="concat($dlfilename, \'_\', $page_num, \'.\', $ext)"/>
998
						</xsl:attribute>
999
						<xsl:value-of select="$page_num"/>
1000
					</a>
1001
				</xsl:when>
1002
				<xsl:when test="$page_num = 2 or $page_num = ($current_page + 2)">
1003
					<span class="expand_pages" onclick="$(\'.nav_page\').removeClass(\'hidden\'); $(\'.expand_pages\').hide();"> ... </span>
1004
					<a class="nav_page hidden">
1005
						<xsl:attribute name="href">
1006
							<xsl:value-of select="concat($dlfilename, \'_\', $page_num, \'.\', $ext)"/>
1007
						</xsl:attribute>
1008
						<xsl:value-of select="$page_num"/>
1009
					</a>
1010
				</xsl:when>
1011
				<xsl:otherwise>
1012
					<a class="nav_page hidden">
1013
						<xsl:attribute name="href">
1014
							<xsl:value-of select="concat($dlfilename, \'_\', $page_num, \'.\', $ext)"/>
1015
						</xsl:attribute>
1016
						<xsl:value-of select="$page_num"/>
1017
					</a>
1018
				</xsl:otherwise>
1019
			</xsl:choose>
1020
1021
			<xsl:text> </xsl:text>
1022
1023
			<xsl:if test="$page_num &lt; $last_page">
1024
				<xsl:call-template name="page_links">
1025
					<xsl:with-param name="page_num" select="$page_num + 1"/>
1026
				</xsl:call-template>
1027
			</xsl:if>
1028
		</xsl:template>';
1029
}
1030
1031
/**
1032
 * Template to insert CSS and JavaScript into an export file
1033
 */
1034
function xslt_export_html_css_js()
1035
{
1036
	global $context;
1037
1038
	$template = '
1039
		<xsl:template name="css_js">';
1040
1041
	if (!empty($context['export_css_files']))
1042
	{
1043
		foreach ($context['export_css_files'] as $css_file)
1044
		{
1045
			$template .= '
1046
			<link rel="stylesheet">
1047
					<xsl:attribute name="href">
1048
						<xsl:text>' . $css_file['fileUrl'] . '</xsl:text>
1049
					</xsl:attribute>';
1050
1051
			if (!empty($css_file['options']['attributes']))
1052
			{
1053
				foreach ($css_file['options']['attributes'] as $key => $value)
1054
					$template .= '
1055
					<xsl:attribute name="' . $key . '">
1056
						<xsl:text>' . (is_bool($value) ? $key : $value) . '</xsl:text>
1057
					</xsl:attribute>';
1058
			}
1059
1060
			$template .= '
1061
				</link>';
1062
		}
1063
	}
1064
1065
	if (!empty($context['export_css_header']))
1066
	{
1067
		$template .=  '
1068
			<style><![CDATA[' . "\n" . implode("\n", $context['export_css_header']) . "\n" . ']]>
1069
			</style>';
1070
	}
1071
1072
	if (!empty($context['export_javascript_vars']))
1073
	{
1074
		$template .=  '
1075
			<script><![CDATA[';
1076
1077
		foreach ($context['export_javascript_vars'] as $var => $val)
1078
			$template .= "\nvar " . $var . (!empty($val) ? ' = ' . $val : '') . ';';
1079
1080
		$template .= "\n" . ']]>
1081
			</script>';
1082
	}
1083
1084
	if (!empty($context['export_javascript_files']))
1085
	{
1086
		foreach ($context['export_javascript_files'] as $js_file)
1087
		{
1088
			$template .= '
1089
				<script>
1090
					<xsl:attribute name="src">
1091
						<xsl:text>' . $js_file['fileUrl'] . '</xsl:text>
1092
					</xsl:attribute>';
1093
1094
			if (!empty($js_file['options']['attributes']))
1095
			{
1096
				foreach ($js_file['options']['attributes'] as $key => $value)
1097
					$template .= '
1098
					<xsl:attribute name="' . $key . '">
1099
						<xsl:text>' . (is_bool($value) ? $key : $value) . '</xsl:text>
1100
					</xsl:attribute>';
1101
			}
1102
1103
			$template .= '
1104
				</script>';
1105
		}
1106
	}
1107
1108
	if (!empty($context['export_javascript_inline']['standard']))
1109
	{
1110
		$template .=  '
1111
			<script><![CDATA[' . "\n" . implode("\n", $context['export_javascript_inline']['standard']) . "\n" . ']]>
1112
			</script>';
1113
	}
1114
1115
	if (!empty($context['export_javascript_inline']['defer']))
1116
	{
1117
		$template .= '
1118
			<script><![CDATA[' . "\n" . 'window.addEventListener("DOMContentLoaded", function() {';
1119
1120
		$template .= "\n\t" . str_replace("\n", "\n\t", implode("\n", $context['export_javascript_inline']['defer']));
1121
1122
		$template .= "\n" . '});'. "\n" . ']]>
1123
			</script>';
1124
	}
1125
1126
	$template .= '
1127
		</xsl:template>';
1128
1129
	return $template;
1130
}
1131
1132
?>