Make WordPress Core

Changeset 30085


Ignore:
Timestamp:
10/29/2014 02:31:37 AM (10 years ago)
Author:
boonebgorges
Message:

Improve global variable setting in setup_postdata().

setup_postdata() is responsible for setting a number of global variables
that are used for post pagination ($pages, $page, $nextpage) and the
generation of post excerpts ($more). These variables should be sensitive to
the currently running instance of WP_Query - rather than the main query -
so that these features work properly inside of secondary WP_Query loops.

This changeset moves the logic of setup_postdata() into a method on WP_Query,
and converts setup_postdata() to a wrapper.

Props boonebgorges, wonderboymusic.
See #25349.
Fixes #9256, #20904.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/query.php

    r29912 r30085  
    37113711
    37123712        $post = $this->next_post();
    3713         setup_postdata($post);
     3713        $this->setup_postdata( $post );
    37143714    }
    37153715
     
    45464546
    45474547    /**
     4548     * Set up global post data.
     4549     *
     4550     * @since 4.1.0
     4551     *
     4552     * @param object $post Post data.
     4553     * @return bool True when finished.
     4554     */
     4555    public function setup_postdata( $post ) {
     4556        global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
     4557
     4558        $id = (int) $post->ID;
     4559
     4560        $authordata = get_userdata($post->post_author);
     4561
     4562        $currentday = mysql2date('d.m.y', $post->post_date, false);
     4563        $currentmonth = mysql2date('m', $post->post_date, false);
     4564        $numpages = 1;
     4565        $multipage = 0;
     4566        $page = $this->get( 'page' );
     4567        if ( ! $page )
     4568            $page = 1;
     4569
     4570        // Force full post content when viewing the permalink for the $post, or
     4571        // when on an RSS feed. Otherwise respect the 'more' tag.
     4572        if ( $post->ID === get_queried_object_id() && ( $this->is_page() || $this->is_single() ) ) {
     4573            $more = 1;
     4574        } else if ( $this->is_feed() ) {
     4575            $more = 1;
     4576        } else {
     4577            $more = 0;
     4578        }
     4579
     4580        $content = $post->post_content;
     4581        if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
     4582            if ( $page > 1 )
     4583                $more = 1;
     4584            $content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
     4585            $content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
     4586            $content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
     4587            // Ignore nextpage at the beginning of the content.
     4588            if ( 0 === strpos( $content, '<!--nextpage-->' ) )
     4589                $content = substr( $content, 15 );
     4590            $pages = explode('<!--nextpage-->', $content);
     4591            $numpages = count($pages);
     4592            if ( $numpages > 1 )
     4593                $multipage = 1;
     4594        } else {
     4595            $pages = array( $post->post_content );
     4596        }
     4597
     4598        /**
     4599         * Fires once the post data has been setup.
     4600         *
     4601         * @since 2.8.0
     4602         *
     4603         * @param WP_Post &$post The Post object (passed by reference).
     4604         */
     4605        do_action_ref_array( 'the_post', array( &$post ) );
     4606
     4607        return true;
     4608    }
     4609    /**
    45484610     * After looping through a nested query, this function
    45494611     * restores the $post global to the current post in this query.
     
    46314693 */
    46324694function setup_postdata( $post ) {
    4633     global $id, $authordata, $currentday, $currentmonth, $page, $pages, $multipage, $more, $numpages;
    4634 
    4635     $id = (int) $post->ID;
    4636 
    4637     $authordata = get_userdata($post->post_author);
    4638 
    4639     $currentday = mysql2date('d.m.y', $post->post_date, false);
    4640     $currentmonth = mysql2date('m', $post->post_date, false);
    4641     $numpages = 1;
    4642     $multipage = 0;
    4643     $page = get_query_var('page');
    4644     if ( ! $page )
    4645         $page = 1;
    4646     if ( is_single() || is_page() || is_feed() )
    4647         $more = 1;
    4648     $content = $post->post_content;
    4649     if ( false !== strpos( $content, '<!--nextpage-->' ) ) {
    4650         if ( $page > 1 )
    4651             $more = 1;
    4652         $content = str_replace( "\n<!--nextpage-->\n", '<!--nextpage-->', $content );
    4653         $content = str_replace( "\n<!--nextpage-->", '<!--nextpage-->', $content );
    4654         $content = str_replace( "<!--nextpage-->\n", '<!--nextpage-->', $content );
    4655         // Ignore nextpage at the beginning of the content.
    4656         if ( 0 === strpos( $content, '<!--nextpage-->' ) )
    4657             $content = substr( $content, 15 );
    4658         $pages = explode('<!--nextpage-->', $content);
    4659         $numpages = count($pages);
    4660         if ( $numpages > 1 )
    4661             $multipage = 1;
    4662     } else {
    4663         $pages = array( $post->post_content );
    4664     }
    4665 
    4666     /**
    4667      * Fires once the post data has been setup.
    4668      *
    4669      * @since 2.8.0
    4670      *
    4671      * @param WP_Post &$post The Post object (passed by reference).
    4672      */
    4673     do_action_ref_array( 'the_post', array( &$post ) );
    4674 
    4675     return true;
     4695    global $wp_query;
     4696
     4697    if ( ! empty( $wp_query ) && $wp_query instanceof WP_Query ) {
     4698        return $wp_query->setup_postdata( $post );
     4699    }
     4700
     4701    return false;
    46764702}
  • trunk/tests/phpunit/tests/query.php

    r28967 r30085  
    1313
    1414        $wp_rewrite->flush_rules();
    15     }
    16 
    17     /**
    18      * @ticket 16746
    19      */
    20     function test_nextpage_at_start_of_content() {
    21         $post = $this->factory->post->create_and_get( array( 'post_content' => '<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3' ) );
    22         setup_postdata( $post );
    23 
    24         $this->assertEquals( 1, $GLOBALS['multipage'] );
    25         $this->assertCount(  3, $GLOBALS['pages']     );
    26         $this->assertEquals( 3, $GLOBALS['numpages']  );
    27         $this->assertEquals( array( 'Page 1', 'Page 2', 'Page 3' ), $GLOBALS['pages'] );
    28     }
    29 
    30     function test_setup_postdata_single_page() {
    31         $post = $this->factory->post->create_and_get( array( 'post_content' => 'Page 0' ) );
    32         setup_postdata( $post );
    33 
    34         $this->assertEquals( 0, $GLOBALS['multipage'] );
    35         $this->assertCount(  1, $GLOBALS['pages']     );
    36         $this->assertEquals( 1, $GLOBALS['numpages']  );
    37         $this->assertEquals( array( 'Page 0' ), $GLOBALS['pages'] );
    38     }
    39 
    40     function test_setup_postdata_multi_page() {
    41         $post = $this->factory->post->create_and_get( array( 'post_content' => 'Page 0<!--nextpage-->Page 1<!--nextpage-->Page 2<!--nextpage-->Page 3' ) );
    42         setup_postdata( $post );
    43 
    44         $this->assertEquals( 1, $GLOBALS['multipage'] );
    45         $this->assertCount(  4, $GLOBALS['pages']     );
    46         $this->assertEquals( 4, $GLOBALS['numpages']  );
    47         $this->assertEquals( array( 'Page 0', 'Page 1', 'Page 2', 'Page 3' ), $GLOBALS['pages'] );
    48     }
    49 
    50     /**
    51      * @ticket 24330
    52      *
    53      * setup_postdata( $a_post ) followed by the_content() in a loop that does not update
    54      * global $post should use the content of $a_post rather then the global post.
    55      */
    56     function test_setup_postdata_loop() {
    57         $post_id = $this->factory->post->create( array( 'post_content' => 'global post' ) );
    58         $GLOBALS['wp_query']->post = $GLOBALS['post'] = get_post( $post_id );
    59 
    60         $ids = $this->factory->post->create_many(5);
    61         foreach ( $ids as $id ) {
    62             $page = get_post( $id );
    63             if ( $page ) {
    64                 setup_postdata( $page );
    65                 $content = get_echo( 'the_content', array() );
    66                 $this->assertEquals( $post_id, $GLOBALS['post']->ID );
    67                 $this->assertNotEquals( '<p>global post</p>', strip_ws( $content ) );
    68                 wp_reset_postdata();
    69             }
    70         }
    7115    }
    7216
Note: See TracChangeset for help on using the changeset viewer.