Issues (2010)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

wp-includes/feed.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * WordPress Feed API
4
 *
5
 * Many of the functions used in here belong in The Loop, or The Loop for the
6
 * Feeds.
7
 *
8
 * @package WordPress
9
 * @subpackage Feed
10
 * @since 2.1.0
11
 */
12
13
/**
14
 * RSS container for the bloginfo function.
15
 *
16
 * You can retrieve anything that you can using the get_bloginfo() function.
17
 * Everything will be stripped of tags and characters converted, when the values
18
 * are retrieved for use in the feeds.
19
 *
20
 * @since 1.5.1
21
 * @see get_bloginfo() For the list of possible values to display.
22
 *
23
 * @param string $show See get_bloginfo() for possible values.
24
 * @return string
25
 */
26
function get_bloginfo_rss($show = '') {
27
	$info = strip_tags(get_bloginfo($show));
28
	/**
29
	 * Filters the bloginfo for use in RSS feeds.
30
	 *
31
	 * @since 2.2.0
32
	 *
33
	 * @see convert_chars()
34
	 * @see get_bloginfo()
35
	 *
36
	 * @param string $info Converted string value of the blog information.
37
	 * @param string $show The type of blog information to retrieve.
38
	 */
39
	return apply_filters( 'get_bloginfo_rss', convert_chars( $info ), $show );
40
}
41
42
/**
43
 * Display RSS container for the bloginfo function.
44
 *
45
 * You can retrieve anything that you can using the get_bloginfo() function.
46
 * Everything will be stripped of tags and characters converted, when the values
47
 * are retrieved for use in the feeds.
48
 *
49
 * @since 0.71
50
 * @see get_bloginfo() For the list of possible values to display.
51
 *
52
 * @param string $show See get_bloginfo() for possible values.
53
 */
54
function bloginfo_rss($show = '') {
55
	/**
56
	 * Filters the bloginfo for display in RSS feeds.
57
	 *
58
	 * @since 2.1.0
59
	 *
60
	 * @see get_bloginfo()
61
	 *
62
	 * @param string $rss_container RSS container for the blog information.
63
	 * @param string $show          The type of blog information to retrieve.
64
	 */
65
	echo apply_filters( 'bloginfo_rss', get_bloginfo_rss( $show ), $show );
66
}
67
68
/**
69
 * Retrieve the default feed.
70
 *
71
 * The default feed is 'rss2', unless a plugin changes it through the
72
 * {@see 'default_feed'} filter.
73
 *
74
 * @since 2.5.0
75
 *
76
 * @return string Default feed, or for example 'rss2', 'atom', etc.
77
 */
78
function get_default_feed() {
79
	/**
80
	 * Filters the default feed type.
81
	 *
82
	 * @since 2.5.0
83
	 *
84
	 * @param string $feed_type Type of default feed. Possible values include 'rss2', 'atom'.
85
	 *                          Default 'rss2'.
86
	 */
87
	$default_feed = apply_filters( 'default_feed', 'rss2' );
88
	return 'rss' == $default_feed ? 'rss2' : $default_feed;
89
}
90
91
/**
92
 * Retrieve the blog title for the feed title.
93
 *
94
 * @since 2.2.0
95
 * @since 4.4.0 The optional `$sep` parameter was deprecated and renamed to `$deprecated`.
96
 *
97
 * @param string $deprecated Unused..
98
 * @return string The document title.
99
 */
100 View Code Duplication
function get_wp_title_rss( $deprecated = '&#8211;' ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
	if ( '&#8211;' !== $deprecated ) {
102
		/* translators: %s: 'document_title_separator' filter name */
103
		_deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) );
104
	}
105
106
	/**
107
	 * Filters the blog title for use as the feed title.
108
	 *
109
	 * @since 2.2.0
110
	 * @since 4.4.0 The `$sep` parameter was deprecated and renamed to `$deprecated`.
111
	 *
112
	 * @param string $title      The current blog title.
113
	 * @param string $deprecated Unused.
114
	 */
