From a2b4bc456f898ba1df9d6392c7b03a3be51e341a Mon Sep 17 00:00:00 2001 From: Ryan Boren Date: Mon, 20 May 2013 11:05:50 +0000 Subject: [PATCH] * Introduce wp_parse_post_content() and use it in setup_postdata(), get_the_content(), and get_the_remaining_content(). * Add a post ID argument to the_content(), get_the_content(), the_remaining_content(), and get_the_remaining_content(). * Pass the post ID to the the_content filter. * Remove the format_pages global. * Declare format_content and split_content as vars in WP_Post. * phpdoc for the the_content filter that documents the new ID argument and denotes it as not-so-portable. Props gcorne, DrewAPicture, duck_, aaroncampbell see #24330 git-svn-id: http://core.svn.wordpress.org/trunk@24301 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-includes/comment.php | 2 +- wp-includes/default-filters.php | 2 +- wp-includes/post-formats.php | 30 ++++++++------ wp-includes/post-template.php | 40 +++++++++++++----- wp-includes/post.php | 73 +++++++++++++++++++++++++++++++++ wp-includes/query.php | 46 +++------------------ 6 files changed, 128 insertions(+), 65 deletions(-) diff --git a/wp-includes/comment.php b/wp-includes/comment.php index 439cd098fa..983d90561c 100644 --- a/wp-includes/comment.php +++ b/wp-includes/comment.php @@ -1749,7 +1749,7 @@ function do_trackbacks($post_id) { } if ( empty($post->post_excerpt) ) - $excerpt = apply_filters('the_content', $post->post_content); + $excerpt = apply_filters('the_content', $post->post_content, $post->ID); else $excerpt = apply_filters('the_excerpt', $post->post_excerpt); $excerpt = str_replace(']]>', ']]>', $excerpt); diff --git a/wp-includes/default-filters.php b/wp-includes/default-filters.php index c513e7f082..1829321e14 100644 --- a/wp-includes/default-filters.php +++ b/wp-includes/default-filters.php @@ -136,7 +136,7 @@ add_filter( 'the_title', 'convert_chars' ); add_filter( 'the_title', 'trim' ); add_filter( 'the_title', '_post_formats_title', 10, 2 ); -add_filter( 'the_content', 'post_formats_compat', 7 ); +add_filter( 'the_content', 'post_formats_compat', 7, 2 ); add_filter( 'the_content', 'wptexturize' ); add_filter( 'the_content', 'convert_smilies' ); add_filter( 'the_content', 'convert_chars' ); diff --git a/wp-includes/post-formats.php b/wp-includes/post-formats.php index 6ef2aaa0cc..5a2c1f7030 100644 --- a/wp-includes/post-formats.php +++ b/wp-includes/post-formats.php @@ -866,12 +866,15 @@ function the_post_format_url() { * * @param string $more_link_text Optional. Content for when there is more text. * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false. + * @param int $id Optional. A post id. Defaults to the current post when in The Loop, undefined otherwise. * @return string The content minus the extracted post format content. */ -function get_the_remaining_content( $more_link_text = null, $strip_teaser = false ) { - global $more, $page, $format_pages, $multipage, $preview; +function get_the_remaining_content( $more_link_text = null, $strip_teaser = false, $id = 0 ) { + global $more, $page, $preview; - $post = get_post(); + $post = get_post( $id ); + + extract( wp_parse_post_content( $post, true ) ); if ( null === $more_link_text ) $more_link_text = __( '(more…)' ); @@ -880,13 +883,13 @@ function get_the_remaining_content( $more_link_text = null, $strip_teaser = fals $has_teaser = false; // If post password required and it doesn't match the cookie. - if ( post_password_required() ) - return get_the_password_form(); + if ( post_password_required( $post ) ) + return get_the_password_form( $post ); - if ( $page > count( $format_pages ) ) // if the requested page doesn't exist - $page = count( $format_pages ); // give them the highest numbered page that DOES exist + if ( $page > count( $pages ) ) // if the requested page doesn't exist + $page = count( $pages ); // give them the highest numbered page that DOES exist - $content = $format_pages[$page-1]; + $content = $pages[$page-1]; if ( preg_match( '//', $content, $matches ) ) { $content = explode( $matches[0], $content, 2 ); if ( ! empty( $matches[1] ) && ! empty( $more_link_text ) ) @@ -931,13 +934,16 @@ function get_the_remaining_content( $more_link_text = null, $strip_teaser = fals * * @param string $more_link_text Optional. Content for when there is more text. * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false. + * @param int $id Optional. A post id. Defaults to the current post when in The Loop, undefined otherwise. */ -function the_remaining_content( $more_link_text = null, $strip_teaser = false ) { - $extra = get_the_remaining_content( $more_link_text, $strip_teaser ); +function the_remaining_content( $more_link_text = null, $strip_teaser = false, $id = 0 ) { + $post = get_post( $id ); + + $extra = get_the_remaining_content( $more_link_text, $strip_teaser, $post->ID ); remove_filter( 'the_content', 'post_formats_compat', 7 ); - $content = apply_filters( 'the_content', $extra ); - add_filter( 'the_content', 'post_formats_compat', 7 ); + $content = apply_filters( 'the_content', $extra, $post->ID ); + add_filter( 'the_content', 'post_formats_compat', 7, 2 ); echo str_replace( ']]>', ']]>', $content ); } diff --git a/wp-includes/post-template.php b/wp-includes/post-template.php index 84976fecf9..0eeaa5bb40 100644 --- a/wp-includes/post-template.php +++ b/wp-includes/post-template.php @@ -160,9 +160,20 @@ function get_the_guid( $id = 0 ) { * * @param string $more_link_text Optional. Content for when there is more text. * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false. + * @param int $id Optional. A post id. Defaults to the current post when in The Loop, undefined otherwise. */ -function the_content( $more_link_text = null, $strip_teaser = false ) { - $content = apply_filters( 'the_content', get_the_content( $more_link_text, $strip_teaser ) ); +function the_content( $more_link_text = null, $strip_teaser = false, $id = 0 ) { + $post = get_post( $id ); + + /* + * Filter: the_content + * + * param string Post content as returned by get_the_content() + * param int The ID of the post to which the content belongs. This was introduced + * in 3.6.0 and is not reliably passed by all plugins and themes that + * directly apply the_content. As such, it is not considered portable. + */ + $content = apply_filters( 'the_content', get_the_content( $more_link_text, $strip_teaser, $post->ID ), $post->ID ); echo str_replace( ']]>', ']]>', $content ); } @@ -173,12 +184,19 @@ function the_content( $more_link_text = null, $strip_teaser = false ) { * * @param string $more_link_text Optional. Content for when there is more text. * @param bool $stripteaser Optional. Strip teaser content before the more text. Default is false. + * @param int $id Optional. A post id. Defaults to the current post when in The Loop, undefined otherwise. * @return string */ -function get_the_content( $more_link_text = null, $strip_teaser = false ) { - global $more, $page, $pages, $multipage, $preview; +function get_the_content( $more_link_text = null, $strip_teaser = false, $id = 0 ) { + global $page, $more, $preview; - $post = get_post(); + $post = get_post( $id ); + // Avoid parsing again if the post is the same one parsed by setup_postdata(). + // The extract() will set up $pages and $multipage. + if ( $post->ID != $GLOBALS['id'] ) + extract( wp_parse_post_content( $post, false ) ); + else + global $pages, $multipage; if ( null === $more_link_text ) $more_link_text = __( '(more…)' ); @@ -187,8 +205,8 @@ function get_the_content( $more_link_text = null, $strip_teaser = false ) { $has_teaser = false; // If post password required and it doesn't match the cookie. - if ( post_password_required() ) - return get_the_password_form(); + if ( post_password_required( $post ) ) + return get_the_password_form( $post ); if ( $page > count( $pages ) ) // if the requested page doesn't exist $page = count( $pages ); // give them the highest numbered page that DOES exist @@ -566,7 +584,7 @@ function get_body_class( $class = '' ) { * * @since 2.7.0 * - * @param int|object $post An optional post. Global $post used if not provided. + * @param int|WP_Post $post An optional post. Global $post used if not provided. * @return bool false if a password is not required or the correct password cookie is present, true otherwise. */ function post_password_required( $post = null ) { @@ -1225,11 +1243,11 @@ function prepend_attachment($content) { * * @since 1.0.0 * @uses apply_filters() Calls 'the_password_form' filter on output. - * + * @param int|WP_Post $post Optional. A post id or post object. Defaults to the current post when in The Loop, undefined otherwise. * @return string HTML content for password form for password protected post. */ -function get_the_password_form() { - $post = get_post(); +function get_the_password_form( $post = 0 ) { + $post = get_post( $post ); $label = 'pwbox-' . ( empty($post->ID) ? rand() : $post->ID ); $output = '

