Completed
Push — patch_1-1-4 ( 3f780f...826343 )
by Emanuele
25:17 queued 11:40
created

Xml.template.php ➔ template_generic_xml_recursive()   B

Complexity

Conditions 8
Paths 5

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 5
nop 4
dl 0
loc 27
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @name      ElkArte Forum
5
 * @copyright ElkArte Forum contributors
6
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
7
 *
8
 * This file contains code covered by:
9
 * copyright:	2011 Simple Machines (http://www.simplemachines.org)
10
 * license:  	BSD, See included LICENSE.TXT for terms and conditions.
11
 *
12
 * @version 1.1
13
 *
14
 */
15
16
/**
17
 * @deprecated since 1.0
18
 */
19
function template_sendbody()
20
{
21
	global $context;
22
23
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
24
<elk>
25
	<message view="', $context['view'], '">', cleanXml($context['message']), '</message>
26
</elk>';
27
}
28
29
/**
30
 * Returns the text of a post in response to a quote request for loading into the current editing text box
31
 */
32
function template_quotefast()
33
{
34
	global $context;
35
36
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
37
<elk>
38
	<quote>', cleanXml($context['quote']['xml']), '</quote>
39
</elk>';
40
}
41
42
/**
43
 * Returns a message text and subject for use in the quick modify screen
44
 */
45
function template_modifyfast()
46
{
47
	global $context;
48
49
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
50
<elk>
51
	<subject><![CDATA[', cleanXml($context['message']['subject']), ']]></subject>
52
	<message id="msg_', $context['message']['id'], '"><![CDATA[', cleanXml($context['message']['body']), ']]></message>
53
</elk>';
54
}
55
56
/**
57
 * Returns updated message details so the topic display can be updated after a quick edit is completed
58
 */
59
function template_modifydone()
60
{
61
	global $context, $txt;
62
63
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
64
<elk>
65
	<message id="msg_', $context['message']['id'], '">';
66
	if (empty($context['message']['errors']))
67
	{
68
		echo '
69
		<modified><![CDATA[', empty($context['message']['modified']['time']) ? '' : cleanXml(sprintf($txt['last_edit_by'], $context['message']['modified']['time'], $context['message']['modified']['name'])), ']]></modified>
70
		<subject is_first="', $context['message']['first_in_topic'] ? '1' : '0', '"><![CDATA[', cleanXml($context['message']['subject']), ']]></subject>
71
		<body><![CDATA[', $context['message']['body'], ']]></body>';
72
	}
73
	else
74
		echo '
75
		<error in_subject="', $context['message']['error_in_subject'] ? '1' : '0', '" in_body="', cleanXml($context['message']['error_in_body']) ? '1' : '0', '"><![CDATA[', implode('<br />', $context['message']['errors']), ']]></error>';
76
77
	echo '
78
	</message>
79
</elk>';
80
}
81
82
/**
83
 * When done modifying a topic title, updates the board listing
84
 */
85
function template_modifytopicdone()
86
{
87
	global $context, $txt;
88
89
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
90
<elk>
91
	<message id="msg_', $context['message']['id'], '">';
92
	if (empty($context['message']['errors']))
93
	{
94
		echo '
95
		<modified><![CDATA[', empty($context['message']['modified']['time']) ? '' : cleanXml('&#171; <em>' . sprintf($txt['last_edit_by'], $context['message']['modified']['time'], $context['message']['modified']['name']) . '</em> &#187;'), ']]></modified>';
96
		if (!empty($context['message']['subject']))
97
			echo '
98
		<subject><![CDATA[', cleanXml($context['message']['subject']), ']]></subject>';
99
	}
100
	else
101
		echo '
102
		<error in_subject="', $context['message']['error_in_subject'] ? '1' : '0', '"><![CDATA[', cleanXml(implode('<br />', $context['message']['errors'])), ']]></error>';
103
	echo '
104
	</message>
105
</elk>';
106
}
107
108
/**
109
 * Used to return a post preview
110
 */
111
function template_post()
112
{
113
	global $context;
114
115
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
116
<elk>
117
	<preview>
118
		<subject><![CDATA[', $context['preview_subject'], ']]></subject>
119
		<body><![CDATA[', $context['preview_message'], ']]></body>
120
	</preview>
121
	<errors serious="', empty($context['errors']['type']) || $context['errors']['type'] != 'serious' ? '0' : '1', '" topic_locked="', $context['locked'] ? '1' : '0', '">';
122
123 View Code Duplication
	if (!empty($context['post_error']['errors']))
124
		foreach ($context['post_error']['errors'] as $key => $message)
125
			echo '
126
		<error code="', cleanXml($key), '"><![CDATA[', cleanXml($message), ']]></error>';
127
128
	echo '
129
		<caption name="guestname" class="', isset($context['post_error']['long_name']) || isset($context['post_error']['no_name']) || isset($context['post_error']['bad_name']) ? 'error' : '', '" />
130
		<caption name="email" class="', isset($context['post_error']['no_email']) || isset($context['post_error']['bad_email']) ? 'error' : '', '" />
131
		<caption name="evtitle" class="', isset($context['post_error']['no_event']) ? 'error' : '', '" />
132
		<caption name="subject" class="', isset($context['post_error']['no_subject']) ? 'error' : '', '" />
133
		<caption name="question" class="', isset($context['post_error']['no_question']) ? 'error' : '', '" />
134
	</errors>
135
	<last_msg>', isset($context['topic_last_message']) ? $context['topic_last_message'] : '0', '</last_msg>';
136
137
	if (!empty($context['previous_posts']))
138
	{
139
		echo '
140
	<new_posts>';
141
		foreach ($context['previous_posts'] as $post)
142
			echo '
143
		<post id="', $post['id'], '">
144
			<time><![CDATA[', $post['time'], ']]></time>
145
			<poster><![CDATA[', cleanXml($post['poster']), ']]></poster>
146
			<message><![CDATA[', cleanXml($post['body']), ']]></message>
147
			<is_ignored>', $post['is_ignored'] ? '1' : '0', '</is_ignored>
148
		</post>';
149
		echo '
150
	</new_posts>';
151
	}
152
153
	echo '
154
</elk>';
155
}
156
157
/**
158
 * Returns a preview, used by personal messages, newsletters, bounce templates, etc
159
 */
160
function template_generic_preview()
161
{
162
	global $context, $txt;
163
164
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
165
<elk>
166
	<preview>
167
		<subject><![CDATA[', empty($context['preview_subject']) ? $txt['not_applicable'] : $context['preview_subject'], ']]></subject>
168
		<body><![CDATA[', $context['preview_message'], ']]></body>
169
	</preview>
170
	<errors serious="', empty($context['error_type']) || $context['error_type'] != 'serious' ? '0' : '1', '">';
171
172 View Code Duplication
	if (!empty($context['post_error']['errors']))
173
		foreach ($context['post_error']['errors'] as $key => $message)
174
			echo '
175
		<error code="', cleanXml($key), '"><![CDATA[', cleanXml($message), ']]></error>';
176
177
	// This is the not so generic section, mainly used by PM preview, can be used by others as well
178
	echo '
179
		<caption name="to" class="', isset($context['post_error']['no_to']) ? 'error' : '', '" />
180
		<caption name="bbc" class="', isset($context['post_error']['no_bbc']) ? 'error' : '', '" />
181
		<caption name="subject" class="', isset($context['post_error']['no_subject']) ? 'error' : '', '" />
182
		<caption name="question" class="', isset($context['post_error']['no_question']) ? 'error' : '', '" />',
183
	isset($context['post_error']['no_message']) || isset($context['post_error']['long_message']) ? '<post_error />' : '', '
184
	</errors>';
185
186
	echo '
187
</elk>';
188
}
189
190
/**
191
 * Returns additional statistics when a year/month is expanded
192
 */
193
function template_stats()
194
{
195
	global $context, $modSettings;
196
197
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
198
<elk>';
199
	foreach ($context['yearly'] as $year)
200
		foreach ($year['months'] as $month)
201
		{
202
			echo '
203
	<month id="', $month['date']['year'], $month['date']['month'], '">';
204
			foreach ($month['days'] as $day)
205
				echo '
206
		<day date="', $day['year'], '-', $day['month'], '-', $day['day'], '" new_topics="', $day['new_topics'], '" new_posts="', $day['new_posts'], '" new_members="', $day['new_members'], '" most_members_online="', $day['most_members_online'], '"', empty($modSettings['hitStats']) ? '' : ' hits="' . $day['hits'] . '"', ' />';
207
			echo '
208
	</month>';
209
		}
210
	echo '
211
</elk>';
212
}
213
214
/**
215
 * Breaking up is not so hard to do
216
 */
217
function template_split()
218
{
219
	global $context;
220
221
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
222
<elk>
223
	<pageIndex section="not_selected" startFrom="', $context['not_selected']['start'], '"><![CDATA[', $context['not_selected']['page_index'], ']]></pageIndex>
224
	<pageIndex section="selected" startFrom="', $context['selected']['start'], '"><![CDATA[', $context['selected']['page_index'], ']]></pageIndex>';
225
	foreach ($context['changes'] as $change)
226
	{
227
		if ($change['type'] == 'remove')
228
			echo '
229
	<change id="', $change['id'], '" curAction="remove" section="', $change['section'], '" />';
230
		else
231
			echo '
232
	<change id="', $change['id'], '" curAction="insert" section="', $change['section'], '">
233
		<subject><![CDATA[', cleanXml($change['insert_value']['subject']), ']]></subject>
234
		<time><![CDATA[', cleanXml($change['insert_value']['time']), ']]></time>
235
		<body><![CDATA[', cleanXml($change['insert_value']['body']), ']]></body>
236
		<poster><![CDATA[', cleanXml($change['insert_value']['poster']), ']]></poster>
237
	</change>';
238
	}
239
240
	echo '
241
</elk>';
242
}
243
244
/**
245
 * Return search results
246
 */
247
function template_results()
248
{
249
	global $context, $txt;
250
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
251
<elk>';
252
253
	if (empty($context['topics']))
254
		echo '
255
		<noresults>', $txt['search_no_results'], '</noresults>';
256
	else
257
	{
258
		echo '
259
		<results>';
260
261
		while ($topic = $context['get_topics']())
262
		{
263
			echo '
264
			<result>
265
				<id>', $topic['id'], '</id>
266
				<relevance>', $topic['relevance'], '</relevance>
267
				<board>
268
					<id>', $topic['board']['id'], '</id>
269
					<name>', cleanXml($topic['board']['name']), '</name>
270
					<href>', $topic['board']['href'], '</href>
271
				</board>
272
				<category>
273
					<id>', $topic['category']['id'], '</id>
274
					<name>', cleanXml($topic['category']['name']), '</name>
275
					<href>', $topic['category']['href'], '</href>
276
				</category>
277
				<messages>';
278
279
			foreach ($topic['matches'] as $message)
280
			{
281
				echo '
282
					<message>
283
						<id>', $message['id'], '</id>
284
						<subject><![CDATA[', cleanXml($message['subject_highlighted'] != '' ? $message['subject_highlighted'] : $message['subject']), ']]></subject>
285
						<body><![CDATA[', cleanXml($message['body_highlighted'] != '' ? $message['body_highlighted'] : $message['body']), ']]></body>
286
						<time>', $message['time'], '</time>
287
						<timestamp>', $message['timestamp'], '</timestamp>
288
						<start>', $message['start'], '</start>
289
290
						<author>
291
							<id>', $message['member']['id'], '</id>
292
							<name>', cleanXml($message['member']['name']), '</name>
293
							<href>', $message['member']['href'], '</href>
294
						</author>
295
					</message>';
296
			}
297
298
			echo '
299
				</messages>
300
			</result>';
301
		}
302
303
		echo '
304
		</results>';
305
	}
306
307
	echo '
308
</elk>';
309
}
310
311
/**
312
 * Build the jump to box
313
 */
314
function template_jump_to()
315
{
316
	global $context;
317
318
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
319
<elk>';
320
321
	foreach ($context['categories'] as $category)
322
	{
323
		echo '
324
	<item type="category" id="', $category['id'], '"><![CDATA[', cleanXml($category['name']), ']]></item>';
325
		foreach ($category['boards'] as $board)
326
			echo '
327
	<item type="board" id="', $board['id'], '" childlevel="', $board['child_level'], '"><![CDATA[', cleanXml($board['name']), ']]></item>';
328
	}
329
330
	echo '
331
</elk>';
332
}
333
334
/**
335
 * Loads the message icons for changing them via the quick edit
336
 */
337
function template_message_icons()
338
{
339
	global $context;
340
341
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
342
<elk>';
343
344 View Code Duplication
	foreach ($context['icons'] as $icon)
345
		echo '
346
	<icon value="', $icon['value'], '" url="', $icon['url'], '"><![CDATA[', cleanXml($icon['name']), ']]></icon>';
347
348
	echo '
349
</elk>';
350
}
351
352
/**
353
 * Returns if the username is valid or not, used during registration
354
 */
355
function template_check_username()
356
{
357
	global $context;
358
359
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
360
<elk>
361
	<username valid="', $context['valid_username'] ? 1 : 0, '">', cleanXml($context['checked_username']), '</username>
362
</elk>';
363
}
364
365
/**
366
 * @todo ... maybe emanuele can explain :D
367
 */
368
function template_generic_xml_buttons()
369
{
370
	global $context;
371
372
	$tag = empty($context['xml_data']['error']) ? 'button' : 'error';
373
374
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
375
<elk>
376
	<', $tag, '>';
377
378
	foreach ($context['xml_data'] as $key => $val)
379
	{
380
		if ($key != 'error')
381
			echo '
382
			<', $key, '><![CDATA[', cleanXml($val), ']]></', $key, '>';
383
	}
384
385
	echo '
386
	</', $tag, '>
387
</elk>';
388
}
389
390
/**
391
 * This prints XML in it's most generic form.
392
 */
393
function template_generic_xml()
394
{
395
	global $context;
396
397
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>';
398
399
	// Show the data.
400
	template_generic_xml_recursive($context['xml_data'], 'elk', '', -1);
401
}
402
403
/**
404
 * Recursive function for displaying generic XML data.
405
 *
406
 * @param array $xml_data
407
 * @param string $parent_ident
408
 * @param string $child_ident
409
 * @param int $level
410
 */
411
function template_generic_xml_recursive($xml_data, $parent_ident, $child_ident, $level)
412
{
413
	// This is simply for neat indentation.
414
	$level++;
415
416
	echo "\n" . str_repeat("\t", $level), '<', $parent_ident, '>';
417
418
	foreach ($xml_data as $key => $data)
419
	{
420
		// A group?
421
		if (is_array($data) && isset($data['identifier']))
422
			template_generic_xml_recursive($data['children'], $key, $data['identifier'], $level);
423
		// An item...
424
		elseif (is_array($data) && isset($data['value']))
425
		{
426
			echo "\n", str_repeat("\t", $level), '<', $child_ident;
427
428
			if (!empty($data['attributes']))
429
				foreach ($data['attributes'] as $k => $v)
430
					echo ' ' . $k . '="' . $v . '"';
431
432
			echo '><![CDATA[', cleanXml($data['value']), ']]></', $child_ident, '>';
433
		}
434
	}
435
436
	echo "\n", str_repeat("\t", $level), '</', $parent_ident, '>';
437
}
438
439
/**
440
 * Formats data retrieved in other functions into xml format.
441
 * Additionally formats data based on the specific format passed.
442
 * This function is recursively called to handle sub arrays of data.
443
 *
444
 * @param mixed[] $data the array to output as xml data
445
 * @param int $i the amount of indentation to use.
446
 * @param string|null $tag if specified, it will be used instead of the keys of data.
447
 * @param string $xml_format one of rss, rss2, rdf, atom
448
 */
449
function template_xml_news($data, $i, $tag = null, $xml_format = 'rss')
450
{
451
	// For every array in the data...
452
	foreach ($data as $key => $val)
453
	{
454
		// Skip it, it's been set to null.
455
		if ($val === null)
456
			continue;
457
458
		// If a tag was passed, use it instead of the key.
459
		$key = isset($tag) ? $tag : $key;
460
461
		// First let's indent!
462
		echo "\n", str_repeat("\t", $i);
463
464
		// Grr, I hate kludges... almost worth doing it properly, here, but not quite.
465
		if ($xml_format == 'atom' && $key == 'link')
466
		{
467
			echo '<link rel="alternate" type="text/html" href="', fix_possible_url($val), '" />';
468
			continue;
469
		}
470
471
		// If it's empty/0/nothing simply output an empty tag.
472
		if ($val == '')
473
			echo '<', $key, ' />';
474
		elseif ($xml_format == 'atom' && $key == 'category')
475
			echo '<', $key, ' term="', $val, '" />';
476
		else
477
		{
478
			// Beginning tag.
479
			if ($xml_format == 'rdf' && $key == 'item' && isset($val['link']))
480
			{
481
				echo '<', $key, ' rdf:about="', fix_possible_url($val['link']), '">';
482
				echo "\n", str_repeat("\t", $i + 1);
483
				echo '<dc:format>text/html</dc:format>';
484
			}
485
			elseif ($xml_format == 'atom' && $key == 'summary')
486
				echo '<', $key, ' type="html">';
487
			else
488
				echo '<', $key, '>';
489
490
			if (is_array($val))
491
			{
492
				// An array.  Dump it, and then indent the tag.
493
				template_xml_news($val, $i + 1, null, $xml_format);
494
				echo "\n", str_repeat("\t", $i), '</', $key, '>';
495
			}
496
			// A string with returns in it.... show this as a multiline element.
497
			elseif (strpos($val, "\n") !== false || strpos($val, '<br />') !== false)
498
				echo "\n", fix_possible_url($val), "\n", str_repeat("\t", $i), '</', $key, '>';
499
			// A simple string.
500
			else
501
				echo fix_possible_url($val), '</', $key, '>';
502
		}
503
	}
504
}
505
506
/**
507
 * Main Atom feed template
508
 */
509
function template_rdf()
510
{
511
	global $context, $scripturl, $txt;
512
513
	echo '<?xml version="1.0" encoding="UTF-8"?' . '>
514
	<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://purl.org/rss/1.0/">
515
		<channel rdf:about="', $scripturl, '">
516
			<title>', $context['feed_title'], '</title>
517
			<link>', $scripturl, '</link>
518
			<description><![CDATA[', strip_tags($txt['xml_rss_desc']), ']]></description>
519
			<items>
520
				<rdf:Seq>';
521
522
	foreach ($context['recent_posts_data'] as $item)
523
		echo '
524
					<rdf:li rdf:resource="', $item['link'], '" />';
525
526
	echo '
527
				</rdf:Seq>
528
			</items>
529
		</channel>
530
	';
531
532
	template_xml_news($context['recent_posts_data'], 1, 'item', $context['xml_format']);
533
534
	echo '
535
	</rdf:RDF>';
536
}
537
538
/**
539
 * Main Atom feed template
540
 */
541
function template_feedatom()
542
{
543
	global $context, $scripturl, $txt;
544
545
	echo '<?xml version="1.0" encoding="UTF-8"?' . '>
546
	<feed xmlns="http://www.w3.org/2005/Atom">
547
		<title>', $context['feed_title'], '</title>
548
		<link rel="alternate" type="text/html" href="', $scripturl, '" />
549
		<link rel="self" type="application/rss+xml" href="', $scripturl, '?type=atom;action=.xml', $context['url_parts'], '" />
550
		<id>', $scripturl, '</id>
551
		<icon>', $context['favicon'] . '</icon>
552
		<logo>', $context['header_logo_url_html_safe'], '</logo>
553
554
		<updated>', gmstrftime('%Y-%m-%dT%H:%M:%SZ'), '</updated>
555
		<subtitle><![CDATA[', strip_tags(un_htmlspecialchars($txt['xml_rss_desc'])), ']]></subtitle>
556
		<generator uri="http://www.elkarte.net" version="', strtr(FORUM_VERSION, array('ElkArte' => '')), '">ElkArte</generator>
557
		<author>
558
			<name>', strip_tags(un_htmlspecialchars($context['forum_name'])), '</name>
559
		</author>';
560
561
	template_xml_news($context['recent_posts_data'], 2, 'entry', $context['xml_format']);
562
563
	echo '
564
	</feed>';
565
}
566
567
/**
568
 * Main RSS feed template (0.92 and 2.0)
569
 */
570
function template_feedrss()
571
{
572
	global $context, $scripturl, $txt;
573
574
	echo '<?xml version="1.0" encoding="UTF-8"?' . '>
575
	<rss version=', $context['xml_format'] == 'rss2' ? '"2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"' : '"0.92"', ' xml:lang="', strtr($txt['lang_locale'], '_', '-'), '">
576
		<channel>
577
			<title>', $context['feed_title'], '</title>
578
			<link>', $scripturl, '</link>
579
			<description><![CDATA[', un_htmlspecialchars(strip_tags($txt['xml_rss_desc'])), ']]></description>
580
			<generator>ElkArte</generator>
581
			<ttl>30</ttl>
582
			<image>
583
				<url>', $context['header_logo_url_html_safe'], '</url>
584
				<title>', $context['feed_title'], '</title>
585
				<link>', $scripturl, '</link>
586
			</image>';
587
588
	// Output all of the associative array, start indenting with 2 tabs, and name everything "item".
589
	template_xml_news($context['recent_posts_data'], 2, 'item', $context['xml_format']);
590
591
	// Output the footer of the xml.
592
	echo '
593
		</channel>
594
	</rss>';
595
}
596
597
/**
598
 * Returns an xml response to a draft autosave request
599
 * provides the id of the draft saved and the time it was saved in the response
600
 */
601
function template_xml_draft()
602
{
603
	global $context, $txt;
604
605
	echo '<', '?xml version="1.0" encoding="UTF-8"?', '>
606
<drafts>
607
	<draft id="', $context['id_draft'], '"><![CDATA[', $txt['draft_saved_on'], ': ', standardTime($context['draft_saved_on']), ']]></draft>
608
</drafts>';
609
}
610