115
	return apply_filters( 'get_wp_title_rss', wp_get_document_title(), $deprecated );
116
}
117
118
/**
119
 * Display the blog title for display of the feed title.
120
 *
121
 * @since 2.2.0
122
 * @since 4.4.0 The optional `$sep` parameter was deprecated and renamed to `$deprecated`.
123
 *
124
 * @param string $deprecated Unused.
125
 */
126 View Code Duplication
function wp_title_rss( $deprecated = '&#8211;' ) {
0 ignored issues
show
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
	if ( '&#8211;' !== $deprecated ) {
128
		/* translators: %s: 'document_title_separator' filter name */
129
		_deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) );
130
	}
131
132
	/**
133
	 * Filters the blog title for display of the feed title.
134
	 *
135
	 * @since 2.2.0
136
	 * @since 4.4.0 The `$sep` parameter was deprecated and renamed to `$deprecated`.
137
	 *
138
	 * @see get_wp_title_rss()
139
	 *
140
	 * @param string $wp_title_rss The current blog title.
141
	 * @param string $deprecated   Unused.
142
	 */
143
	echo apply_filters( 'wp_title_rss', get_wp_title_rss(), $deprecated );
144
}
145
146
/**
147
 * Retrieve the current post title for the feed.
148
 *
149
 * @since 2.0.0
150
 *
151
 * @return string Current post title.
152
 */
153
function get_the_title_rss() {
154
	$title = get_the_title();
155
156
	/**
157
	 * Filters the post title for use in a feed.
158
	 *
159
	 * @since 1.2.0
160
	 *
161
	 * @param string $title The current post title.
162
	 */
163
	$title = apply_filters( 'the_title_rss', $title );
164
	return $title;
165
}
166
167
/**
168
 * Display the post title in the feed.
169
 *
170
 * @since 0.71
171
 */
172
function the_title_rss() {
173
	echo get_the_title_rss();
174
}
175
176
/**
177
 * Retrieve the post content for feeds.
178
 *
179
 * @since 2.9.0
180
 * @see get_the_content()
181
 *
182
 * @param string $feed_type The type of feed. rss2 | atom | rss | rdf
183
 * @return string The filtered content.
184
 */
185
function get_the_content_feed($feed_type = null) {
186
	if ( !$feed_type )
0 ignored issues
show
Bug Best Practice introduced by
The expression $feed_type of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
187
		$feed_type = get_default_feed();
188
189
	/** This filter is documented in wp-includes/post-template.php */
190
	$content = apply_filters( 'the_content', get_the_content() );
191
	$content = str_replace(']]>', ']]&gt;', $content);
192
	/**
193
	 * Filters the post content for use in feeds.
194
	 *
195
	 * @since 2.9.0
196
	 *
197
	 * @param string $content   The current post content.
198
	 * @param string $feed_type Type of feed. Possible values include 'rss2', 'atom'.
199
	 *                          Default 'rss2'.
200
	 */
201
	return apply_filters( 'the_content_feed', $content, $feed_type );
202
}
203
204
/**
205
 * Display the post content for feeds.
206
 *
207
 * @since 2.9.0
208
 *
209
 * @param string $feed_type The type of feed. rss2 | atom | rss | rdf
210
 */
211
function the_content_feed($feed_type = null) {
212
	echo get_the_content_feed($feed_type);
213
}
214
215
/**
216
 * Display the post excerpt for the feed.
217
 *
218
 * @since 0.71
219
 */
220
function the_excerpt_rss() {
221
	$output = get_the_excerpt();
222
	/**
223
	 * Filters the post excerpt for a feed.
224
	 *
225
	 * @since 1.2.0
226
	 *
227
	 * @param string $output The current post excerpt.
228
	 */
229
	echo apply_filters( 'the_excerpt_rss', $output );
230
}
231
232
/**
233
 * Display the permalink to the post for use in feeds.
234
 *
235
 * @since 2.3.0
236
 */