' . __("This post is password protected. To view it please enter your password below:") . '

diff --git a/wp-includes/post.php b/wp-includes/post.php index 84d9c27952..297e69ff11 100644 --- a/wp-includes/post.php +++ b/wp-includes/post.php @@ -567,6 +567,26 @@ final class WP_Post { */ public $filter; + /** + * Private variable used by post formats to cache parsed content. + * + * @since 3.6.0 + * + * @var array + * @access private + */ + public $format_content; + + /** + * Private variable used by post formats to cache parsed content. + * + * @since 3.6.0 + * + * @var string + * @access private + */ + public $split_content; + public static function get_instance( $post_id ) { global $wpdb; @@ -4962,3 +4982,56 @@ function _prime_post_caches( $ids, $update_term_cache = true, $update_meta_cache update_post_caches( $fresh_posts, 'any', $update_term_cache, $update_meta_cache ); } } + +/** + * Parse post content for pagination + * + * @since 3.6.0 + * + * @uses paginate_content() + * + * @param object $post The post object. + * @param bool $remaining Whether to parse post formats from the content. Defaults to false. + * @return array An array of values used for paginating the parsed content. + */ +function wp_parse_post_content( $post, $remaining = false ) { + $numpages = 1; + + if ( $remaining ) { + $format = get_post_format( $post ); + if ( $format && in_array( $format, array( 'image', 'audio', 'video', 'quote' ) ) ) { + // Call get_the_post_format_*() to set $post->split_content + switch ( $format ) { + case 'image': + get_the_post_format_image( 'full', $post ); + break; + case 'audio': + get_the_post_format_media( 'audio', $post, 1 ); + break; + case 'video': + get_the_post_format_media( 'video', $post, 1 ); + break; + case 'quote': + get_the_post_format_quote( $post ); + break; + } + } + } + + if ( strpos( $post->post_content, '' ) ) { + $multipage = 1; + if ( $remaining && isset( $post->split_content ) ) + $pages = paginate_content( $post->split_content ); + else + $pages = paginate_content( $post->post_content ); + $numpages = count( $pages ); + } else { + if ( $remaining && isset( $post->split_content ) ) + $pages = array( $post->split_content ); + else + $pages = array( $post->post_content ); + $multipage = 0; + } + + return compact( 'multipage', 'pages', 'numpages' ); +} diff --git a/wp-includes/query.php b/wp-includes/query.php index 441e5a84ca..29b2661165 100644 --- a/wp-includes/query.php +++ b/wp-includes/query.php @@ -3681,8 +3681,8 @@ function get_paged_content( $content = '', $paged = 0 ) { * @uses do_action_ref_array() Calls 'the_post' * @return bool True when finished. */ -function setup_postdata($post) { - global $id, $authordata, $currentday, $currentmonth, $page, $pages, $format_pages, $multipage, $more, $numpages; +function setup_postdata( $post ) { + global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages; $id = (int) $post->ID; @@ -3692,49 +3692,15 @@ function setup_postdata($post) { $currentmonth = mysql2date('m', $post->post_date, false); $numpages = 1; $page = get_query_var('page'); - if ( !$page ) + if ( ! $page ) $page = 1; if ( is_single() || is_page() || is_feed() ) $more = 1; - $split_content = $content = $post->post_content; - $format = get_post_format( $post ); - if ( $format && in_array( $format, array( 'image', 'audio', 'video', 'quote' ) ) ) { - switch ( $format ) { - case 'image': - get_the_post_format_image( 'full', $post ); - if ( isset( $post->split_content ) ) - $split_content = $post->split_content; - break; - case 'audio': - get_the_post_format_media( 'audio', $post, 1 ); - if ( isset( $post->split_content ) ) - $split_content = $post->split_content; - break; - case 'video': - get_the_post_format_media( 'video', $post, 1 ); - if ( isset( $post->split_content ) ) - $split_content = $post->split_content; - break; - case 'quote': - get_the_post_format_quote( $post ); - if ( isset( $post->split_content ) ) - $split_content = $post->split_content; - break; - } - } - if ( strpos( $content, '' ) ) { - if ( $page > 1 ) + extract( wp_parse_post_content( $post, false ) ); + + if ( $multipage && ( $page > 1 ) ) $more = 1; - $multipage = 1; - $pages = paginate_content( $content ); - $format_pages = paginate_content( $split_content ); - $numpages = count( $pages ); - } else { - $pages = array( $post->post_content ); - $format_pages = array( $split_content ); - $multipage = 0; - } do_action_ref_array('the_post', array(&$post));