From c8bbc31c39f6a0d20f9a43d3e59b7925ee67e882 Mon Sep 17 00:00:00 2001 From: Andrew Nacin Date: Wed, 20 Nov 2013 22:58:09 +0000 Subject: [PATCH] Add an experimental rssjs feed based on the experimental rss.js spec. This is simply a JSON representation of the RSS 2.0 feed, accessible at /feed/rssjs/ anywhere. props pento. see #25639. Built from https://develop.svn.wordpress.org/trunk@26294 git-svn-id: http://core.svn.wordpress.org/trunk@26199 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/class-wp.php | 2 +- wp-includes/default-filters.php | 1 + wp-includes/feed-rssjs-comments.php | 127 ++++++++++++++++++++++++++++ wp-includes/feed-rssjs.php | 109 ++++++++++++++++++++++++ wp-includes/feed.php | 3 +- wp-includes/functions.php | 15 ++++ wp-includes/rewrite.php | 2 +- wp-includes/version.php | 4 +- 8 files changed, 258 insertions(+), 5 deletions(-) create mode 100644 wp-includes/feed-rssjs-comments.php create mode 100644 wp-includes/feed-rssjs.php diff --git a/wp-includes/class-wp.php b/wp-includes/class-wp.php index 2fe76fc8b7..0541d6a710 100644 --- a/wp-includes/class-wp.php +++ b/wp-includes/class-wp.php @@ -15,7 +15,7 @@ class WP { * @access public * @var array */ - var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type'); + var $public_query_vars = array('m', 'p', 'posts', 'w', 'cat', 'withcomments', 'withoutcomments', 's', 'search', 'exact', 'sentence', 'calendar', 'page', 'paged', 'more', 'tb', 'pb', 'author', 'order', 'orderby', 'year', 'monthnum', 'day', 'hour', 'minute', 'second', 'name', 'category_name', 'tag', 'feed', 'author_name', 'static', 'pagename', 'page_id', 'error', 'comments_popup', 'attachment', 'attachment_id', 'subpost', 'subpost_id', 'preview', 'robots', 'taxonomy', 'term', 'cpage', 'post_type', 'callback'); /** * Private query variables. diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php index b6c7527553..5725c1c55c 100644 --- a/wp-includes/default-filters.php +++ b/wp-includes/default-filters.php @@ -237,6 +237,7 @@ add_action( 'do_feed_rdf', 'do_feed_rdf', add_action( 'do_feed_rss', 'do_feed_rss', 10, 1 ); add_action( 'do_feed_rss2', 'do_feed_rss2', 10, 1 ); add_action( 'do_feed_atom', 'do_feed_atom', 10, 1 ); +add_action( 'do_feed_rssjs', 'do_feed_rssjs', 10, 1 ); add_action( 'do_pings', 'do_all_pings', 10, 1 ); add_action( 'do_robots', 'do_robots' ); add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 2 ); diff --git a/wp-includes/feed-rssjs-comments.php b/wp-includes/feed-rssjs-comments.php new file mode 100644 index 0000000000..a31f58dff2 --- /dev/null +++ b/wp-includes/feed-rssjs-comments.php @@ -0,0 +1,127 @@ +rss = new stdClass(); + +$json->rss->version = "2.0"; +$json->rss->channel = new stdClass(); + +if ( is_singular() ) + $json->rss->channel->title = sprintf( __( 'Comments on: %s' ), get_the_title() ); +elseif ( is_search() ) + $json->rss->channel->title = sprintf( __( 'Comments for %1$s searching on %2$s' ), get_bloginfo( 'name' ), get_search_query() ); +else + $json->rss->channel->title = sprintf( __( 'Comments for %s' ), get_bloginfo( 'name' ) . get_the_title() ); + +$json->rss->channel->link = get_bloginfo( 'url' ); +$json->rss->channel->description = get_bloginfo( 'description' ); +$json->rss->channel->language = get_bloginfo( 'language' ); +$json->rss->channel->lastBuildDate = mysql2date( 'D, d M Y H:i:s +0000', get_lastcommentmodified( 'GMT' ), false ); +$json->rss->channel->docs = "http://cyber.law.harvard.edu/rss/rss.html"; +$json->rss->channel->generator = 'WordPress ' . get_bloginfo( 'version' ); +$json->rss->channel->ttl = 15; + +$json->rss->channel->item = array(); + +header( 'Content-Type: ' . feed_content_type( 'rssjs' ) . '; charset=' . get_option( 'blog_charset' ), true ); + +/* + * The JSONP callback function to add to the JSON feed + * + * @since 3.8.0 + * + * @param string $callback The JSONP callback function name + */ +$callback = apply_filters( 'json_feed_callback', get_query_var( 'callback' ) ); + +if ( ! empty( $callback ) && ! apply_filters( 'json_jsonp_enabled', true ) ) { + status_header( 400 ); + echo json_encode( array( + 'code' => 'json_callback_disabled', + 'message' => 'JSONP support is disabled on this site.' + ) ); + exit; +} + +if ( preg_match( '/\W/', $callback ) ) { + status_header( 400 ); + echo json_encode( array( + 'code' => 'json_callback_invalid', + 'message' => 'The JSONP callback function is invalid.' + ) ); + exit; +} + +/* + * Action triggerd prior to the JSON feed being created and sent to the client + * + * @since 3.8.0 + */ +do_action( 'json_feed_pre' ); + +while( have_comments() ) { + the_comment(); + + $comment_post = $GLOBALS['post'] = get_post( $comment->comment_post_ID ); + + $item = new stdClass(); + + if ( !is_singular() ) { + $title = get_the_title( $comment_post->ID ); + $item->title = sprintf( __('Comment on %1$s by %2$s') , $title, get_comment_author() ); + } else { + $item->title = sprintf( __('By: %s'), get_comment_author() ); + } + + $item->link = get_comment_link(); + $item->guid = get_comment_guid(); + $item->pubDate = mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); + + if ( post_password_required( $comment_post ) ) { + $item->description = __( 'Protected Comments: Please enter your password to view comments.' ); + } else { + $item->description = get_comment_text(); + } + + /* + * The item to be added to the rss.js Comment feed + * + * @since 3.8.0 + * + * @param object $item The rss.js Comment item + */ + $item = apply_filters( 'comment_rssjs_feed_item', $item ); + + $json->rss->channel->item[] = $item; +} + +/* + * The data to be sent to the user as JSON + * + * @since 3.8.0 + * + * @param object $json The JSON data object + */ +$json = apply_filters( 'comment_rssjs_feed', $json ); + +$json_str = json_encode( $json ); + +if ( ! empty( $callback ) ) { + echo "$callback( $json_str );"; +} else { + echo $json_str; +} + +/* + * Action triggerd after the JSON feed has been created and sent to the client + * + * @since 3.8.0 + */ +do_action( 'json_feed_post' ); diff --git a/wp-includes/feed-rssjs.php b/wp-includes/feed-rssjs.php new file mode 100644 index 0000000000..3081fa0152 --- /dev/null +++ b/wp-includes/feed-rssjs.php @@ -0,0 +1,109 @@ +rss = new stdClass(); + +$json->rss->version = "2.0"; +$json->rss->channel = new stdClass(); + +$json->rss->channel->title = get_bloginfo( 'name' ); +$json->rss->channel->link = get_bloginfo( 'url' ); +$json->rss->channel->description = get_bloginfo( 'description' ); +$json->rss->channel->language = get_bloginfo( 'language' ); +$json->rss->channel->lastBuildDate = mysql2date( 'D, d M Y H:i:s +0000', get_lastpostmodified( 'GMT' ), false ); +$json->rss->channel->docs = "http://cyber.law.harvard.edu/rss/rss.html"; +$json->rss->channel->generator = 'WordPress ' . get_bloginfo( 'version' ); +$json->rss->channel->ttl = 15; + +$json->rss->channel->item = array(); + +header( 'Content-Type: ' . feed_content_type( 'rssjs' ) . '; charset=' . get_option( 'blog_charset' ), true ); + +/* + * The JSONP callback function to add to the JSON feed + * + * @since 3.8.0 + * + * @param string $callback The JSONP callback function name + */ +$callback = apply_filters( 'json_feed_callback', get_query_var( 'callback' ) ); + +if ( ! empty( $callback ) && ! apply_filters( 'json_jsonp_enabled', true ) ) { + status_header( 400 ); + echo json_encode( array( + 'code' => 'json_callback_disabled', + 'message' => 'JSONP support is disabled on this site.' + ) ); + exit; +} + +if ( preg_match( '/\W/', $callback ) ) { + status_header( 400 ); + echo json_encode( array( + 'code' => 'json_callback_invalid', + 'message' => 'The JSONP callback function is invalid.' + ) ); + exit; +} + +/* + * Action triggerd prior to the JSON feed being created and sent to the client + * + * @since 3.8.0 + */ +do_action( 'json_feed_pre' ); + +while( have_posts() ) { + the_post(); + + $item = new stdClass(); + + $item->title = get_the_title(); + $item->link = get_permalink(); + $item->guid = get_the_guid(); + $item->description = get_the_content(); + $item->pubDate = mysql2date( 'D, d M Y H:i:s +0000', get_post_time( 'Y-m-d H:i:s', true ), false ); + + /* + * The item to be added to the rss.js Post feed + * + * @since 3.8.0 + * + * @param object $item The rss.js Post item + */ + $item = apply_filters( 'rssjs_feed_item', $item ); + + $json->rss->channel->item[] = $item; +} + +/* + * The data to be sent to the user as JSON + * + * @since 3.8.0 + * + * @param object $json The JSON data object + */ +$json = apply_filters( 'rssjs_feed', $json ); + + +$json_str = json_encode( $json ); + +if ( ! empty( $callback ) ) { + echo "$callback( $json_str );"; +} else { + echo $json_str; +} + +/* + * Action triggerd after the JSON feed has been created and sent to the client + * + * @since 3.8.0 + */ +do_action( 'json_feed_post' ); diff --git a/wp-includes/feed.php b/wp-includes/feed.php index 99e2286ce1..e0491d7d0e 100644 --- a/wp-includes/feed.php +++ b/wp-includes/feed.php @@ -507,7 +507,8 @@ function feed_content_type( $type = '' ) { 'rss2' => 'application/rss+xml', 'rss-http' => 'text/xml', 'atom' => 'application/atom+xml', - 'rdf' => 'application/rdf+xml' + 'rdf' => 'application/rdf+xml', + 'rssjs' => 'application/json', ); $content_type = ( !empty($types[$type]) ) ? $types[$type] : 'application/octet-stream'; diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 12b1b603b2..f4e0d126b2 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -1082,6 +1082,21 @@ function do_feed_atom( $for_comments ) { load_template( ABSPATH . WPINC . '/feed-atom.php' ); } +/** + * Load either rssjs comment feed or rssjs posts feed. + * + * @since 3.8.0 + * + * @param bool $for_comments True for the comment feed, false for normal feed. + */ +function do_feed_rssjs( $for_comments ) { + if ( $for_comments ) { + load_template( ABSPATH . WPINC . '/feed-rssjs-comments.php' ); + } else { + load_template( ABSPATH . WPINC . '/feed-rssjs.php' ); + } +} + /** * Display the robots.txt file content. * diff --git a/wp-includes/rewrite.php b/wp-includes/rewrite.php index 2b48cdf83c..f4b9980576 100644 --- a/wp-includes/rewrite.php +++ b/wp-includes/rewrite.php @@ -743,7 +743,7 @@ class WP_Rewrite { * @access private * @var array */ - var $feeds = array( 'feed', 'rdf', 'rss', 'rss2', 'atom' ); + var $feeds = array( 'feed', 'rdf', 'rss', 'rss2', 'atom', 'rssjs' ); /** * Whether permalinks are being used. diff --git a/wp-includes/version.php b/wp-includes/version.php index 45a0f13576..9c27a3180a 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,14 +4,14 @@ * * @global string $wp_version */ -$wp_version = '3.8-alpha-26127'; +$wp_version = '3.8-alpha-26294'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. * * @global int $wp_db_version */ -$wp_db_version = 26148; +$wp_db_version = 26294; /** * Holds the TinyMCE version