237
function the_permalink_rss() {
238
	/**
239
	 * Filters the permalink to the post for use in feeds.
240
	 *
241
	 * @since 2.3.0
242
	 *
243
	 * @param string $post_permalink The current post permalink.
244
	 */
245
	echo esc_url( apply_filters( 'the_permalink_rss', get_permalink() ) );
246
}
247
248
/**
249
 * Outputs the link to the comments for the current post in an xml safe way
250
 *
251
 * @since 3.0.0
252
 * @return none
253
 */
254
function comments_link_feed() {
255
	/**
256
	 * Filters the comments permalink for the current post.
257
	 *
258
	 * @since 3.6.0
259
	 *
260
	 * @param string $comment_permalink The current comment permalink with
261
	 *                                  '#comments' appended.
262
	 */
263
	echo esc_url( apply_filters( 'comments_link_feed', get_comments_link() ) );
264
}
265
266
/**
267
 * Display the feed GUID for the current comment.
268
 *
269
 * @since 2.5.0
270
 *
271
 * @param int|WP_Comment $comment_id Optional comment object or id. Defaults to global comment object.
272
 */
273
function comment_guid($comment_id = null) {
274
	echo esc_url( get_comment_guid($comment_id) );
0 ignored issues
show
It seems like get_comment_guid($comment_id) targeting get_comment_guid() can also be of type false; however, esc_url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
275
}
276
277
/**
278
 * Retrieve the feed GUID for the current comment.
279
 *
280
 * @since 2.5.0
281
 *
282
 * @param int|WP_Comment $comment_id Optional comment object or id. Defaults to global comment object.
283
 * @return false|string false on failure or guid for comment on success.
284
 */
285
function get_comment_guid($comment_id = null) {
286
	$comment = get_comment($comment_id);
287
288
	if ( !is_object($comment) )
289
		return false;
290
291
	return get_the_guid($comment->comment_post_ID) . '#comment-' . $comment->comment_ID;
292
}
293
294
/**
295
 * Display the link to the comments.
296
 *
297
 * @since 1.5.0
298
 * @since 4.4.0 Introduced the `$comment` argument.
299
 *
300
 * @param int|WP_Comment $comment Optional. Comment object or id. Defaults to global comment object.
301
 */
302
function comment_link( $comment = null ) {
303
	/**
304
	 * Filters the current comment's permalink.
305
	 *
306
	 * @since 3.6.0
307
	 *
308
	 * @see get_comment_link()
309
	 *
310
	 * @param string $comment_permalink The current comment permalink.
311
	 */
312
	echo esc_url( apply_filters( 'comment_link', get_comment_link( $comment ) ) );
313
}
314
315
/**
316
 * Retrieve the current comment author for use in the feeds.
317
 *
318
 * @since 2.0.0
319
 *
320
 * @return string Comment Author
321
 */
322
function get_comment_author_rss() {
323
	/**
324
	 * Filters the current comment author for use in a feed.
325
	 *
326
	 * @since 1.5.0
327
	 *
328
	 * @see get_comment_author()
329
	 *
330
	 * @param string $comment_author The current comment author.
331
	 */
332
	return apply_filters( 'comment_author_rss', get_comment_author() );
333
}
334
335
/**
336
 * Display the current comment author in the feed.
337
 *
338
 * @since 1.0.0
339
 */
340
function comment_author_rss() {
341
	echo get_comment_author_rss();
342
}
343
344
/**
345
 * Display the current comment content for use in the feeds.
346
 *
347
 * @since 1.0.0
348
 */
