diff --git src/wp-includes/query.php src/wp-includes/query.php index 1334272..15da274 100644 --- src/wp-includes/query.php +++ src/wp-includes/query.php @@ -3710,7 +3710,7 @@ class WP_Query { do_action_ref_array( 'loop_start', array( &$this ) ); $post = $this->next_post(); - setup_postdata($post); + $this->setup_postdata( $post ); } /** @@ -4545,6 +4545,68 @@ class WP_Query { } /** + * Set up global post data. + * + * @since 4.1.0 + * + * @param object $post Post data. + * @return bool True when finished. + */ + public function setup_postdata( $post ) { + global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages; + + $id = (int) $post->ID; + + $authordata = get_userdata($post->post_author); + + $currentday = mysql2date('d.m.y', $post->post_date, false); + $currentmonth = mysql2date('m', $post->post_date, false); + $numpages = 1; + $multipage = 0; + $page = $this->get( 'page' ); + if ( ! $page ) + $page = 1; + + // Force full post content when viewing the permalink for the $post, or + // when on an RSS feed. Otherwise respect the 'more' tag. + if ( $post->ID === get_queried_object_id() && ( $this->is_page() || $this->is_single() ) ) { + $more = 1; + } else if ( $this->is_feed() ) { + $more = 1; + } else { + $more = 0; + } + + $content = $post->post_content; + if ( false !== strpos( $content, '' ) ) { + if ( $page > 1 ) + $more = 1; + $content = str_replace( "\n\n", '', $content ); + $content = str_replace( "\n", '', $content ); + $content = str_replace( "\n", '', $content ); + // Ignore nextpage at the beginning of the content. + if ( 0 === strpos( $content, '' ) ) + $content = substr( $content, 15 ); + $pages = explode('', $content); + $numpages = count($pages); + if ( $numpages > 1 ) + $multipage = 1; + } else { + $pages = array( $post->post_content ); + } + + /** + * Fires once the post data has been setup. + * + * @since 2.8.0 + * + * @param WP_Post &$post The Post object (passed by reference). + */ + do_action_ref_array( 'the_post', array( &$post ) ); + + return true; + } + /** * After looping through a nested query, this function * restores the $post global to the current post in this query. * @@ -4630,47 +4692,11 @@ function wp_old_slug_redirect() { * @return bool True when finished. */ function setup_postdata( $post ) { - global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages; - - $id = (int) $post->ID; - - $authordata = get_userdata($post->post_author); + global $wp_query; - $currentday = mysql2date('d.m.y', $post->post_date, false); - $currentmonth = mysql2date('m', $post->post_date, false); - $numpages = 1; - $multipage = 0; - $page = get_query_var('page'); - if ( ! $page ) - $page = 1; - if ( is_single() || is_page() || is_feed() ) - $more = 1; - $content = $post->post_content; - if ( false !== strpos( $content, '' ) ) { - if ( $page > 1 ) - $more = 1; - $content = str_replace( "\n\n", '', $content ); - $content = str_replace( "\n", '', $content ); - $content = str_replace( "\n", '', $content ); - // Ignore nextpage at the beginning of the content. - if ( 0 === strpos( $content, '' ) ) - $content = substr( $content, 15 ); - $pages = explode('', $content); - $numpages = count($pages); - if ( $numpages > 1 ) - $multipage = 1; - } else { - $pages = array( $post->post_content ); + if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) { + return $wp_query->setup_postdata( $post ); } - /** - * Fires once the post data has been setup. - * - * @since 2.8.0 - * - * @param WP_Post &$post The Post object (passed by reference). - */ - do_action_ref_array( 'the_post', array( &$post ) ); - - return true; + return false; } diff --git tests/phpunit/tests/formatting/WpTrimExcerpt.php tests/phpunit/tests/formatting/WpTrimExcerpt.php new file mode 100644 index 0000000..564e4b7 --- /dev/null +++ tests/phpunit/tests/formatting/WpTrimExcerpt.php @@ -0,0 +1,57 @@ +factory->post->create( array( + 'post_content' => 'Post 1 Page 1Post 1 Page 2', + ) ); + $post2 = $this->factory->post->create( array( + 'post_content' => 'Post 2 Page 1Post 2 Page 2', + ) ); + + $this->go_to( '/?p=' . $post1 ); + setup_postdata( get_post( $post1 ) ); + + $q = new WP_Query( array( + 'post__in' => array( $post2 ), + ) ); + if ( $q->have_posts() ) { + while ( $q->have_posts() ) { + $q->the_post(); + $this->assertSame( 'Post 2 Page 1', wp_trim_excerpt() ); + } + } + } + + /** + * @ticket 25349 + */ + public function test_secondary_loop_respect_nextpage() { + $post1 = $this->factory->post->create( array( + 'post_content' => 'Post 1 Page 1Post 1 Page 2', + ) ); + $post2 = $this->factory->post->create( array( + 'post_content' => 'Post 2 Page 1Post 2 Page 2', + ) ); + + $this->go_to( '/?p=' . $post1 ); + setup_postdata( get_post( $post1 ) ); + + $q = new WP_Query( array( + 'post__in' => array( $post2 ), + ) ); + if ( $q->have_posts() ) { + while ( $q->have_posts() ) { + $q->the_post(); + $this->assertSame( 'Post 2 Page 1', wp_trim_excerpt() ); + } + } + } +} diff --git tests/phpunit/tests/query.php tests/phpunit/tests/query.php index cf59d90..a6f68c2 100644 --- tests/phpunit/tests/query.php +++ tests/phpunit/tests/query.php @@ -15,62 +15,6 @@ class Tests_Query extends WP_UnitTestCase { } /** - * @ticket 16746 - */ - function test_nextpage_at_start_of_content() { - $post = $this->factory->post->create_and_get( array( 'post_content' => 'Page 1Page 2Page 3' ) ); - setup_postdata( $post ); - - $this->assertEquals( 1, $GLOBALS['multipage'] ); - $this->assertCount( 3, $GLOBALS['pages'] ); - $this->assertEquals( 3, $GLOBALS['numpages'] ); - $this->assertEquals( array( 'Page 1', 'Page 2', 'Page 3' ), $GLOBALS['pages'] ); - } - - function test_setup_postdata_single_page() { - $post = $this->factory->post->create_and_get( array( 'post_content' => 'Page 0' ) ); - setup_postdata( $post ); - - $this->assertEquals( 0, $GLOBALS['multipage'] ); - $this->assertCount( 1, $GLOBALS['pages'] ); - $this->assertEquals( 1, $GLOBALS['numpages'] ); - $this->assertEquals( array( 'Page 0' ), $GLOBALS['pages'] ); - } - - function test_setup_postdata_multi_page() { - $post = $this->factory->post->create_and_get( array( 'post_content' => 'Page 0Page 1Page 2Page 3' ) ); - setup_postdata( $post ); - - $this->assertEquals( 1, $GLOBALS['multipage'] ); - $this->assertCount( 4, $GLOBALS['pages'] ); - $this->assertEquals( 4, $GLOBALS['numpages'] ); - $this->assertEquals( array( 'Page 0', 'Page 1', 'Page 2', 'Page 3' ), $GLOBALS['pages'] ); - } - - /** - * @ticket 24330 - * - * setup_postdata( $a_post ) followed by the_content() in a loop that does not update - * global $post should use the content of $a_post rather then the global post. - */ - function test_setup_postdata_loop() { - $post_id = $this->factory->post->create( array( 'post_content' => 'global post' ) ); - $GLOBALS['wp_query']->post = $GLOBALS['post'] = get_post( $post_id ); - - $ids = $this->factory->post->create_many(5); - foreach ( $ids as $id ) { - $page = get_post( $id ); - if ( $page ) { - setup_postdata( $page ); - $content = get_echo( 'the_content', array() ); - $this->assertEquals( $post_id, $GLOBALS['post']->ID ); - $this->assertNotEquals( '
global post
', strip_ws( $content ) ); - wp_reset_postdata(); - } - } - } - - /** * @ticket 24785 * */ @@ -147,4 +91,4 @@ class Tests_Query extends WP_UnitTestCase { $this->assertCount( 1, $query->get( 'tag_slug__in' ) ); $this->assertEquals( $query->get_queried_object(), $tag ); } -} \ No newline at end of file +} diff --git tests/phpunit/tests/query/setupPostdata.php tests/phpunit/tests/query/setupPostdata.php new file mode 100644 index 0000000..1a8967c --- /dev/null +++ tests/phpunit/tests/query/setupPostdata.php @@ -0,0 +1,363 @@ +global_keys as $global_key ) { + if ( isset( $GLOBALS[ $global_key ] ) ) { + $this->global_data[ $global_key ] = $GLOBALS[ $global_key ]; + unset( $GLOBALS[ $global_key ] ); + } else { + $this->global_data[ $global_key ] = null; + } + } + } + + public function tearDown() { + parent::tearDown(); + return; + + foreach ( $this->global_keys as $global_key ) { + if ( ! is_null( $this->global_data[ $global_key ] ) ) { + $GLOBALS[ $global_key ] = $this->global_data[ $global_key ]; + } else { + unset( $GLOBALS[ $global_key ] ); + } + } + + $this->global_data = array(); + } + + public function test_id() { + $p = $this->factory->post->create_and_get(); + setup_postdata( $p ); + + $this->assertNotEmpty( $p->ID ); + $this->assertSame( $p->ID, $GLOBALS['id'] ); + } + + public function test_authordata() { + $u = $this->factory->user->create_and_get(); + $p = $this->factory->post->create_and_get( array( + 'post_author' => $u->ID, + ) ); + setup_postdata( $p ); + + $this->assertNotEmpty( $GLOBALS['authordata'] ); + $this->assertEquals( $u, $GLOBALS['authordata'] ); + } + + public function test_currentday() { + $p = $this->factory->post->create_and_get( array( + 'post_date' => '1980-09-09 06:30:00', + ) ); + setup_postdata( $p ); + + $this->assertSame( '09.09.80', $GLOBALS['currentday'] ); + } + + public function test_currentmonth() { + $p = $this->factory->post->create_and_get( array( + 'post_date' => '1980-09-09 06:30:00', + ) ); + setup_postdata( $p ); + + $this->assertSame( '09', $GLOBALS['currentmonth'] ); + } + + public function test_secondary_query_post_vars() { + $users = $this->factory->user->create_many( 2 ); + + $post1 = $this->factory->post->create_and_get( array( + 'post_author' => $users[0], + 'post_date' => '2012-02-02 02:00:00', + ) ); + + $post2 = $this->factory->post->create_and_get( array( + 'post_author' => $users[1], + 'post_date' => '2013-03-03 03:00:00', + ) ); + + $this->go_to( get_permalink( $post1 ) ); + setup_postdata( $post1 ); + + // Main loop. + $this->assertSame( $post1->ID, $GLOBALS['id'] ); + $this->assertEquals( get_userdata( $users[0] ), $GLOBALS['authordata'] ); + $this->assertSame( '02.02.12', $GLOBALS['currentday'] ); + $this->assertSame( '02', $GLOBALS['currentmonth'] ); + + // Secondary loop. + $q = new WP_Query( array( + 'posts_per_page' => 1, + ) ); + if ( $q->have_posts() ) { + while ( $q->have_posts() ) { + $q->the_post(); + + // Should refer to the current loop. + $this->assertSame( $post2->ID, $GLOBALS['id'] ); + $this->assertEquals( get_userdata( $users[1] ), $GLOBALS['authordata'] ); + $this->assertSame( '03.03.13', $GLOBALS['currentday'] ); + $this->assertSame( '03', $GLOBALS['currentmonth'] ); + } + } + wp_reset_postdata(); + + // Should be reset to main loop. + $this->assertSame( $post1->ID, $GLOBALS['id'] ); + $this->assertEquals( get_userdata( $users[0] ), $GLOBALS['authordata'] ); + $this->assertSame( '02.02.12', $GLOBALS['currentday'] ); + $this->assertSame( '02', $GLOBALS['currentmonth'] ); + } + + public function test_single_page() { + $post = $this->factory->post->create_and_get( array( + 'post_content' => 'Page 0', + ) ); + setup_postdata( $post ); + + $this->assertSame( 0, $GLOBALS['multipage'] ); + $this->assertSame( 1, $GLOBALS['numpages'] ); + $this->assertEquals( array( 'Page 0' ), $GLOBALS['pages'] ); + } + + public function test_multi_page() { + $post = $this->factory->post->create_and_get( array( + 'post_content' => 'Page 0Page 1Page 2Page 3', + ) ); + setup_postdata( $post ); + + $this->assertSame( 1, $GLOBALS['multipage'] ); + $this->assertSame( 4, $GLOBALS['numpages'] ); + $this->assertEquals( array( 'Page 0', 'Page 1', 'Page 2', 'Page 3' ), $GLOBALS['pages'] ); + } + + /** + * @ticket 16746 + */ + public function test_nextpage_at_start_of_content() { + $post = $this->factory->post->create_and_get( array( + 'post_content' => 'Page 1Page 2Page 3', + ) ); + setup_postdata( $post ); + + $this->assertSame( 1, $GLOBALS['multipage'] ); + $this->assertSame( 3, $GLOBALS['numpages'] ); + $this->assertEquals( array( 'Page 1', 'Page 2', 'Page 3' ), $GLOBALS['pages'] ); + } + + public function test_trim_nextpage_linebreaks() { + $post = $this->factory->post->create_and_get( array( + 'post_content' => "Page 0\n\nPage 1\nhas a line break\nPage 2\n\nPage 3", + ) ); + setup_postdata( $post ); + + $this->assertEquals( array( 'Page 0', "Page 1\nhas a line break", 'Page 2', "\nPage 3" ), $GLOBALS['pages'] ); + } + + /** + * @ticket 25349 + */ + public function test_secondary_query_nextpage() { + $post1 = $this->factory->post->create( array( + 'post_content' => 'Post 1 Page 1Post 1 Page 2', + ) ); + $post2 = $this->factory->post->create( array( + 'post_content' => 'Post 2 Page 1Post 2 Page 2', + ) ); + + $this->go_to( '/?p=' . $post1 ); + setup_postdata( get_post( $post1 ) ); + + // Main loop. + $this->assertSame( array( 'Post 1 Page 1', 'Post 1 Page 2' ), $GLOBALS['pages'] ); + + // Secondary loop. + $q = new WP_Query( array( + 'post__in' => array( $post2 ), + ) ); + if ( $q->have_posts() ) { + while ( $q->have_posts() ) { + $q->the_post(); + + // Should refer to the current loop. + $this->assertSame( array( 'Post 2 Page 1', 'Post 2 Page 2' ), $GLOBALS['pages'] ); + } + } + wp_reset_postdata(); + + // Should be reset to main loop. + $this->assertSame( array( 'Post 1 Page 1', 'Post 1 Page 2' ), $GLOBALS['pages'] ); + } + + public function test_page_from_wp_query() { + $page = $this->factory->post->create_and_get( array( + 'post_type' => 'page', + ) ); + + $this->go_to( '/?page=78' ); + + $GLOBALS['wp_query']->query_vars['page'] = 78; + setup_postdata( $page ); + + $this->assertSame( 78, $GLOBALS['page'] ); + } + + public function test_page_when_on_page() { + $page = $this->factory->post->create_and_get( array( + 'post_type' => 'page', + ) ); + $this->go_to( get_permalink( $page ) ); + setup_postdata( $page ); + + $this->assertSame( 1, $GLOBALS['page'] ); + } + + /** + * @ticket 20904 + */ + public function test_secondary_query_page() { + $post = $this->factory->post->create_and_get(); + $this->go_to( '/?page=3' ); + setup_postdata( $post ); + + // Main loop. + $this->assertSame( 3, $GLOBALS['page'] ); + + // Secondary loop. + $posts = $this->factory->post->create_many( 5 ); + $q = new WP_Query( array( + 'page' => 4, + 'posts_per_page' => 1, + ) ); + if ( $q->have_posts() ) { + while ( $q->have_posts() ) { + $q->the_post(); + + // $page should refer to the current loop. + $this->assertSame( 4, $GLOBALS['page'] ); + } + } + wp_reset_postdata(); + + // $page should be reset to main loop. + $this->assertSame( 3, $GLOBALS['page'] ); + } + + /** + * @ticket 20904 + */ + public function test_more_when_on_setup_post() { + $post = $this->factory->post->create_and_get(); + $this->go_to( get_permalink( $post ) ); + setup_postdata( $post ); + + $this->assertSame( 1, $GLOBALS['more'] ); + } + + /** + * @ticket 20904 + * + * $more should not be true when the set-up post is not the same as the current post. + */ + public function test_more_when_on_single() { + $post1 = $this->factory->post->create_and_get(); + $post2 = $this->factory->post->create_and_get(); + $this->go_to( get_permalink( $post1 ) ); + setup_postdata( $post2 ); + + $this->assertTrue( empty( $GLOBALS['more'] ) ); + } + + /** + * @ticket 20904 + * + * $more should not be true when the set-up post is not the same as the current page. + */ + public function test_more_when_on_page() { + $post = $this->factory->post->create_and_get(); + $page = $this->factory->post->create_and_get( array( + 'post_type' => 'page', + ) ); + $this->go_to( get_permalink( $page ) ); + setup_postdata( $post ); + + $this->assertTrue( empty( $GLOBALS['more'] ) ); + } + + /** + * @ticket 20904 + */ + public function test_more_when_on_feed() { + $post = $this->factory->post->create_and_get(); + $this->go_to( '/?feed=rss' ); + setup_postdata( $post ); + + $this->assertSame( 1, $GLOBALS['more'] ); + } + + /** + * @ticket 20904 + * @ticket 25349 + */ + public function test_secondary_query_more() { + $post = $this->factory->post->create_and_get(); + $this->go_to( get_permalink( $post ) ); + setup_postdata( $post ); + + // Main loop. + $this->assertSame( 1, $GLOBALS['more'] ); + + // Secondary loop. + $q = new WP_Query( array( + 'posts_per_page' => 1, + ) ); + if ( $q->have_posts() ) { + while ( $q->have_posts() ) { + $q->the_post(); + + // $more should refer to the current loop. + $this->assertTrue( empty( $GLOBALS['more'] ) ); + } + } + wp_reset_postdata(); + + // $page should be reset to main loop. + $this->assertSame( 1, $GLOBALS['more'] ); + } + + /** + * @ticket 24330 + * + * setup_postdata( $a_post ) followed by the_content() in a loop that does not update + * global $post should use the content of $a_post rather then the global post. + */ + function test_setup_postdata_loop() { + $post_id = $this->factory->post->create( array( 'post_content' => 'global post' ) ); + $GLOBALS['wp_query']->post = $GLOBALS['post'] = get_post( $post_id ); + + $ids = $this->factory->post->create_many(5); + foreach ( $ids as $id ) { + $page = get_post( $id ); + if ( $page ) { + setup_postdata( $page ); + $content = get_echo( 'the_content', array() ); + $this->assertEquals( $post_id, $GLOBALS['post']->ID ); + $this->assertNotEquals( 'global post
', strip_ws( $content ) ); + wp_reset_postdata(); + } + } + } + +}