]> scripts.mit.edu Git - autoinstalls/wordpress.git/blob - wp-includes/feed.php
Wordpress 2.8.3
[autoinstalls/wordpress.git] / wp-includes / feed.php
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  */
11
12 /**
13  * RSS container for the bloginfo function.
14  *
15  * You can retrieve anything that you can using the get_bloginfo() function.
16  * Everything will be stripped of tags and characters converted, when the values
17  * are retrieved for use in the feeds.
18  *
19  * @package WordPress
20  * @subpackage Feed
21  * @since 1.5.1
22  * @uses apply_filters() Calls 'get_bloginfo_rss' hook with two parameters.
23  * @see get_bloginfo() For the list of possible values to display.
24  *
25  * @param string $show See get_bloginfo() for possible values.
26  * @return string
27  */
28 function get_bloginfo_rss($show = '') {
29         $info = strip_tags(get_bloginfo($show));
30         return apply_filters('get_bloginfo_rss', convert_chars($info), $show);
31 }
32
33 /**
34  * Display RSS container for the bloginfo function.
35  *
36  * You can retrieve anything that you can using the get_bloginfo() function.
37  * Everything will be stripped of tags and characters converted, when the values
38  * are retrieved for use in the feeds.
39  *
40  * @package WordPress
41  * @subpackage Feed
42  * @since 0.71
43  * @uses apply_filters() Calls 'bloginfo_rss' hook with two parameters.
44  * @see get_bloginfo() For the list of possible values to display.
45  *
46  * @param string $show See get_bloginfo() for possible values.
47  */
48 function bloginfo_rss($show = '') {
49         echo apply_filters('bloginfo_rss', get_bloginfo_rss($show), $show);
50 }
51
52 /**
53  * Retrieve the default feed.
54  *
55  * The default feed is 'rss2', unless a plugin changes it through the
56  * 'default_feed' filter.
57  *
58  * @package WordPress
59  * @subpackage Feed
60  * @since 2.5
61  * @uses apply_filters() Calls 'default_feed' hook on the default feed string.
62  *
63  * @return string Default feed, or for example 'rss2', 'atom', etc.
64  */
65 function get_default_feed() {
66         return apply_filters('default_feed', 'rss2');
67 }
68
69 /**
70  * Retrieve the blog title for the feed title.
71  *
72  * @package WordPress
73  * @subpackage Feed
74  * @since 2.2.0
75  * @uses apply_filters() Calls 'get_wp_title_rss' hook on title.
76  * @uses wp_title() See function for $sep parameter usage.
77  *
78  * @param string $sep Optional.How to separate the title. See wp_title() for more info.
79  * @return string Error message on failure or blog title on success.
80  */
81 function get_wp_title_rss($sep = '&#187;') {
82         $title = wp_title($sep, false);
83         if ( is_wp_error( $title ) )
84                 return $title->get_error_message();
85         $title = apply_filters('get_wp_title_rss', $title);
86         return $title;
87 }
88
89 /**
90  * Display the blog title for display of the feed title.
91  *
92  * @package WordPress
93  * @subpackage Feed
94  * @since 2.2.0
95  * @uses apply_filters() Calls 'wp_title_rss' on the blog title.
96  * @see wp_title() $sep parameter usage.
97  *
98  * @param string $sep Optional.
99  */
100 function wp_title_rss($sep = '&#187;') {
101         echo apply_filters('wp_title_rss', get_wp_title_rss($sep));
102 }
103
104 /**
105  * Retrieve the current post title for the feed.
106  *
107  * @package WordPress
108  * @subpackage Feed
109  * @since 2.0.0
110  * @uses apply_filters() Calls 'the_title_rss' on the post title.
111  *
112  * @return string Current post title.
113  */
114 function get_the_title_rss() {
115         $title = get_the_title();
116         $title = apply_filters('the_title_rss', $title);
117         return $title;
118 }
119
120 /**
121  * Display the post title in the feed.
122  *
123  * @package WordPress
124  * @subpackage Feed
125  * @since 0.71
126  * @uses get_the_title_rss() Used to retrieve current post title.
127  */
128 function the_title_rss() {
129         echo get_the_title_rss();
130 }
131
132 /**
133  * Display the post content for the feed.
134  *
135  * For encoding the html or the $encode_html parameter, there are three possible
136  * values. '0' will make urls footnotes and use make_url_footnote(). '1' will
137  * encode special characters and automatically display all of the content. The
138  * value of '2' will strip all HTML tags from the content.
139  *
140  * Also note that you cannot set the amount of words and not set the html
141  * encoding. If that is the case, then the html encoding will default to 2,
142  * which will strip all HTML tags.
143  *
144  * To restrict the amount of words of the content, you can use the cut
145  * parameter. If the content is less than the amount, then there won't be any
146  * dots added to the end. If there is content left over, then dots will be added
147  * and the rest of the content will be removed.
148  *
149  * @package WordPress
150  * @subpackage Feed
151  * @since 0.71
152  * @uses apply_filters() Calls 'the_content_rss' on the content before processing.
153  * @see get_the_content() For the $more_link_text, $stripteaser, and $more_file
154  *              parameters.
155  *
156  * @param string $more_link_text Optional. Text to display when more content is available but not displayed.
157  * @param int|bool $stripteaser Optional. Default is 0.
158  * @param string $more_file Optional.
159  * @param int $cut Optional. Amount of words to keep for the content.
160  * @param int $encode_html Optional. How to encode the content.
161  */
162 function the_content_rss($more_link_text='(more...)', $stripteaser=0, $more_file='', $cut = 0, $encode_html = 0) {
163         $content = get_the_content($more_link_text, $stripteaser, $more_file);
164         $content = apply_filters('the_content_rss', $content);
165         if ( $cut && !$encode_html )
166                 $encode_html = 2;
167         if ( 1== $encode_html ) {
168                 $content = esc_html($content);
169                 $cut = 0;
170         } elseif ( 0 == $encode_html ) {
171                 $content = make_url_footnote($content);
172         } elseif ( 2 == $encode_html ) {
173                 $content = strip_tags($content);
174         }
175         if ( $cut ) {
176                 $blah = explode(' ', $content);
177                 if ( count($blah) > $cut ) {
178                         $k = $cut;
179                         $use_dotdotdot = 1;
180                 } else {
181                         $k = count($blah);
182                         $use_dotdotdot = 0;
183                 }
184
185                 /** @todo Check performance, might be faster to use array slice instead. */
186                 for ( $i=0; $i<$k; $i++ )
187                         $excerpt .= $blah[$i].' ';
188                 $excerpt .= ($use_dotdotdot) ? '...' : '';
189                 $content = $excerpt;
190         }
191         $content = str_replace(']]>', ']]&gt;', $content);
192         echo $content;
193 }
194
195 /**
196  * Display the post excerpt for the feed.
197  *
198  * @package WordPress
199  * @subpackage Feed
200  * @since 0.71
201  * @uses apply_filters() Calls 'the_excerpt_rss' hook on the excerpt.
202  */
203 function the_excerpt_rss() {
204         $output = get_the_excerpt();
205         echo apply_filters('the_excerpt_rss', $output);
206 }
207
208 /**
209  * Display the permalink to the post for use in feeds.
210  *
211  * @package WordPress
212  * @subpackage Feed
213  * @since 2.3.0
214  * @uses apply_filters() Call 'the_permalink_rss' on the post permalink
215  */
216 function the_permalink_rss() {
217         echo apply_filters('the_permalink_rss', get_permalink());
218 }
219
220 /**
221  * Display the feed GUID for the current comment.
222  *
223  * @package WordPress
224  * @subpackage Feed
225  * @since unknown
226  *
227  * @param int|object $comment_id Optional comment object or id. Defaults to global comment object.
228  */
229 function comment_guid($comment_id = null) {
230         echo get_comment_guid($comment_id);
231 }
232
233 /**
234  * Retrieve the feed GUID for the current comment.
235  *
236  * @package WordPress
237  * @subpackage Feed
238  * @since unknown
239  *
240  * @param int|object $comment_id Optional comment object or id. Defaults to global comment object.
241  * @return bool|string false on failure or guid for comment on success.
242  */
243 function get_comment_guid($comment_id = null) {
244         $comment = get_comment($comment_id);
245
246         if ( !is_object($comment) )
247                 return false;
248
249         return get_the_guid($comment->comment_post_ID) . '#comment-' . $comment->comment_ID;
250 }
251
252 /**
253  * Display the link to the comments.
254  *
255  * @since 1.5.0
256  */
257 function comment_link() {
258         echo esc_url( get_comment_link() );
259 }
260
261 /**
262  * Retrieve the current comment author for use in the feeds.
263  *
264  * @package WordPress
265  * @subpackage Feed
266  * @since 2.0.0
267  * @uses apply_filters() Calls 'comment_author_rss' hook on comment author.
268  * @uses get_comment_author()
269  *
270  * @return string Comment Author
271  */
272 function get_comment_author_rss() {
273         return apply_filters('comment_author_rss', get_comment_author() );
274 }
275
276 /**
277  * Display the current comment author in the feed.
278  *
279  * @package WordPress
280  * @subpackage Feed
281  * @since 1.0.0
282  */
283 function comment_author_rss() {
284         echo get_comment_author_rss();
285 }
286
287 /**
288  * Display the current comment content for use in the feeds.
289  *
290  * @package WordPress
291  * @subpackage Feed
292  * @since 1.0.0
293  * @uses apply_filters() Calls 'comment_text_rss' filter on comment content.
294  * @uses get_comment_text()
295  */
296 function comment_text_rss() {
297         $comment_text = get_comment_text();
298         $comment_text = apply_filters('comment_text_rss', $comment_text);
299         echo $comment_text;
300 }
301
302 /**
303  * Retrieve all of the post categories, formatted for use in feeds.
304  *
305  * All of the categories for the current post in the feed loop, will be
306  * retrieved and have feed markup added, so that they can easily be added to the
307  * RSS2, Atom, or RSS1 and RSS0.91 RDF feeds.
308  *
309  * @package WordPress
310  * @subpackage Feed
311  * @since 2.1.0
312  * @uses apply_filters()
313  *
314  * @param string $type Optional, default is 'rss'. Either 'rss', 'atom', or 'rdf'.
315  * @return string All of the post categories for displaying in the feed.
316  */
317 function get_the_category_rss($type = 'rss') {
318         $categories = get_the_category();
319         $tags = get_the_tags();
320         $the_list = '';
321         $cat_names = array();
322
323         $filter = 'rss';
324         if ( 'atom' == $type )
325                 $filter = 'raw';
326
327         if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
328                 $cat_names[] = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);
329         }
330
331         if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
332                 $cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);
333         }
334
335         $cat_names = array_unique($cat_names);
336
337         foreach ( $cat_names as $cat_name ) {
338                 if ( 'rdf' == $type )
339                         $the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
340                 elseif ( 'atom' == $type )
341                         $the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), esc_attr( $cat_name ) );
342                 else
343                         $the_list .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option('blog_charset') ) . "]]></category>\n";
344         }
345
346         return apply_filters('the_category_rss', $the_list, $type);
347 }
348
349 /**
350  * Display the post categories in the feed.
351  *
352  * @package WordPress
353  * @subpackage Feed
354  * @since 0.71
355  * @see get_the_category_rss() For better explanation.
356  *
357  * @param string $type Optional, default is 'rss'. Either 'rss', 'atom', or 'rdf'.
358  */
359 function the_category_rss($type = 'rss') {
360         echo get_the_category_rss($type);
361 }
362
363 /**
364  * Display the HTML type based on the blog setting.
365  *
366  * The two possible values are either 'xhtml' or 'html'.
367  *
368  * @package WordPress
369  * @subpackage Feed
370  * @since 2.2.0
371  */
372 function html_type_rss() {
373         $type = get_bloginfo('html_type');
374         if (strpos($type, 'xhtml') !== false)
375                 $type = 'xhtml';
376         else
377                 $type = 'html';
378         echo $type;
379 }
380
381 /**
382  * Display the rss enclosure for the current post.
383  *
384  * Uses the global $post to check whether the post requires a password and if
385  * the user has the password for the post. If not then it will return before
386  * displaying.
387  *
388  * Also uses the function get_post_custom() to get the post's 'enclosure'
389  * metadata field and parses the value to display the enclosure(s). The
390  * enclosure(s) consist of enclosure HTML tag(s) with a URI and other
391  * attributes.
392  *
393  * @package WordPress
394  * @subpackage Template
395  * @since 1.5.0
396  * @uses apply_filters() Calls 'rss_enclosure' hook on rss enclosure.
397  * @uses get_post_custom() To get the current post enclosure metadata.
398  */
399 function rss_enclosure() {
400         if ( post_password_required() )
401                 return;
402
403         foreach ( (array) get_post_custom() as $key => $val) {
404                 if ($key == 'enclosure') {
405                         foreach ( (array) $val as $enc ) {
406                                 $enclosure = explode("\n", $enc);
407
408                                 //only get the the first element eg, audio/mpeg from 'audio/mpeg mpga mp2 mp3'
409                                 $t = preg_split('/[ \t]/', trim($enclosure[2]) );
410                                 $type = $t[0];
411
412                                 echo apply_filters('rss_enclosure', '<enclosure url="' . trim(htmlspecialchars($enclosure[0])) . '" length="' . trim($enclosure[1]) . '" type="' . $type . '" />' . "\n");
413                         }
414                 }
415         }
416 }
417
418 /**
419  * Display the atom enclosure for the current post.
420  *
421  * Uses the global $post to check whether the post requires a password and if
422  * the user has the password for the post. If not then it will return before
423  * displaying.
424  *
425  * Also uses the function get_post_custom() to get the post's 'enclosure'
426  * metadata field and parses the value to display the enclosure(s). The
427  * enclosure(s) consist of link HTML tag(s) with a URI and other attributes.
428  *
429  * @package WordPress
430  * @subpackage Template
431  * @since 2.2.0
432  * @uses apply_filters() Calls 'atom_enclosure' hook on atom enclosure.
433  * @uses get_post_custom() To get the current post enclosure metadata.
434  */
435 function atom_enclosure() {
436         if ( post_password_required() )
437                 return;
438
439         foreach ( (array) get_post_custom() as $key => $val ) {
440                 if ($key == 'enclosure') {
441                         foreach ( (array) $val as $enc ) {
442                                 $enclosure = split("\n", $enc);
443                                 echo apply_filters('atom_enclosure', '<link href="' . trim(htmlspecialchars($enclosure[0])) . '" rel="enclosure" length="' . trim($enclosure[1]) . '" type="' . trim($enclosure[2]) . '" />' . "\n");
444                         }
445                 }
446         }
447 }
448
449 /**
450  * Determine the type of a string of data with the data formatted.
451  *
452  * Tell whether the type is text, html, or xhtml, per RFC 4287 section 3.1.
453  *
454  * In the case of WordPress, text is defined as containing no markup,
455  * xhtml is defined as "well formed", and html as tag soup (i.e., the rest).
456  *
457  * Container div tags are added to xhtml values, per section 3.1.1.3.
458  *
459  * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1
460  *
461  * @package WordPress
462  * @subpackage Feed
463  * @since 2.5
464  *
465  * @param string $data Input string
466  * @return array array(type, value)
467  */
468 function prep_atom_text_construct($data) {
469         if (strpos($data, '<') === false && strpos($data, '&') === false) {
470                 return array('text', $data);
471         }
472
473         $parser = xml_parser_create();
474         xml_parse($parser, '<div>' . $data . '</div>', true);
475         $code = xml_get_error_code($parser);
476         xml_parser_free($parser);
477
478         if (!$code) {
479                 if (strpos($data, '<') === false) {
480                         return array('text', $data);
481                 } else {
482                         $data = "<div xmlns='http://www.w3.org/1999/xhtml'>$data</div>";
483                         return array('xhtml', $data);
484                 }
485         }
486
487         if (strpos($data, ']]>') == false) {
488                 return array('html', "<![CDATA[$data]]>");
489         } else {
490                 return array('html', htmlspecialchars($data));
491         }
492 }
493
494 /**
495  * Display the link for the currently displayed feed in a XSS safe way.
496  *
497  * Generate a correct link for the atom:self element.
498  *
499  * @package WordPress
500  * @subpackage Feed
501  * @since 2.5
502  */
503 function self_link() {
504         $host = @parse_url(get_option('home'));
505         $host = $host['host'];
506         echo esc_url(
507                 'http'
508                 . ( (isset($_SERVER['https']) && $_SERVER['https'] == 'on') ? 's' : '' ) . '://'
509                 . $host
510                 . stripslashes($_SERVER['REQUEST_URI'])
511                 );
512 }
513
514 /**
515  * Return the content type for specified feed type.
516  *
517  * @package WordPress
518  * @subpackage Feed
519  * @since 2.8.0
520  */
521 function feed_content_type( $type = '' ) {
522         if ( empty($type) )
523                 $type = get_default_feed();
524
525         $types = array(
526                 'rss'  => 'application/rss+xml',
527                 'rss2' => 'application/rss+xml',
528                 'rss-http'  => 'text/xml',
529                 'atom' => 'application/atom+xml',
530                 'rdf'  => 'application/rdf+xml'
531         );
532
533         $content_type = ( !empty($types[$type]) ) ? $types[$type] : 'application/octet-stream';
534
535         return apply_filters( 'feed_content_type', $content_type, $type );
536 }
537
538 /**
539  * Build SimplePie object based on RSS or Atom feed from URL.
540  *
541  * @since 2.8
542  *
543  * @param string $url URL to retrieve feed
544  * @return WP_Error|SimplePie WP_Error object on failure or SimplePie object on success
545  */
546 function fetch_feed($url) {
547         require_once (ABSPATH . WPINC . '/class-feed.php');
548
549         $feed = new SimplePie();
550         $feed->set_feed_url($url);
551         $feed->set_cache_class('WP_Feed_Cache');
552         $feed->set_file_class('WP_SimplePie_File');
553         $feed->set_cache_duration(apply_filters('wp_feed_cache_transient_lifetime', 43200));
554         $feed->init();
555         $feed->handle_content_type();
556
557         if ( $feed->error() )
558                 return new WP_Error('simplepie-error', $feed->error());
559
560         return $feed;
561 }