349
function comment_text_rss() {
350
	$comment_text = get_comment_text();
351
	/**
352
	 * Filters the current comment content for use in a feed.
353
	 *
354
	 * @since 1.5.0
355
	 *
356
	 * @param string $comment_text The content of the current comment.
357
	 */
358
	$comment_text = apply_filters( 'comment_text_rss', $comment_text );
359
	echo $comment_text;
360
}
361
362
/**
363
 * Retrieve all of the post categories, formatted for use in feeds.
364
 *
365
 * All of the categories for the current post in the feed loop, will be
366
 * retrieved and have feed markup added, so that they can easily be added to the
367
 * RSS2, Atom, or RSS1 and RSS0.91 RDF feeds.
368
 *
369
 * @since 2.1.0
370
 *
371
 * @param string $type Optional, default is the type returned by get_default_feed().
372
 * @return string All of the post categories for displaying in the feed.
373
 */
374
function get_the_category_rss($type = null) {
375
	if ( empty($type) )
376
		$type = get_default_feed();
377
	$categories = get_the_category();
378
	$tags = get_the_tags();
379
	$the_list = '';
380
	$cat_names = array();
381
382
	$filter = 'rss';
383
	if ( 'atom' == $type )
384
		$filter = 'raw';
385
386
	if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
387
		$cat_names[] = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);
388
	}
389
390
	if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
391
		$cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);
392
	}
393
394
	$cat_names = array_unique($cat_names);
395
396
	foreach ( $cat_names as $cat_name ) {
397
		if ( 'rdf' == $type )
398
			$the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
399
		elseif ( 'atom' == $type )
400
			$the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( get_bloginfo_rss( 'url' ) ), esc_attr( $cat_name ) );
401
		else
402
			$the_list .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";
403
	}
404
405
	/**
406
	 * Filters all of the post categories for display in a feed.
407
	 *
408
	 * @since 1.2.0
409
	 *
410
	 * @param string $the_list All of the RSS post categories.
411
	 * @param string $type     Type of feed. Possible values include 'rss2', 'atom'.
412
	 *                         Default 'rss2'.
413
	 */
414
	return apply_filters( 'the_category_rss', $the_list, $type );
415
}
416
417
/**
418
 * Display the post categories in the feed.
419
 *
420
 * @since 0.71
421
 * @see get_the_category_rss() For better explanation.
422
 *
423
 * @param string $type Optional, default is the type returned by get_default_feed().
424
 */
425
function the_category_rss($type = null) {
426
	echo get_the_category_rss($type);
427
}
428
429
/**
430
 * Display the HTML type based on the blog setting.
431
 *
432
 * The two possible values are either 'xhtml' or 'html'.
433
 *
434
 * @since 2.2.0
435
 */
436
function html_type_rss() {
437
	$type = get_bloginfo('html_type');
438
	if (strpos($type, 'xhtml') !== false)
439
		$type = 'xhtml';
440
	else
441
		$type = 'html';
442
	echo $type;
443
}
444
445
/**
446
 * Display the rss enclosure for the current post.
447
 *
448
 * Uses the global $post to check whether the post requires a password and if
449
 * the user has the password for the post. If not then it will return before
450
 * displaying.
451
 *
452
 * Also uses the function get_post_custom() to get the post's 'enclosure'
453
 * metadata field and parses the value to display the enclosure(s). The
454
 * enclosure(s) consist of enclosure HTML tag(s) with a URI and other
455
 * attributes.
456
 *
457
 * @since 1.5.0
458
 */
459
function rss_enclosure() {
460
	if ( post_password_required() )
461
		return;
462
463
	foreach ( (array) get_post_custom() as $key => $val) {
464
		if ($key == 'enclosure') {
465
			foreach ( (array) $val as $enc ) {
466
				$enclosure = explode("\n", $enc);
467
468
				// only get the first element, e.g. audio/mpeg from 'audio/mpeg mpga mp2 mp3'
469
				$t = preg_split('/[ \t]/', trim($enclosure[2]) );
470
				$type = $t[0];
471
472
				/**
473
				 * Filters the RSS enclosure HTML link tag for the current post.
474
				 *
475
				 * @since 2.2.0
476
				 *
477
				 * @param string $html_link_tag The HTML link tag with a URI and other attributes.
478
				 */
479
				echo apply_filters( 'rss_enclosure', '<enclosure url="' . trim( htmlspecialchars( $enclosure[0] ) ) . '" length="' . trim( $enclosure[1] ) . '" type="' . $type . '" />' . "\n" );
480
			}
481
		}
482
	}
483
}
484
485
/**
486
 * Display the atom enclosure for the current post.
487
 *
488
 * Uses the global $post to check whether the post requires a password and if
489
 * the user has the password for the post. If not then it will return before
490
 * displaying.
491
 *
492
 * Also uses the function get_post_custom() to get the post's 'enclosure'
493
 * metadata field and parses the value to display the enclosure(s). The
494
 * enclosure(s) consist of link HTML tag(s) with a URI and other attributes.
495
 *
496
 * @since 2.2.0
497
 */
