Ticket #36934: 36934.4.diff
File 36934.4.diff, 18.9 KB (added by , 7 years ago) |
---|
-
src/wp-includes/class-wp-post.php
diff --git src/wp-includes/class-wp-post.php src/wp-includes/class-wp-post.php index 2e3a32ada4..125b8ec4d8 100644
12 12 * 13 13 * @since 3.5.0 14 14 * 15 * @property string $page_template15 * @property string $page_template The post type template specified for this post. 16 16 * 17 * @property-read array $ancestors 18 * @property-read int $post_category 19 * @property-read string $tag_input 17 * @property-read array $ancestors The post's ancestors. 18 * @property-read array $post_category The categories associated with the post. 19 * @property-read array $tags_input The tags associated with the post. 20 * @property-read array $pages Array of all pages in post/page. Each array element contains part of the content 21 * separated by the <!--nextpage--> tag. 22 * @property-read int $multipage Boolean indicator for whether multiple pages are in play. 20 23 */ 21 24 final class WP_Post { 22 25 … … final class WP_Post { 277 280 * @return bool 278 281 */ 279 282 public function __isset( $key ) { 280 if ( 'ancestors' == $key ) { 281 return true; 282 } 283 284 if ( 'page_template' == $key ) { 285 return true; 286 } 287 288 if ( 'post_category' == $key ) { 289 return true; 290 } 291 292 if ( 'tags_input' == $key ) { 293 return true; 283 switch( $key ) { 284 case 'ancestors': 285 case 'page_template': 286 case 'post_category': 287 case 'tags_input': 288 case 'pages': 289 case 'multipage': 290 return true; 291 default: 292 return metadata_exists( 'post', $this->ID, $key ); 294 293 } 295 296 return metadata_exists( 'post', $this->ID, $key );297 294 } 298 295 299 296 /** … … final class WP_Post { 333 330 return wp_list_pluck( $terms, 'name' ); 334 331 } 335 332 333 if ( 'pages' === $key ) { 334 $content = $this->post_content; 335 if ( false !== strpos( $content, '<!--nextpage-->' ) ) { 336 $content = str_replace( 337 array( 338 "\n<!--nextpage-->\n", 339 "\n<!--nextpage-->", 340 "<!--nextpage-->\n" 341 ), 342 '<!--nextpage-->', 343 $content 344 ); 345 346 // Ignore nextpage at the beginning of the content. 347 if ( 0 === strpos( $content, '<!--nextpage-->' ) ) { 348 $content = substr( $content, 15 ); 349 } 350 351 $pages = explode( '<!--nextpage-->', $content ); 352 } else { 353 $pages = array( $this->post_content ); 354 } 355 356 /** 357 * Filters the "pages" derived from splitting the post content. 358 * 359 * "Pages" are determined by splitting the post content based on the presence 360 * of `<!-- nextpage -->` tags. 361 * 362 * @since 4.4.0 363 * 364 * @param array $pages Array of "pages" derived from the post content. 365 * of `<!-- nextpage -->` tags. 366 * @param WP_Post $post Current post object. 367 */ 368 return apply_filters( 'content_pagination', $pages, $this ); 369 } 370 371 if ( 'multipage' === $key ) { 372 $numpages = count( $this->pages ); 373 374 return ( $numpages > 1 ) ? 1 : 0; 375 } 376 336 377 // Rest of the values need filtering. 337 378 if ( 'ancestors' == $key ) { 338 379 $value = get_post_ancestors( $this ); -
src/wp-includes/class-wp-query.php
diff --git src/wp-includes/class-wp-query.php src/wp-includes/class-wp-query.php index 930e33d883..8c6886fe39 100644
class WP_Query { 3161 3161 if ( is_array( $this->posts ) ) { 3162 3162 $this->found_posts = count( $this->posts ); 3163 3163 } else { 3164 if ( null === $this->posts ) { 3164 if ( null === $this->posts ) { 3165 3165 $this->found_posts = 0; 3166 3166 } else { 3167 3167 $this->found_posts = 1; … … class WP_Query { 4135 4135 $numpages = 1; 4136 4136 $multipage = 0; 4137 4137 $page = $this->get( 'page' ); 4138 if ( ! $page ) {4138 if ( ! $page || $post->ID !== get_queried_object_id() ) { 4139 4139 $page = 1; 4140 4140 } 4141 4141 … … class WP_Query { 4151 4151 $more = 0; 4152 4152 } 4153 4153 4154 $content = $post->post_content; 4155 if ( false !== strpos( $content, '<!--nextpage-->' ) ) { 4156 $content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content ); 4157 $content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content ); 4158 $content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content ); 4159 4160 // Ignore nextpage at the beginning of the content. 4161 if ( 0 === strpos( $content, '<!--nextpage-->' ) ) { 4162 $content = substr( $content, 15 ); 4163 } 4164 4165 $pages = explode( '<!--nextpage-->', $content ); 4166 } else { 4167 $pages = array( $post->post_content ); 4168 } 4169 4170 /** 4171 * Filters the "pages" derived from splitting the post content. 4172 * 4173 * "Pages" are determined by splitting the post content based on the presence 4174 * of `<!-- nextpage -->` tags. 4175 * 4176 * @since 4.4.0 4177 * 4178 * @param array $pages Array of "pages" derived from the post content. 4179 * of `<!-- nextpage -->` tags.. 4180 * @param WP_Post $post Current post object. 4181 */ 4182 $pages = apply_filters( 'content_pagination', $pages, $post ); 4183 4154 $pages = $post->pages; 4184 4155 $numpages = count( $pages ); 4156 $multipage = $post->multipage; 4185 4157 4186 if ( $numpages > 1 ) { 4187 if ( $page > 1 ) { 4188 $more = 1; 4189 } 4190 $multipage = 1; 4191 } else { 4192 $multipage = 0; 4158 if ( $numpages > 1 && $page > 1 ) { 4159 $more = 1; 4193 4160 } 4194 4161 4195 4162 /** -
src/wp-includes/default-filters.php
diff --git src/wp-includes/default-filters.php src/wp-includes/default-filters.php index 53f1d7b247..29b89a7e64 100644
add_filter( 'the_excerpt', 'convert_smilies' ); 155 155 add_filter( 'the_excerpt', 'convert_chars' ); 156 156 add_filter( 'the_excerpt', 'wpautop' ); 157 157 add_filter( 'the_excerpt', 'shortcode_unautop' ); 158 add_filter( 'get_the_excerpt', 'wp_trim_excerpt' );158 add_filter( 'get_the_excerpt', 'wp_trim_excerpt', 10, 2 ); 159 159 160 160 add_filter( 'the_post_thumbnail_caption', 'wptexturize' ); 161 161 add_filter( 'the_post_thumbnail_caption', 'convert_smilies' ); -
src/wp-includes/formatting.php
diff --git src/wp-includes/formatting.php src/wp-includes/formatting.php index 8648287f81..1e24e473a1 100644
function human_time_diff( $from, $to = '' ) { 3558 3558 * The ' […]' string can be modified by plugins/themes using the {@see 'excerpt_more'} filter 3559 3559 * 3560 3560 * @since 1.5.0 3561 * @since 4.7.0 Introduced the `$post` parameter. 3561 3562 * 3562 3563 * @param string $text Optional. The excerpt. If set to empty, an excerpt is generated. 3564 * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. 3563 3565 * @return string The excerpt. 3564 3566 */ 3565 function wp_trim_excerpt( $text = '' ) {3567 function wp_trim_excerpt( $text = '', $post = null ) { 3566 3568 $raw_excerpt = $text; 3567 if ( '' == $text ) {3568 $text = get_the_content( '');3569 if ( '' === $text ) { 3570 $text = get_the_content( $post, array( 'more_link_text' => '' ) ); 3569 3571 3570 3572 $text = strip_shortcodes( $text ); 3571 3573 -
src/wp-includes/post-template.php
diff --git src/wp-includes/post-template.php src/wp-includes/post-template.php index 22d9864939..39a47893a4 100644
function the_content( $more_link_text = null, $strip_teaser = false ) { 257 257 * @global int $page Page number of a single post/page. 258 258 * @global int $more Boolean indicator for whether single post/page is being viewed. 259 259 * @global bool $preview Whether post/page is in preview mode. 260 * @global array $pages Array of all pages in post/page. Each array element contains part of the content separated by the <!--nextpage--> tag.261 * @global int $multipage Boolean indicator for whether multiple pages are in play.262 260 * 263 * @param string $more_link_text Optional. Content for when there is more text. 264 * @param bool $strip_teaser Optional. Strip teaser content before the more text. Default is false. 261 * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. 262 * @param array $args { 263 * Array of arguments. 264 * 265 * @type string $more_link_text Optional. Content for when there is more text. Default null. 266 * @type bool $strip_teaser Optional. Strip teaser content before the more text. Default is false. 267 * } 265 268 * @return string 266 269 */ 267 function get_the_content( $more_link_text = null, $strip_teaser = false ) { 268 global $page, $more, $preview, $pages, $multipage; 270 function get_the_content( $post = null, $args = null ) { 271 global $page, $more, $preview; 272 273 $more_link_text = sprintf( 274 '<span aria-label="%1$s">%2$s</span>', 275 sprintf( 276 /* translators: %s: Name of current post */ 277 __( 'Continue reading %s' ), 278 the_title_attribute( array( 'echo' => false ) ) 279 ), 280 __( '(more…)' ) 281 ); 269 282 270 $post = get_post(); 283 $defaults = array( 284 'more_link_text' => $more_link_text, 285 'strip_teaser' => false, 286 ); 271 287 272 if ( null === $more_link_text ) { 273 $more_link_text = sprintf( 274 '<span aria-label="%1$s">%2$s</span>', 275 sprintf( 276 /* translators: %s: Name of current post */ 277 __( 'Continue reading %s' ), 278 the_title_attribute( array( 'echo' => false ) ) 279 ), 280 __( '(more…)' ) 288 // Backward compatibility for the old function signature. 289 if ( is_bool( $args ) || is_string( $post ) ) { 290 $args = array( 291 'more_link_text' => $post, 292 'strip_teaser' => $args, 281 293 ); 294 295 $post = null; 282 296 } 283 297 298 $args = wp_parse_args( $args, $defaults ); 299 300 $post = get_post( $post ); 301 284 302 $output = ''; 285 303 $has_teaser = false; 286 304 … … function get_the_content( $more_link_text = null, $strip_teaser = false ) { 289 307 return get_the_password_form( $post ); 290 308 } 291 309 292 if ( $page > count( $pages ) ) { // if the requested page doesn't exist 293 $page = count( $pages ); // give them the highest numbered page that DOES exist 310 setup_postdata( $post ); 311 312 if ( $page > count( $post->pages ) ) { // if the requested page doesn't exist 313 $page = count( $post->pages ); // give them the highest numbered page that DOES exist 294 314 } 295 315 296 $content = $p ages[ $page - 1 ];316 $content = $post->pages[ $page - 1 ]; 297 317 if ( preg_match( '/<!--more(.*?)?-->/', $content, $matches ) ) { 298 318 $content = explode( $matches[0], $content, 2 ); 299 if ( ! empty( $matches[1] ) && ! empty( $ more_link_text) ) {300 $ more_link_text= strip_tags( wp_kses_no_null( trim( $matches[1] ) ) );319 if ( ! empty( $matches[1] ) && ! empty( $args['more_link_text'] ) ) { 320 $args['more_link_text'] = strip_tags( wp_kses_no_null( trim( $matches[1] ) ) ); 301 321 } 302 322 303 323 $has_teaser = true; … … function get_the_content( $more_link_text = null, $strip_teaser = false ) { 305 325 $content = array( $content ); 306 326 } 307 327 308 if ( false !== strpos( $post->post_content, '<!--noteaser-->' ) && ( ! $ multipage || $page== 1 ) ) {309 $ strip_teaser= true;328 if ( false !== strpos( $post->post_content, '<!--noteaser-->' ) && ( ! $post->multipage || (int) $page === 1 ) ) { 329 $args['strip_teaser'] = true; 310 330 } 311 331 312 332 $teaser = $content[0]; 313 333 314 if ( $more && $ strip_teaser&& $has_teaser ) {334 if ( $more && $args['strip_teaser'] && $has_teaser ) { 315 335 $teaser = ''; 316 336 } 317 337 … … function get_the_content( $more_link_text = null, $strip_teaser = false ) { 321 341 if ( $more ) { 322 342 $output .= '<span id="more-' . $post->ID . '"></span>' . $content[1]; 323 343 } else { 324 if ( ! empty( $more_link_text ) ) { 344 if ( ! empty( $args['more_link_text'] ) ) { 345 $more_link = sprintf( 346 ' <a href="%s#more-%d" class="more-link">%s</a>', 347 get_permalink(), 348 $post->ID, 349 $args['more_link_text'] 350 ); 325 351 326 352 /** 327 353 * Filters the Read More link text. … … function get_the_content( $more_link_text = null, $strip_teaser = false ) { 331 357 * @param string $more_link_element Read More link element. 332 358 * @param string $more_link_text Read More text. 333 359 */ 334 $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-{$post->ID}\" class=\"more-link\">$more_link_text</a>", $more_link_text );360 $output .= apply_filters( 'the_content_more_link', $more_link, $more_link_text ); 335 361 } 336 362 $output = force_balance_tags( $output ); 337 363 } … … function get_the_content( $more_link_text = null, $strip_teaser = false ) { 341 367 $output = preg_replace_callback( '/\%u([0-9A-F]{4})/', '_convert_urlencoded_to_entities', $output ); 342 368 } 343 369 370 wp_reset_postdata(); 371 344 372 return $output; 345 373 } 346 374 … … function get_the_excerpt( $post = null ) { 413 441 414 442 /** 415 443 * Determines whether the post has a custom excerpt. 416 * 444 * 417 445 * For more information on this and similar theme functions, check out 418 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 446 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 419 447 * Conditional Tags} article in the Theme Developer Handbook. 420 448 * 421 449 * @since 2.3.0 … … function get_the_password_form( $post = 0 ) { 1695 1723 * This template tag allows you to determine if you are in a page template. 1696 1724 * You can optionally provide a template name or array of template names 1697 1725 * and then the check will be specific to that template. 1698 * 1726 * 1699 1727 * For more information on this and similar theme functions, check out 1700 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 1728 * the {@link https://developer.wordpress.org/themes/basics/conditional-tags/ 1701 1729 * Conditional Tags} article in the Theme Developer Handbook. 1702 * 1730 * 1703 1731 * @since 2.5.0 1704 1732 * @since 4.2.0 The `$template` parameter was changed to also accept an array of page templates. 1705 1733 * @since 4.7.0 Now works with any post type, not just pages. -
tests/phpunit/tests/formatting/WpTrimExcerpt.php
diff --git tests/phpunit/tests/formatting/WpTrimExcerpt.php tests/phpunit/tests/formatting/WpTrimExcerpt.php index b2c026a957..9628fe4cbe 100644
class Tests_Formatting_WpTrimExcerpt extends WP_UnitTestCase { 32 32 while ( $q->have_posts() ) { 33 33 $q->the_post(); 34 34 $this->assertSame( 'Post 2 Page 1', wp_trim_excerpt() ); 35 $this->assertSame( 'Post 1 Page 1Post 1 Page 2', wp_trim_excerpt( '', $post1 ) ); 35 36 } 36 37 } 37 38 } … … class Tests_Formatting_WpTrimExcerpt extends WP_UnitTestCase { 63 64 while ( $q->have_posts() ) { 64 65 $q->the_post(); 65 66 $this->assertSame( 'Post 2 Page 1', wp_trim_excerpt() ); 67 $this->assertSame( 'Post 1 Page 1', wp_trim_excerpt( '', $post1 ) ); 66 68 } 67 69 } 68 70 } 71 72 /** 73 * @ticket 36934 74 */ 75 public function test_should_fall_back_on_current_post_when_text_is_empty() { 76 $GLOBALS['post'] = self::factory()->post->create_and_get( array( 'post_content' => 'Foo' ) ); 77 78 $this->assertSame( 'Foo', wp_trim_excerpt( '' ) ); 79 } 80 81 /** 82 * @ticket 36934 83 */ 84 public function test_should_respect_post_param_when_text_is_empty() { 85 $GLOBALS['post'] = self::factory()->post->create_and_get( array( 'post_content' => 'Foo' ) ); 86 87 $other_post = self::factory()->post->create_and_get( array( 'post_content' => 'Bar' ) ); 88 $this->assertSame( 'Bar', wp_trim_excerpt( '', $other_post ) ); 89 } 90 91 /** 92 * @ticket 36934 93 */ 94 public function test_should_give_precedence_to_passed_excerpt() { 95 $post = self::factory()->post->create_and_get( array( 'post_content' => 'Foo' ) ); 96 $this->assertSame( 'Foo', wp_trim_excerpt( 'Foo', $post ) ); 97 } 69 98 } -
new file tests/phpunit/tests/post/getTheContent.php
diff --git tests/phpunit/tests/post/getTheContent.php tests/phpunit/tests/post/getTheContent.php new file mode 100644 index 0000000000..9e1da323b5
- + 1 <?php 2 3 /** 4 * @group post 5 */ 6 class Tests_Post_GetTheContent extends WP_UnitTestCase { 7 /** 8 * @ticket 36934 9 */ 10 public function test_argument_back_compat_more_link_text() { 11 $text = 'Foo<!--more-->Bar'; 12 $p = self::factory()->post->create( array( 'post_content' => $text ) ); 13 14 $q = new WP_Query( array( 'p' => $p ) ); 15 while ( $q->have_posts() ) { 16 $q->the_post(); 17 18 $found = get_the_content( 'Ping' ); 19 } 20 21 $this->assertContains( '>Ping<', $found ); 22 } 23 24 /** 25 * @ticket 36934 26 */ 27 public function test_argument_back_compat_strip_teaser() { 28 $text = 'Foo<!--more-->Bar'; 29 $p = self::factory()->post->create( array( 'post_content' => $text ) ); 30 31 $this->go_to( get_permalink( $p ) ); 32 33 $q = new WP_Query( array( 'p' => $p ) ); 34 while ( $q->have_posts() ) { 35 $q->the_post(); 36 37 $found = get_the_content( null, true ); 38 } 39 40 $this->assertNotContains( 'Foo', $found ); 41 } 42 43 /** 44 * @ticket 36934 45 */ 46 public function test_should_respect_pagination_of_inner_post() { 47 $text_1 = 'Foo<!--nextpage-->Bar<!--nextpage-->Baz'; 48 $post_1 = self::factory()->post->create_and_get( array( 'post_content' => $text_1 ) ); 49 50 $text_2 = 'Bing<!--nextpage-->Bang<!--nextpage-->Boom'; 51 $post_2 = self::factory()->post->create_and_get( array( 'post_content' => $text_2 ) ); 52 $go_to = add_query_arg( 'page', '2', get_permalink( $post_1->ID ) ); 53 $this->go_to( $go_to ); 54 55 while ( have_posts() ) { 56 the_post(); 57 $found = get_the_content( $post_2, array( 'more_link_text' => '' ) ); 58 } 59 60 $this->assertSame( 'Bing', $found ); 61 } 62 } -
tests/phpunit/tests/post/getTheExcerpt.php
diff --git tests/phpunit/tests/post/getTheExcerpt.php tests/phpunit/tests/post/getTheExcerpt.php index 65e5bb0f03..e4b31c60f3 100644
class Tests_Post_GetTheExcerpt extends WP_UnitTestCase { 57 57 $post_id = self::factory()->post->create( array( 'post_excerpt' => 'Bar' ) ); 58 58 $this->assertSame( 'Bar', get_the_excerpt( $post_id ) ); 59 59 } 60 61 /** 62 * @ticket 36934 63 */ 64 public function test_should_fall_back_on_post_content_if_excerpt_is_empty_and_post_is_inferred_from_context() { 65 $post_id = self::factory()->post->create( array( 'post_content' => 'Foo', 'post_excerpt' => '' ) ); 66 $q = new WP_Query( array( 67 'p' => $post_id, 68 ) ); 69 70 while ( $q->have_posts() ) { 71 $q->the_post(); 72 $found = get_the_excerpt(); 73 } 74 75 $this->assertSame( 'Foo', $found ); 76 } 77 78 /** 79 * @ticket 36934 80 */ 81 public function test_should_fall_back_on_post_content_if_excerpt_is_empty_and_post_is_provided() { 82 $GLOBALS['post'] = self::factory()->post->create_and_get( array( 'post_content' => 'Foo', 'post_excerpt' => '' ) ); 83 $this->assertSame( 'Foo', get_the_excerpt( $GLOBALS['post'] ) ); 84 } 85 86 /** 87 * @ticket 36934 88 */ 89 public function test_should_respect_post_parameter_in_the_loop() { 90 $p1 = self::factory()->post->create_and_get( array( 'post_excerpt' => 'Foo' ) ); 91 $p2 = self::factory()->post->create_and_get( array( 'post_excerpt' => 'Bar' ) ); 92 $q = new WP_Query( array( 93 'p' => $p1->ID, 94 ) ); 95 96 while ( $q->have_posts() ) { 97 $q->the_post(); 98 $found = get_the_excerpt( $p2 ); 99 } 100 101 $this->assertSame( 'Bar', $found ); 102 } 103 104 /** 105 * @ticket 36934 106 */ 107 public function test_should_respect_post_parameter_in_the_loop_when_falling_back_on_post_content() { 108 $p1 = self::factory()->post->create_and_get( array( 'post_content' => 'Foo', 'post_excerpt' => '' ) ); 109 $p2 = self::factory()->post->create_and_get( array( 'post_content' => 'Bar', 'post_excerpt' => '' ) ); 110 $q = new WP_Query( array( 111 'p' => $p1->ID, 112 ) ); 113 114 while ( $q->have_posts() ) { 115 $q->the_post(); 116 $found = get_the_excerpt( $p2 ); 117 } 118 119 $this->assertSame( 'Bar', $found ); 120 } 60 121 }