Wordpress 2.6.2
[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 = wp_specialchars($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 function comment_guid() {
228         echo get_comment_guid();
229 }
230
231 /**
232  * Retrieve the feed GUID for the current comment.
233  *
234  * @package WordPress
235  * @subpackage Feed
236  * @since unknown
237  *
238  * @return bool|string false on failure or guid for comment on success.
239  */
240 function get_comment_guid() {
241         global $comment;
242
243         if ( !is_object($comment) )
244                 return false;
245
246         return get_the_guid($comment->comment_post_ID) . '#comment-' . $comment->comment_ID;
247 }
248
249 /**
250  * Display the link to the comments.
251  *
252  * @since 1.5.0
253  */
254 function comment_link() {
255         echo get_comment_link();
256 }
257
258 /**
259  * Retrieve the current comment author for use in the feeds.
260  *
261  * @package WordPress
262  * @subpackage Feed
263  * @since 2.0.0
264  * @uses apply_filters() Calls 'comment_author_rss' hook on comment author.
265  * @uses get_comment_author()
266  *
267  * @return string Comment Author
268  */
269 function get_comment_author_rss() {
270         return apply_filters('comment_author_rss', get_comment_author() );
271 }
272
273 /**
274  * Display the current comment author in the feed.
275  *
276  * @package WordPress
277  * @subpackage Feed
278  * @since 1.0.0
279  */
280 function comment_author_rss() {
281         echo get_comment_author_rss();
282 }
283
284 /**
285  * Display the current comment content for use in the feeds.
286  *
287  * @package WordPress
288  * @subpackage Feed
289  * @since 1.0.0
290  * @uses apply_filters() Calls 'comment_text_rss' filter on comment content.
291  * @uses get_comment_text()
292  */
293 function comment_text_rss() {
294         $comment_text = get_comment_text();
295         $comment_text = apply_filters('comment_text_rss', $comment_text);
296         echo $comment_text;
297 }
298
299 /**
300  * Retrieve all of the post categories, formatted for use in feeds.
301  *
302  * All of the categories for the current post in the feed loop, will be
303  * retrieved and have feed markup added, so that they can easily be added to the
304  * RSS2, Atom, or RSS1 and RSS0.91 RDF feeds.
305  *
306  * @package WordPress
307  * @subpackage Feed
308  * @since 2.1.0
309  * @uses apply_filters() 
310  *
311  * @param string $type Optional, default is 'rss'. Either 'rss', 'atom', or 'rdf'.
312  * @return string All of the post categories for displaying in the feed.
313  */
314 function get_the_category_rss($type = 'rss') {
315         $categories = get_the_category();
316         $tags = get_the_tags();
317         $the_list = '';
318         $cat_names = array();
319
320         $filter = 'rss';
321         if ( 'atom' == $type )
322                 $filter = 'raw';
323
324         if ( !empty($categories) ) foreach ( (array) $categories as $category ) {
325                 $cat_names[] = sanitize_term_field('name', $category->name, $category->term_id, 'category', $filter);
326         }
327
328         if ( !empty($tags) ) foreach ( (array) $tags as $tag ) {
329                 $cat_names[] = sanitize_term_field('name', $tag->name, $tag->term_id, 'post_tag', $filter);
330         }
331
332         $cat_names = array_unique($cat_names);
333
334         foreach ( $cat_names as $cat_name ) {
335                 if ( 'rdf' == $type )
336                         $the_list .= "\n\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n";
337                 elseif ( 'atom' == $type )
338                         $the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', attribute_escape( apply_filters( 'get_bloginfo_rss', get_bloginfo( 'url' ) ) ), attribute_escape( $cat_name ) );
339                 else
340                         $the_list .= "\n\t\t<category><![CDATA[$cat_name]]></category>\n";
341         }
342
343         return apply_filters('the_category_rss', $the_list, $type);
344 }
345
346 /**
347  * Display the post categories in the feed.
348  *
349  * @package WordPress
350  * @subpackage Feed
351  * @since 0.71
352  * @see get_the_category_rss() For better explanation.
353  *
354  * @param string $type Optional, default is 'rss'. Either 'rss', 'atom', or 'rdf'.
355  */
356 function the_category_rss($type = 'rss') {
357         echo get_the_category_rss($type);
358 }
359
360 /**
361  * Display the HTML type based on the blog setting.
362  *
363  * The two possible values are either 'xhtml' or 'html'.
364  *
365  * @package WordPress
366  * @subpackage Feed
367  * @since 2.2.0
368  */
369 function html_type_rss() {
370         $type = get_bloginfo('html_type');
371         if (strpos($type, 'xhtml') !== false)
372                 $type = 'xhtml';
373         else
374                 $type = 'html';
375         echo $type;
376 }
377
378 /**
379  * Display the rss enclosure for the current post.
380  *
381  * Uses the global $post to check whether the post requires a password and if
382  * the user has the password for the post. If not then it will return before
383  * displaying.
384  *
385  * Also uses the function get_post_custom() to get the post's 'enclosure'
386  * metadata field and parses the value to display the enclosure(s). The
387  * enclosure(s) consist of enclosure HTML tag(s) with a URI and other
388  * attributes.
389  *
390  * @package WordPress
391  * @subpackage Template
392  * @since 1.5.0
393  * @uses apply_filters() Calls 'rss_enclosure' hook on rss enclosure.
394  * @uses get_post_custom() To get the current post enclosure metadata.
395  */
396 function rss_enclosure() {
397         global $post;
398         if ( !empty($post->post_password) && (!isset($_COOKIE['wp-postpass_'.COOKIEHASH]) || $_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) )
399                 return;
400
401         foreach (get_post_custom() as $key => $val) {
402                 if ($key == 'enclosure') {
403                         foreach ((array)$val as $enc) {
404                                 $enclosure = split("\n", $enc);
405                                 echo apply_filters('rss_enclosure', '<enclosure url="' . trim(htmlspecialchars($enclosure[0])) . '" length="' . trim($enclosure[1]) . '" type="' . trim($enclosure[2]) . '" />' . "\n");
406                         }
407                 }
408         }
409 }
410
411 /**
412  * Display the atom enclosure for the current post.
413  *
414  * Uses the global $post to check whether the post requires a password and if
415  * the user has the password for the post. If not then it will return before
416  * displaying.
417  *
418  * Also uses the function get_post_custom() to get the post's 'enclosure'
419  * metadata field and parses the value to display the enclosure(s). The
420  * enclosure(s) consist of link HTML tag(s) with a URI and other attributes.
421  *
422  * @package WordPress
423  * @subpackage Template
424  * @since 2.2.0
425  * @uses apply_filters() Calls 'atom_enclosure' hook on atom enclosure.
426  * @uses get_post_custom() To get the current post enclosure metadata.
427  */
428 function atom_enclosure() {
429         global $post;
430         if ( !empty($post->post_password) && ($_COOKIE['wp-postpass_'.COOKIEHASH] != $post->post_password) )
431                 return;
432
433         foreach (get_post_custom() as $key => $val) {
434                 if ($key == 'enclosure') {
435                         foreach ((array)$val as $enc) {
436                                 $enclosure = split("\n", $enc);
437                                 echo apply_filters('atom_enclosure', '<link href="' . trim(htmlspecialchars($enclosure[0])) . '" rel="enclosure" length="' . trim($enclosure[1]) . '" type="' . trim($enclosure[2]) . '" />' . "\n");
438                         }
439                 }
440         }
441 }
442
443 /**
444  * Determine the type of a string of data with the data formatted.
445  *
446  * Tell whether the type is text, html, or xhtml, per RFC 4287 section 3.1.
447  *
448  * In the case of WordPress, text is defined as containing no markup,
449  * xhtml is defined as "well formed", and html as tag soup (i.e., the rest).
450  *
451  * Container div tags are added to xhtml values, per section 3.1.1.3.
452  *
453  * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1
454  *
455  * @package WordPress
456  * @subpackage Feed
457  * @since 2.5
458  *
459  * @param string $data Input string
460  * @return array array(type, value)
461  */
462 function prep_atom_text_construct($data) {
463         if (strpos($data, '<') === false && strpos($data, '&') === false) {
464                 return array('text', $data);
465         }
466
467         $parser = xml_parser_create();
468         xml_parse($parser, '<div>' . $data . '</div>', true);
469         $code = xml_get_error_code($parser);
470         xml_parser_free($parser);
471
472         if (!$code) {
473                 if (strpos($data, '<') === false) {
474                         return array('text', $data);
475                 } else {
476                         $data = "<div xmlns='http://www.w3.org/1999/xhtml'>$data</div>";
477                         return array('xhtml', $data);
478                 }
479         }
480
481         if (strpos($data, ']]>') == false) {
482                 return array('html', "<![CDATA[$data]]>");
483         } else {
484                 return array('html', htmlspecialchars($data));
485         }
486 }
487
488 /**
489  * Display the link for the currently displayed feed in a XSS safe way.
490  *
491  * Generate a correct link for the atom:self element.
492  *
493  * @package WordPress
494  * @subpackage Feed
495  * @since 2.5
496  */
497 function self_link() {
498         echo 'http'
499                 . ( $_SERVER['https'] == 'on' ? 's' : '' ) . '://'
500                 . $_SERVER['HTTP_HOST']
501                 . wp_specialchars(stripslashes($_SERVER['REQUEST_URI']), 1);
502 }
503
504 ?>