498
function atom_enclosure() {
499
	if ( post_password_required() )
500
		return;
501
502
	foreach ( (array) get_post_custom() as $key => $val ) {
503
		if ($key == 'enclosure') {
504
			foreach ( (array) $val as $enc ) {
505
				$enclosure = explode("\n", $enc);
506
				/**
507
				 * Filters the atom enclosure HTML link tag for the current post.
508
				 *
509
				 * @since 2.2.0
510
				 *
511
				 * @param string $html_link_tag The HTML link tag with a URI and other attributes.
512
				 */
513
				echo apply_filters( 'atom_enclosure', '<link href="' . trim( htmlspecialchars( $enclosure[0] ) ) . '" rel="enclosure" length="' . trim( $enclosure[1] ) . '" type="' . trim( $enclosure[2] ) . '" />' . "\n" );
514
			}
515
		}
516
	}
517
}
518
519
/**
520
 * Determine the type of a string of data with the data formatted.
521
 *
522
 * Tell whether the type is text, html, or xhtml, per RFC 4287 section 3.1.
523
 *
524
 * In the case of WordPress, text is defined as containing no markup,
525
 * xhtml is defined as "well formed", and html as tag soup (i.e., the rest).
526
 *
527
 * Container div tags are added to xhtml values, per section 3.1.1.3.
528
 *
529
 * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1
530
 *
531
 * @since 2.5.0
532
 *
533
 * @param string $data Input string
534
 * @return array array(type, value)
535
 */
536
function prep_atom_text_construct($data) {
537
	if (strpos($data, '<') === false && strpos($data, '&') === false) {
538
		return array('text', $data);
539
	}
540
541
	$parser = xml_parser_create();
542
	xml_parse($parser, '<div>' . $data . '</div>', true);
543
	$code = xml_get_error_code($parser);
544
	xml_parser_free($parser);
545
546
	if (!$code) {
547
		if (strpos($data, '<') === false) {
548
			return array('text', $data);
549
		} else {
550
			$data = "<div xmlns='http://www.w3.org/1999/xhtml'>$data</div>";
551
			return array('xhtml', $data);
552
		}
553
	}
554
555
	if (strpos($data, ']]>') === false) {
556
		return array('html', "<![CDATA[$data]]>");
557
	} else {
558
		return array('html', htmlspecialchars($data));
559
	}
560
}
561
562
/**
563
 * Displays Site Icon in atom feeds.
564
 *
565
 * @since 4.3.0
566
 *
567
 * @see get_site_icon_url()
568
 */
569
function atom_site_icon() {
570
	$url = get_site_icon_url( 32 );
571
	if ( $url ) {
572
		echo "<icon>$url</icon>\n";
573
	}
574
}
575
576
/**
577
 * Displays Site Icon in RSS2.
578
 *
579
 * @since 4.3.0
580
 */
581
function rss2_site_icon() {
582
	$rss_title = get_wp_title_rss();
583
	if ( empty( $rss_title ) ) {
584
		$rss_title = get_bloginfo_rss( 'name' );
585
	}
586
587
	$url = get_site_icon_url( 32 );
588
	if ( $url ) {
589
		echo '
590
<image>
591
	<url>' . convert_chars( $url ) . '</url>
592
	<title>' . $rss_title . '</title>
593
	<link>' . get_bloginfo_rss( 'url' ) . '</link>
594
	<width>32</width>
595
	<height>32</height>
596
</image> ' . "\n";
597
	}
598
}
599
600
/**
601
 * Display the link for the currently displayed feed in a XSS safe way.
602
 *
603
 * Generate a correct link for the atom:self element.
604
 *
605
 * @since 2.5.0
606
 */
607
function self_link() {
608
	$host = @parse_url(home_url());
609
	/**
610
	 * Filters the current feed URL.
611
	 *
612
	 * @since 3.6.0
613
	 *
614
	 * @see set_url_scheme()
615
	 * @see wp_unslash()
616
	 *
617
	 * @param string $feed_link The link for the feed with set URL scheme.
618
	 */
619
	echo esc_url( apply_filters( 'self_link', set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) );
620
}
621
622
/**
623
 * Return the content type for specified feed type.
624
 *
625
 * @since 2.8.0
626
 *
627
 * @param string $type Type of feed. Possible values include 'rss', rss2', 'atom', and 'rdf'.
628
 */
629
function feed_content_type( $type = '' ) {
630
	if ( empty($type) )
631
		$type = get_default_feed();
632
633
	$types = array(
634
		'rss'      => 'application/rss+xml',
635
		'rss2'     => 'application/rss+xml',
636
		'rss-http' => 'text/xml',
637
		'atom'     => 'application/atom+xml',
638
		'rdf'      => 'application/rdf+xml'
639
	);
640
641
	$content_type = ( !empty($types[$type]) ) ? $types[$type] : 'application/octet-stream';
642
643
	/**
644
	 * Filters the content type for a specific feed type.
645
	 *
646
	 * @since 2.8.0
647
	 *
648
	 * @param string $content_type Content type indicating the type of data that a feed contains.
649
	 * @param string $type         Type of feed. Possible values include 'rss', rss2', 'atom', and 'rdf'.
650
	 */
651
	return apply_filters( 'feed_content_type', $content_type, $type );
652
}
653
654
/**
655
 * Build SimplePie object based on RSS or Atom feed from URL.
656
 *
657
 * @since 2.8.0
658
 *
659
 * @param mixed $url URL of feed to retrieve. If an array of URLs, the feeds are merged
660
 * using SimplePie's multifeed feature.
661
 * See also {@link ​http://simplepie.org/wiki/faq/typical_multifeed_gotchas}
662
 *
663
 * @return WP_Error|SimplePie WP_Error object on failure or SimplePie object on success
664
 */
665
function fetch_feed( $url ) {
666
	require_once( ABSPATH . WPINC . '/class-feed.php' );
667
668
	$feed = new SimplePie();
669
670
	$feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' );
671
	// We must manually overwrite $feed->sanitize because SimplePie's
672
	// constructor sets it before we have a chance to set the sanitization class
673
	$feed->sanitize = new WP_SimplePie_Sanitize_KSES();
674
675
	$feed->set_cache_class( 'WP_Feed_Cache' );
676
	$feed->set_file_class( 'WP_SimplePie_File' );
677
678
	$feed->set_feed_url( $url );
679
	/** This filter is documented in wp-includes/class-feed.php */
680
	$feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) );
681
	/**
682
	 * Fires just before processing the SimplePie feed object.
683
	 *
684
	 * @since 3.0.0
685
	 *
686
	 * @param object &$feed SimplePie feed object, passed by reference.
687
	 * @param mixed  $url   URL of feed to retrieve. If an array of URLs, the feeds are merged.
688
	 */
689
	do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
690
	$feed->init();
691
	$feed->set_output_encoding( get_option( 'blog_charset' ) );
692
	$feed->handle_content_type();
693
694
	if ( $feed->error() )
695
		return new WP_Error( 'simplepie-error', $feed->error() );
696
697
	return $feed;
698
}
699